diff --git a/CREDITS b/CREDITS
index 7fb4c73..192f749 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1097,7 +1097,7 @@ S: 80050-430 - Curitiba - Paraná
 S: Brazil
 
 N: Kumar Gala
-E: kumar.gala@freescale.com
+E: galak@kernel.crashing.org
 D: Embedded PowerPC 6xx/7xx/74xx/82xx/83xx/85xx support
 S: Austin, Texas 78729
 S: USA
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 7018f5c..1c95588 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -20,6 +20,12 @@ DOCBOOKS := wanbook.xml z8530book.xml mc
 #                        +--> DIR=file  (htmldocs)
 #                        +--> man/      (mandocs)
 
+
+# for PDF and PS output you can choose between xmlto and docbook-utils tools
+PDF_METHOD	= $(prefer-db2x)
+PS_METHOD	= $(prefer-db2x)
+
+
 ###
 # The targets that may be used.
 .PHONY:	xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs
@@ -93,27 +99,39 @@ C-procfs-example = procfs_example.xml
 C-procfs-example2 = $(addprefix $(obj)/,$(C-procfs-example))
 $(obj)/procfs-guide.xml: $(C-procfs-example2)
 
-###
-# Rules to generate postscript, PDF and HTML
-# db2html creates a directory. Generate a html file used for timestamp
+notfoundtemplate = echo "*** You have to install docbook-utils or xmlto ***"; \
+		   exit 1
+db2xtemplate = db2TYPE -o $(dir $@) $<
+xmltotemplate = xmlto TYPE $(XMLTOFLAGS) -o $(dir $@) $<
+
+# determine which methods are available
+ifeq ($(shell which db2ps >/dev/null 2>&1 && echo found),found)
+	use-db2x = db2x
+	prefer-db2x = db2x
+else
+	use-db2x = notfound
+	prefer-db2x = $(use-xmlto)
+endif
+ifeq ($(shell which xmlto >/dev/null 2>&1 && echo found),found)
+	use-xmlto = xmlto
+	prefer-xmlto = xmlto
+else
+	use-xmlto = notfound
+	prefer-xmlto = $(use-db2x)
+endif
 
-quiet_cmd_db2ps = XMLTO    $@
-      cmd_db2ps = xmlto ps $(XMLTOFLAGS) -o $(dir $@) $<
+# the commands, generated from the chosen template
+quiet_cmd_db2ps = PS      $@
+      cmd_db2ps = $(subst TYPE,ps, $($(PS_METHOD)template))
 %.ps : %.xml
-	@(which xmlto > /dev/null 2>&1) || \
-	 (echo "*** You need to install xmlto ***"; \
-	  exit 1)
 	$(call cmd,db2ps)
 
-quiet_cmd_db2pdf = XMLTO   $@
-      cmd_db2pdf = xmlto pdf $(XMLTOFLAGS) -o $(dir $@) $<
+quiet_cmd_db2pdf = PDF      $@
+      cmd_db2pdf = $(subst TYPE,pdf, $($(PDF_METHOD)template))
 %.pdf : %.xml
-	@(which xmlto > /dev/null 2>&1) || \
-	 (echo "*** You need to install xmlto ***"; \
-	  exit 1)
 	$(call cmd,db2pdf)
 
-quiet_cmd_db2html = XMLTO  $@
+quiet_cmd_db2html = HTML   $@
       cmd_db2html = xmlto xhtml $(XMLTOFLAGS) -o $(patsubst %.html,%,$@) $< && \
 		echo '<a HREF="$(patsubst %.html,%,$(notdir $@))/index.html"> \
          Goto $(patsubst %.html,%,$(notdir $@))</a><p>' > $@
@@ -127,7 +145,7 @@ quiet_cmd_db2html = XMLTO  $@
 	@if [ ! -z "$(PNG-$(basename $(notdir $@)))" ]; then \
             cp $(PNG-$(basename $(notdir $@))) $(patsubst %.html,%,$@); fi
 
-quiet_cmd_db2man = XMLTO   $@
+quiet_cmd_db2man = MAN     $@
       cmd_db2man = if grep -q refentry $<; then xmlto man $(XMLTOFLAGS) -o $(obj)/man $< ; gzip -f $(obj)/man/*.9; fi
 %.9 : %.xml
 	@(which xmlto > /dev/null 2>&1) || \
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index a8316b1..096aed6 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -68,9 +68,7 @@ X!Iinclude/linux/kobject.h
 
      <sect1><title>Kernel utility functions</title>
 !Iinclude/linux/kernel.h
-<!-- This needs to clean up to make kernel-doc happy
-X!Ekernel/printk.c
- -->
+!Ekernel/printk.c
 !Ekernel/panic.c
 !Ekernel/sys.c
 !Ekernel/rcupdate.c
@@ -388,7 +386,7 @@ X!Edrivers/pnp/system.c
 
   <chapter id="blkdev">
      <title>Block Devices</title>
-!Edrivers/block/ll_rw_blk.c
+!Eblock/ll_rw_blk.c
   </chapter>
 
   <chapter id="miscdev">
diff --git a/Documentation/DocBook/stylesheet.xsl b/Documentation/DocBook/stylesheet.xsl
index 64be9f7..3ccce88 100644
--- a/Documentation/DocBook/stylesheet.xsl
+++ b/Documentation/DocBook/stylesheet.xsl
@@ -3,4 +3,5 @@
 <param name="chunk.quietly">1</param>
 <param name="funcsynopsis.style">ansi</param>
 <param name="funcsynopsis.tabular.threshold">80</param>
+<!-- <param name="paper.type">A4</param> -->
 </stylesheet>
diff --git a/Documentation/atomic_ops.txt b/Documentation/atomic_ops.txt
index 8eedaa2..23a1c24 100644
--- a/Documentation/atomic_ops.txt
+++ b/Documentation/atomic_ops.txt
@@ -115,6 +115,33 @@ boolean is return which indicates whethe
 is negative.  It requires explicit memory barrier semantics around the
 operation.
 
+Then:
+
+	int atomic_cmpxchg(atomic_t *v, int old, int new);
+
+This performs an atomic compare exchange operation on the atomic value v,
+with the given old and new values. Like all atomic_xxx operations,
+atomic_cmpxchg will only satisfy its atomicity semantics as long as all
+other accesses of *v are performed through atomic_xxx operations.
+
+atomic_cmpxchg requires explicit memory barriers around the operation.
+
+The semantics for atomic_cmpxchg are the same as those defined for 'cas'
+below.
+
+Finally:
+
+	int atomic_add_unless(atomic_t *v, int a, int u);
+
+If the atomic value v is not equal to u, this function adds a to v, and
+returns non zero. If v is equal to u then it returns zero. This is done as
+an atomic operation.
+
+atomic_add_unless requires explicit memory barriers around the operation.
+
+atomic_inc_not_zero, equivalent to atomic_add_unless(v, 1, 0)
+
+
 If a caller requires memory barrier semantics around an atomic_t
 operation which does not return a value, a set of interfaces are
 defined which accomplish this:
diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
index 2d65c21..0fe01c8 100644
--- a/Documentation/block/biodoc.txt
+++ b/Documentation/block/biodoc.txt
@@ -1063,8 +1063,8 @@ Aside:
 4.4 I/O contexts
 I/O contexts provide a dynamically allocated per process data area. They may
 be used in I/O schedulers, and in the block layer (could be used for IO statis,
-priorities for example). See *io_context in drivers/block/ll_rw_blk.c, and
-as-iosched.c for an example of usage in an i/o scheduler.
+priorities for example). See *io_context in block/ll_rw_blk.c, and as-iosched.c
+for an example of usage in an i/o scheduler.
 
 
 5. Scalability related changes
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 429db4b..24fe8ed 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -140,3 +140,12 @@ What:	EXPORT_SYMBOL(lookup_hash)
 When:	January 2006
 Why:	Too low-level interface.  Use lookup_one_len or lookup_create instead.
 Who:	Christoph Hellwig <hch@lst.de>
+
+---------------------------
+
+What:	START_ARRAY ioctl for md
+When:	July 2006
+Files:	drivers/md/md.c
+Why:	Not reliable by design - can fail when most needed.
+	Alternatives exist
+Who:	NeilBrown <neilb@suse.de>
diff --git a/Documentation/oops-tracing.txt b/Documentation/oops-tracing.txt
index c563842..05960f8 100644
--- a/Documentation/oops-tracing.txt
+++ b/Documentation/oops-tracing.txt
@@ -30,7 +30,12 @@ the disk is not available then you have 
 
 (1) Hand copy the text from the screen and type it in after the machine
     has restarted.  Messy but it is the only option if you have not
-    planned for a crash.
+    planned for a crash. Alternatively, you can take a picture of
+    the screen with a digital camera - not nice, but better than
+    nothing.  If the messages scroll off the top of the console, you
+    may find that booting with a higher resolution (eg, vga=791)
+    will allow you to read more of the text. (Caveat: This needs vesafb,
+    so won't help for 'early' oopses)
 
 (2) Boot with a serial console (see Documentation/serial-console.txt),
     run a null modem to a second machine and capture the output there
diff --git a/Documentation/video4linux/CARDLIST.bttv b/Documentation/video4linux/CARDLIST.bttv
index 2404099..330246a 100644
--- a/Documentation/video4linux/CARDLIST.bttv
+++ b/Documentation/video4linux/CARDLIST.bttv
@@ -140,3 +140,4 @@
 139 -> Prolink PixelView PlayTV MPEG2 PV-M4900
 140 -> Osprey 440                                          [0070:ff07]
 141 -> Asound Skyeye PCTV
+142 -> Sabrent TV-FM (bttv version)
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 57c9d63..efb708e 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -80,3 +80,5 @@
  79 -> Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)
  80 -> ASUS Digimatrix TV                       [1043:0210]
  81 -> Philips Tiger reference design           [1131:2018]
+ 82 -> MSI TV@Anywhere plus                     [1462:6231]
+
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index ec840ca..9d6544e 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -67,3 +67,4 @@ tuner=65 - Ymec TVF66T5-B/DFF
 tuner=66 - LG NTSC (TALN mini series)
 tuner=67 - Philips TD1316 Hybrid Tuner
 tuner=68 - Philips TUV1236D ATSC/NTSC dual in
+tuner=69 - Tena TNF 5335 MF
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt
index ffe1c06..e566aff 100644
--- a/Documentation/x86_64/boot-options.txt
+++ b/Documentation/x86_64/boot-options.txt
@@ -7,10 +7,12 @@ Machine check
 
    mce=off disable machine check
    mce=bootlog Enable logging of machine checks left over from booting.
-               Disabled by default because some BIOS leave bogus ones.
+               Disabled by default on AMD because some BIOS leave bogus ones.
                If your BIOS doesn't do that it's a good idea to enable though
                to make sure you log even machine check events that result
-               in a reboot.
+               in a reboot. On Intel systems it is enabled by default.
+   mce=nobootlog
+		Disable boot machine check logging.
    mce=tolerancelevel (number)
 		0: always panic, 1: panic if deadlock possible,
 		2: try to avoid panic, 3: never panic or exit (for testing)
@@ -122,6 +124,9 @@ SMP
 
   cpumask=MASK   only use cpus with bits set in mask
 
+  additional_cpus=NUM Allow NUM more CPUs for hotplug
+		 (defaults are specified by the BIOS or half the available CPUs)
+
 NUMA
 
   numa=off	Only set up a single NUMA node spanning all memory.
@@ -188,6 +193,9 @@ Debugging
 
   kstack=N   Print that many words from the kernel stack in oops dumps.
 
+  pagefaulttrace Dump all page faults. Only useful for extreme debugging
+		and will create a lot of output.
+
 Misc
 
   noreplacement  Don't replace instructions with more appropiate ones
diff --git a/Documentation/x86_64/mm.txt b/Documentation/x86_64/mm.txt
index 662b739..133561b 100644
--- a/Documentation/x86_64/mm.txt
+++ b/Documentation/x86_64/mm.txt
@@ -6,7 +6,7 @@ Virtual memory map with 4 level page tab
 0000000000000000 - 00007fffffffffff (=47bits) user space, different per mm
 hole caused by [48:63] sign extension
 ffff800000000000 - ffff80ffffffffff (=40bits) guard hole
-ffff810000000000 - ffffc0ffffffffff (=46bits) direct mapping of phys. memory
+ffff810000000000 - ffffc0ffffffffff (=46bits) direct mapping of all phys. memory
 ffffc10000000000 - ffffc1ffffffffff (=40bits) hole
 ffffc20000000000 - ffffe1ffffffffff (=45bits) vmalloc/ioremap space
 ... unused hole ...
@@ -14,6 +14,10 @@ ffffffff80000000 - ffffffff82800000 (=40
 ... unused hole ...
 ffffffff88000000 - fffffffffff00000 (=1919MB) module mapping space
 
+The direct mapping covers all memory in the system upto the highest
+memory address (this means in some cases it can also include PCI memory
+holes)
+
 vmalloc space is lazily synchronized into the different PML4 pages of
 the processes using the page fault handler, with init_level4_pgt as
 reference.
diff --git a/MAINTAINERS b/MAINTAINERS
index 2313de2..509927e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1565,7 +1565,7 @@ S:	Maintained
 
 LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX
 P:     Kumar Gala
-M:     kumar.gala@freescale.com
+M:     galak@kernel.crashing.org
 W:     http://www.penguinppc.org/
 L:     linuxppc-embedded@ozlabs.org
 S:     Maintained
@@ -1873,6 +1873,16 @@ L:	linux-tr@linuxtr.net
 W:	http://www.linuxtr.net
 S:	Maintained
 
+OMNIKEY CARDMAN 4000 DRIVER
+P:	Harald Welte
+M:	laforge@gnumonks.org
+S:	Maintained
+
+OMNIKEY CARDMAN 4040 DRIVER
+P:	Harald Welte
+M:	laforge@gnumonks.org
+S:	Maintained
+
 ONSTREAM SCSI TAPE DRIVER
 P:	Willem Riede
 M:	osst@riede.org
diff --git a/Makefile b/Makefile
index 8560b79..bfcd77b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 15
-EXTRAVERSION =-rc1
+EXTRAVERSION = -rc1-git4
 NAME=Affluent Albatross
 
 # *DOCUMENTATION*
@@ -1193,6 +1193,17 @@ else
 __srctree = $(srctree)/
 endif
 
+ifeq ($(ALLSOURCE_ARCHS),)
+ifeq ($(ARCH),um)
+ALLINCLUDE_ARCHS := $(ARCH) $(SUBARCH)
+else
+ALLINCLUDE_ARCHS := $(ARCH)
+endif
+else
+#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behaviour.
+ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS)
+endif
+
 ALLSOURCE_ARCHS := $(ARCH)
 
 define all-sources
@@ -1208,7 +1219,7 @@ define all-sources
 	  find $(__srctree)include $(RCS_FIND_IGNORE) \
 	       \( -name config -o -name 'asm-*' \) -prune \
 	       -o -name '*.[chS]' -print; \
-	  for ARCH in $(ALLSOURCE_ARCHS) ; do \
+	  for ARCH in $(ALLINCLUDE_ARCHS) ; do \
 	       find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \
 	            -name '*.[chS]' -print; \
 	  done ; \
diff --git a/README b/README
index 4ee7dda..61c4f74 100644
--- a/README
+++ b/README
@@ -81,6 +81,11 @@ INSTALLING the kernel:
    failed patches (xxx# or xxx.rej). If there are, either you or me has
    made a mistake.
 
+   Unlike patches for the 2.6.x kernels, patches for the 2.6.x.y kernels
+   (also known as the -stable kernels) are not incremental but instead apply
+   directly to the base 2.6.x kernel.  Please read
+   Documentation/applying-patches.txt for more information.
+
    Alternatively, the script patch-kernel can be used to automate this
    process.  It determines the current kernel version and applies any
    patches found.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3df7cbd..4b15f5f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -652,25 +652,11 @@ endmenu
 
 menu "Power management options"
 
-config PM
-	bool "Power Management support"
-	---help---
-	  "Power Management" means that parts of your computer are shut
-	  off or put into a power conserving "sleep" mode if they are not
-	  being used.  There are two competing standards for doing this: APM
-	  and ACPI.  If you want to use either one, say Y here and then also
-	  to the requisite support below.
-
-	  Power Management is most important for battery powered laptop
-	  computers; if you have a laptop, check out the Linux Laptop home
-	  page on the WWW at <http://www.linux-on-laptops.com/> or
-	  Tuxmobil - Linux on Mobile Computers at <http://www.tuxmobil.org/>
-	  and the Battery Powered Linux mini-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
+source "kernel/power/Kconfig"
 
 config APM
 	tristate "Advanced Power Management Emulation"
-	depends on PM
+	depends on PM_LEGACY
 	---help---
 	  APM is a BIOS specification for saving power using several different
 	  techniques. This is mostly useful for battery powered laptops with
@@ -702,6 +688,8 @@ menu "Device Drivers"
 
 source "drivers/base/Kconfig"
 
+source "drivers/connector/Kconfig"
+
 if ALIGNMENT_TRAP
 source "drivers/mtd/Kconfig"
 endif
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index 557e52c..1b7eaab 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -623,8 +623,6 @@ static int locomo_resume(struct platform
 	locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD);
 
 	spin_unlock_irqrestore(&lchip->lock, flags);
-
-	dev->power.saved_state = NULL;
 	kfree(save);
 
 	return 0;
@@ -775,7 +773,7 @@ static int locomo_probe(struct platform_
 
 static int locomo_remove(struct platform_device *dev)
 {
-	struct locomo *lchip = platform__get_drvdata(dev);
+	struct locomo *lchip = platform_get_drvdata(dev);
 
 	if (lchip) {
 		__locomo_remove(lchip);
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 7b07acb..39a6eea 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -1266,7 +1266,7 @@ static void __exit sa1111_exit(void)
 	bus_unregister(&sa1111_bus_type);
 }
 
-module_init(sa1111_init);
+subsys_initcall(sa1111_init);
 module_exit(sa1111_exit);
 
 MODULE_DESCRIPTION("Intel Corporation SA1111 core driver");
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index 32924c6..0c3cbd9 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -153,7 +153,7 @@ int __init scoop_probe(struct platform_d
 	printk("Sharp Scoop Device found at 0x%08x -> 0x%08x\n",(unsigned int)mem->start,(unsigned int)devptr->base);
 
 	SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140;
-	reset_scoop(dev);
+	reset_scoop(&pdev->dev);
 	SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff;
 	SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff;
 
diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c
index b0bbd1e..a2843be 100644
--- a/arch/arm/kernel/apm.c
+++ b/arch/arm/kernel/apm.c
@@ -20,6 +20,7 @@
 #include <linux/apm_bios.h>
 #include <linux/sched.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index e55ea95..373c095 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -256,9 +256,7 @@ void __cpuexit cpu_die(void)
 asmlinkage void __cpuinit secondary_start_kernel(void)
 {
 	struct mm_struct *mm = &init_mm;
-	unsigned int cpu;
-
-	cpu = smp_processor_id();
+	unsigned int cpu = smp_processor_id();
 
 	printk("CPU%u: Booted secondary processor\n", cpu);
 
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
index dc09fd2..bbe6e4a 100644
--- a/arch/arm/mach-footbridge/common.c
+++ b/arch/arm/mach-footbridge/common.c
@@ -132,14 +132,14 @@ void __init footbridge_init_irq(void)
 static struct map_desc fb_common_io_desc[] __initdata = {
 	{
 		.virtual	= ARMCSR_BASE,
-		.pfn		= DC21285_ARMCSR_BASE,
+		.pfn		= __phys_to_pfn(DC21285_ARMCSR_BASE),
 		.length		= ARMCSR_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= XBUS_BASE,
 		.pfn		= __phys_to_pfn(0x40000000),
 		.length		= XBUS_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_DEVICE,
 	}
 };
 
@@ -153,28 +153,28 @@ static struct map_desc ebsa285_host_io_d
 		.virtual	= PCIMEM_BASE,
 		.pfn		= __phys_to_pfn(DC21285_PCI_MEM),
 		.length		= PCIMEM_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= PCICFG0_BASE,
 		.pfn		= __phys_to_pfn(DC21285_PCI_TYPE_0_CONFIG),
 		.length		= PCICFG0_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= PCICFG1_BASE,
 		.pfn		= __phys_to_pfn(DC21285_PCI_TYPE_1_CONFIG),
 		.length		= PCICFG1_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= PCIIACK_BASE,
 		.pfn		= __phys_to_pfn(DC21285_PCI_IACK),
 		.length		= PCIIACK_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= PCIO_BASE,
 		.pfn		= __phys_to_pfn(DC21285_PCI_IO),
 		.length		= PCIO_SIZE,
-		.type		= MT_DEVICE
-	}
+		.type		= MT_DEVICE,
+	},
 #endif
 };
 
@@ -187,13 +187,13 @@ static struct map_desc co285_io_desc[] _
 		.virtual	= PCIO_BASE,
 		.pfn		= __phys_to_pfn(DC21285_PCI_IO),
 		.length		= PCIO_SIZE,
-		.type		= MT_DEVICE
+		.type		= MT_DEVICE,
 	}, {
 		.virtual	= PCIMEM_BASE,
 		.pfn		= __phys_to_pfn(DC21285_PCI_MEM),
 		.length		= PCIMEM_SIZE,
-		.type		= MT_DEVICE
-	}
+		.type		= MT_DEVICE,
+	},
 #endif
 };
 
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index e201aa9..cd50664 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -72,6 +72,12 @@ config MACH_HUSKY
 	depends PXA_SHARPSL_25x
 	select PXA_SHARP_C7xx
 
+config MACH_AKITA
+	bool "Enable Sharp SL-1000 (Akita) Support"
+	depends PXA_SHARPSL_27x
+	select PXA_SHARP_Cxx00
+	select MACH_SPITZ
+
 config MACH_SPITZ
 	bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
 	depends PXA_SHARPSL_27x
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
index d210bd5..32526a0 100644
--- a/arch/arm/mach-pxa/Makefile
+++ b/arch/arm/mach-pxa/Makefile
@@ -11,8 +11,9 @@ obj-$(CONFIG_PXA27x) += pxa27x.o
 obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
 obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
 obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
-obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o corgi_ssp.o corgi_lcd.o
-obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o corgi_ssp.o corgi_lcd.o
+obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o
+obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
+obj-$(CONFIG_MACH_AKITA)	+= akita-ioexp.o
 obj-$(CONFIG_MACH_POODLE)	+= poodle.o
 obj-$(CONFIG_MACH_TOSA)         += tosa.o
 
diff --git a/arch/arm/mach-pxa/akita-ioexp.c b/arch/arm/mach-pxa/akita-ioexp.c
new file mode 100644
index 0000000..f6d73cc
--- /dev/null
+++ b/arch/arm/mach-pxa/akita-ioexp.c
@@ -0,0 +1,223 @@
+/*
+ * Support for the Extra GPIOs on the Sharp SL-C1000 (Akita)
+ * (uses a Maxim MAX7310 8 Port IO Expander)
+ *
+ * Copyright 2005 Openedhand Ltd.
+ *
+ * Author: Richard Purdie <richard@openedhand.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <asm/arch/akita.h>
+
+/* MAX7310 Regiser Map */
+#define MAX7310_INPUT    0x00
+#define MAX7310_OUTPUT   0x01
+#define MAX7310_POLINV   0x02
+#define MAX7310_IODIR    0x03 /* 1 = Input, 0 = Output */
+#define MAX7310_TIMEOUT  0x04
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x18, I2C_CLIENT_END };
+
+/* I2C Magic */
+I2C_CLIENT_INSMOD;
+
+static int max7310_write(struct i2c_client *client, int address, int data);
+static struct i2c_client max7310_template;
+static void akita_ioexp_work(void *private_);
+
+static struct device *akita_ioexp_device;
+static unsigned char ioexp_output_value = AKITA_IOEXP_IO_OUT;
+DECLARE_WORK(akita_ioexp, akita_ioexp_work, NULL);
+
+
+/*
+ * MAX7310 Access
+ */
+static int max7310_config(struct device *dev, int iomode, int polarity)
+{
+	int ret;
+	struct i2c_client *client = to_i2c_client(dev);
+
+	ret = max7310_write(client, MAX7310_POLINV, polarity);
+	if (ret < 0)
+		return ret;
+	ret = max7310_write(client, MAX7310_IODIR, iomode);
+	return ret;
+}
+
+static int max7310_set_ouputs(struct device *dev, int outputs)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+
+	return max7310_write(client, MAX7310_OUTPUT, outputs);
+}
+
+/*
+ * I2C Functions
+ */
+static int max7310_write(struct i2c_client *client, int address, int value)
+{
+	u8 data[2];
+
+	data[0] = address & 0xff;
+	data[1] = value & 0xff;
+
+	if (i2c_master_send(client, data, 2) == 2)
+		return 0;
+	return -1;
+}
+
+static int max7310_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	int err;
+
+	if (!(new_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL)))
+		return -ENOMEM;
+
+	max7310_template.adapter = adapter;
+	max7310_template.addr = address;
+
+	memcpy(new_client, &max7310_template, sizeof(struct i2c_client));
+
+	if ((err = i2c_attach_client(new_client))) {
+		kfree(new_client);
+		return err;
+	}
+
+	max7310_config(&new_client->dev, AKITA_IOEXP_IO_DIR, 0);
+	akita_ioexp_device = &new_client->dev;
+	schedule_work(&akita_ioexp);
+
+	return 0;
+}
+
+static int max7310_attach_adapter(struct i2c_adapter *adapter)
+{
+	return i2c_probe(adapter, &addr_data, max7310_detect);
+}
+
+static int max7310_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	akita_ioexp_device = NULL;
+
+	if ((err = i2c_detach_client(client)))
+		return err;
+
+	kfree(client);
+	return 0;
+}
+
+static struct i2c_driver max7310_i2c_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "akita-max7310",
+	.id		= I2C_DRIVERID_AKITAIOEXP,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= max7310_attach_adapter,
+	.detach_client	= max7310_detach_client,
+};
+
+static struct i2c_client max7310_template = {
+	name:   "akita-max7310",
+	flags:  I2C_CLIENT_ALLOW_USE,
+	driver: &max7310_i2c_driver,
+};
+
+void akita_set_ioexp(struct device *dev, unsigned char bit)
+{
+	ioexp_output_value |= bit;
+
+	if (akita_ioexp_device)
+		schedule_work(&akita_ioexp);
+	return;
+}
+
+void akita_reset_ioexp(struct device *dev, unsigned char bit)
+{
+	ioexp_output_value &= ~bit;
+
+	if (akita_ioexp_device)
+		schedule_work(&akita_ioexp);
+	return;
+}
+
+EXPORT_SYMBOL(akita_set_ioexp);
+EXPORT_SYMBOL(akita_reset_ioexp);
+
+static void akita_ioexp_work(void *private_)
+{
+	if (akita_ioexp_device)
+		max7310_set_ouputs(akita_ioexp_device, ioexp_output_value);
+}
+
+
+#ifdef CONFIG_PM
+static int akita_ioexp_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	flush_scheduled_work();
+	return 0;
+}
+
+static int akita_ioexp_resume(struct platform_device *pdev)
+{
+	schedule_work(&akita_ioexp);
+	return 0;
+}
+#else
+#define akita_ioexp_suspend NULL
+#define akita_ioexp_resume NULL
+#endif
+
+static int __init akita_ioexp_probe(struct platform_device *pdev)
+{
+	return i2c_add_driver(&max7310_i2c_driver);
+}
+
+static int akita_ioexp_remove(struct platform_device *pdev)
+{
+	i2c_del_driver(&max7310_i2c_driver);
+	return 0;
+}
+
+static struct platform_driver akita_ioexp_driver = {
+	.probe		= akita_ioexp_probe,
+	.remove		= akita_ioexp_remove,
+	.suspend	= akita_ioexp_suspend,
+	.resume		= akita_ioexp_resume,
+	.driver		= {
+		.name	= "akita-ioexp",
+	},
+};
+
+static int __init akita_ioexp_init(void)
+{
+	return platform_driver_register(&akita_ioexp_driver);
+}
+
+static void __exit akita_ioexp_exit(void)
+{
+	platform_driver_unregister(&akita_ioexp_driver);
+}
+
+MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
+MODULE_DESCRIPTION("Akita IO-Expander driver");
+MODULE_LICENSE("GPL");
+
+fs_initcall(akita_ioexp_init);
+module_exit(akita_ioexp_exit);
+
diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c
new file mode 100644
index 0000000..599be14
--- /dev/null
+++ b/arch/arm/mach-pxa/corgi_pm.c
@@ -0,0 +1,228 @@
+/*
+ * Battery and Power Management code for the Sharp SL-C7xx
+ *
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/stat.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <asm/apm.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/hardware/scoop.h>
+
+#include <asm/arch/sharpsl.h>
+#include <asm/arch/corgi.h>
+#include <asm/arch/pxa-regs.h>
+#include "sharpsl.h"
+
+static void corgi_charger_init(void)
+{
+	pxa_gpio_mode(CORGI_GPIO_ADC_TEMP_ON | GPIO_OUT);
+	pxa_gpio_mode(CORGI_GPIO_CHRG_ON | GPIO_OUT);
+	pxa_gpio_mode(CORGI_GPIO_CHRG_UKN | GPIO_OUT);
+	pxa_gpio_mode(CORGI_GPIO_KEY_INT | GPIO_IN);
+}
+
+static void corgi_charge_led(int val)
+{
+	if (val == SHARPSL_LED_ERROR) {
+		dev_dbg(sharpsl_pm.dev, "Charge LED Error\n");
+	} else if (val == SHARPSL_LED_ON) {
+		dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
+		GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
+	} else {
+		dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
+		GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
+	}
+}
+
+static void corgi_measure_temp(int on)
+{
+	if (on)
+		GPSR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
+	else
+		GPCR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
+}
+
+static void corgi_charge(int on)
+{
+	if (on) {
+		if (machine_is_corgi() && (sharpsl_pm.flags & SHARPSL_SUSPENDED)) {
+			GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
+			GPSR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
+		} else {
+			GPSR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
+			GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
+		}
+	} else {
+		GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);
+		GPCR(CORGI_GPIO_CHRG_UKN) = GPIO_bit(CORGI_GPIO_CHRG_UKN);
+	}
+}
+
+static void corgi_discharge(int on)
+{
+	if (on)
+		GPSR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON);
+	else
+		GPCR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON);
+}
+
+static void corgi_presuspend(void)
+{
+	int i;
+	unsigned long wakeup_mask;
+
+	/* charging , so CHARGE_ON bit is HIGH during OFF. */
+	if (READ_GPIO_BIT(CORGI_GPIO_CHRG_ON))
+		PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_ON);
+	else
+		PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_ON);
+
+	if (READ_GPIO_BIT(CORGI_GPIO_LED_ORANGE))
+		PGSR0 |= GPIO_bit(CORGI_GPIO_LED_ORANGE);
+	else
+		PGSR0 &= ~GPIO_bit(CORGI_GPIO_LED_ORANGE);
+
+	if (READ_GPIO_BIT(CORGI_GPIO_CHRG_UKN))
+		PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_UKN);
+	else
+		PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_UKN);
+
+	/* Resume on keyboard power key */
+	PGSR2 = (PGSR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(0);
+
+	wakeup_mask = GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) | GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_CHRG_FULL);
+
+	if (!machine_is_corgi())
+		wakeup_mask |= GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW);
+
+	PWER = wakeup_mask | PWER_RTC;
+	PRER = wakeup_mask;
+	PFER = wakeup_mask;
+
+	for (i = 0; i <=15; i++) {
+		if (PRER & PFER & GPIO_bit(i)) {
+			if (GPLR0 & GPIO_bit(i) )
+				PRER &= ~GPIO_bit(i);
+			else
+				PFER &= ~GPIO_bit(i);
+		}
+	}
+}
+
+static void corgi_postsuspend(void)
+{
+}
+
+/*
+ * Check what brought us out of the suspend.
+ * Return: 0 to sleep, otherwise wake
+ */
+static int corgi_should_wakeup(unsigned int resume_on_alarm)
+{
+	int is_resume = 0;
+
+	dev_dbg(sharpsl_pm.dev, "GPLR0 = %x,%x\n", GPLR0, PEDR);
+
+	if ((PEDR & GPIO_bit(CORGI_GPIO_AC_IN))) {
+		if (STATUS_AC_IN()) {
+			/* charge on */
+			dev_dbg(sharpsl_pm.dev, "ac insert\n");
+			sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
+		} else {
+			/* charge off */
+			dev_dbg(sharpsl_pm.dev, "ac remove\n");
+			CHARGE_LED_OFF();
+			CHARGE_OFF();
+			sharpsl_pm.charge_mode = CHRG_OFF;
+		}
+	}
+
+	if ((PEDR & GPIO_bit(CORGI_GPIO_CHRG_FULL)))
+		dev_dbg(sharpsl_pm.dev, "Charge full interrupt\n");
+
+	if (PEDR & GPIO_bit(CORGI_GPIO_KEY_INT))
+		is_resume |= GPIO_bit(CORGI_GPIO_KEY_INT);
+
+	if (PEDR & GPIO_bit(CORGI_GPIO_WAKEUP))
+		is_resume |= GPIO_bit(CORGI_GPIO_WAKEUP);
+
+	if (resume_on_alarm && (PEDR & PWER_RTC))
+		is_resume |= PWER_RTC;
+
+	dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume);
+	return is_resume;
+}
+
+static unsigned long corgi_charger_wakeup(void)
+{
+	return ~GPLR0 & ( GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) );
+}
+
+static int corgi_acin_status(void)
+{
+	return ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0);
+}
+
+static struct sharpsl_charger_machinfo corgi_pm_machinfo = {
+	.init            = corgi_charger_init,
+	.gpio_batlock    = CORGI_GPIO_BAT_COVER,
+	.gpio_acin       = CORGI_GPIO_AC_IN,
+	.gpio_batfull    = CORGI_GPIO_CHRG_FULL,
+	.status_acin     = corgi_acin_status,
+	.discharge       = corgi_discharge,
+	.charge          = corgi_charge,
+	.chargeled       = corgi_charge_led,
+	.measure_temp    = corgi_measure_temp,
+	.presuspend      = corgi_presuspend,
+	.postsuspend     = corgi_postsuspend,
+	.charger_wakeup  = corgi_charger_wakeup,
+	.should_wakeup   = corgi_should_wakeup,
+	.bat_levels      = 40,
+	.bat_levels_noac = spitz_battery_levels_noac,
+	.bat_levels_acin = spitz_battery_levels_acin,
+	.status_high_acin = 188,
+	.status_low_acin  = 178,
+	.status_high_noac = 185,
+	.status_low_noac  = 175,
+};
+
+static struct platform_device *corgipm_device;
+
+static int __devinit corgipm_init(void)
+{
+	int ret;
+
+	corgipm_device = platform_device_alloc("sharpsl-pm", -1);
+	if (!corgipm_device)
+		return -ENOMEM;
+
+	corgipm_device->dev.platform_data = &corgi_pm_machinfo;
+	ret = platform_device_add(corgipm_device);
+
+	if (ret)
+		platform_device_put(corgipm_device);
+
+	return ret;
+}
+
+static void corgipm_exit(void)
+{
+	platform_device_unregister(corgipm_device);
+}
+
+module_init(corgipm_init);
+module_exit(corgipm_exit);
diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h
index 4879c0f..b0c40a1 100644
--- a/arch/arm/mach-pxa/sharpsl.h
+++ b/arch/arm/mach-pxa/sharpsl.h
@@ -115,7 +115,7 @@ extern struct battery_thresh spitz_batte
 #define CHARGE_LED_ERR()    sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ERROR)
 #define DISCHARGE_ON()      sharpsl_pm.machinfo->discharge(1)
 #define DISCHARGE_OFF()     sharpsl_pm.machinfo->discharge(0)
-#define STATUS_AC_IN        sharpsl_pm.machinfo->status_acin()
-#define STATUS_BATT_LOCKED  READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock)
-#define STATUS_CHRG_FULL    READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull)
-#define STATUS_FATAL        READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal)
+#define STATUS_AC_IN()      sharpsl_pm.machinfo->status_acin()
+#define STATUS_BATT_LOCKED()  READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock)
+#define STATUS_CHRG_FULL()  READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull)
+#define STATUS_FATAL()      READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal)
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index 6c9e871..c10be00 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -21,7 +21,7 @@
 #include <linux/apm_bios.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 
 #include <asm/hardware.h>
 #include <asm/hardware/scoop.h>
@@ -45,15 +45,15 @@
 #define SHARPSL_WAIT_DISCHARGE_ON              100 /* 100 msec */
 #define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP   10  /* 10 msec */
 #define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT   10  /* 10 msec */
-#define SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD  10  /* 10 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN   10  /* 10 msec */
 #define SHARPSL_CHARGE_WAIT_TIME               15  /* 15 msec */
 #define SHARPSL_CHARGE_CO_CHECK_TIME           5   /* 5 msec */
 #define SHARPSL_CHARGE_RETRY_CNT               1   /* eqv. 10 min */
 
 #define SHARPSL_CHARGE_ON_VOLT         0x99  /* 2.9V */
 #define SHARPSL_CHARGE_ON_TEMP         0xe0  /* 2.9V */
-#define SHARPSL_CHARGE_ON_JKVAD_HIGH   0x9b  /* 6V */
-#define SHARPSL_CHARGE_ON_JKVAD_LOW    0x34  /* 2V */
+#define SHARPSL_CHARGE_ON_ACIN_HIGH    0x9b  /* 6V */
+#define SHARPSL_CHARGE_ON_ACIN_LOW     0x34  /* 2V */
 #define SHARPSL_FATAL_ACIN_VOLT        182   /* 3.45V */
 #define SHARPSL_FATAL_NOACIN_VOLT      170   /* 3.40V */
 
@@ -160,9 +160,10 @@ struct battery_thresh  spitz_battery_lev
 /*
  * Prototypes
  */
-static int sharpsl_read_MainBattery(void);
+static int sharpsl_read_main_battery(void);
 static int sharpsl_off_charge_battery(void);
-static int sharpsl_check_battery(int mode);
+static int sharpsl_check_battery_temp(void);
+static int sharpsl_check_battery_voltage(void);
 static int sharpsl_ac_check(void);
 static int sharpsl_fatal_check(void);
 static int sharpsl_average_value(int ad);
@@ -228,7 +229,7 @@ static void sharpsl_battery_thread(void 
 	if (!sharpsl_pm.machinfo)
 		return;
 
-	sharpsl_pm.battstat.ac_status = (!(STATUS_AC_IN) ? APM_AC_OFFLINE : APM_AC_ONLINE);
+	sharpsl_pm.battstat.ac_status = (STATUS_AC_IN() ? APM_AC_ONLINE : APM_AC_OFFLINE);
 
 	/* Corgi cannot confirm when battery fully charged so periodically kick! */
 	if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON)
@@ -236,7 +237,7 @@ static void sharpsl_battery_thread(void 
 		schedule_work(&toggle_charger);
 
 	while(1) {
-		voltage = sharpsl_read_MainBattery();
+		voltage = sharpsl_read_main_battery();
 		if (voltage > 0) break;
 		if (i++ > 5) {
 			voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
@@ -317,10 +318,10 @@ static void sharpsl_charge_toggle(void *
 {
 	dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
 
-	if (STATUS_AC_IN == 0) {
+	if (STATUS_AC_IN() == 0) {
 		sharpsl_charge_off();
 		return;
-	} else if ((sharpsl_check_battery(1) < 0) || (sharpsl_ac_check() < 0)) {
+	} else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) {
 		sharpsl_charge_error();
 		return;
 	}
@@ -335,7 +336,7 @@ static void sharpsl_charge_toggle(void *
 
 static void sharpsl_ac_timer(unsigned long data)
 {
-	int acin = STATUS_AC_IN;
+	int acin = STATUS_AC_IN();
 
 	dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin);
 
@@ -364,7 +365,7 @@ static void sharpsl_chrg_full_timer(unsi
 
 	sharpsl_pm.full_count++;
 
-	if (STATUS_AC_IN == 0) {
+	if (STATUS_AC_IN() == 0) {
 		dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n");
 		if (sharpsl_pm.charge_mode == CHRG_ON)
 			sharpsl_charge_off();
@@ -399,12 +400,12 @@ static irqreturn_t sharpsl_fatal_isr(int
 {
 	int is_fatal = 0;
 
-	if (STATUS_BATT_LOCKED == 0) {
+	if (STATUS_BATT_LOCKED() == 0) {
 		dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n");
 		is_fatal = 1;
 	}
 
-	if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL == 0)) {
+	if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL() == 0)) {
 		dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n");
 		is_fatal = 1;
 	}
@@ -461,12 +462,12 @@ static int read_max1111(int channel)
 			| MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
 }
 
-static int sharpsl_read_MainBattery(void)
+static int sharpsl_read_main_battery(void)
 {
 	return read_max1111(BATT_AD);
 }
 
-static int sharpsl_read_Temp(void)
+static int sharpsl_read_temp(void)
 {
 	int temp;
 
@@ -480,7 +481,7 @@ static int sharpsl_read_Temp(void)
 	return temp;
 }
 
-static int sharpsl_read_jkvad(void)
+static int sharpsl_read_acin(void)
 {
 	return read_max1111(JK_VAD);
 }
@@ -522,16 +523,14 @@ static int get_select_val(int *val)
 	return (sum/3);
 }
 
-/*  mode 0 - Check temperature and voltage
- *       1 - Check temperature only */
-static int sharpsl_check_battery(int mode)
+static int sharpsl_check_battery_temp(void)
 {
 	int val, i, buff[5];
 
 	/* Check battery temperature */
 	for (i=0; i<5; i++) {
 		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
-		buff[i] = sharpsl_read_Temp();
+		buff[i] = sharpsl_read_temp();
 	}
 
 	val = get_select_val(buff);
@@ -539,8 +538,13 @@ static int sharpsl_check_battery(int mod
 	dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
 	if (val > SHARPSL_CHARGE_ON_TEMP)
 		return -1;
-	if (mode == 1)
-		return 0;
+
+	return 0;
+}
+
+static int sharpsl_check_battery_voltage(void)
+{
+	int val, i, buff[5];
 
 	/* disable charge, enable discharge */
 	CHARGE_OFF();
@@ -552,7 +556,7 @@ static int sharpsl_check_battery(int mod
 
 	/* Check battery voltage */
 	for (i=0; i<5; i++) {
-		buff[i] = sharpsl_read_MainBattery();
+		buff[i] = sharpsl_read_main_battery();
 		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
 	}
 
@@ -575,14 +579,14 @@ static int sharpsl_ac_check(void)
 	int temp, i, buff[5];
 
 	for (i=0; i<5; i++) {
-		buff[i] = sharpsl_read_jkvad();
-		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD);
+		buff[i] = sharpsl_read_acin();
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN);
 	}
 
 	temp = get_select_val(buff);
 	dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
 
-	if ((temp > SHARPSL_CHARGE_ON_JKVAD_HIGH) || (temp < SHARPSL_CHARGE_ON_JKVAD_LOW)) {
+	if ((temp > SHARPSL_CHARGE_ON_ACIN_HIGH) || (temp < SHARPSL_CHARGE_ON_ACIN_LOW)) {
 		dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
 		return -1;
 	}
@@ -591,7 +595,7 @@ static int sharpsl_ac_check(void)
 }
 
 #ifdef CONFIG_PM
-static int sharpsl_pm_suspend(struct device *dev, pm_message_t state)
+static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state)
 {
 	sharpsl_pm.flags |= SHARPSL_SUSPENDED;
 	flush_scheduled_work();
@@ -604,7 +608,7 @@ static int sharpsl_pm_suspend(struct dev
 	return 0;
 }
 
-static int sharpsl_pm_resume(struct device *dev)
+static int sharpsl_pm_resume(struct platform_device *pdev)
 {
 	/* Clear the reset source indicators as they break the bootloader upon reboot */
 	RCSR = 0x0f;
@@ -622,7 +626,7 @@ static void corgi_goto_sleep(unsigned lo
 	dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
 	/* not charging and AC-IN! */
 
-	if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN != 0)) {
+	if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN() != 0)) {
 		dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");
 		sharpsl_pm.charge_mode = CHRG_OFF;
 		sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
@@ -671,7 +675,7 @@ static int corgi_enter_suspend(unsigned 
 		dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
 	}
 
-	if ((STATUS_BATT_LOCKED == 0) || (sharpsl_fatal_check() < 0) )
+	if ((STATUS_BATT_LOCKED() == 0) || (sharpsl_fatal_check() < 0) )
 	{
 		dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
 		corgi_goto_sleep(alarm_time, alarm_enable, state);
@@ -711,7 +715,7 @@ static int sharpsl_fatal_check(void)
 	dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
 
 	/* Check AC-Adapter */
-	acin = STATUS_AC_IN;
+	acin = STATUS_AC_IN();
 
 	if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
 		CHARGE_OFF();
@@ -725,7 +729,7 @@ static int sharpsl_fatal_check(void)
 
 	/* Check battery : check inserting battery ? */
 	for (i=0; i<5; i++) {
-		buff[i] = sharpsl_read_MainBattery();
+		buff[i] = sharpsl_read_main_battery();
 		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
 	}
 
@@ -739,7 +743,7 @@ static int sharpsl_fatal_check(void)
 	}
 
 	temp = get_select_val(buff);
-	dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_MainBattery());
+	dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_main_battery());
 
 	if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) ||
 			(!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT)))
@@ -771,7 +775,7 @@ static int sharpsl_off_charge_battery(vo
 		dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
 
 		/* AC Check */
-		if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery(1) < 0))
+		if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0))
 			return sharpsl_off_charge_error();
 
 		/* Start Charging */
@@ -793,7 +797,7 @@ static int sharpsl_off_charge_battery(vo
 
 		dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
 
-		if (sharpsl_check_battery(0) < 0)
+		if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0))
 			return sharpsl_off_charge_error();
 
 		CHARGE_OFF();
@@ -811,7 +815,7 @@ static int sharpsl_off_charge_battery(vo
 			/* Check for timeout */
 			if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
 				return 1;
-			if (STATUS_CHRG_FULL) {
+			if (STATUS_CHRG_FULL()) {
 				dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n");
 	   			sharpsl_pm.full_count++;
 				CHARGE_OFF();
@@ -840,7 +844,7 @@ static int sharpsl_off_charge_battery(vo
 			sharpsl_pm.full_count++;
 			return 1;
 		}
-		if (STATUS_CHRG_FULL) {
+		if (STATUS_CHRG_FULL()) {
 			dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");
 			CHARGE_LED_OFF();
 			CHARGE_OFF();
@@ -886,13 +890,13 @@ static struct pm_ops sharpsl_pm_ops = {
 	.finish		= pxa_pm_finish,
 };
 
-static int __init sharpsl_pm_probe(struct device *dev)
+static int __init sharpsl_pm_probe(struct platform_device *pdev)
 {
-	if (!dev->platform_data)
+	if (!pdev->dev.platform_data)
 		return -EINVAL;
 
-	sharpsl_pm.dev = dev;
-	sharpsl_pm.machinfo = dev->platform_data;
+	sharpsl_pm.dev = &pdev->dev;
+	sharpsl_pm.machinfo = pdev->dev.platform_data;
 	sharpsl_pm.charge_mode = CHRG_OFF;
 	sharpsl_pm.flags = 0;
 
@@ -935,8 +939,8 @@ static int __init sharpsl_pm_probe(struc
 		else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING);
 	}
 
-	device_create_file(dev, &dev_attr_battery_percentage);
-	device_create_file(dev, &dev_attr_battery_voltage);
+	device_create_file(&pdev->dev, &dev_attr_battery_percentage);
+	device_create_file(&pdev->dev, &dev_attr_battery_voltage);
 
 	apm_get_power_status = sharpsl_apm_get_power_status;
 
@@ -947,12 +951,12 @@ static int __init sharpsl_pm_probe(struc
 	return 0;
 }
 
-static int sharpsl_pm_remove(struct device *dev)
+static int sharpsl_pm_remove(struct platform_device *pdev)
 {
 	pm_set_ops(NULL);
 
-	device_remove_file(dev, &dev_attr_battery_percentage);
-	device_remove_file(dev, &dev_attr_battery_voltage);
+	device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
+	device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
 
 	free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
 	free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
@@ -969,23 +973,24 @@ static int sharpsl_pm_remove(struct devi
 	return 0;
 }
 
-static struct device_driver sharpsl_pm_driver = {
-	.name		= "sharpsl-pm",
-	.bus		= &platform_bus_type,
+static struct platform_driver sharpsl_pm_driver = {
 	.probe		= sharpsl_pm_probe,
 	.remove		= sharpsl_pm_remove,
 	.suspend	= sharpsl_pm_suspend,
 	.resume		= sharpsl_pm_resume,
+	.driver		= {
+		.name		= "sharpsl-pm",
+	},
 };
 
 static int __devinit sharpsl_pm_init(void)
 {
-	return driver_register(&sharpsl_pm_driver);
+	return platform_driver_register(&sharpsl_pm_driver);
 }
 
 static void sharpsl_pm_exit(void)
 {
- 	driver_unregister(&sharpsl_pm_driver);
+ 	platform_driver_unregister(&sharpsl_pm_driver);
 }
 
 late_initcall(sharpsl_pm_init);
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 4e9a699..2df1b56 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -345,6 +345,16 @@ static void spitz_irda_transceiver_mode(
 		reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
 }
 
+#ifdef CONFIG_MACH_AKITA
+static void akita_irda_transceiver_mode(struct device *dev, int mode)
+{
+	if (mode & IR_OFF)
+		akita_set_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON);
+	else
+		akita_reset_ioexp(&akitaioexp_device.dev, AKITA_IOEXP_IR_ON);
+}
+#endif
+
 static struct pxaficp_platform_data spitz_ficp_platform_data = {
 	.transceiver_cap  = IR_SIRMODE | IR_OFF,
 	.transceiver_mode = spitz_irda_transceiver_mode,
@@ -417,6 +427,32 @@ static void __init spitz_init(void)
 	platform_device_register(&spitzscoop2_device);
 }
 
+#ifdef CONFIG_MACH_AKITA
+/*
+ * Akita IO Expander
+ */
+struct platform_device akitaioexp_device = {
+	.name		= "akita-ioexp",
+	.id		= -1,
+};
+
+static void __init akita_init(void)
+{
+	spitz_ficp_platform_data.transceiver_mode = akita_irda_transceiver_mode;
+
+	/* We just pretend the second element of the array doesn't exist */
+	spitz_pcmcia_config.num_devs = 1;
+	platform_scoop_config = &spitz_pcmcia_config;
+	spitz_bl_machinfo.set_bl_intensity = akita_bl_set_intensity;
+
+	platform_device_register(&akitaioexp_device);
+
+	spitzscoop_device.dev.parent = &akitaioexp_device.dev;
+	common_init();
+}
+#endif
+
+
 static void __init fixup_spitz(struct machine_desc *desc,
 		struct tag *tags, char **cmdline, struct meminfo *mi)
 {
@@ -452,3 +488,16 @@ MACHINE_START(BORZOI, "SHARP Borzoi")
 	.timer		= &pxa_timer,
 MACHINE_END
 #endif
+
+#ifdef CONFIG_MACH_AKITA
+MACHINE_START(AKITA, "SHARP Akita")
+	.phys_ram	= 0xa0000000,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.fixup		= fixup_spitz,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa_init_irq,
+	.init_machine	= akita_init,
+	.timer		= &pxa_timer,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
new file mode 100644
index 0000000..3ce7486
--- /dev/null
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -0,0 +1,233 @@
+/*
+ * Battery and Power Management code for the Sharp SL-Cxx00
+ *
+ * Copyright (c) 2005 Richard Purdie
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/stat.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <asm/apm.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/hardware/scoop.h>
+
+#include <asm/arch/sharpsl.h>
+#include <asm/arch/spitz.h>
+#include <asm/arch/pxa-regs.h>
+#include "sharpsl.h"
+
+static int spitz_last_ac_status;
+
+static void spitz_charger_init(void)
+{
+	pxa_gpio_mode(SPITZ_GPIO_KEY_INT | GPIO_IN);
+	pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN);
+}
+
+static void spitz_charge_led(int val)
+{
+	if (val == SHARPSL_LED_ERROR) {
+		dev_dbg(sharpsl_pm.dev, "Charge LED Error\n");
+	} else if (val == SHARPSL_LED_ON) {
+		dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
+		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
+	} else {
+		dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
+		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
+	}
+}
+
+static void spitz_measure_temp(int on)
+{
+	if (on)
+		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_ADC_TEMP_ON);
+	else
+		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_ADC_TEMP_ON);
+}
+
+static void spitz_charge(int on)
+{
+	if (on) {
+		if (sharpsl_pm.flags & SHARPSL_SUSPENDED) {
+			set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
+			reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
+		} else {
+			reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
+			reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
+		}
+	} else {
+		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_B);
+		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CHRG_ON);
+	}
+}
+
+static void spitz_discharge(int on)
+{
+	if (on)
+		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_A);
+	else
+		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_JK_A);
+}
+
+/* HACK - For unknown reasons, accurate voltage readings are only made with a load
+   on the power bus which the green led on spitz provides */
+static void spitz_discharge1(int on)
+{
+	if (on)
+		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
+	else
+		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_GREEN);
+}
+
+static void spitz_presuspend(void)
+{
+	spitz_last_ac_status = STATUS_AC_IN();
+
+	/* GPIO Sleep Register */
+	PGSR0 = 0x00144018;
+	PGSR1 = 0x00EF0000;
+	if (machine_is_akita()) {
+		PGSR2 = 0x2121C000;
+		PGSR3 = 0x00600400;
+	} else {
+		PGSR2 = 0x0121C000;
+		PGSR3 = 0x00600000;
+	}
+
+	PGSR0 &= ~SPITZ_GPIO_G0_STROBE_BIT;
+	PGSR1 &= ~SPITZ_GPIO_G1_STROBE_BIT;
+	PGSR2 &= ~SPITZ_GPIO_G2_STROBE_BIT;
+	PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT;
+	PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0);
+
+	pxa_gpio_mode(GPIO18_RDY|GPIO_OUT | GPIO_DFLT_HIGH);
+
+	PRER = GPIO_bit(SPITZ_GPIO_KEY_INT);
+	PFER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
+	PWER = GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET) | PWER_RTC;
+	PKWR = GPIO_bit(SPITZ_GPIO_SYNC) | GPIO_bit(SPITZ_GPIO_KEY_INT) | GPIO_bit(SPITZ_GPIO_RESET);
+	PKSR = 0xffffffff; // clear
+
+	/* nRESET_OUT Disable */
+	PSLR |= PSLR_SL_ROD;
+
+	/* Clear reset status */
+	RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
+	/* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
+	PCFR = PCFR_GPR_EN | PCFR_OPDE;
+}
+
+static void spitz_postsuspend(void)
+{
+	pxa_gpio_mode(GPIO18_RDY_MD);
+	pxa_gpio_mode(10 | GPIO_IN);
+}
+
+static int spitz_should_wakeup(unsigned int resume_on_alarm)
+{
+	int is_resume = 0;
+	int acin = STATUS_AC_IN();
+
+	if (spitz_last_ac_status != acin) {
+		if (acin) {
+			/* charge on */
+			sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
+			dev_dbg(sharpsl_pm.dev, "AC Inserted\n");
+		} else {
+			/* charge off */
+			dev_dbg(sharpsl_pm.dev, "AC Removed\n");
+			CHARGE_LED_OFF();
+			CHARGE_OFF();
+			sharpsl_pm.charge_mode = CHRG_OFF;
+		}
+		spitz_last_ac_status = acin;
+		/* Return to suspend as this must be what we were woken for */
+		return 0;
+	}
+
+	if (PEDR & GPIO_bit(SPITZ_GPIO_KEY_INT))
+		is_resume |= GPIO_bit(SPITZ_GPIO_KEY_INT);
+
+	if (PKSR & GPIO_bit(SPITZ_GPIO_SYNC))
+		is_resume |= GPIO_bit(SPITZ_GPIO_SYNC);
+
+	if (resume_on_alarm && (PEDR & PWER_RTC))
+		is_resume |= PWER_RTC;
+
+	dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume);
+	return is_resume;
+}
+
+static unsigned long spitz_charger_wakeup(void)
+{
+	return (~GPLR0 & GPIO_bit(SPITZ_GPIO_KEY_INT)) | (GPLR0 & GPIO_bit(SPITZ_GPIO_SYNC));
+}
+
+static int spitz_acin_status(void)
+{
+	return (((~GPLR(SPITZ_GPIO_AC_IN)) & GPIO_bit(SPITZ_GPIO_AC_IN)) != 0);
+}
+
+struct sharpsl_charger_machinfo spitz_pm_machinfo = {
+	.init             = spitz_charger_init,
+	.gpio_batlock     = SPITZ_GPIO_BAT_COVER,
+	.gpio_acin        = SPITZ_GPIO_AC_IN,
+	.gpio_batfull     = SPITZ_GPIO_CHRG_FULL,
+	.gpio_fatal       = SPITZ_GPIO_FATAL_BAT,
+	.status_acin      = spitz_acin_status,
+	.discharge        = spitz_discharge,
+	.discharge1       = spitz_discharge1,
+	.charge           = spitz_charge,
+	.chargeled        = spitz_charge_led,
+	.measure_temp     = spitz_measure_temp,
+	.presuspend       = spitz_presuspend,
+	.postsuspend      = spitz_postsuspend,
+	.charger_wakeup   = spitz_charger_wakeup,
+	.should_wakeup    = spitz_should_wakeup,
+	.bat_levels       = 40,
+	.bat_levels_noac  = spitz_battery_levels_noac,
+	.bat_levels_acin  = spitz_battery_levels_acin,
+	.status_high_acin = 188,
+	.status_low_acin  = 178,
+	.status_high_noac = 185,
+	.status_low_noac  = 175,
+};
+
+static struct platform_device *spitzpm_device;
+
+static int __devinit spitzpm_init(void)
+{
+	int ret;
+
+	spitzpm_device = platform_device_alloc("sharpsl-pm", -1);
+	if (!spitzpm_device)
+		return -ENOMEM;
+
+	spitzpm_device->dev.platform_data = &spitz_pm_machinfo;
+	ret = platform_device_add(spitzpm_device);
+
+	if (ret)
+		platform_device_put(spitzpm_device);
+
+	return ret;
+}
+
+static void spitzpm_exit(void)
+{
+ 	platform_device_unregister(spitzpm_device);
+}
+
+module_init(spitzpm_init);
+module_exit(spitzpm_exit);
diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c
index 1a1e8a1..712c3c2 100644
--- a/arch/frv/kernel/pm.c
+++ b/arch/frv/kernel/pm.c
@@ -14,6 +14,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/sysctl.h>
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index dbf90ad..6004bb0 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -699,7 +699,7 @@ depends on PM && !X86_VISWS
 
 config APM
 	tristate "APM (Advanced Power Management) BIOS support"
-	depends on PM
+	depends on PM && PM_LEGACY
 	---help---
 	  APM is a BIOS specification for saving power using several different
 	  techniques. This is mostly useful for battery powered laptops with
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index b66c13c..f366772 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -39,17 +39,14 @@
 
 #ifdef	CONFIG_X86_64
 
-static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-}
 extern void __init clustered_apic_check(void);
-static inline int ioapic_setup_disabled(void)
-{
-	return 0;
-}
 
+extern int gsi_irq_sharing(int gsi);
 #include <asm/proto.h>
 
+static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; }
+
+
 #else				/* X86 */
 
 #ifdef	CONFIG_X86_LOCAL_APIC
@@ -57,6 +54,8 @@ static inline int ioapic_setup_disabled(
 #include <mach_mpparse.h>
 #endif				/* CONFIG_X86_LOCAL_APIC */
 
+static inline int gsi_irq_sharing(int gsi) { return gsi; }
+
 #endif				/* X86 */
 
 #define BAD_MADT_ENTRY(entry, end) (					    \
@@ -459,7 +458,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned in
 		*irq = IO_APIC_VECTOR(gsi);
 	else
 #endif
-		*irq = gsi;
+		*irq = gsi_irq_sharing(gsi);
 	return 0;
 }
 
@@ -543,7 +542,7 @@ acpi_scan_rsdp(unsigned long start, unsi
 	 * RSDP signature.
 	 */
 	for (offset = 0; offset < length; offset += 16) {
-		if (strncmp((char *)(start + offset), "RSD PTR ", sig_len))
+		if (strncmp((char *)(phys_to_virt(start) + offset), "RSD PTR ", sig_len))
 			continue;
 		return (start + offset);
 	}
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 003548b..1e60acb 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -218,6 +218,7 @@
 #include <linux/time.h>
 #include <linux/sched.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/smp.h>
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 53a1681..e344ef8 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -206,9 +206,9 @@ static void __init init_amd(struct cpuin
 	display_cacheinfo(c);
 
 	if (cpuid_eax(0x80000000) >= 0x80000008) {
-		c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
-		if (c->x86_num_cores & (c->x86_num_cores - 1))
-			c->x86_num_cores = 1;
+		c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
+		if (c->x86_max_cores & (c->x86_max_cores - 1))
+			c->x86_max_cores = 1;
 	}
 
 #ifdef CONFIG_X86_HT
@@ -217,15 +217,15 @@ static void __init init_amd(struct cpuin
 	 * distingush the cores.  Assumes number of cores is a power
 	 * of two.
 	 */
-	if (c->x86_num_cores > 1) {
+	if (c->x86_max_cores > 1) {
 		int cpu = smp_processor_id();
 		unsigned bits = 0;
-		while ((1 << bits) < c->x86_num_cores)
+		while ((1 << bits) < c->x86_max_cores)
 			bits++;
 		cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1);
 		phys_proc_id[cpu] >>= bits;
 		printk(KERN_INFO "CPU %d(%d) -> Core %d\n",
-		       cpu, c->x86_num_cores, cpu_core_id[cpu]);
+		       cpu, c->x86_max_cores, cpu_core_id[cpu]);
 	}
 #endif
 }
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index c145fb3..31e344b 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -231,10 +231,10 @@ static void __init early_cpu_detect(void
 		cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
 		c->x86 = (tfms >> 8) & 15;
 		c->x86_model = (tfms >> 4) & 15;
-		if (c->x86 == 0xf) {
+		if (c->x86 == 0xf)
 			c->x86 += (tfms >> 20) & 0xff;
+		if (c->x86 >= 0x6)
 			c->x86_model += ((tfms >> 16) & 0xF) << 4;
-		}
 		c->x86_mask = tfms & 15;
 		if (cap0 & (1<<19))
 			c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8;
@@ -333,7 +333,7 @@ void __devinit identify_cpu(struct cpuin
 	c->x86_model = c->x86_mask = 0;	/* So far unknown... */
 	c->x86_vendor_id[0] = '\0'; /* Unset */
 	c->x86_model_id[0] = '\0';  /* Unset */
-	c->x86_num_cores = 1;
+	c->x86_max_cores = 1;
 	memset(&c->x86_capability, 0, sizeof c->x86_capability);
 
 	if (!have_cpuid_p()) {
@@ -443,52 +443,44 @@ void __devinit identify_cpu(struct cpuin
 void __devinit detect_ht(struct cpuinfo_x86 *c)
 {
 	u32 	eax, ebx, ecx, edx;
-	int 	index_msb, tmp;
+	int 	index_msb, core_bits;
 	int 	cpu = smp_processor_id();
 
+	cpuid(1, &eax, &ebx, &ecx, &edx);
+
+	c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0);
+
 	if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
 		return;
 
-	cpuid(1, &eax, &ebx, &ecx, &edx);
 	smp_num_siblings = (ebx & 0xff0000) >> 16;
 
 	if (smp_num_siblings == 1) {
 		printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
 	} else if (smp_num_siblings > 1 ) {
-		index_msb = 31;
 
 		if (smp_num_siblings > NR_CPUS) {
 			printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
 			smp_num_siblings = 1;
 			return;
 		}
-		tmp = smp_num_siblings;
-		while ((tmp & 0x80000000 ) == 0) {
-			tmp <<=1 ;
-			index_msb--;
-		}
-		if (smp_num_siblings & (smp_num_siblings - 1))
-			index_msb++;
+
+		index_msb = get_count_order(smp_num_siblings);
 		phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
 
 		printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
 		       phys_proc_id[cpu]);
 
-		smp_num_siblings = smp_num_siblings / c->x86_num_cores;
+		smp_num_siblings = smp_num_siblings / c->x86_max_cores;
 
-		tmp = smp_num_siblings;
-		index_msb = 31;
-		while ((tmp & 0x80000000) == 0) {
-			tmp <<=1 ;
-			index_msb--;
-		}
+		index_msb = get_count_order(smp_num_siblings) ;
 
-		if (smp_num_siblings & (smp_num_siblings - 1))
-			index_msb++;
+		core_bits = get_count_order(c->x86_max_cores);
 
-		cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
+		cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) &
+					       ((1 << core_bits) - 1);
 
-		if (c->x86_num_cores > 1)
+		if (c->x86_max_cores > 1)
 			printk(KERN_INFO  "CPU: Processor Core ID: %d\n",
 			       cpu_core_id[cpu]);
 	}
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c
index 43601de..5e2da70 100644
--- a/arch/i386/kernel/cpu/intel.c
+++ b/arch/i386/kernel/cpu/intel.c
@@ -6,6 +6,7 @@
 #include <linux/bitops.h>
 #include <linux/smp.h>
 #include <linux/thread_info.h>
+#include <linux/module.h>
 
 #include <asm/processor.h>
 #include <asm/msr.h>
@@ -157,7 +158,7 @@ static void __devinit init_intel(struct 
 	if ( p )
 		strcpy(c->x86_model_id, p);
 	
-	c->x86_num_cores = num_cpu_cores(c);
+	c->x86_max_cores = num_cpu_cores(c);
 
 	detect_ht(c);
 
@@ -264,5 +265,52 @@ __init int intel_cpu_init(void)
 	return 0;
 }
 
+#ifndef CONFIG_X86_CMPXCHG
+unsigned long cmpxchg_386_u8(volatile void *ptr, u8 old, u8 new)
+{
+	u8 prev;
+	unsigned long flags;
+
+	/* Poor man's cmpxchg for 386. Unsuitable for SMP */
+	local_irq_save(flags);
+	prev = *(u8 *)ptr;
+	if (prev == old)
+		*(u8 *)ptr = new;
+	local_irq_restore(flags);
+	return prev;
+}
+EXPORT_SYMBOL(cmpxchg_386_u8);
+
+unsigned long cmpxchg_386_u16(volatile void *ptr, u16 old, u16 new)
+{
+	u16 prev;
+	unsigned long flags;
+
+	/* Poor man's cmpxchg for 386. Unsuitable for SMP */
+	local_irq_save(flags);
+	prev = *(u16 *)ptr;
+	if (prev == old)
+		*(u16 *)ptr = new;
+	local_irq_restore(flags);
+	return prev;
+}
+EXPORT_SYMBOL(cmpxchg_386_u16);
+
+unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new)
+{
+	u32 prev;
+	unsigned long flags;
+
+	/* Poor man's cmpxchg for 386. Unsuitable for SMP */
+	local_irq_save(flags);
+	prev = *(u32 *)ptr;
+	if (prev == old)
+		*(u32 *)ptr = new;
+	local_irq_restore(flags);
+	return prev;
+}
+EXPORT_SYMBOL(cmpxchg_386_u32);
+#endif
+
 // arch_initcall(intel_cpu_init);
 
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
index 4dc42a1..fbfd374 100644
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -293,29 +293,45 @@ static struct _cpuid4_info *cpuid4_info[
 #ifdef CONFIG_SMP
 static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
 {
-	struct _cpuid4_info	*this_leaf;
+	struct _cpuid4_info	*this_leaf, *sibling_leaf;
 	unsigned long num_threads_sharing;
-#ifdef CONFIG_X86_HT
-	struct cpuinfo_x86 *c = cpu_data + cpu;
-#endif
+	int index_msb, i;
+	struct cpuinfo_x86 *c = cpu_data;
 
 	this_leaf = CPUID4_INFO_IDX(cpu, index);
 	num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
 
 	if (num_threads_sharing == 1)
 		cpu_set(cpu, this_leaf->shared_cpu_map);
-#ifdef CONFIG_X86_HT
-	else if (num_threads_sharing == smp_num_siblings)
-		this_leaf->shared_cpu_map = cpu_sibling_map[cpu];
-	else if (num_threads_sharing == (c->x86_num_cores * smp_num_siblings))
-		this_leaf->shared_cpu_map = cpu_core_map[cpu];
-	else
-		printk(KERN_DEBUG "Number of CPUs sharing cache didn't match "
-				"any known set of CPUs\n");
-#endif
+	else {
+		index_msb = get_count_order(num_threads_sharing);
+
+		for_each_online_cpu(i) {
+			if (c[i].apicid >> index_msb ==
+			    c[cpu].apicid >> index_msb) {
+				cpu_set(i, this_leaf->shared_cpu_map);
+				if (i != cpu && cpuid4_info[i])  {
+					sibling_leaf = CPUID4_INFO_IDX(i, index);
+					cpu_set(cpu, sibling_leaf->shared_cpu_map);
+				}
+			}
+		}
+	}
+}
+static void __devinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
+{
+	struct _cpuid4_info	*this_leaf, *sibling_leaf;
+	int sibling;
+
+	this_leaf = CPUID4_INFO_IDX(cpu, index);
+	for_each_cpu_mask(sibling, this_leaf->shared_cpu_map) {
+		sibling_leaf = CPUID4_INFO_IDX(sibling, index);	
+		cpu_clear(cpu, sibling_leaf->shared_cpu_map);
+	}
 }
 #else
 static void __init cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
+static void __init cache_remove_shared_cpu_map(unsigned int cpu, int index) {}
 #endif
 
 static void free_cache_attributes(unsigned int cpu)
@@ -574,8 +590,10 @@ static void __cpuexit cache_remove_dev(s
 	unsigned int cpu = sys_dev->id;
 	unsigned long i;
 
-	for (i = 0; i < num_cache_leaves; i++)
+	for (i = 0; i < num_cache_leaves; i++) {
+		cache_remove_shared_cpu_map(cpu, i);
 		kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
+	}
 	kobject_unregister(cache_kobject[cpu]);
 	cpuid4_cache_sysfs_exit(cpu);
 	return;
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c
index dd4ebd6..1e9db19 100644
--- a/arch/i386/kernel/cpu/mtrr/main.c
+++ b/arch/i386/kernel/cpu/mtrr/main.c
@@ -626,6 +626,14 @@ void __init mtrr_bp_init(void)
 		if (cpuid_eax(0x80000000) >= 0x80000008) {
 			u32 phys_addr;
 			phys_addr = cpuid_eax(0x80000008) & 0xff;
+			/* CPUID workaround for Intel 0F33/0F34 CPU */
+			if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
+			    boot_cpu_data.x86 == 0xF &&
+			    boot_cpu_data.x86_model == 0x3 &&
+			    (boot_cpu_data.x86_mask == 0x3 ||
+			     boot_cpu_data.x86_mask == 0x4))
+				phys_addr = 36;
+
 			size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
 			size_and_mask = ~size_or_mask & 0xfff00000;
 		} else if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR &&
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index 41b871e..e792131 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -94,12 +94,11 @@ static int show_cpuinfo(struct seq_file 
 	if (c->x86_cache_size >= 0)
 		seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
 #ifdef CONFIG_X86_HT
-	if (c->x86_num_cores * smp_num_siblings > 1) {
+	if (c->x86_max_cores * smp_num_siblings > 1) {
 		seq_printf(m, "physical id\t: %d\n", phys_proc_id[n]);
-		seq_printf(m, "siblings\t: %d\n",
-				c->x86_num_cores * smp_num_siblings);
+		seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[n]));
 		seq_printf(m, "core id\t\t: %d\n", cpu_core_id[n]);
-		seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores);
+		seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
 	}
 #endif
 	
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index af809cc..0248e08 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -21,6 +21,7 @@
 #include <asm/hardirq.h>
 #include <asm/nmi.h>
 #include <asm/hw_irq.h>
+#include <asm/apic.h>
 #include <mach_ipi.h>
 
 
@@ -147,6 +148,7 @@ static int crash_nmi_callback(struct pt_
 		regs = &fixed_regs;
 	}
 	crash_save_this_cpu(regs, cpu);
+	disable_local_APIC();
 	atomic_dec(&waiting_for_crash_ipi);
 	/* Assume hlt works */
 	halt();
@@ -186,6 +188,7 @@ static void nmi_shootdown_cpus(void)
 	}
 
 	/* Leave the nmi callback set */
+	disable_local_APIC();
 }
 #else
 static void nmi_shootdown_cpus(void)
@@ -210,5 +213,9 @@ void machine_crash_shutdown(struct pt_re
 	/* Make a note of crashing cpu. Will be used in NMI callback.*/
 	crashing_cpu = smp_processor_id();
 	nmi_shootdown_cpus();
+	lapic_shutdown();
+#if defined(CONFIG_X86_IO_APIC)
+	disable_IO_APIC();
+#endif
 	crash_save_self(regs);
 }
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 9e24f7b..e50b931 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -560,11 +560,10 @@ nmi_stack_fixup:
 nmi_debug_stack_check:
 	cmpw $__KERNEL_CS,16(%esp)
 	jne nmi_stack_correct
-	cmpl $debug - 1,(%esp)
-	jle nmi_stack_correct
+	cmpl $debug,(%esp)
+	jb nmi_stack_correct
 	cmpl $debug_esp_fix_insn,(%esp)
-	jle nmi_debug_stack_fixup
-nmi_debug_stack_fixup:
+	ja nmi_stack_correct
 	FIX_STACK(24,nmi_stack_correct, 1)
 	jmp nmi_stack_correct
 
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index bc5a9d9..d16520d 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -72,9 +72,11 @@ int phys_proc_id[NR_CPUS] __read_mostly 
 /* Core ID of each logical CPU */
 int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
 
+/* representing HT siblings of each logical CPU */
 cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
 EXPORT_SYMBOL(cpu_sibling_map);
 
+/* representing HT and core siblings of each logical CPU */
 cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
 EXPORT_SYMBOL(cpu_core_map);
 
@@ -442,35 +444,60 @@ static void __devinit smp_callin(void)
 
 static int cpucount;
 
+/* representing cpus for which sibling maps can be computed */
+static cpumask_t cpu_sibling_setup_map;
+
 static inline void
 set_cpu_sibling_map(int cpu)
 {
 	int i;
+	struct cpuinfo_x86 *c = cpu_data;
+
+	cpu_set(cpu, cpu_sibling_setup_map);
 
 	if (smp_num_siblings > 1) {
-		for (i = 0; i < NR_CPUS; i++) {
-			if (!cpu_isset(i, cpu_callout_map))
-				continue;
-			if (cpu_core_id[cpu] == cpu_core_id[i]) {
+		for_each_cpu_mask(i, cpu_sibling_setup_map) {
+			if (phys_proc_id[cpu] == phys_proc_id[i] &&
+			    cpu_core_id[cpu] == cpu_core_id[i]) {
 				cpu_set(i, cpu_sibling_map[cpu]);
 				cpu_set(cpu, cpu_sibling_map[i]);
+				cpu_set(i, cpu_core_map[cpu]);
+				cpu_set(cpu, cpu_core_map[i]);
 			}
 		}
 	} else {
 		cpu_set(cpu, cpu_sibling_map[cpu]);
 	}
 
-	if (current_cpu_data.x86_num_cores > 1) {
-		for (i = 0; i < NR_CPUS; i++) {
-			if (!cpu_isset(i, cpu_callout_map))
-				continue;
-			if (phys_proc_id[cpu] == phys_proc_id[i]) {
-				cpu_set(i, cpu_core_map[cpu]);
-				cpu_set(cpu, cpu_core_map[i]);
-			}
-		}
-	} else {
+	if (current_cpu_data.x86_max_cores == 1) {
 		cpu_core_map[cpu] = cpu_sibling_map[cpu];
+		c[cpu].booted_cores = 1;
+		return;
+	}
+
+	for_each_cpu_mask(i, cpu_sibling_setup_map) {
+		if (phys_proc_id[cpu] == phys_proc_id[i]) {
+			cpu_set(i, cpu_core_map[cpu]);
+			cpu_set(cpu, cpu_core_map[i]);
+			/*
+			 *  Does this new cpu bringup a new core?
+			 */
+			if (cpus_weight(cpu_sibling_map[cpu]) == 1) {
+				/*
+				 * for each core in package, increment
+				 * the booted_cores for this new cpu
+				 */
+				if (first_cpu(cpu_sibling_map[i]) == i)
+					c[cpu].booted_cores++;
+				/*
+				 * increment the core count for all
+				 * the other cpus in this package
+				 */
+				if (i != cpu)
+					c[i].booted_cores++;
+			} else if (i != cpu && !c[cpu].booted_cores)
+				c[cpu].booted_cores = c[i].booted_cores;
+		}
 	}
 }
 
@@ -1095,11 +1122,8 @@ static void __init smp_boot_cpus(unsigne
 
 	current_thread_info()->cpu = 0;
 	smp_tune_scheduling();
-	cpus_clear(cpu_sibling_map[0]);
-	cpu_set(0, cpu_sibling_map[0]);
 
-	cpus_clear(cpu_core_map[0]);
-	cpu_set(0, cpu_core_map[0]);
+	set_cpu_sibling_map(0);
 
 	/*
 	 * If we couldn't find an SMP configuration at boot time,
@@ -1278,15 +1302,24 @@ static void
 remove_siblinginfo(int cpu)
 {
 	int sibling;
+	struct cpuinfo_x86 *c = cpu_data;
 
+	for_each_cpu_mask(sibling, cpu_core_map[cpu]) {
+		cpu_clear(cpu, cpu_core_map[sibling]);
+		/*
+		 * last thread sibling in this cpu core going down
+		 */
+		if (cpus_weight(cpu_sibling_map[cpu]) == 1)
+			c[sibling].booted_cores--;
+	}
+			
 	for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
 		cpu_clear(cpu, cpu_sibling_map[sibling]);
-	for_each_cpu_mask(sibling, cpu_core_map[cpu])
-		cpu_clear(cpu, cpu_core_map[sibling]);
 	cpus_clear(cpu_sibling_map[cpu]);
 	cpus_clear(cpu_core_map[cpu]);
 	phys_proc_id[cpu] = BAD_APICID;
 	cpu_core_id[cpu] = BAD_APICID;
+	cpu_clear(cpu, cpu_sibling_setup_map);
 }
 
 int __cpu_disable(void)
diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
index 8de658d..52b3ed5 100644
--- a/arch/i386/kernel/srat.c
+++ b/arch/i386/kernel/srat.c
@@ -137,8 +137,8 @@ static void __init parse_memory_affinity
 		 "enabled and removable" : "enabled" ) );
 }
 
-#if MAX_NR_ZONES != 3
-#error "MAX_NR_ZONES != 3, chunk_to_zone requires review"
+#if MAX_NR_ZONES != 4
+#error "MAX_NR_ZONES != 4, chunk_to_zone requires review"
 #endif
 /* Take a chunk of pages from page frame cstart to cend and count the number
  * of pages in each zone, returned via zones[].
diff --git a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c
index e42e46d..b9b6bd5 100644
--- a/arch/i386/kernel/timers/timer_pit.c
+++ b/arch/i386/kernel/timers/timer_pit.c
@@ -25,8 +25,9 @@ static int __init init_pit(char* overrid
 {
  	/* check clock override */
  	if (override[0] && strncmp(override,"pit",3))
- 		printk(KERN_ERR "Warning: clock= override failed. Defaulting to PIT\n");
- 
+ 		printk(KERN_ERR "Warning: clock= override failed. Defaulting "
+				"to PIT\n");
+ 	init_cpu_khz();
 	count_p = LATCH;
 	return 0;
 }
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 542d929..06e26f0 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -28,6 +28,7 @@
 #include <linux/proc_fs.h>
 #include <linux/efi.h>
 #include <linux/memory_hotplug.h>
+#include <linux/initrd.h>
 
 #include <asm/processor.h>
 #include <asm/system.h>
@@ -267,7 +268,7 @@ static void __init permanent_kmaps_init(
 	pkmap_page_table = pte;	
 }
 
-void __devinit free_new_highpage(struct page *page)
+static void __devinit free_new_highpage(struct page *page)
 {
 	set_page_count(page, 1);
 	__free_page(page);
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 8796e12..b76ce1f 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -58,6 +58,10 @@ config IA64_UNCACHED_ALLOCATOR
 	bool
 	select GENERIC_ALLOCATOR
 
+config ZONE_DMA_IS_DMA32
+	bool
+	default y
+
 choice
 	prompt "System type"
 	default IA64_GENERIC
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index e92ea64..4305d2b 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -202,12 +202,9 @@ default_idle (void)
 {
 	local_irq_enable();
 	while (!need_resched()) {
-		if (can_do_pal_halt) {
-			local_irq_disable();
-			if (!need_resched())
-				safe_halt();
-			local_irq_enable();
-		} else
+		if (can_do_pal_halt)
+			safe_halt();
+		else
 			cpu_relax();
 	}
 }
@@ -272,10 +269,14 @@ cpu_idle (void)
 {
 	void (*mark_idle)(int) = ia64_mark_idle;
   	int cpu = smp_processor_id();
-	set_thread_flag(TIF_POLLING_NRFLAG);
 
 	/* endless idle loop with no priority at all */
 	while (1) {
+		if (can_do_pal_halt)
+			clear_thread_flag(TIF_POLLING_NRFLAG);
+		else
+			set_thread_flag(TIF_POLLING_NRFLAG);
+
 		if (!need_resched()) {
 			void (*idle)(void);
 #ifdef CONFIG_SMP
diff --git a/arch/m68k/fpsp040/skeleton.S b/arch/m68k/fpsp040/skeleton.S
index 9571a21..a162919 100644
--- a/arch/m68k/fpsp040/skeleton.S
+++ b/arch/m68k/fpsp040/skeleton.S
@@ -381,10 +381,8 @@ fpsp_done:
 .Lnotkern:
 	SAVE_ALL_INT
 	GET_CURRENT(%d0)
-	tstb	%curptr@(TASK_NEEDRESCHED)
-	jne	ret_from_exception	| deliver signals,
-					| reschedule etc..
-	RESTORE_ALL
+	| deliver signals, reschedule etc..
+	jra	ret_from_exception
 
 |
 |	mem_write --- write to user or supervisor address space
diff --git a/arch/m68k/ifpsp060/iskeleton.S b/arch/m68k/ifpsp060/iskeleton.S
index 4ba2c74..b2dbdf5 100644
--- a/arch/m68k/ifpsp060/iskeleton.S
+++ b/arch/m68k/ifpsp060/iskeleton.S
@@ -75,10 +75,8 @@ _060_isp_done:
 .Lnotkern:
 	SAVE_ALL_INT
 	GET_CURRENT(%d0)
-	tstb	%curptr@(TASK_NEEDRESCHED)
-	jne	ret_from_exception	| deliver signals,
-					| reschedule etc..
-	RESTORE_ALL
+	| deliver signals, reschedule etc..
+	jra	ret_from_exception
 
 |
 | _060_real_chk():
diff --git a/arch/m68k/kernel/asm-offsets.c b/arch/m68k/kernel/asm-offsets.c
index cee3317..c787c5b 100644
--- a/arch/m68k/kernel/asm-offsets.c
+++ b/arch/m68k/kernel/asm-offsets.c
@@ -25,12 +25,8 @@ int main(void)
 	DEFINE(TASK_STATE, offsetof(struct task_struct, state));
 	DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
 	DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
-	DEFINE(TASK_WORK, offsetof(struct task_struct, thread.work));
-	DEFINE(TASK_NEEDRESCHED, offsetof(struct task_struct, thread.work.need_resched));
-	DEFINE(TASK_SYSCALL_TRACE, offsetof(struct task_struct, thread.work.syscall_trace));
-	DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, thread.work.sigpending));
-	DEFINE(TASK_NOTIFY_RESUME, offsetof(struct task_struct, thread.work.notify_resume));
 	DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+	DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
 	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
 	DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
 
@@ -45,6 +41,10 @@ int main(void)
 	DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
 	DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
 
+	/* offsets into the thread_info struct */
+	DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
+	DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
+
 	/* offsets into the pt_regs */
 	DEFINE(PT_D0, offsetof(struct pt_regs, d0));
 	DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0));
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 23ca60a..320fde0 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -44,9 +44,7 @@
 
 #include <asm/asm-offsets.h>
 
-.globl system_call, buserr, trap
-.globl resume, ret_from_exception
-.globl ret_from_signal
+.globl system_call, buserr, trap, resume
 .globl inthandler, sys_call_table
 .globl sys_fork, sys_clone, sys_vfork
 .globl ret_from_interrupt, bad_interrupt
@@ -58,7 +56,7 @@ ENTRY(buserr)
 	movel	%sp,%sp@-		| stack frame pointer argument
 	bsrl	buserr_c
 	addql	#4,%sp
-	jra	ret_from_exception
+	jra	.Lret_from_exception
 
 ENTRY(trap)
 	SAVE_ALL_INT
@@ -66,7 +64,7 @@ ENTRY(trap)
 	movel	%sp,%sp@-		| stack frame pointer argument
 	bsrl	trap_c
 	addql	#4,%sp
-	jra	ret_from_exception
+	jra	.Lret_from_exception
 
 	| After a fork we jump here directly from resume,
 	| so that %d1 contains the previous task
@@ -75,30 +73,31 @@ ENTRY(ret_from_fork)
 	movel	%d1,%sp@-
 	jsr	schedule_tail
 	addql	#4,%sp
-	jra	ret_from_exception
+	jra	.Lret_from_exception
 
-badsys:
-	movel	#-ENOSYS,%sp@(PT_D0)
-	jra	ret_from_exception
-
-do_trace:
+do_trace_entry:
 	movel	#-ENOSYS,%sp@(PT_D0)	| needed for strace
 	subql	#4,%sp
 	SAVE_SWITCH_STACK
 	jbsr	syscall_trace
 	RESTORE_SWITCH_STACK
 	addql	#4,%sp
-	movel	%sp@(PT_ORIG_D0),%d1
-	movel	#-ENOSYS,%d0
-	cmpl	#NR_syscalls,%d1
-	jcc	1f
-	jbsr	@(sys_call_table,%d1:l:4)@(0)
-1:	movel	%d0,%sp@(PT_D0)		| save the return value
-	subql	#4,%sp			| dummy return address
+	movel	%sp@(PT_ORIG_D0),%d0
+	cmpl	#NR_syscalls,%d0
+	jcs	syscall
+badsys:
+	movel	#-ENOSYS,%sp@(PT_D0)
+	jra	ret_from_syscall
+
+do_trace_exit:
+	subql	#4,%sp
 	SAVE_SWITCH_STACK
 	jbsr	syscall_trace
+	RESTORE_SWITCH_STACK
+	addql	#4,%sp
+	jra	.Lret_from_exception
 
-ret_from_signal:
+ENTRY(ret_from_signal)
 	RESTORE_SWITCH_STACK
 	addql	#4,%sp
 /* on 68040 complete pending writebacks if any */
@@ -111,7 +110,7 @@ ret_from_signal:
 	addql	#4,%sp
 1:
 #endif
-	jra	ret_from_exception
+	jra	.Lret_from_exception
 
 ENTRY(system_call)
 	SAVE_ALL_SYS
@@ -120,30 +119,34 @@ ENTRY(system_call)
 	| save top of frame
 	movel	%sp,%curptr@(TASK_THREAD+THREAD_ESP0)
 
-	tstb	%curptr@(TASK_SYSCALL_TRACE)
-	jne	do_trace
+	| syscall trace?
+	tstb	%curptr@(TASK_INFO+TINFO_FLAGS+2)
+	jmi	do_trace_entry
 	cmpl	#NR_syscalls,%d0
 	jcc	badsys
+syscall:
 	jbsr	@(sys_call_table,%d0:l:4)@(0)
 	movel	%d0,%sp@(PT_D0)		| save the return value
-
+ret_from_syscall:
 	|oriw	#0x0700,%sr
-	movel	%curptr@(TASK_WORK),%d0
+	movew	%curptr@(TASK_INFO+TINFO_FLAGS+2),%d0
 	jne	syscall_exit_work
 1:	RESTORE_ALL
 
 syscall_exit_work:
 	btst	#5,%sp@(PT_SR)		| check if returning to kernel
 	bnes	1b			| if so, skip resched, signals
-	tstw	%d0
-	jeq	do_signal_return
-	tstb	%d0
-	jne	do_delayed_trace
-
+	lslw	#1,%d0
+	jcs	do_trace_exit
+	jmi	do_delayed_trace
+	lslw	#8,%d0
+	jmi	do_signal_return
 	pea	resume_userspace
-	jmp	schedule
+	jra	schedule
+
 
-ret_from_exception:
+ENTRY(ret_from_exception)
+.Lret_from_exception:
 	btst	#5,%sp@(PT_SR)		| check if returning to kernel
 	bnes	1f			| if so, skip resched, signals
 	| only allow interrupts when we are really the last one on the
@@ -152,19 +155,18 @@ ret_from_exception:
 	andw	#ALLOWINT,%sr
 
 resume_userspace:
-	movel	%curptr@(TASK_WORK),%d0
-	lsrl	#8,%d0
+	moveb	%curptr@(TASK_INFO+TINFO_FLAGS+3),%d0
 	jne	exit_work
 1:	RESTORE_ALL
 
 exit_work:
 	| save top of frame
 	movel	%sp,%curptr@(TASK_THREAD+THREAD_ESP0)
-	tstb	%d0
-	jeq	do_signal_return
-
+	lslb	#1,%d0
+	jmi	do_signal_return
 	pea	resume_userspace
-	jmp	schedule
+	jra	schedule
+
 
 do_signal_return:
 	|andw	#ALLOWINT,%sr
@@ -254,7 +256,7 @@ ret_from_interrupt:
 
 	/* check if we need to do software interrupts */
 	tstl	irq_stat+CPUSTAT_SOFTIRQ_PENDING
-	jeq	ret_from_exception
+	jeq	.Lret_from_exception
 	pea	ret_from_exception
 	jra	do_softirq
 
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index 7e54422..540638c 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -109,7 +109,7 @@ static inline void singlestep_disable(st
 {
 	unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
 	put_reg(child, PT_SR, tmp);
-	child->thread.work.delayed_trace = 0;
+	clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
 }
 
 /*
@@ -118,7 +118,7 @@ static inline void singlestep_disable(st
 void ptrace_disable(struct task_struct *child)
 {
 	singlestep_disable(child);
-	child->thread.work.syscall_trace = 0;
+	clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 }
 
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -198,9 +198,9 @@ long arch_ptrace(struct task_struct *chi
 			goto out_eio;
 
 		if (request == PTRACE_SYSCALL)
-			child->thread.work.syscall_trace = ~0;
+			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		else
-			child->thread.work.syscall_trace = 0;
+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		child->exit_code = data;
 		singlestep_disable(child);
 		wake_up_process(child);
@@ -223,10 +223,10 @@ long arch_ptrace(struct task_struct *chi
 		if (!valid_signal(data))
 			goto out_eio;
 
-		child->thread.work.syscall_trace = 0;
+		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
 		put_reg(child, PT_SR, tmp);
-		child->thread.work.delayed_trace = 1;
+		set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
 
 		child->exit_code = data;
 		/* give it a chance to run. */
@@ -288,9 +288,6 @@ out_eio:
 
 asmlinkage void syscall_trace(void)
 {
-	if (!current->thread.work.delayed_trace &&
-	    !current->thread.work.syscall_trace)
-		return;
 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
 				 ? 0x80 : 0));
 	/*
diff --git a/arch/mips/au1000/common/power.c b/arch/mips/au1000/common/power.c
index f85093b..f492631 100644
--- a/arch/mips/au1000/common/power.c
+++ b/arch/mips/au1000/common/power.c
@@ -32,6 +32,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/slab.h>
 #include <linux/sysctl.h>
 #include <linux/jiffies.h>
diff --git a/arch/mips/au1000/common/usbdev.c b/arch/mips/au1000/common/usbdev.c
index 0b21bed..2cab762 100644
--- a/arch/mips/au1000/common/usbdev.c
+++ b/arch/mips/au1000/common/usbdev.c
@@ -348,7 +348,7 @@ endpoint_stall(endpoint_t * ep)
 {
 	u32 cs;
 
-	warn(__FUNCTION__);
+	warn("%s", __FUNCTION__);
 
 	cs = au_readl(ep->reg->ctrl_stat) | USBDEV_CS_STALL;
 	au_writel(cs, ep->reg->ctrl_stat);
@@ -360,7 +360,7 @@ endpoint_unstall(endpoint_t * ep)
 {
 	u32 cs;
 
-	warn(__FUNCTION__);
+	warn("%s", __FUNCTION__);
 
 	cs = au_readl(ep->reg->ctrl_stat) & ~USBDEV_CS_STALL;
 	au_writel(cs, ep->reg->ctrl_stat);
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index c523029..94df74b 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -261,7 +261,7 @@ config PPC_ISERIES
 
 config EMBEDDED6xx
 	bool "Embedded 6xx/7xx/7xxx-based board"
-	depends on PPC32
+	depends on PPC32 && BROKEN
 
 config APUS
 	bool "Amiga-APUS"
@@ -305,7 +305,7 @@ config PPC_PMAC64
 
 config PPC_PREP
 	bool "  PowerPC Reference Platform (PReP) based machines"
-	depends on PPC_MULTIPLATFORM && PPC32
+	depends on PPC_MULTIPLATFORM && PPC32 && BROKEN
 	select PPC_I8259
 	select PPC_INDIRECT_PCI
 	default y
@@ -932,6 +932,7 @@ source "arch/powerpc/oprofile/Kconfig"
 
 config KPROBES
 	bool "Kprobes (EXPERIMENTAL)"
+	depends on PPC64
 	help
 	  Kprobes allows you to trap at almost any kernel address and
 	  execute a callback function.  register_kprobe() establishes
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 5bc11bd..d41ad2e 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -187,7 +187,7 @@ archprepare: checkbin
 
 # Temporary hack until we have migrated to asm-powerpc
 include/asm: arch/$(ARCH)/include/asm
-arch/$(ARCH)/include/asm:
+arch/$(ARCH)/include/asm: FORCE
 	$(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi
 	$(Q)ln -fsn $(srctree)/include/asm-$(OLDARCH) arch/$(ARCH)/include/asm
 
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 9f09dff..913962c 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -1,18 +1,33 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-rc4
-# Thu Oct 20 08:32:17 2005
+# Linux kernel version: 2.6.15-rc1
+# Mon Nov 14 15:27:00 2005
 #
+CONFIG_PPC64=y
 CONFIG_64BIT=y
+CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_ARCH_MAY_HAVE_PC_FDC=y
-CONFIG_FORCE_MAX_ZONEORDER=13
+
+#
+# Processor support
+#
+# CONFIG_POWER4_ONLY is not set
+CONFIG_POWER3=y
+CONFIG_POWER4=y
+CONFIG_PPC_FPU=y
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=128
 
 #
 # Code maturity level options
@@ -68,75 +83,103 @@ CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
-CONFIG_SYSVIPC_COMPAT=y
+
+#
+# Block layer
+#
+
+#
+# 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"
 
 #
 # Platform support
 #
-# CONFIG_PPC_ISERIES is not set
 CONFIG_PPC_MULTIPLATFORM=y
+# CONFIG_PPC_ISERIES is not set
+# CONFIG_EMBEDDED6xx is not set
+# CONFIG_APUS is not set
 CONFIG_PPC_PSERIES=y
-# CONFIG_PPC_BPA is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_MAPLE is not set
-CONFIG_PPC=y
-CONFIG_PPC64=y
+# CONFIG_PPC_CELL is not set
 CONFIG_PPC_OF=y
 CONFIG_XICS=y
+# CONFIG_U3_DART is not set
 CONFIG_MPIC=y
-CONFIG_ALTIVEC=y
-CONFIG_PPC_SPLPAR=y
-CONFIG_KEXEC=y
+CONFIG_PPC_RTAS=y
+CONFIG_RTAS_ERROR_LOGGING=y
+CONFIG_RTAS_PROC=y
+CONFIG_RTAS_FLASH=m
+# CONFIG_MMIO_NVRAM is not set
 CONFIG_IBMVIO=y
-# CONFIG_U3_DART is not set
-# CONFIG_BOOTX_TEXT is not set
-# CONFIG_POWER4_ONLY is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# Kernel options
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_PREEMPT_BKL is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_FORCE_MAX_ZONEORDER=13
 CONFIG_IOMMU_VMERGE=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=128
+CONFIG_HOTPLUG_CPU=y
+CONFIG_KEXEC=y
+# CONFIG_IRQ_ALL_CPUS is not set
+CONFIG_PPC_SPLPAR=y
+CONFIG_EEH=y
+CONFIG_SCANLOG=m
+CONFIG_LPARCFG=y
+CONFIG_NUMA=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
-CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
-CONFIG_DISCONTIGMEM_MANUAL=y
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_DISCONTIGMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
 CONFIG_NEED_MULTIPLE_NODES=y
+CONFIG_HAVE_MEMORY_PRESENT=y
 # CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_EXTREME=y
+# CONFIG_MEMORY_HOTPLUG is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
 CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
 CONFIG_NODES_SPAN_OTHER_NODES=y
-CONFIG_NUMA=y
+# CONFIG_PPC_64K_PAGES is not set
 CONFIG_SCHED_SMT=y
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-# CONFIG_PREEMPT_BKL is not set
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
-CONFIG_EEH=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_PPC_RTAS=y
-CONFIG_RTAS_PROC=y
-CONFIG_RTAS_FLASH=m
-CONFIG_SCANLOG=m
-CONFIG_LPARCFG=y
-CONFIG_SECCOMP=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_HOTPLUG_CPU=y
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
 
 #
-# Bus Options
+# Bus options
 #
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_I8259=y
+# CONFIG_PPC_INDIRECT_PCI is not set
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 CONFIG_PCI_LEGACY_PROC=y
@@ -156,6 +199,7 @@ CONFIG_HOTPLUG_PCI=m
 # CONFIG_HOTPLUG_PCI_SHPC is not set
 CONFIG_HOTPLUG_PCI_RPA=m
 CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
+CONFIG_KERNEL_START=0xc000000000000000
 
 #
 # Networking
@@ -197,6 +241,10 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
 CONFIG_NETFILTER_NETLINK=y
 CONFIG_NETFILTER_NETLINK_QUEUE=m
 CONFIG_NETFILTER_NETLINK_LOG=m
@@ -299,6 +347,10 @@ CONFIG_LLC=y
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
 # CONFIG_NET_SCHED is not set
 CONFIG_NET_CLS_ROUTE=y
 
@@ -368,14 +420,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=65536
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -473,6 +517,7 @@ CONFIG_SCSI_ISCSI_ATTRS=m
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -559,6 +604,7 @@ CONFIG_DM_MULTIPATH_EMC=m
 #
 # Macintosh device drivers
 #
+# CONFIG_WINDFARM is not set
 
 #
 # Network device support
@@ -645,7 +691,6 @@ CONFIG_IXGB=m
 # CONFIG_IXGB_NAPI is not set
 CONFIG_S2IO=m
 # CONFIG_S2IO_NAPI is not set
-# CONFIG_2BUFF_MODE is not set
 
 #
 # Token Ring devices
@@ -674,6 +719,7 @@ CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
 CONFIG_PPP_DEFLATE=m
 CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
 CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
 # CONFIG_NET_FC is not set
@@ -784,6 +830,8 @@ CONFIG_HVCS=m
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -801,6 +849,7 @@ CONFIG_MAX_RAW_DEVS=1024
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -852,6 +901,7 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
 # CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -893,7 +943,6 @@ CONFIG_FB=y
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
 CONFIG_FB_MACMODES=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
@@ -905,6 +954,7 @@ CONFIG_FB_OF=y
 # CONFIG_FB_ASILIANT is not set
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_NVIDIA is not set
 # CONFIG_FB_RIVA is not set
 CONFIG_FB_MATROX=y
@@ -927,7 +977,6 @@ CONFIG_FB_RADEON_I2C=y
 # CONFIG_FB_VOODOO1 is not set
 # CONFIG_FB_CYBLA is not set
 # CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -936,6 +985,7 @@ CONFIG_FB_RADEON_I2C=y
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 # CONFIG_FONTS is not set
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
@@ -990,12 +1040,15 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 #
 # USB Device Class drivers
 #
-# CONFIG_USB_BLUETOOTH_TTY is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# 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
@@ -1106,6 +1159,7 @@ CONFIG_INFINIBAND_MTHCA=m
 # CONFIG_INFINIBAND_MTHCA_DEBUG is not set
 CONFIG_INFINIBAND_IPOIB=m
 # CONFIG_INFINIBAND_IPOIB_DEBUG is not set
+# CONFIG_INFINIBAND_SRP is not set
 
 #
 # SN Devices
@@ -1288,10 +1342,25 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_UTF8 is not set
 
 #
-# Profiling support
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+
+#
+# Instrumentation Support
 #
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
+# CONFIG_KPROBES is not set
 
 #
 # Kernel hacking
@@ -1308,14 +1377,15 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_STACKOVERFLOW=y
-# CONFIG_KPROBES is not set
 CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_DEBUGGER=y
 CONFIG_XMON=y
 CONFIG_XMON_DEFAULT=y
-# CONFIG_PPCDBG is not set
 CONFIG_IRQSTACKS=y
+# CONFIG_BOOTX_TEXT is not set
 
 #
 # Security options
@@ -1355,17 +1425,3 @@ CONFIG_CRYPTO_TEST=m
 #
 # Hardware crypto devices
 #
-
-#
-# Library routines
-#
-CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=m
-CONFIG_TEXTSEARCH=y
-CONFIG_TEXTSEARCH_KMP=m
-CONFIG_TEXTSEARCH_BM=m
-CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 9a74b7a..4970e37 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -25,7 +25,7 @@ obj-$(CONFIG_PPC_OF)		+= of_device.o
 procfs-$(CONFIG_PPC64)		:= proc_ppc64.o
 obj-$(CONFIG_PROC_FS)		+= $(procfs-y)
 rtaspci-$(CONFIG_PPC64)		:= rtas_pci.o
-obj-$(CONFIG_PPC_RTAS)		+= rtas.o $(rtaspci-y)
+obj-$(CONFIG_PPC_RTAS)		+= rtas.o rtas-rtc.o $(rtaspci-y)
 obj-$(CONFIG_RTAS_FLASH)	+= rtas_flash.o
 obj-$(CONFIG_RTAS_PROC)		+= rtas-proc.o
 obj-$(CONFIG_LPARCFG)		+= lparcfg.o
@@ -49,12 +49,23 @@ extra-y				+= vmlinux.lds
 obj-y				+= process.o init_task.o time.o \
 				   prom.o traps.o setup-common.o
 obj-$(CONFIG_PPC32)		+= entry_32.o setup_32.o misc_32.o systbl.o
-obj-$(CONFIG_PPC64)		+= misc_64.o
+obj-$(CONFIG_PPC64)		+= misc_64.o dma_64.o iommu.o
 obj-$(CONFIG_PPC_OF)		+= prom_init.o
 obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
 obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
 obj-$(CONFIG_6xx)		+= idle_6xx.o
 obj-$(CONFIG_SMP)		+= smp.o
+obj-$(CONFIG_KPROBES)		+= kprobes.o
+
+module-$(CONFIG_PPC64)		+= module_64.o
+obj-$(CONFIG_MODULES)		+= $(module-y)
+
+pci64-$(CONFIG_PPC64)		+= pci_64.o pci_dn.o pci_iommu.o \
+				   pci_direct_iommu.o iomap.o
+obj-$(CONFIG_PCI)		+= $(pci64-y)
+
+kexec64-$(CONFIG_PPC64)		+= machine_kexec_64.o
+obj-$(CONFIG_KEXEC)		+= $(kexec64-y)
 
 ifeq ($(CONFIG_PPC_ISERIES),y)
 $(obj)/head_64.o: $(obj)/lparmap.s
@@ -62,11 +73,8 @@ AFLAGS_head_64.o += -I$(obj)
 endif
 
 else
-# stuff used from here for ARCH=ppc or ARCH=ppc64
+# stuff used from here for ARCH=ppc
 smpobj-$(CONFIG_SMP)		+= smp.o
-obj-$(CONFIG_PPC64)		+= traps.o process.o init_task.o time.o \
-				   setup-common.o $(smpobj-y)
-
 
 endif
 
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 4550eb4..91538d2 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -270,13 +270,15 @@ int main(void)
 	DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec));
 	DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec));
 	DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec));
+	DEFINE(TSPC64_TV_SEC, offsetof(struct timespec, tv_sec));
+	DEFINE(TSPC64_TV_NSEC, offsetof(struct timespec, tv_nsec));
 	DEFINE(TSPC32_TV_SEC, offsetof(struct compat_timespec, tv_sec));
 	DEFINE(TSPC32_TV_NSEC, offsetof(struct compat_timespec, tv_nsec));
 #else
 	DEFINE(TVAL32_TV_SEC, offsetof(struct timeval, tv_sec));
 	DEFINE(TVAL32_TV_USEC, offsetof(struct timeval, tv_usec));
-	DEFINE(TSPEC32_TV_SEC, offsetof(struct timespec, tv_sec));
-	DEFINE(TSPEC32_TV_NSEC, offsetof(struct timespec, tv_nsec));
+	DEFINE(TSPC32_TV_SEC, offsetof(struct timespec, tv_sec));
+	DEFINE(TSPC32_TV_NSEC, offsetof(struct timespec, tv_nsec));
 #endif
 	/* timeval/timezone offsets for use by vdso */
 	DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
new file mode 100644
index 0000000..7c34196
--- /dev/null
+++ b/arch/powerpc/kernel/dma_64.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Implements the generic device dma API for ppc64. Handles
+ * the pci and vio busses
+ */
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+/* Include the busses we support */
+#include <linux/pci.h>
+#include <asm/vio.h>
+#include <asm/scatterlist.h>
+#include <asm/bug.h>
+
+static struct dma_mapping_ops *get_dma_ops(struct device *dev)
+{
+#ifdef CONFIG_PCI
+	if (dev->bus == &pci_bus_type)
+		return &pci_dma_ops;
+#endif
+#ifdef CONFIG_IBMVIO
+	if (dev->bus == &vio_bus_type)
+		return &vio_dma_ops;
+#endif
+	return NULL;
+}
+
+int dma_supported(struct device *dev, u64 mask)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	if (dma_ops)
+		return dma_ops->dma_supported(dev, mask);
+	BUG();
+	return 0;
+}
+EXPORT_SYMBOL(dma_supported);
+
+int dma_set_mask(struct device *dev, u64 dma_mask)
+{
+#ifdef CONFIG_PCI
+	if (dev->bus == &pci_bus_type)
+		return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
+#endif
+#ifdef CONFIG_IBMVIO
+	if (dev->bus == &vio_bus_type)
+		return -EIO;
+#endif /* CONFIG_IBMVIO */
+	BUG();
+	return 0;
+}
+EXPORT_SYMBOL(dma_set_mask);
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+		dma_addr_t *dma_handle, gfp_t flag)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	if (dma_ops)
+		return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
+	BUG();
+	return NULL;
+}
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
+		dma_addr_t dma_handle)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	if (dma_ops)
+		dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
+	else
+		BUG();
+}
+EXPORT_SYMBOL(dma_free_coherent);
+
+dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size,
+		enum dma_data_direction direction)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	if (dma_ops)
+		return dma_ops->map_single(dev, cpu_addr, size, direction);
+	BUG();
+	return (dma_addr_t)0;
+}
+EXPORT_SYMBOL(dma_map_single);
+
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		enum dma_data_direction direction)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	if (dma_ops)
+		dma_ops->unmap_single(dev, dma_addr, size, direction);
+	else
+		BUG();
+}
+EXPORT_SYMBOL(dma_unmap_single);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+		unsigned long offset, size_t size,
+		enum dma_data_direction direction)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	if (dma_ops)
+		return dma_ops->map_single(dev,
+				(page_address(page) + offset), size, direction);
+	BUG();
+	return (dma_addr_t)0;
+}
+EXPORT_SYMBOL(dma_map_page);
+
+void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+		enum dma_data_direction direction)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	if (dma_ops)
+		dma_ops->unmap_single(dev, dma_address, size, direction);
+	else
+		BUG();
+}
+EXPORT_SYMBOL(dma_unmap_page);
+
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+		enum dma_data_direction direction)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	if (dma_ops)
+		return dma_ops->map_sg(dev, sg, nents, direction);
+	BUG();
+	return 0;
+}
+EXPORT_SYMBOL(dma_map_sg);
+
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+		enum dma_data_direction direction)
+{
+	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+	if (dma_ops)
+		dma_ops->unmap_sg(dev, sg, nhwentries, direction);
+	else
+		BUG();
+}
+EXPORT_SYMBOL(dma_unmap_sg);
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 5063c60..8d60fa9 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -24,7 +24,7 @@
  *    Copyright 2002-2004 MontaVista Software, Inc.
  *      PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org>
  *    Copyright 2004 Freescale Semiconductor, Inc
- *      PowerPC e500 modifications, Kumar Gala <kumar.gala@freescale.com>
+ *      PowerPC e500 modifications, Kumar Gala <galak@kernel.crashing.org>
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
diff --git a/arch/powerpc/kernel/ioctl32.c b/arch/powerpc/kernel/ioctl32.c
index 3fa6a93..0fa3d27 100644
--- a/arch/powerpc/kernel/ioctl32.c
+++ b/arch/powerpc/kernel/ioctl32.c
@@ -40,10 +40,6 @@ IOCTL_TABLE_START
 #define DECLARES
 #include "compat_ioctl.c"
 
-/* Little p (/dev/rtc, /dev/envctrl, etc.) */
-COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
-COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
-
 IOCTL_TABLE_END
 
 int ioctl_table_size = ARRAY_SIZE(ioctl_start);
diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c
new file mode 100644
index 0000000..6160c8d
--- /dev/null
+++ b/arch/powerpc/kernel/iomap.c
@@ -0,0 +1,146 @@
+/*
+ * arch/ppc64/kernel/iomap.c
+ *
+ * ppc64 "iomap" interface implementation.
+ *
+ * (C) Copyright 2004 Linus Torvalds
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+
+/*
+ * Here comes the ppc64 implementation of the IOMAP 
+ * interfaces.
+ */
+unsigned int fastcall ioread8(void __iomem *addr)
+{
+	return readb(addr);
+}
+unsigned int fastcall ioread16(void __iomem *addr)
+{
+	return readw(addr);
+}
+unsigned int fastcall ioread16be(void __iomem *addr)
+{
+	return in_be16(addr);
+}
+unsigned int fastcall ioread32(void __iomem *addr)
+{
+	return readl(addr);
+}
+unsigned int fastcall ioread32be(void __iomem *addr)
+{
+	return in_be32(addr);
+}
+EXPORT_SYMBOL(ioread8);
+EXPORT_SYMBOL(ioread16);
+EXPORT_SYMBOL(ioread16be);
+EXPORT_SYMBOL(ioread32);
+EXPORT_SYMBOL(ioread32be);
+
+void fastcall iowrite8(u8 val, void __iomem *addr)
+{
+	writeb(val, addr);
+}
+void fastcall iowrite16(u16 val, void __iomem *addr)
+{
+	writew(val, addr);
+}
+void fastcall iowrite16be(u16 val, void __iomem *addr)
+{
+	out_be16(addr, val);
+}
+void fastcall iowrite32(u32 val, void __iomem *addr)
+{
+	writel(val, addr);
+}
+void fastcall iowrite32be(u32 val, void __iomem *addr)
+{
+	out_be32(addr, val);
+}
+EXPORT_SYMBOL(iowrite8);
+EXPORT_SYMBOL(iowrite16);
+EXPORT_SYMBOL(iowrite16be);
+EXPORT_SYMBOL(iowrite32);
+EXPORT_SYMBOL(iowrite32be);
+
+/*
+ * These are the "repeat read/write" functions. Note the
+ * non-CPU byte order. We do things in "IO byteorder"
+ * here.
+ *
+ * FIXME! We could make these do EEH handling if we really
+ * wanted. Not clear if we do.
+ */
+void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	_insb((u8 __iomem *) addr, dst, count);
+}
+void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	_insw_ns((u16 __iomem *) addr, dst, count);
+}
+void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
+{
+	_insl_ns((u32 __iomem *) addr, dst, count);
+}
+EXPORT_SYMBOL(ioread8_rep);
+EXPORT_SYMBOL(ioread16_rep);
+EXPORT_SYMBOL(ioread32_rep);
+
+void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	_outsb((u8 __iomem *) addr, src, count);
+}
+void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	_outsw_ns((u16 __iomem *) addr, src, count);
+}
+void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
+{
+	_outsl_ns((u32 __iomem *) addr, src, count);
+}
+EXPORT_SYMBOL(iowrite8_rep);
+EXPORT_SYMBOL(iowrite16_rep);
+EXPORT_SYMBOL(iowrite32_rep);
+
+void __iomem *ioport_map(unsigned long port, unsigned int len)
+{
+	if (!_IO_IS_VALID(port))
+		return NULL;
+	return (void __iomem *) (port+pci_io_base);
+}
+
+void ioport_unmap(void __iomem *addr)
+{
+	/* Nothing to do */
+}
+EXPORT_SYMBOL(ioport_map);
+EXPORT_SYMBOL(ioport_unmap);
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
+{
+	unsigned long start = pci_resource_start(dev, bar);
+	unsigned long len = pci_resource_len(dev, bar);
+	unsigned long flags = pci_resource_flags(dev, bar);
+
+	if (!len)
+		return NULL;
+	if (max && len > max)
+		len = max;
+	if (flags & IORESOURCE_IO)
+		return ioport_map(start, len);
+	if (flags & IORESOURCE_MEM)
+		return ioremap(start, len);
+	/* What? */
+	return NULL;
+}
+
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
+{
+	/* Nothing to do */
+}
+EXPORT_SYMBOL(pci_iomap);
+EXPORT_SYMBOL(pci_iounmap);
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
new file mode 100644
index 0000000..4d9b438
--- /dev/null
+++ b/arch/powerpc/kernel/iommu.c
@@ -0,0 +1,572 @@
+/*
+ * arch/ppc64/kernel/iommu.c
+ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
+ * 
+ * Rewrite, cleanup, new allocation schemes, virtual merging: 
+ * Copyright (C) 2004 Olof Johansson, IBM Corporation
+ *               and  Ben. Herrenschmidt, IBM Corporation
+ *
+ * Dynamic DMA mapping support, bus-independent parts.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/iommu.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+
+#define DBG(...)
+
+#ifdef CONFIG_IOMMU_VMERGE
+static int novmerge = 0;
+#else
+static int novmerge = 1;
+#endif
+
+static int __init setup_iommu(char *str)
+{
+	if (!strcmp(str, "novmerge"))
+		novmerge = 1;
+	else if (!strcmp(str, "vmerge"))
+		novmerge = 0;
+	return 1;
+}
+
+__setup("iommu=", setup_iommu);
+
+static unsigned long iommu_range_alloc(struct iommu_table *tbl,
+                                       unsigned long npages,
+                                       unsigned long *handle,
+                                       unsigned int align_order)
+{ 
+	unsigned long n, end, i, start;
+	unsigned long limit;
+	int largealloc = npages > 15;
+	int pass = 0;
+	unsigned long align_mask;
+
+	align_mask = 0xffffffffffffffffl >> (64 - align_order);
+
+	/* This allocator was derived from x86_64's bit string search */
+
+	/* Sanity check */
+	if (unlikely(npages) == 0) {
+		if (printk_ratelimit())
+			WARN_ON(1);
+		return DMA_ERROR_CODE;
+	}
+
+	if (handle && *handle)
+		start = *handle;
+	else
+		start = largealloc ? tbl->it_largehint : tbl->it_hint;
+
+	/* Use only half of the table for small allocs (15 pages or less) */
+	limit = largealloc ? tbl->it_size : tbl->it_halfpoint;
+
+	if (largealloc && start < tbl->it_halfpoint)
+		start = tbl->it_halfpoint;
+
+	/* The case below can happen if we have a small segment appended
+	 * to a large, or when the previous alloc was at the very end of
+	 * the available space. If so, go back to the initial start.
+	 */
+	if (start >= limit)
+		start = largealloc ? tbl->it_largehint : tbl->it_hint;
+	
+ again:
+
+	n = find_next_zero_bit(tbl->it_map, limit, start);
+
+	/* Align allocation */
+	n = (n + align_mask) & ~align_mask;
+
+	end = n + npages;
+
+	if (unlikely(end >= limit)) {
+		if (likely(pass < 2)) {
+			/* First failure, just rescan the half of the table.
+			 * Second failure, rescan the other half of the table.
+			 */
+			start = (largealloc ^ pass) ? tbl->it_halfpoint : 0;
+			limit = pass ? tbl->it_size : limit;
+			pass++;
+			goto again;
+		} else {
+			/* Third failure, give up */
+			return DMA_ERROR_CODE;
+		}
+	}
+
+	for (i = n; i < end; i++)
+		if (test_bit(i, tbl->it_map)) {
+			start = i+1;
+			goto again;
+		}
+
+	for (i = n; i < end; i++)
+		__set_bit(i, tbl->it_map);
+
+	/* Bump the hint to a new block for small allocs. */
+	if (largealloc) {
+		/* Don't bump to new block to avoid fragmentation */
+		tbl->it_largehint = end;
+	} else {
+		/* Overflow will be taken care of at the next allocation */
+		tbl->it_hint = (end + tbl->it_blocksize - 1) &
+		                ~(tbl->it_blocksize - 1);
+	}
+
+	/* Update handle for SG allocations */
+	if (handle)
+		*handle = end;
+
+	return n;
+}
+
+static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page,
+		       unsigned int npages, enum dma_data_direction direction,
+		       unsigned int align_order)
+{
+	unsigned long entry, flags;
+	dma_addr_t ret = DMA_ERROR_CODE;
+	
+	spin_lock_irqsave(&(tbl->it_lock), flags);
+
+	entry = iommu_range_alloc(tbl, npages, NULL, align_order);
+
+	if (unlikely(entry == DMA_ERROR_CODE)) {
+		spin_unlock_irqrestore(&(tbl->it_lock), flags);
+		return DMA_ERROR_CODE;
+	}
+
+	entry += tbl->it_offset;	/* Offset into real TCE table */
+	ret = entry << PAGE_SHIFT;	/* Set the return dma address */
+
+	/* Put the TCEs in the HW table */
+	ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & PAGE_MASK,
+			 direction);
+
+
+	/* Flush/invalidate TLB caches if necessary */
+	if (ppc_md.tce_flush)
+		ppc_md.tce_flush(tbl);
+
+	spin_unlock_irqrestore(&(tbl->it_lock), flags);
+
+	/* Make sure updates are seen by hardware */
+	mb();
+
+	return ret;
+}
+
+static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, 
+			 unsigned int npages)
+{
+	unsigned long entry, free_entry;
+	unsigned long i;
+
+	entry = dma_addr >> PAGE_SHIFT;
+	free_entry = entry - tbl->it_offset;
+
+	if (((free_entry + npages) > tbl->it_size) ||
+	    (entry < tbl->it_offset)) {
+		if (printk_ratelimit()) {
+			printk(KERN_INFO "iommu_free: invalid entry\n");
+			printk(KERN_INFO "\tentry     = 0x%lx\n", entry); 
+			printk(KERN_INFO "\tdma_addr  = 0x%lx\n", (u64)dma_addr);
+			printk(KERN_INFO "\tTable     = 0x%lx\n", (u64)tbl);
+			printk(KERN_INFO "\tbus#      = 0x%lx\n", (u64)tbl->it_busno);
+			printk(KERN_INFO "\tsize      = 0x%lx\n", (u64)tbl->it_size);
+			printk(KERN_INFO "\tstartOff  = 0x%lx\n", (u64)tbl->it_offset);
+			printk(KERN_INFO "\tindex     = 0x%lx\n", (u64)tbl->it_index);
+			WARN_ON(1);
+		}
+		return;
+	}
+
+	ppc_md.tce_free(tbl, entry, npages);
+	
+	for (i = 0; i < npages; i++)
+		__clear_bit(free_entry+i, tbl->it_map);
+}
+
+static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
+		unsigned int npages)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&(tbl->it_lock), flags);
+
+	__iommu_free(tbl, dma_addr, npages);
+
+	/* Make sure TLB cache is flushed if the HW needs it. We do
+	 * not do an mb() here on purpose, it is not needed on any of
+	 * the current platforms.
+	 */
+	if (ppc_md.tce_flush)
+		ppc_md.tce_flush(tbl);
+
+	spin_unlock_irqrestore(&(tbl->it_lock), flags);
+}
+
+int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
+		struct scatterlist *sglist, int nelems,
+		enum dma_data_direction direction)
+{
+	dma_addr_t dma_next = 0, dma_addr;
+	unsigned long flags;
+	struct scatterlist *s, *outs, *segstart;
+	int outcount, incount;
+	unsigned long handle;
+
+	BUG_ON(direction == DMA_NONE);
+
+	if ((nelems == 0) || !tbl)
+		return 0;
+
+	outs = s = segstart = &sglist[0];
+	outcount = 1;
+	incount = nelems;
+	handle = 0;
+
+	/* Init first segment length for backout at failure */
+	outs->dma_length = 0;
+
+	DBG("mapping %d elements:\n", nelems);
+
+	spin_lock_irqsave(&(tbl->it_lock), flags);
+
+	for (s = outs; nelems; nelems--, s++) {
+		unsigned long vaddr, npages, entry, slen;
+
+		slen = s->length;
+		/* Sanity check */
+		if (slen == 0) {
+			dma_next = 0;
+			continue;
+		}
+		/* Allocate iommu entries for that segment */
+		vaddr = (unsigned long)page_address(s->page) + s->offset;
+		npages = PAGE_ALIGN(vaddr + slen) - (vaddr & PAGE_MASK);
+		npages >>= PAGE_SHIFT;
+		entry = iommu_range_alloc(tbl, npages, &handle, 0);
+
+		DBG("  - vaddr: %lx, size: %lx\n", vaddr, slen);
+
+		/* Handle failure */
+		if (unlikely(entry == DMA_ERROR_CODE)) {
+			if (printk_ratelimit())
+				printk(KERN_INFO "iommu_alloc failed, tbl %p vaddr %lx"
+				       " npages %lx\n", tbl, vaddr, npages);
+			goto failure;
+		}
+
+		/* Convert entry to a dma_addr_t */
+		entry += tbl->it_offset;
+		dma_addr = entry << PAGE_SHIFT;
+		dma_addr |= s->offset;
+
+		DBG("  - %lx pages, entry: %lx, dma_addr: %lx\n",
+			    npages, entry, dma_addr);
+
+		/* Insert into HW table */
+		ppc_md.tce_build(tbl, entry, npages, vaddr & PAGE_MASK, direction);
+
+		/* If we are in an open segment, try merging */
+		if (segstart != s) {
+			DBG("  - trying merge...\n");
+			/* We cannot merge if:
+			 * - allocated dma_addr isn't contiguous to previous allocation
+			 */
+			if (novmerge || (dma_addr != dma_next)) {
+				/* Can't merge: create a new segment */
+				segstart = s;
+				outcount++; outs++;
+				DBG("    can't merge, new segment.\n");
+			} else {
+				outs->dma_length += s->length;
+				DBG("    merged, new len: %lx\n", outs->dma_length);
+			}
+		}
+
+		if (segstart == s) {
+			/* This is a new segment, fill entries */
+			DBG("  - filling new segment.\n");
+			outs->dma_address = dma_addr;
+			outs->dma_length = slen;
+		}
+
+		/* Calculate next page pointer for contiguous check */
+		dma_next = dma_addr + slen;
+
+		DBG("  - dma next is: %lx\n", dma_next);
+	}
+
+	/* Flush/invalidate TLB caches if necessary */
+	if (ppc_md.tce_flush)
+		ppc_md.tce_flush(tbl);
+
+	spin_unlock_irqrestore(&(tbl->it_lock), flags);
+
+	/* Make sure updates are seen by hardware */
+	mb();
+
+	DBG("mapped %d elements:\n", outcount);
+
+	/* For the sake of iommu_unmap_sg, we clear out the length in the
+	 * next entry of the sglist if we didn't fill the list completely
+	 */
+	if (outcount < incount) {
+		outs++;
+		outs->dma_address = DMA_ERROR_CODE;
+		outs->dma_length = 0;
+	}
+	return outcount;
+
+ failure:
+	for (s = &sglist[0]; s <= outs; s++) {
+		if (s->dma_length != 0) {
+			unsigned long vaddr, npages;
+
+			vaddr = s->dma_address & PAGE_MASK;
+			npages = (PAGE_ALIGN(s->dma_address + s->dma_length) - vaddr)
+				>> PAGE_SHIFT;
+			__iommu_free(tbl, vaddr, npages);
+		}
+	}
+	spin_unlock_irqrestore(&(tbl->it_lock), flags);
+	return 0;
+}
+
+
+void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
+		int nelems, enum dma_data_direction direction)
+{
+	unsigned long flags;
+
+	BUG_ON(direction == DMA_NONE);
+
+	if (!tbl)
+		return;
+
+	spin_lock_irqsave(&(tbl->it_lock), flags);
+
+	while (nelems--) {
+		unsigned int npages;
+		dma_addr_t dma_handle = sglist->dma_address;
+
+		if (sglist->dma_length == 0)
+			break;
+		npages = (PAGE_ALIGN(dma_handle + sglist->dma_length)
+			  - (dma_handle & PAGE_MASK)) >> PAGE_SHIFT;
+		__iommu_free(tbl, dma_handle, npages);
+		sglist++;
+	}
+
+	/* Flush/invalidate TLBs if necessary. As for iommu_free(), we
+	 * do not do an mb() here, the affected platforms do not need it
+	 * when freeing.
+	 */
+	if (ppc_md.tce_flush)
+		ppc_md.tce_flush(tbl);
+
+	spin_unlock_irqrestore(&(tbl->it_lock), flags);
+}
+
+/*
+ * Build a iommu_table structure.  This contains a bit map which
+ * is used to manage allocation of the tce space.
+ */
+struct iommu_table *iommu_init_table(struct iommu_table *tbl)
+{
+	unsigned long sz;
+	static int welcomed = 0;
+
+	/* Set aside 1/4 of the table for large allocations. */
+	tbl->it_halfpoint = tbl->it_size * 3 / 4;
+
+	/* number of bytes needed for the bitmap */
+	sz = (tbl->it_size + 7) >> 3;
+
+	tbl->it_map = (unsigned long *)__get_free_pages(GFP_ATOMIC, get_order(sz));
+	if (!tbl->it_map)
+		panic("iommu_init_table: Can't allocate %ld bytes\n", sz);
+
+	memset(tbl->it_map, 0, sz);
+
+	tbl->it_hint = 0;
+	tbl->it_largehint = tbl->it_halfpoint;
+	spin_lock_init(&tbl->it_lock);
+
+	/* Clear the hardware table in case firmware left allocations in it */
+	ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
+
+	if (!welcomed) {
+		printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n",
+		       novmerge ? "disabled" : "enabled");
+		welcomed = 1;
+	}
+
+	return tbl;
+}
+
+void iommu_free_table(struct device_node *dn)
+{
+	struct pci_dn *pdn = dn->data;
+	struct iommu_table *tbl = pdn->iommu_table;
+	unsigned long bitmap_sz, i;
+	unsigned int order;
+
+	if (!tbl || !tbl->it_map) {
+		printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__,
+				dn->full_name);
+		return;
+	}
+
+	/* verify that table contains no entries */
+	/* it_size is in entries, and we're examining 64 at a time */
+	for (i = 0; i < (tbl->it_size/64); i++) {
+		if (tbl->it_map[i] != 0) {
+			printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
+				__FUNCTION__, dn->full_name);
+			break;
+		}
+	}
+
+	/* calculate bitmap size in bytes */
+	bitmap_sz = (tbl->it_size + 7) / 8;
+
+	/* free bitmap */
+	order = get_order(bitmap_sz);
+	free_pages((unsigned long) tbl->it_map, order);
+
+	/* free table */
+	kfree(tbl);
+}
+
+/* Creates TCEs for a user provided buffer.  The user buffer must be
+ * contiguous real kernel storage (not vmalloc).  The address of the buffer
+ * passed here is the kernel (virtual) address of the buffer.  The buffer
+ * need not be page aligned, the dma_addr_t returned will point to the same
+ * byte within the page as vaddr.
+ */
+dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
+		size_t size, enum dma_data_direction direction)
+{
+	dma_addr_t dma_handle = DMA_ERROR_CODE;
+	unsigned long uaddr;
+	unsigned int npages;
+
+	BUG_ON(direction == DMA_NONE);
+
+	uaddr = (unsigned long)vaddr;
+	npages = PAGE_ALIGN(uaddr + size) - (uaddr & PAGE_MASK);
+	npages >>= PAGE_SHIFT;
+
+	if (tbl) {
+		dma_handle = iommu_alloc(tbl, vaddr, npages, direction, 0);
+		if (dma_handle == DMA_ERROR_CODE) {
+			if (printk_ratelimit())  {
+				printk(KERN_INFO "iommu_alloc failed, "
+						"tbl %p vaddr %p npages %d\n",
+						tbl, vaddr, npages);
+			}
+		} else
+			dma_handle |= (uaddr & ~PAGE_MASK);
+	}
+
+	return dma_handle;
+}
+
+void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
+		size_t size, enum dma_data_direction direction)
+{
+	BUG_ON(direction == DMA_NONE);
+
+	if (tbl)
+		iommu_free(tbl, dma_handle, (PAGE_ALIGN(dma_handle + size) -
+					(dma_handle & PAGE_MASK)) >> PAGE_SHIFT);
+}
+
+/* Allocates a contiguous real buffer and creates mappings over it.
+ * Returns the virtual address of the buffer and sets dma_handle
+ * to the dma address (mapping) of the first page.
+ */
+void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
+		dma_addr_t *dma_handle, gfp_t flag)
+{
+	void *ret = NULL;
+	dma_addr_t mapping;
+	unsigned int npages, order;
+
+	size = PAGE_ALIGN(size);
+	npages = size >> PAGE_SHIFT;
+	order = get_order(size);
+
+ 	/*
+	 * Client asked for way too much space.  This is checked later
+	 * anyway.  It is easier to debug here for the drivers than in
+	 * the tce tables.
+	 */
+	if (order >= IOMAP_MAX_ORDER) {
+		printk("iommu_alloc_consistent size too large: 0x%lx\n", size);
+		return NULL;
+	}
+
+	if (!tbl)
+		return NULL;
+
+	/* Alloc enough pages (and possibly more) */
+	ret = (void *)__get_free_pages(flag, order);
+	if (!ret)
+		return NULL;
+	memset(ret, 0, size);
+
+	/* Set up tces to cover the allocated range */
+	mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL, order);
+	if (mapping == DMA_ERROR_CODE) {
+		free_pages((unsigned long)ret, order);
+		ret = NULL;
+	} else
+		*dma_handle = mapping;
+	return ret;
+}
+
+void iommu_free_coherent(struct iommu_table *tbl, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	unsigned int npages;
+
+	if (tbl) {
+		size = PAGE_ALIGN(size);
+		npages = size >> PAGE_SHIFT;
+		iommu_free(tbl, dma_handle, npages);
+		free_pages((unsigned long)vaddr, get_order(size));
+	}
+}
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 4b79406..5a71ed9 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -71,6 +71,11 @@
 #include <asm/paca.h>
 #endif
 
+int __irq_offset_value;
+#ifdef CONFIG_PPC32
+EXPORT_SYMBOL(__irq_offset_value);
+#endif
+
 static int ppc_spurious_interrupts;
 
 #if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP)
@@ -98,7 +103,6 @@ extern atomic_t ipi_sent;
 EXPORT_SYMBOL(irq_desc);
 
 int distribute_irqs = 1;
-int __irq_offset_value;
 u64 ppc64_interrupt_controller;
 #endif /* CONFIG_PPC64 */
 
@@ -311,7 +315,6 @@ void __init init_IRQ(void)
 }
 
 #ifdef CONFIG_PPC64
-#ifndef CONFIG_PPC_ISERIES
 /*
  * Virtual IRQ mapping code, used on systems with XICS interrupt controllers.
  */
@@ -420,8 +423,6 @@ unsigned int real_irq_to_virt_slowpath(u
 
 }
 
-#endif /* CONFIG_PPC_ISERIES */
-
 #ifdef CONFIG_IRQSTACKS
 struct thread_info *softirq_ctx[NR_CPUS];
 struct thread_info *hardirq_ctx[NR_CPUS];
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
new file mode 100644
index 0000000..511af54
--- /dev/null
+++ b/arch/powerpc/kernel/kprobes.c
@@ -0,0 +1,459 @@
+/*
+ *  Kernel Probes (KProbes)
+ *  arch/ppc64/kernel/kprobes.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2002, 2004
+ *
+ * 2002-Oct	Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel
+ *		Probes initial implementation ( includes contributions from
+ *		Rusty Russell).
+ * 2004-July	Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
+ *		interface to access function arguments.
+ * 2004-Nov	Ananth N Mavinakayanahalli <ananth@in.ibm.com> kprobes port
+ *		for PPC64
+ */
+
+#include <linux/config.h>
+#include <linux/kprobes.h>
+#include <linux/ptrace.h>
+#include <linux/preempt.h>
+#include <asm/cacheflush.h>
+#include <asm/kdebug.h>
+#include <asm/sstep.h>
+
+static DECLARE_MUTEX(kprobe_mutex);
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
+{
+	int ret = 0;
+	kprobe_opcode_t insn = *p->addr;
+
+	if ((unsigned long)p->addr & 0x03) {
+		printk("Attempt to register kprobe at an unaligned address\n");
+		ret = -EINVAL;
+	} else if (IS_MTMSRD(insn) || IS_RFID(insn)) {
+		printk("Cannot register a kprobe on rfid or mtmsrd\n");
+		ret = -EINVAL;
+	}
+
+	/* insn must be on a special executable page on ppc64 */
+	if (!ret) {
+		down(&kprobe_mutex);
+		p->ainsn.insn = get_insn_slot();
+		up(&kprobe_mutex);
+		if (!p->ainsn.insn)
+			ret = -ENOMEM;
+	}
+	return ret;
+}
+
+void __kprobes arch_copy_kprobe(struct kprobe *p)
+{
+	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+	p->opcode = *p->addr;
+}
+
+void __kprobes arch_arm_kprobe(struct kprobe *p)
+{
+	*p->addr = BREAKPOINT_INSTRUCTION;
+	flush_icache_range((unsigned long) p->addr,
+			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
+}
+
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
+{
+	*p->addr = p->opcode;
+	flush_icache_range((unsigned long) p->addr,
+			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
+}
+
+void __kprobes arch_remove_kprobe(struct kprobe *p)
+{
+	down(&kprobe_mutex);
+	free_insn_slot(p->ainsn.insn);
+	up(&kprobe_mutex);
+}
+
+static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+{
+	kprobe_opcode_t insn = *p->ainsn.insn;
+
+	regs->msr |= MSR_SE;
+
+	/* single step inline if it is a trap variant */
+	if (is_trap(insn))
+		regs->nip = (unsigned long)p->addr;
+	else
+		regs->nip = (unsigned long)p->ainsn.insn;
+}
+
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+	kcb->prev_kprobe.kp = kprobe_running();
+	kcb->prev_kprobe.status = kcb->kprobe_status;
+	kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr;
+}
+
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+	__get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+	kcb->kprobe_status = kcb->prev_kprobe.status;
+	kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr;
+}
+
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+				struct kprobe_ctlblk *kcb)
+{
+	__get_cpu_var(current_kprobe) = p;
+	kcb->kprobe_saved_msr = regs->msr;
+}
+
+/* Called with kretprobe_lock held */
+void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+				      struct pt_regs *regs)
+{
+	struct kretprobe_instance *ri;
+
+	if ((ri = get_free_rp_inst(rp)) != NULL) {
+		ri->rp = rp;
+		ri->task = current;
+		ri->ret_addr = (kprobe_opcode_t *)regs->link;
+
+		/* Replace the return addr with trampoline addr */
+		regs->link = (unsigned long)kretprobe_trampoline;
+		add_rp_inst(ri);
+	} else {
+		rp->nmissed++;
+	}
+}
+
+static inline int kprobe_handler(struct pt_regs *regs)
+{
+	struct kprobe *p;
+	int ret = 0;
+	unsigned int *addr = (unsigned int *)regs->nip;
+	struct kprobe_ctlblk *kcb;
+
+	/*
+	 * We don't want to be preempted for the entire
+	 * duration of kprobe processing
+	 */
+	preempt_disable();
+	kcb = get_kprobe_ctlblk();
+
+	/* Check we're not actually recursing */
+	if (kprobe_running()) {
+		p = get_kprobe(addr);
+		if (p) {
+			kprobe_opcode_t insn = *p->ainsn.insn;
+			if (kcb->kprobe_status == KPROBE_HIT_SS &&
+					is_trap(insn)) {
+				regs->msr &= ~MSR_SE;
+				regs->msr |= kcb->kprobe_saved_msr;
+				goto no_kprobe;
+			}
+			/* We have reentered the kprobe_handler(), since
+			 * another probe was hit while within the handler.
+			 * We here save the original kprobes variables and
+			 * just single step on the instruction of the new probe
+			 * without calling any user handlers.
+			 */
+			save_previous_kprobe(kcb);
+			set_current_kprobe(p, regs, kcb);
+			kcb->kprobe_saved_msr = regs->msr;
+			p->nmissed++;
+			prepare_singlestep(p, regs);
+			kcb->kprobe_status = KPROBE_REENTER;
+			return 1;
+		} else {
+			p = __get_cpu_var(current_kprobe);
+			if (p->break_handler && p->break_handler(p, regs)) {
+				goto ss_probe;
+			}
+		}
+		goto no_kprobe;
+	}
+
+	p = get_kprobe(addr);
+	if (!p) {
+		if (*addr != BREAKPOINT_INSTRUCTION) {
+			/*
+			 * PowerPC has multiple variants of the "trap"
+			 * instruction. If the current instruction is a
+			 * trap variant, it could belong to someone else
+			 */
+			kprobe_opcode_t cur_insn = *addr;
+			if (is_trap(cur_insn))
+		       		goto no_kprobe;
+			/*
+			 * The breakpoint instruction was removed right
+			 * after we hit it.  Another cpu has removed
+			 * either a probepoint or a debugger breakpoint
+			 * at this address.  In either case, no further
+			 * handling of this interrupt is appropriate.
+			 */
+			ret = 1;
+		}
+		/* Not one of ours: let kernel handle it */
+		goto no_kprobe;
+	}
+
+	kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+	set_current_kprobe(p, regs, kcb);
+	if (p->pre_handler && p->pre_handler(p, regs))
+		/* handler has already set things up, so skip ss setup */
+		return 1;
+
+ss_probe:
+	prepare_singlestep(p, regs);
+	kcb->kprobe_status = KPROBE_HIT_SS;
+	return 1;
+
+no_kprobe:
+	preempt_enable_no_resched();
+	return ret;
+}
+
+/*
+ * Function return probe trampoline:
+ * 	- init_kprobes() establishes a probepoint here
+ * 	- When the probed function returns, this probe
+ * 		causes the handlers to fire
+ */
+void kretprobe_trampoline_holder(void)
+{
+	asm volatile(".global kretprobe_trampoline\n"
+			"kretprobe_trampoline:\n"
+			"nop\n");
+}
+
+/*
+ * Called when the probe at kretprobe trampoline is hit
+ */
+int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+{
+        struct kretprobe_instance *ri = NULL;
+        struct hlist_head *head;
+        struct hlist_node *node, *tmp;
+	unsigned long flags, orig_ret_address = 0;
+	unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
+
+	spin_lock_irqsave(&kretprobe_lock, flags);
+        head = kretprobe_inst_table_head(current);
+
+	/*
+	 * It is possible to have multiple instances associated with a given
+	 * task either because an multiple functions in the call path
+	 * have a return probe installed on them, and/or more then one return
+	 * return probe was registered for a target function.
+	 *
+	 * We can handle this because:
+	 *     - instances are always inserted at the head of the list
+	 *     - when multiple return probes are registered for the same
+         *       function, the first instance's ret_addr will point to the
+	 *       real return address, and all the rest will point to
+	 *       kretprobe_trampoline
+	 */
+	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+                if (ri->task != current)
+			/* another task is sharing our hash bucket */
+                        continue;
+
+		if (ri->rp && ri->rp->handler)
+			ri->rp->handler(ri, regs);
+
+		orig_ret_address = (unsigned long)ri->ret_addr;
+		recycle_rp_inst(ri);
+
+		if (orig_ret_address != trampoline_address)
+			/*
+			 * This is the real return address. Any other
+			 * instances associated with this task are for
+			 * other calls deeper on the call stack
+			 */
+			break;
+	}
+
+	BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
+	regs->nip = orig_ret_address;
+
+	reset_current_kprobe();
+	spin_unlock_irqrestore(&kretprobe_lock, flags);
+	preempt_enable_no_resched();
+
+        /*
+         * By returning a non-zero value, we are telling
+         * kprobe_handler() that we don't want the post_handler
+         * to run (and have re-enabled preemption)
+         */
+        return 1;
+}
+
+/*
+ * Called after single-stepping.  p->addr is the address of the
+ * instruction whose first byte has been replaced by the "breakpoint"
+ * instruction.  To avoid the SMP problems that can occur when we
+ * temporarily put back the original opcode to single-step, we
+ * single-stepped a copy of the instruction.  The address of this
+ * copy is p->ainsn.insn.
+ */
+static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
+{
+	int ret;
+	unsigned int insn = *p->ainsn.insn;
+
+	regs->nip = (unsigned long)p->addr;
+	ret = emulate_step(regs, insn);
+	if (ret == 0)
+		regs->nip = (unsigned long)p->addr + 4;
+}
+
+static inline int post_kprobe_handler(struct pt_regs *regs)
+{
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (!cur)
+		return 0;
+
+	if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+		kcb->kprobe_status = KPROBE_HIT_SSDONE;
+		cur->post_handler(cur, regs, 0);
+	}
+
+	resume_execution(cur, regs);
+	regs->msr |= kcb->kprobe_saved_msr;
+
+	/*Restore back the original saved kprobes variables and continue. */
+	if (kcb->kprobe_status == KPROBE_REENTER) {
+		restore_previous_kprobe(kcb);
+		goto out;
+	}
+	reset_current_kprobe();
+out:
+	preempt_enable_no_resched();
+
+	/*
+	 * if somebody else is singlestepping across a probe point, msr
+	 * will have SE set, in which case, continue the remaining processing
+	 * of do_debug, as if this is not a probe hit.
+	 */
+	if (regs->msr & MSR_SE)
+		return 0;
+
+	return 1;
+}
+
+static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+{
+	struct kprobe *cur = kprobe_running();
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
+		return 1;
+
+	if (kcb->kprobe_status & KPROBE_HIT_SS) {
+		resume_execution(cur, regs);
+		regs->msr &= ~MSR_SE;
+		regs->msr |= kcb->kprobe_saved_msr;
+
+		reset_current_kprobe();
+		preempt_enable_no_resched();
+	}
+	return 0;
+}
+
+/*
+ * Wrapper routine to for handling exceptions.
+ */
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+				       unsigned long val, void *data)
+{
+	struct die_args *args = (struct die_args *)data;
+	int ret = NOTIFY_DONE;
+
+	switch (val) {
+	case DIE_BPT:
+		if (kprobe_handler(args->regs))
+			ret = NOTIFY_STOP;
+		break;
+	case DIE_SSTEP:
+		if (post_kprobe_handler(args->regs))
+			ret = NOTIFY_STOP;
+		break;
+	case DIE_PAGE_FAULT:
+		/* kprobe_running() needs smp_processor_id() */
+		preempt_disable();
+		if (kprobe_running() &&
+		    kprobe_fault_handler(args->regs, args->trapnr))
+			ret = NOTIFY_STOP;
+		preempt_enable();
+		break;
+	default:
+		break;
+	}
+	return ret;
+}
+
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	struct jprobe *jp = container_of(p, struct jprobe, kp);
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
+
+	/* setup return addr to the jprobe handler routine */
+	regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry);
+	regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
+
+	return 1;
+}
+
+void __kprobes jprobe_return(void)
+{
+	asm volatile("trap" ::: "memory");
+}
+
+void __kprobes jprobe_return_end(void)
+{
+};
+
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+	/*
+	 * FIXME - we should ideally be validating that we got here 'cos
+	 * of the "trap" in jprobe_return() above, before restoring the
+	 * saved regs...
+	 */
+	memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
+	preempt_enable_no_resched();
+	return 1;
+}
+
+static struct kprobe trampoline_p = {
+	.addr = (kprobe_opcode_t *) &kretprobe_trampoline,
+	.pre_handler = trampoline_probe_handler
+};
+
+int __init arch_init_kprobes(void)
+{
+	return register_kprobe(&trampoline_p);
+}
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 1b3ba8a..9dda16c 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -42,32 +42,6 @@
 
 /* #define LPARCFG_DEBUG */
 
-/* find a better place for this function... */
-static void log_plpar_hcall_return(unsigned long rc, char *tag)
-{
-	if (rc == 0)		/* success, return */
-		return;
-/* check for null tag ? */
-	if (rc == H_Hardware)
-		printk(KERN_INFO
-		       "plpar-hcall (%s) failed with hardware fault\n", tag);
-	else if (rc == H_Function)
-		printk(KERN_INFO
-		       "plpar-hcall (%s) failed; function not allowed\n", tag);
-	else if (rc == H_Authority)
-		printk(KERN_INFO
-		       "plpar-hcall (%s) failed; not authorized to this function\n",
-		       tag);
-	else if (rc == H_Parameter)
-		printk(KERN_INFO "plpar-hcall (%s) failed; Bad parameter(s)\n",
-		       tag);
-	else
-		printk(KERN_INFO
-		       "plpar-hcall (%s) failed with unexpected rc(0x%lx)\n",
-		       tag, rc);
-
-}
-
 static struct proc_dir_entry *proc_ppc64_lparcfg;
 #define LPARCFG_BUFF_SIZE 4096
 
@@ -172,6 +146,31 @@ static int lparcfg_data(struct seq_file 
 /*
  * Methods used to fetch LPAR data when running on a pSeries platform.
  */
+/* find a better place for this function... */
+static void log_plpar_hcall_return(unsigned long rc, char *tag)
+{
+	if (rc == 0)		/* success, return */
+		return;
+/* check for null tag ? */
+	if (rc == H_Hardware)
+		printk(KERN_INFO
+		       "plpar-hcall (%s) failed with hardware fault\n", tag);
+	else if (rc == H_Function)
+		printk(KERN_INFO
+		       "plpar-hcall (%s) failed; function not allowed\n", tag);
+	else if (rc == H_Authority)
+		printk(KERN_INFO
+		       "plpar-hcall (%s) failed; not authorized to this function\n",
+		       tag);
+	else if (rc == H_Parameter)
+		printk(KERN_INFO "plpar-hcall (%s) failed; Bad parameter(s)\n",
+		       tag);
+	else
+		printk(KERN_INFO
+		       "plpar-hcall (%s) failed with unexpected rc(0x%lx)\n",
+		       tag, rc);
+
+}
 
 /*
  * H_GET_PPP hcall returns info in 4 parms.
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
new file mode 100644
index 0000000..97c51e4
--- /dev/null
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -0,0 +1,358 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ *
+ * Copyright (C) 2004-2005, IBM Corp.
+ *
+ * Created by: Milton D Miller II
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2.  See the file COPYING for more details.
+ */
+
+
+#include <linux/cpumask.h>
+#include <linux/kexec.h>
+#include <linux/smp.h>
+#include <linux/thread_info.h>
+#include <linux/errno.h>
+
+#include <asm/page.h>
+#include <asm/current.h>
+#include <asm/machdep.h>
+#include <asm/cacheflush.h>
+#include <asm/paca.h>
+#include <asm/mmu.h>
+#include <asm/sections.h>	/* _end */
+#include <asm/prom.h>
+#include <asm/smp.h>
+
+#define HASH_GROUP_SIZE 0x80	/* size of each hash group, asm/mmu.h */
+
+/* Have this around till we move it into crash specific file */
+note_buf_t crash_notes[NR_CPUS];
+
+/* Dummy for now. Not sure if we need to have a crash shutdown in here
+ * and if what it will achieve. Letting it be now to compile the code
+ * in generic kexec environment
+ */
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+	/* do nothing right now */
+	/* smp_relase_cpus() if we want smp on panic kernel */
+	/* cpu_irq_down to isolate us until we are ready */
+}
+
+int machine_kexec_prepare(struct kimage *image)
+{
+	int i;
+	unsigned long begin, end;	/* limits of segment */
+	unsigned long low, high;	/* limits of blocked memory range */
+	struct device_node *node;
+	unsigned long *basep;
+	unsigned int *sizep;
+
+	if (!ppc_md.hpte_clear_all)
+		return -ENOENT;
+
+	/*
+	 * Since we use the kernel fault handlers and paging code to
+	 * handle the virtual mode, we must make sure no destination
+	 * overlaps kernel static data or bss.
+	 */
+	for (i = 0; i < image->nr_segments; i++)
+		if (image->segment[i].mem < __pa(_end))
+			return -ETXTBSY;
+
+	/*
+	 * For non-LPAR, we absolutely can not overwrite the mmu hash
+	 * table, since we are still using the bolted entries in it to
+	 * do the copy.  Check that here.
+	 *
+	 * It is safe if the end is below the start of the blocked
+	 * region (end <= low), or if the beginning is after the
+	 * end of the blocked region (begin >= high).  Use the
+	 * boolean identity !(a || b)  === (!a && !b).
+	 */
+	if (htab_address) {
+		low = __pa(htab_address);
+		high = low + (htab_hash_mask + 1) * HASH_GROUP_SIZE;
+
+		for (i = 0; i < image->nr_segments; i++) {
+			begin = image->segment[i].mem;
+			end = begin + image->segment[i].memsz;
+
+			if ((begin < high) && (end > low))
+				return -ETXTBSY;
+		}
+	}
+
+	/* We also should not overwrite the tce tables */
+	for (node = of_find_node_by_type(NULL, "pci"); node != NULL;
+			node = of_find_node_by_type(node, "pci")) {
+		basep = (unsigned long *)get_property(node, "linux,tce-base",
+							NULL);
+		sizep = (unsigned int *)get_property(node, "linux,tce-size",
+							NULL);
+		if (basep == NULL || sizep == NULL)
+			continue;
+
+		low = *basep;
+		high = low + (*sizep);
+
+		for (i = 0; i < image->nr_segments; i++) {
+			begin = image->segment[i].mem;
+			end = begin + image->segment[i].memsz;
+
+			if ((begin < high) && (end > low))
+				return -ETXTBSY;
+		}
+	}
+
+	return 0;
+}
+
+void machine_kexec_cleanup(struct kimage *image)
+{
+	/* we do nothing in prepare that needs to be undone */
+}
+
+#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
+
+static void copy_segments(unsigned long ind)
+{
+	unsigned long entry;
+	unsigned long *ptr;
+	void *dest;
+	void *addr;
+
+	/*
+	 * We rely on kexec_load to create a lists that properly
+	 * initializes these pointers before they are used.
+	 * We will still crash if the list is wrong, but at least
+	 * the compiler will be quiet.
+	 */
+	ptr = NULL;
+	dest = NULL;
+
+	for (entry = ind; !(entry & IND_DONE); entry = *ptr++) {
+		addr = __va(entry & PAGE_MASK);
+
+		switch (entry & IND_FLAGS) {
+		case IND_DESTINATION:
+			dest = addr;
+			break;
+		case IND_INDIRECTION:
+			ptr = addr;
+			break;
+		case IND_SOURCE:
+			copy_page(dest, addr);
+			dest += PAGE_SIZE;
+		}
+	}
+}
+
+void kexec_copy_flush(struct kimage *image)
+{
+	long i, nr_segments = image->nr_segments;
+	struct  kexec_segment ranges[KEXEC_SEGMENT_MAX];
+
+	/* save the ranges on the stack to efficiently flush the icache */
+	memcpy(ranges, image->segment, sizeof(ranges));
+
+	/*
+	 * After this call we may not use anything allocated in dynamic
+	 * memory, including *image.
+	 *
+	 * Only globals and the stack are allowed.
+	 */
+	copy_segments(image->head);
+
+	/*
+	 * we need to clear the icache for all dest pages sometime,
+	 * including ones that were in place on the original copy
+	 */
+	for (i = 0; i < nr_segments; i++)
+		flush_icache_range(ranges[i].mem + KERNELBASE,
+				ranges[i].mem + KERNELBASE +
+				ranges[i].memsz);
+}
+
+#ifdef CONFIG_SMP
+
+/* FIXME: we should schedule this function to be called on all cpus based
+ * on calling the interrupts, but we would like to call it off irq level
+ * so that the interrupt controller is clean.
+ */
+void kexec_smp_down(void *arg)
+{
+	if (ppc_md.kexec_cpu_down)
+		ppc_md.kexec_cpu_down(0, 1);
+
+	local_irq_disable();
+	kexec_smp_wait();
+	/* NOTREACHED */
+}
+
+static void kexec_prepare_cpus(void)
+{
+	int my_cpu, i, notified=-1;
+
+	smp_call_function(kexec_smp_down, NULL, 0, /* wait */0);
+	my_cpu = get_cpu();
+
+	/* check the others cpus are now down (via paca hw cpu id == -1) */
+	for (i=0; i < NR_CPUS; i++) {
+		if (i == my_cpu)
+			continue;
+
+		while (paca[i].hw_cpu_id != -1) {
+			barrier();
+			if (!cpu_possible(i)) {
+				printk("kexec: cpu %d hw_cpu_id %d is not"
+						" possible, ignoring\n",
+						i, paca[i].hw_cpu_id);
+				break;
+			}
+			if (!cpu_online(i)) {
+				/* Fixme: this can be spinning in
+				 * pSeries_secondary_wait with a paca
+				 * waiting for it to go online.
+				 */
+				printk("kexec: cpu %d hw_cpu_id %d is not"
+						" online, ignoring\n",
+						i, paca[i].hw_cpu_id);
+				break;
+			}
+			if (i != notified) {
+				printk( "kexec: waiting for cpu %d (physical"
+						" %d) to go down\n",
+						i, paca[i].hw_cpu_id);
+				notified = i;
+			}
+		}
+	}
+
+	/* after we tell the others to go down */
+	if (ppc_md.kexec_cpu_down)
+		ppc_md.kexec_cpu_down(0, 0);
+
+	put_cpu();
+
+	local_irq_disable();
+}
+
+#else /* ! SMP */
+
+static void kexec_prepare_cpus(void)
+{
+	/*
+	 * move the secondarys to us so that we can copy
+	 * the new kernel 0-0x100 safely
+	 *
+	 * do this if kexec in setup.c ?
+	 *
+	 * We need to release the cpus if we are ever going from an
+	 * UP to an SMP kernel.
+	 */
+	smp_release_cpus();
+	if (ppc_md.kexec_cpu_down)
+		ppc_md.kexec_cpu_down(0, 0);
+	local_irq_disable();
+}
+
+#endif /* SMP */
+
+/*
+ * kexec thread structure and stack.
+ *
+ * We need to make sure that this is 16384-byte aligned due to the
+ * way process stacks are handled.  It also must be statically allocated
+ * or allocated as part of the kimage, because everything else may be
+ * overwritten when we copy the kexec image.  We piggyback on the
+ * "init_task" linker section here to statically allocate a stack.
+ *
+ * We could use a smaller stack if we don't care about anything using
+ * current, but that audit has not been performed.
+ */
+union thread_union kexec_stack
+	__attribute__((__section__(".data.init_task"))) = { };
+
+/* Our assembly helper, in kexec_stub.S */
+extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start,
+					void *image, void *control,
+					void (*clear_all)(void)) ATTRIB_NORET;
+
+/* too late to fail here */
+void machine_kexec(struct kimage *image)
+{
+
+	/* prepare control code if any */
+
+	/* shutdown other cpus into our wait loop and quiesce interrupts */
+	kexec_prepare_cpus();
+
+	/* switch to a staticly allocated stack.  Based on irq stack code.
+	 * XXX: the task struct will likely be invalid once we do the copy!
+	 */
+	kexec_stack.thread_info.task = current_thread_info()->task;
+	kexec_stack.thread_info.flags = 0;
+
+	/* Some things are best done in assembly.  Finding globals with
+	 * a toc is easier in C, so pass in what we can.
+	 */
+	kexec_sequence(&kexec_stack, image->start, image,
+			page_address(image->control_code_page),
+			ppc_md.hpte_clear_all);
+	/* NOTREACHED */
+}
+
+/* Values we need to export to the second kernel via the device tree. */
+static unsigned long htab_base, htab_size, kernel_end;
+
+static struct property htab_base_prop = {
+	.name = "linux,htab-base",
+	.length = sizeof(unsigned long),
+	.value = (unsigned char *)&htab_base,
+};
+
+static struct property htab_size_prop = {
+	.name = "linux,htab-size",
+	.length = sizeof(unsigned long),
+	.value = (unsigned char *)&htab_size,
+};
+
+static struct property kernel_end_prop = {
+	.name = "linux,kernel-end",
+	.length = sizeof(unsigned long),
+	.value = (unsigned char *)&kernel_end,
+};
+
+static void __init export_htab_values(void)
+{
+	struct device_node *node;
+
+	node = of_find_node_by_path("/chosen");
+	if (!node)
+		return;
+
+	kernel_end = __pa(_end);
+	prom_add_property(node, &kernel_end_prop);
+
+	/* On machines with no htab htab_address is NULL */
+	if (NULL == htab_address)
+		goto out;
+
+	htab_base = __pa(htab_address);
+	prom_add_property(node, &htab_base_prop);
+
+	htab_size = 1UL << ppc64_pft_size;
+	prom_add_property(node, &htab_size_prop);
+
+ out:
+	of_node_put(node);
+}
+
+void __init kexec_setup(void)
+{
+	export_htab_values();
+}
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
new file mode 100644
index 0000000..928b858
--- /dev/null
+++ b/arch/powerpc/kernel/module_64.c
@@ -0,0 +1,455 @@
+/*  Kernel module help for PPC64.
+    Copyright (C) 2001, 2003 Rusty Russell IBM Corporation.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#include <linux/module.h>
+#include <linux/elf.h>
+#include <linux/moduleloader.h>
+#include <linux/err.h>
+#include <linux/vmalloc.h>
+#include <asm/module.h>
+#include <asm/uaccess.h>
+
+/* FIXME: We don't do .init separately.  To do this, we'd need to have
+   a separate r2 value in the init and core section, and stub between
+   them, too.
+
+   Using a magic allocator which places modules within 32MB solves
+   this, and makes other things simpler.  Anton?
+   --RR.  */
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(fmt , ...)
+#endif
+
+/* There's actually a third entry here, but it's unused */
+struct ppc64_opd_entry
+{
+	unsigned long funcaddr;
+	unsigned long r2;
+};
+
+/* Like PPC32, we need little trampolines to do > 24-bit jumps (into
+   the kernel itself).  But on PPC64, these need to be used for every
+   jump, actually, to reset r2 (TOC+0x8000). */
+struct ppc64_stub_entry
+{
+	/* 28 byte jump instruction sequence (7 instructions) */
+	unsigned char jump[28];
+	unsigned char unused[4];
+	/* Data for the above code */
+	struct ppc64_opd_entry opd;
+};
+
+/* We use a stub to fix up r2 (TOC ptr) and to jump to the (external)
+   function which may be more than 24-bits away.  We could simply
+   patch the new r2 value and function pointer into the stub, but it's
+   significantly shorter to put these values at the end of the stub
+   code, and patch the stub address (32-bits relative to the TOC ptr,
+   r2) into the stub. */
+static struct ppc64_stub_entry ppc64_stub =
+{ .jump = {
+	0x3d, 0x82, 0x00, 0x00, /* addis   r12,r2, <high> */
+	0x39, 0x8c, 0x00, 0x00, /* addi    r12,r12, <low> */
+	/* Save current r2 value in magic place on the stack. */
+	0xf8, 0x41, 0x00, 0x28, /* std     r2,40(r1) */
+	0xe9, 0x6c, 0x00, 0x20, /* ld      r11,32(r12) */
+	0xe8, 0x4c, 0x00, 0x28, /* ld      r2,40(r12) */
+	0x7d, 0x69, 0x03, 0xa6, /* mtctr   r11 */
+	0x4e, 0x80, 0x04, 0x20  /* bctr */
+} };
+
+/* Count how many different 24-bit relocations (different symbol,
+   different addend) */
+static unsigned int count_relocs(const Elf64_Rela *rela, unsigned int num)
+{
+	unsigned int i, j, ret = 0;
+
+	/* FIXME: Only count external ones --RR */
+	/* Sure, this is order(n^2), but it's usually short, and not
+           time critical */
+	for (i = 0; i < num; i++) {
+		/* Only count 24-bit relocs, others don't need stubs */
+		if (ELF64_R_TYPE(rela[i].r_info) != R_PPC_REL24)
+			continue;
+		for (j = 0; j < i; j++) {
+			/* If this addend appeared before, it's
+                           already been counted */
+			if (rela[i].r_info == rela[j].r_info
+			    && rela[i].r_addend == rela[j].r_addend)
+				break;
+		}
+		if (j == i) ret++;
+	}
+	return ret;
+}
+
+void *module_alloc(unsigned long size)
+{
+	if (size == 0)
+		return NULL;
+
+	return vmalloc_exec(size);
+}
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+	vfree(module_region);
+	/* FIXME: If module_region == mod->init_region, trim exception
+           table entries. */
+}
+
+/* Get size of potential trampolines required. */
+static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
+				    const Elf64_Shdr *sechdrs)
+{
+	/* One extra reloc so it's always 0-funcaddr terminated */
+	unsigned long relocs = 1;
+	unsigned i;
+
+	/* Every relocated section... */
+	for (i = 1; i < hdr->e_shnum; i++) {
+		if (sechdrs[i].sh_type == SHT_RELA) {
+			DEBUGP("Found relocations in section %u\n", i);
+			DEBUGP("Ptr: %p.  Number: %lu\n",
+			       (void *)sechdrs[i].sh_addr,
+			       sechdrs[i].sh_size / sizeof(Elf64_Rela));
+			relocs += count_relocs((void *)sechdrs[i].sh_addr,
+					       sechdrs[i].sh_size
+					       / sizeof(Elf64_Rela));
+		}
+	}
+
+	DEBUGP("Looks like a total of %lu stubs, max\n", relocs);
+	return relocs * sizeof(struct ppc64_stub_entry);
+}
+
+static void dedotify_versions(struct modversion_info *vers,
+			      unsigned long size)
+{
+	struct modversion_info *end;
+
+	for (end = (void *)vers + size; vers < end; vers++)
+		if (vers->name[0] == '.')
+			memmove(vers->name, vers->name+1, strlen(vers->name));
+}
+
+/* Undefined symbols which refer to .funcname, hack to funcname */
+static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab)
+{
+	unsigned int i;
+
+	for (i = 1; i < numsyms; i++) {
+		if (syms[i].st_shndx == SHN_UNDEF) {
+			char *name = strtab + syms[i].st_name;
+			if (name[0] == '.')
+				memmove(name, name+1, strlen(name));
+		}
+	}
+}
+
+int module_frob_arch_sections(Elf64_Ehdr *hdr,
+			      Elf64_Shdr *sechdrs,
+			      char *secstrings,
+			      struct module *me)
+{
+	unsigned int i;
+
+	/* Find .toc and .stubs sections, symtab and strtab */
+	for (i = 1; i < hdr->e_shnum; i++) {
+		char *p;
+		if (strcmp(secstrings + sechdrs[i].sh_name, ".stubs") == 0)
+			me->arch.stubs_section = i;
+		else if (strcmp(secstrings + sechdrs[i].sh_name, ".toc") == 0)
+			me->arch.toc_section = i;
+		else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0)
+			dedotify_versions((void *)hdr + sechdrs[i].sh_offset,
+					  sechdrs[i].sh_size);
+
+		/* We don't handle .init for the moment: rename to _init */
+		while ((p = strstr(secstrings + sechdrs[i].sh_name, ".init")))
+			p[0] = '_';
+
+		if (sechdrs[i].sh_type == SHT_SYMTAB)
+			dedotify((void *)hdr + sechdrs[i].sh_offset,
+				 sechdrs[i].sh_size / sizeof(Elf64_Sym),
+				 (void *)hdr
+				 + sechdrs[sechdrs[i].sh_link].sh_offset);
+	}
+	if (!me->arch.stubs_section || !me->arch.toc_section) {
+		printk("%s: doesn't contain .toc or .stubs.\n", me->name);
+		return -ENOEXEC;
+	}
+
+	/* Override the stubs size */
+	sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs);
+	return 0;
+}
+
+int apply_relocate(Elf64_Shdr *sechdrs,
+		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *me)
+{
+	printk(KERN_ERR "%s: Non-ADD RELOCATION unsupported\n", me->name);
+	return -ENOEXEC;
+}
+
+/* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this
+   gives the value maximum span in an instruction which uses a signed
+   offset) */
+static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me)
+{
+	return sechdrs[me->arch.toc_section].sh_addr + 0x8000;
+}
+
+/* Both low and high 16 bits are added as SIGNED additions, so if low
+   16 bits has high bit set, high 16 bits must be adjusted.  These
+   macros do that (stolen from binutils). */
+#define PPC_LO(v) ((v) & 0xffff)
+#define PPC_HI(v) (((v) >> 16) & 0xffff)
+#define PPC_HA(v) PPC_HI ((v) + 0x8000)
+
+/* Patch stub to reference function and correct r2 value. */
+static inline int create_stub(Elf64_Shdr *sechdrs,
+			      struct ppc64_stub_entry *entry,
+			      struct ppc64_opd_entry *opd,
+			      struct module *me)
+{
+	Elf64_Half *loc1, *loc2;
+	long reladdr;
+
+	*entry = ppc64_stub;
+
+	loc1 = (Elf64_Half *)&entry->jump[2];
+	loc2 = (Elf64_Half *)&entry->jump[6];
+
+	/* Stub uses address relative to r2. */
+	reladdr = (unsigned long)entry - my_r2(sechdrs, me);
+	if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) {
+		printk("%s: Address %p of stub out of range of %p.\n",
+		       me->name, (void *)reladdr, (void *)my_r2);
+		return 0;
+	}
+	DEBUGP("Stub %p get data from reladdr %li\n", entry, reladdr);
+
+	*loc1 = PPC_HA(reladdr);
+	*loc2 = PPC_LO(reladdr);
+	entry->opd.funcaddr = opd->funcaddr;
+	entry->opd.r2 = opd->r2;
+	return 1;
+}
+
+/* Create stub to jump to function described in this OPD: we need the
+   stub to set up the TOC ptr (r2) for the function. */
+static unsigned long stub_for_addr(Elf64_Shdr *sechdrs,
+				   unsigned long opdaddr,
+				   struct module *me)
+{
+	struct ppc64_stub_entry *stubs;
+	struct ppc64_opd_entry *opd = (void *)opdaddr;
+	unsigned int i, num_stubs;
+
+	num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*stubs);
+
+	/* Find this stub, or if that fails, the next avail. entry */
+	stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr;
+	for (i = 0; stubs[i].opd.funcaddr; i++) {
+		BUG_ON(i >= num_stubs);
+
+		if (stubs[i].opd.funcaddr == opd->funcaddr)
+			return (unsigned long)&stubs[i];
+	}
+
+	if (!create_stub(sechdrs, &stubs[i], opd, me))
+		return 0;
+
+	return (unsigned long)&stubs[i];
+}
+
+/* We expect a noop next: if it is, replace it with instruction to
+   restore r2. */
+static int restore_r2(u32 *instruction, struct module *me)
+{
+	if (*instruction != 0x60000000) {
+		printk("%s: Expect noop after relocate, got %08x\n",
+		       me->name, *instruction);
+		return 0;
+	}
+	*instruction = 0xe8410028;	/* ld r2,40(r1) */
+	return 1;
+}
+
+int apply_relocate_add(Elf64_Shdr *sechdrs,
+		       const char *strtab,
+		       unsigned int symindex,
+		       unsigned int relsec,
+		       struct module *me)
+{
+	unsigned int i;
+	Elf64_Rela *rela = (void *)sechdrs[relsec].sh_addr;
+	Elf64_Sym *sym;
+	unsigned long *location;
+	unsigned long value;
+
+	DEBUGP("Applying ADD relocate section %u to %u\n", relsec,
+	       sechdrs[relsec].sh_info);
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
+		/* This is where to make the change */
+		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+			+ rela[i].r_offset;
+		/* This is the symbol it is referring to */
+		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
+			+ ELF64_R_SYM(rela[i].r_info);
+
+		DEBUGP("RELOC at %p: %li-type as %s (%lu) + %li\n",
+		       location, (long)ELF64_R_TYPE(rela[i].r_info),
+		       strtab + sym->st_name, (unsigned long)sym->st_value,
+		       (long)rela[i].r_addend);
+
+		/* `Everything is relative'. */
+		value = sym->st_value + rela[i].r_addend;
+
+		switch (ELF64_R_TYPE(rela[i].r_info)) {
+		case R_PPC64_ADDR32:
+			/* Simply set it */
+			*(u32 *)location = value;
+			break;
+			
+		case R_PPC64_ADDR64:
+			/* Simply set it */
+			*(unsigned long *)location = value;
+			break;
+
+		case R_PPC64_TOC:
+			*(unsigned long *)location = my_r2(sechdrs, me);
+			break;
+
+		case R_PPC64_TOC16:
+			/* Subtact TOC pointer */
+			value -= my_r2(sechdrs, me);
+			if (value + 0x8000 > 0xffff) {
+				printk("%s: bad TOC16 relocation (%lu)\n",
+				       me->name, value);
+				return -ENOEXEC;
+			}
+			*((uint16_t *) location)
+				= (*((uint16_t *) location) & ~0xffff)
+				| (value & 0xffff);
+			break;
+
+		case R_PPC64_TOC16_DS:
+			/* Subtact TOC pointer */
+			value -= my_r2(sechdrs, me);
+			if ((value & 3) != 0 || value + 0x8000 > 0xffff) {
+				printk("%s: bad TOC16_DS relocation (%lu)\n",
+				       me->name, value);
+				return -ENOEXEC;
+			}
+			*((uint16_t *) location)
+				= (*((uint16_t *) location) & ~0xfffc)
+				| (value & 0xfffc);
+			break;
+
+		case R_PPC_REL24:
+			/* FIXME: Handle weak symbols here --RR */
+			if (sym->st_shndx == SHN_UNDEF) {
+				/* External: go via stub */
+				value = stub_for_addr(sechdrs, value, me);
+				if (!value)
+					return -ENOENT;
+				if (!restore_r2((u32 *)location + 1, me))
+					return -ENOEXEC;
+			}
+
+			/* Convert value to relative */
+			value -= (unsigned long)location;
+			if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0){
+				printk("%s: REL24 %li out of range!\n",
+				       me->name, (long int)value);
+				return -ENOEXEC;
+			}
+
+			/* Only replace bits 2 through 26 */
+			*(uint32_t *)location 
+				= (*(uint32_t *)location & ~0x03fffffc)
+				| (value & 0x03fffffc);
+			break;
+
+		default:
+			printk("%s: Unknown ADD relocation: %lu\n",
+			       me->name,
+			       (unsigned long)ELF64_R_TYPE(rela[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+
+	return 0;
+}
+
+LIST_HEAD(module_bug_list);
+
+int module_finalize(const Elf_Ehdr *hdr,
+		const Elf_Shdr *sechdrs, struct module *me)
+{
+	char *secstrings;
+	unsigned int i;
+
+	me->arch.bug_table = NULL;
+	me->arch.num_bugs = 0;
+
+	/* Find the __bug_table section, if present */
+	secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+	for (i = 1; i < hdr->e_shnum; i++) {
+		if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table"))
+			continue;
+		me->arch.bug_table = (void *) sechdrs[i].sh_addr;
+		me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry);
+		break;
+	}
+
+	/*
+	 * Strictly speaking this should have a spinlock to protect against
+	 * traversals, but since we only traverse on BUG()s, a spinlock
+	 * could potentially lead to deadlock and thus be counter-productive.
+	 */
+	list_add(&me->arch.bug_list, &module_bug_list);
+
+	return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+	list_del(&mod->arch.bug_list);
+}
+
+struct bug_entry *module_find_bug(unsigned long bugaddr)
+{
+	struct mod_arch_specific *mod;
+	unsigned int i;
+	struct bug_entry *bug;
+
+	list_for_each_entry(mod, &module_bug_list, bug_list) {
+		bug = mod->bug_table;
+		for (i = 0; i < mod->num_bugs; ++i, ++bug)
+			if (bugaddr == bug->bug_addr)
+				return bug;
+	}
+	return NULL;
+}
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
new file mode 100644
index 0000000..3cef1b8
--- /dev/null
+++ b/arch/powerpc/kernel/pci_64.c
@@ -0,0 +1,1319 @@
+/*
+ * Port for PPC64 David Engebretsen, IBM Corp.
+ * Contains common pci routines for ppc64 platform, pSeries and iSeries brands.
+ * 
+ * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
+ *   Rework, based on alpha PCI code.
+ *
+ *      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.
+ */
+
+#undef DEBUG
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+#include <linux/syscalls.h>
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/byteorder.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+#include <asm/udbg.h>
+#include <asm/ppc-pci.h>
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+unsigned long pci_probe_only = 1;
+unsigned long pci_assign_all_buses = 0;
+
+/*
+ * legal IO pages under MAX_ISA_PORT.  This is to ensure we don't touch
+ * devices we don't have access to.
+ */
+unsigned long io_page_mask;
+
+EXPORT_SYMBOL(io_page_mask);
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+static void fixup_resource(struct resource *res, struct pci_dev *dev);
+static void do_bus_setup(struct pci_bus *bus);
+#endif
+
+unsigned int pcibios_assign_all_busses(void)
+{
+	return pci_assign_all_buses;
+}
+
+/* pci_io_base -- the base address from which io bars are offsets.
+ * This is the lowest I/O base address (so bar values are always positive),
+ * and it *must* be the start of ISA space if an ISA bus exists because
+ * ISA drivers use hard coded offsets.  If no ISA bus exists a dummy
+ * page is mapped and isa_io_limit prevents access to it.
+ */
+unsigned long isa_io_base;	/* NULL if no ISA bus */
+EXPORT_SYMBOL(isa_io_base);
+unsigned long pci_io_base;
+EXPORT_SYMBOL(pci_io_base);
+
+void iSeries_pcibios_init(void);
+
+LIST_HEAD(hose_list);
+
+struct dma_mapping_ops pci_dma_ops;
+EXPORT_SYMBOL(pci_dma_ops);
+
+int global_phb_number;		/* Global phb counter */
+
+/* Cached ISA bridge dev. */
+struct pci_dev *ppc64_isabridge_dev = NULL;
+
+static void fixup_broken_pcnet32(struct pci_dev* dev)
+{
+	if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
+		dev->vendor = PCI_VENDOR_ID_AMD;
+		pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32);
+
+void  pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+			      struct resource *res)
+{
+	unsigned long offset = 0;
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+
+	if (!hose)
+		return;
+
+	if (res->flags & IORESOURCE_IO)
+	        offset = (unsigned long)hose->io_base_virt - pci_io_base;
+
+	if (res->flags & IORESOURCE_MEM)
+		offset = hose->pci_mem_offset;
+
+	region->start = res->start - offset;
+	region->end = res->end - offset;
+}
+
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			      struct pci_bus_region *region)
+{
+	unsigned long offset = 0;
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+
+	if (!hose)
+		return;
+
+	if (res->flags & IORESOURCE_IO)
+	        offset = (unsigned long)hose->io_base_virt - pci_io_base;
+
+	if (res->flags & IORESOURCE_MEM)
+		offset = hose->pci_mem_offset;
+
+	res->start = region->start + offset;
+	res->end = region->end + offset;
+}
+
+#ifdef CONFIG_HOTPLUG
+EXPORT_SYMBOL(pcibios_resource_to_bus);
+EXPORT_SYMBOL(pcibios_bus_to_resource);
+#endif
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might have be mirrored at 0x0100-0x03ff..
+ */
+void pcibios_align_resource(void *data, struct resource *res,
+			    unsigned long size, unsigned long align)
+{
+	struct pci_dev *dev = data;
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	unsigned long start = res->start;
+	unsigned long alignto;
+
+	if (res->flags & IORESOURCE_IO) {
+	        unsigned long offset = (unsigned long)hose->io_base_virt -
+					pci_io_base;
+		/* Make sure we start at our min on all hoses */
+		if (start - offset < PCIBIOS_MIN_IO)
+			start = PCIBIOS_MIN_IO + offset;
+
+		/*
+		 * Put everything into 0x00-0xff region modulo 0x400
+		 */
+		if (start & 0x300)
+			start = (start + 0x3ff) & ~0x3ff;
+
+	} else if (res->flags & IORESOURCE_MEM) {
+		/* Make sure we start at our min on all hoses */
+		if (start - hose->pci_mem_offset < PCIBIOS_MIN_MEM)
+			start = PCIBIOS_MIN_MEM + hose->pci_mem_offset;
+
+		/* Align to multiple of size of minimum base.  */
+		alignto = max(0x1000UL, align);
+		start = ALIGN(start, alignto);
+	}
+
+	res->start = start;
+}
+
+static DEFINE_SPINLOCK(hose_spinlock);
+
+/*
+ * pci_controller(phb) initialized common variables.
+ */
+void __devinit pci_setup_pci_controller(struct pci_controller *hose)
+{
+	memset(hose, 0, sizeof(struct pci_controller));
+
+	spin_lock(&hose_spinlock);
+	hose->global_number = global_phb_number++;
+	list_add_tail(&hose->list_node, &hose_list);
+	spin_unlock(&hose_spinlock);
+}
+
+static void __init pcibios_claim_one_bus(struct pci_bus *b)
+{
+	struct pci_dev *dev;
+	struct pci_bus *child_bus;
+
+	list_for_each_entry(dev, &b->devices, bus_list) {
+		int i;
+
+		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+			struct resource *r = &dev->resource[i];
+
+			if (r->parent || !r->start || !r->flags)
+				continue;
+			pci_claim_resource(dev, i);
+		}
+	}
+
+	list_for_each_entry(child_bus, &b->children, node)
+		pcibios_claim_one_bus(child_bus);
+}
+
+#ifndef CONFIG_PPC_ISERIES
+static void __init pcibios_claim_of_setup(void)
+{
+	struct pci_bus *b;
+
+	list_for_each_entry(b, &pci_root_buses, node)
+		pcibios_claim_one_bus(b);
+}
+#endif
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
+{
+	u32 *prop;
+	int len;
+
+	prop = (u32 *) get_property(np, name, &len);
+	if (prop && len >= 4)
+		return *prop;
+	return def;
+}
+
+static unsigned int pci_parse_of_flags(u32 addr0)
+{
+	unsigned int flags = 0;
+
+	if (addr0 & 0x02000000) {
+		flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
+		flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
+		flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
+		if (addr0 & 0x40000000)
+			flags |= IORESOURCE_PREFETCH
+				 | PCI_BASE_ADDRESS_MEM_PREFETCH;
+	} else if (addr0 & 0x01000000)
+		flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
+	return flags;
+}
+
+#define GET_64BIT(prop, i)	((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1])
+
+static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
+{
+	u64 base, size;
+	unsigned int flags;
+	struct resource *res;
+	u32 *addrs, i;
+	int proplen;
+
+	addrs = (u32 *) get_property(node, "assigned-addresses", &proplen);
+	if (!addrs)
+		return;
+	for (; proplen >= 20; proplen -= 20, addrs += 5) {
+		flags = pci_parse_of_flags(addrs[0]);
+		if (!flags)
+			continue;
+		base = GET_64BIT(addrs, 1);
+		size = GET_64BIT(addrs, 3);
+		if (!size)
+			continue;
+		i = addrs[0] & 0xff;
+		if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
+			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
+		} else if (i == dev->rom_base_reg) {
+			res = &dev->resource[PCI_ROM_RESOURCE];
+			flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
+		} else {
+			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
+			continue;
+		}
+		res->start = base;
+		res->end = base + size - 1;
+		res->flags = flags;
+		res->name = pci_name(dev);
+		fixup_resource(res, dev);
+	}
+}
+
+struct pci_dev *of_create_pci_dev(struct device_node *node,
+				 struct pci_bus *bus, int devfn)
+{
+	struct pci_dev *dev;
+	const char *type;
+
+	dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
+	if (!dev)
+		return NULL;
+	type = get_property(node, "device_type", NULL);
+	if (type == NULL)
+		type = "";
+
+	memset(dev, 0, sizeof(struct pci_dev));
+	dev->bus = bus;
+	dev->sysdata = node;
+	dev->dev.parent = bus->bridge;
+	dev->dev.bus = &pci_bus_type;
+	dev->devfn = devfn;
+	dev->multifunction = 0;		/* maybe a lie? */
+
+	dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
+	dev->device = get_int_prop(node, "device-id", 0xffff);
+	dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
+	dev->subsystem_device = get_int_prop(node, "subsystem-id", 0);
+
+	dev->cfg_size = 256; /*pci_cfg_space_size(dev);*/
+
+	sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
+		dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
+	dev->class = get_int_prop(node, "class-code", 0);
+
+	dev->current_state = 4;		/* unknown power state */
+
+	if (!strcmp(type, "pci")) {
+		/* a PCI-PCI bridge */
+		dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
+		dev->rom_base_reg = PCI_ROM_ADDRESS1;
+	} else if (!strcmp(type, "cardbus")) {
+		dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
+	} else {
+		dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
+		dev->rom_base_reg = PCI_ROM_ADDRESS;
+		dev->irq = NO_IRQ;
+		if (node->n_intrs > 0) {
+			dev->irq = node->intrs[0].line;
+			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
+					      dev->irq);
+		}
+	}
+
+	pci_parse_of_addrs(node, dev);
+
+	pci_device_add(dev, bus);
+
+	/* XXX pci_scan_msi_device(dev); */
+
+	return dev;
+}
+EXPORT_SYMBOL(of_create_pci_dev);
+
+void __devinit of_scan_bus(struct device_node *node,
+				  struct pci_bus *bus)
+{
+	struct device_node *child = NULL;
+	u32 *reg;
+	int reglen, devfn;
+	struct pci_dev *dev;
+
+	while ((child = of_get_next_child(node, child)) != NULL) {
+		reg = (u32 *) get_property(child, "reg", &reglen);
+		if (reg == NULL || reglen < 20)
+			continue;
+		devfn = (reg[0] >> 8) & 0xff;
+		/* create a new pci_dev for this device */
+		dev = of_create_pci_dev(child, bus, devfn);
+		if (!dev)
+			continue;
+		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+		    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+			of_scan_pci_bridge(child, dev);
+	}
+
+	do_bus_setup(bus);
+}
+EXPORT_SYMBOL(of_scan_bus);
+
+void __devinit of_scan_pci_bridge(struct device_node *node,
+			 	struct pci_dev *dev)
+{
+	struct pci_bus *bus;
+	u32 *busrange, *ranges;
+	int len, i, mode;
+	struct resource *res;
+	unsigned int flags;
+	u64 size;
+
+	/* parse bus-range property */
+	busrange = (u32 *) get_property(node, "bus-range", &len);
+	if (busrange == NULL || len != 8) {
+		printk(KERN_ERR "Can't get bus-range for PCI-PCI bridge %s\n",
+		       node->full_name);
+		return;
+	}
+	ranges = (u32 *) get_property(node, "ranges", &len);
+	if (ranges == NULL) {
+		printk(KERN_ERR "Can't get ranges for PCI-PCI bridge %s\n",
+		       node->full_name);
+		return;
+	}
+
+	bus = pci_add_new_bus(dev->bus, dev, busrange[0]);
+	if (!bus) {
+		printk(KERN_ERR "Failed to create pci bus for %s\n",
+		       node->full_name);
+		return;
+	}
+
+	bus->primary = dev->bus->number;
+	bus->subordinate = busrange[1];
+	bus->bridge_ctl = 0;
+	bus->sysdata = node;
+
+	/* parse ranges property */
+	/* PCI #address-cells == 3 and #size-cells == 2 always */
+	res = &dev->resource[PCI_BRIDGE_RESOURCES];
+	for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) {
+		res->flags = 0;
+		bus->resource[i] = res;
+		++res;
+	}
+	i = 1;
+	for (; len >= 32; len -= 32, ranges += 8) {
+		flags = pci_parse_of_flags(ranges[0]);
+		size = GET_64BIT(ranges, 6);
+		if (flags == 0 || size == 0)
+			continue;
+		if (flags & IORESOURCE_IO) {
+			res = bus->resource[0];
+			if (res->flags) {
+				printk(KERN_ERR "PCI: ignoring extra I/O range"
+				       " for bridge %s\n", node->full_name);
+				continue;
+			}
+		} else {
+			if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
+				printk(KERN_ERR "PCI: too many memory ranges"
+				       " for bridge %s\n", node->full_name);
+				continue;
+			}
+			res = bus->resource[i];
+			++i;
+		}
+		res->start = GET_64BIT(ranges, 1);
+		res->end = res->start + size - 1;
+		res->flags = flags;
+		fixup_resource(res, dev);
+	}
+	sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
+		bus->number);
+
+	mode = PCI_PROBE_NORMAL;
+	if (ppc_md.pci_probe_mode)
+		mode = ppc_md.pci_probe_mode(bus);
+	if (mode == PCI_PROBE_DEVTREE)
+		of_scan_bus(node, bus);
+	else if (mode == PCI_PROBE_NORMAL)
+		pci_scan_child_bus(bus);
+}
+EXPORT_SYMBOL(of_scan_pci_bridge);
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+void __devinit scan_phb(struct pci_controller *hose)
+{
+	struct pci_bus *bus;
+	struct device_node *node = hose->arch_data;
+	int i, mode;
+	struct resource *res;
+
+	bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node);
+	if (bus == NULL) {
+		printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
+		       hose->global_number);
+		return;
+	}
+	bus->secondary = hose->first_busno;
+	hose->bus = bus;
+
+	bus->resource[0] = res = &hose->io_resource;
+	if (res->flags && request_resource(&ioport_resource, res))
+		printk(KERN_ERR "Failed to request PCI IO region "
+		       "on PCI domain %04x\n", hose->global_number);
+
+	for (i = 0; i < 3; ++i) {
+		res = &hose->mem_resources[i];
+		bus->resource[i+1] = res;
+		if (res->flags && request_resource(&iomem_resource, res))
+			printk(KERN_ERR "Failed to request PCI memory region "
+			       "on PCI domain %04x\n", hose->global_number);
+	}
+
+	mode = PCI_PROBE_NORMAL;
+#ifdef CONFIG_PPC_MULTIPLATFORM
+	if (ppc_md.pci_probe_mode)
+		mode = ppc_md.pci_probe_mode(bus);
+	if (mode == PCI_PROBE_DEVTREE) {
+		bus->subordinate = hose->last_busno;
+		of_scan_bus(node, bus);
+	}
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+	if (mode == PCI_PROBE_NORMAL)
+		hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
+	pci_bus_add_devices(bus);
+}
+
+static int __init pcibios_init(void)
+{
+	struct pci_controller *hose, *tmp;
+
+	/* For now, override phys_mem_access_prot. If we need it,
+	 * later, we may move that initialization to each ppc_md
+	 */
+	ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
+
+#ifdef CONFIG_PPC_ISERIES
+	iSeries_pcibios_init(); 
+#endif
+
+	printk("PCI: Probing PCI hardware\n");
+
+	/* Scan all of the recorded PCI controllers.  */
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+		scan_phb(hose);
+
+#ifndef CONFIG_PPC_ISERIES
+	if (pci_probe_only)
+		pcibios_claim_of_setup();
+	else
+		/* FIXME: `else' will be removed when
+		   pci_assign_unassigned_resources() is able to work
+		   correctly with [partially] allocated PCI tree. */
+		pci_assign_unassigned_resources();
+#endif /* !CONFIG_PPC_ISERIES */
+
+	/* Call machine dependent final fixup */
+	if (ppc_md.pcibios_fixup)
+		ppc_md.pcibios_fixup();
+
+	/* Cache the location of the ISA bridge (if we have one) */
+	ppc64_isabridge_dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
+	if (ppc64_isabridge_dev != NULL)
+		printk("ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+	/* map in PCI I/O space */
+	phbs_remap_io();
+#endif
+
+	printk("PCI: Probing PCI hardware done\n");
+
+	return 0;
+}
+
+subsys_initcall(pcibios_init);
+
+char __init *pcibios_setup(char *str)
+{
+	return str;
+}
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	u16 cmd, oldcmd;
+	int i;
+
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	oldcmd = cmd;
+
+	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+		struct resource *res = &dev->resource[i];
+
+		/* Only set up the requested stuff */
+		if (!(mask & (1<<i)))
+			continue;
+
+		if (res->flags & IORESOURCE_IO)
+			cmd |= PCI_COMMAND_IO;
+		if (res->flags & IORESOURCE_MEM)
+			cmd |= PCI_COMMAND_MEMORY;
+	}
+
+	if (cmd != oldcmd) {
+		printk(KERN_DEBUG "PCI: Enabling device: (%s), cmd %x\n",
+		       pci_name(dev), cmd);
+                /* Enable the appropriate bits in the PCI command register.  */
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
+	return 0;
+}
+
+/*
+ * Return the domain number for this bus.
+ */
+int pci_domain_nr(struct pci_bus *bus)
+{
+#ifdef CONFIG_PPC_ISERIES
+	return 0;
+#else
+	struct pci_controller *hose = pci_bus_to_host(bus);
+
+	return hose->global_number;
+#endif
+}
+
+EXPORT_SYMBOL(pci_domain_nr);
+
+/* Decide whether to display the domain number in /proc */
+int pci_proc_domain(struct pci_bus *bus)
+{
+#ifdef CONFIG_PPC_ISERIES
+	return 0;
+#else
+	struct pci_controller *hose = pci_bus_to_host(bus);
+	return hose->buid;
+#endif
+}
+
+/*
+ * Platform support for /proc/bus/pci/X/Y mmap()s,
+ * modelled on the sparc64 implementation by Dave Miller.
+ *  -- paulus.
+ */
+
+/*
+ * Adjust vm_pgoff of VMA such that it is the physical page offset
+ * corresponding to the 32-bit pci bus offset for DEV requested by the user.
+ *
+ * Basically, the user finds the base address for his device which he wishes
+ * to mmap.  They read the 32-bit value from the config space base register,
+ * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
+ * offset parameter of mmap on /proc/bus/pci/XXX for that device.
+ *
+ * Returns negative error code on failure, zero on success.
+ */
+static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
+					       unsigned long *offset,
+					       enum pci_mmap_state mmap_state)
+{
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	unsigned long io_offset = 0;
+	int i, res_bit;
+
+	if (hose == 0)
+		return NULL;		/* should never happen */
+
+	/* If memory, add on the PCI bridge address offset */
+	if (mmap_state == pci_mmap_mem) {
+		*offset += hose->pci_mem_offset;
+		res_bit = IORESOURCE_MEM;
+	} else {
+		io_offset = (unsigned long)hose->io_base_virt - pci_io_base;
+		*offset += io_offset;
+		res_bit = IORESOURCE_IO;
+	}
+
+	/*
+	 * Check that the offset requested corresponds to one of the
+	 * resources of the device.
+	 */
+	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+		struct resource *rp = &dev->resource[i];
+		int flags = rp->flags;
+
+		/* treat ROM as memory (should be already) */
+		if (i == PCI_ROM_RESOURCE)
+			flags |= IORESOURCE_MEM;
+
+		/* Active and same type? */
+		if ((flags & res_bit) == 0)
+			continue;
+
+		/* In the range of this resource? */
+		if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
+			continue;
+
+		/* found it! construct the final physical address */
+		if (mmap_state == pci_mmap_io)
+		       	*offset += hose->io_base_phys - io_offset;
+		return rp;
+	}
+
+	return NULL;
+}
+
+/*
+ * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
+ * device mapping.
+ */
+static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
+				      pgprot_t protection,
+				      enum pci_mmap_state mmap_state,
+				      int write_combine)
+{
+	unsigned long prot = pgprot_val(protection);
+
+	/* Write combine is always 0 on non-memory space mappings. On
+	 * memory space, if the user didn't pass 1, we check for a
+	 * "prefetchable" resource. This is a bit hackish, but we use
+	 * this to workaround the inability of /sysfs to provide a write
+	 * combine bit
+	 */
+	if (mmap_state != pci_mmap_mem)
+		write_combine = 0;
+	else if (write_combine == 0) {
+		if (rp->flags & IORESOURCE_PREFETCH)
+			write_combine = 1;
+	}
+
+	/* XXX would be nice to have a way to ask for write-through */
+	prot |= _PAGE_NO_CACHE;
+	if (write_combine)
+		prot &= ~_PAGE_GUARDED;
+	else
+		prot |= _PAGE_GUARDED;
+
+	printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start,
+	       prot);
+
+	return __pgprot(prot);
+}
+
+/*
+ * This one is used by /dev/mem and fbdev who have no clue about the
+ * PCI device, it tries to find the PCI device first and calls the
+ * above routine
+ */
+pgprot_t pci_phys_mem_access_prot(struct file *file,
+				  unsigned long pfn,
+				  unsigned long size,
+				  pgprot_t protection)
+{
+	struct pci_dev *pdev = NULL;
+	struct resource *found = NULL;
+	unsigned long prot = pgprot_val(protection);
+	unsigned long offset = pfn << PAGE_SHIFT;
+	int i;
+
+	if (page_is_ram(pfn))
+		return __pgprot(prot);
+
+	prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+
+	for_each_pci_dev(pdev) {
+		for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+			struct resource *rp = &pdev->resource[i];
+			int flags = rp->flags;
+
+			/* Active and same type? */
+			if ((flags & IORESOURCE_MEM) == 0)
+				continue;
+			/* In the range of this resource? */
+			if (offset < (rp->start & PAGE_MASK) ||
+			    offset > rp->end)
+				continue;
+			found = rp;
+			break;
+		}
+		if (found)
+			break;
+	}
+	if (found) {
+		if (found->flags & IORESOURCE_PREFETCH)
+			prot &= ~_PAGE_GUARDED;
+		pci_dev_put(pdev);
+	}
+
+	DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
+
+	return __pgprot(prot);
+}
+
+
+/*
+ * Perform the actual remap of the pages for a PCI device mapping, as
+ * appropriate for this architecture.  The region in the process to map
+ * is described by vm_start and vm_end members of VMA, the base physical
+ * address is found in vm_pgoff.
+ * The pci device structure is provided so that architectures may make mapping
+ * decisions on a per-device or per-bus basis.
+ *
+ * Returns a negative error code on failure, zero on success.
+ */
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state,
+			int write_combine)
+{
+	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+	struct resource *rp;
+	int ret;
+
+	rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
+	if (rp == NULL)
+		return -EINVAL;
+
+	vma->vm_pgoff = offset >> PAGE_SHIFT;
+	vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO;
+	vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
+						  vma->vm_page_prot,
+						  mmap_state, write_combine);
+
+	ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
+
+	return ret;
+}
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct pci_dev *pdev;
+	struct device_node *np;
+
+	pdev = to_pci_dev (dev);
+	np = pci_device_to_OF_node(pdev);
+	if (np == NULL || np->full_name == NULL)
+		return 0;
+	return sprintf(buf, "%s", np->full_name);
+}
+static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+void pcibios_add_platform_entries(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PPC_MULTIPLATFORM
+	device_create_file(&pdev->dev, &dev_attr_devspec);
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+}
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+
+#define ISA_SPACE_MASK 0x1
+#define ISA_SPACE_IO 0x1
+
+static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
+				      unsigned long phb_io_base_phys,
+				      void __iomem * phb_io_base_virt)
+{
+	struct isa_range *range;
+	unsigned long pci_addr;
+	unsigned int isa_addr;
+	unsigned int size;
+	int rlen = 0;
+
+	range = (struct isa_range *) get_property(isa_node, "ranges", &rlen);
+	if (range == NULL || (rlen < sizeof(struct isa_range))) {
+		printk(KERN_ERR "no ISA ranges or unexpected isa range size,"
+		       "mapping 64k\n");
+		__ioremap_explicit(phb_io_base_phys,
+				   (unsigned long)phb_io_base_virt,
+				   0x10000, _PAGE_NO_CACHE | _PAGE_GUARDED);
+		return;	
+	}
+	
+	/* From "ISA Binding to 1275"
+	 * The ranges property is laid out as an array of elements,
+	 * each of which comprises:
+	 *   cells 0 - 1:	an ISA address
+	 *   cells 2 - 4:	a PCI address 
+	 *			(size depending on dev->n_addr_cells)
+	 *   cell 5:		the size of the range
+	 */
+	if ((range->isa_addr.a_hi && ISA_SPACE_MASK) == ISA_SPACE_IO) {
+		isa_addr = range->isa_addr.a_lo;
+		pci_addr = (unsigned long) range->pci_addr.a_mid << 32 | 
+			range->pci_addr.a_lo;
+
+		/* Assume these are both zero */
+		if ((pci_addr != 0) || (isa_addr != 0)) {
+			printk(KERN_ERR "unexpected isa to pci mapping: %s\n",
+					__FUNCTION__);
+			return;
+		}
+		
+		size = PAGE_ALIGN(range->size);
+
+		__ioremap_explicit(phb_io_base_phys, 
+				   (unsigned long) phb_io_base_virt, 
+				   size, _PAGE_NO_CACHE | _PAGE_GUARDED);
+	}
+}
+
+void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
+					    struct device_node *dev, int prim)
+{
+	unsigned int *ranges, pci_space;
+	unsigned long size;
+	int rlen = 0;
+	int memno = 0;
+	struct resource *res;
+	int np, na = prom_n_addr_cells(dev);
+	unsigned long pci_addr, cpu_phys_addr;
+
+	np = na + 5;
+
+	/* From "PCI Binding to 1275"
+	 * The ranges property is laid out as an array of elements,
+	 * each of which comprises:
+	 *   cells 0 - 2:	a PCI address
+	 *   cells 3 or 3+4:	a CPU physical address
+	 *			(size depending on dev->n_addr_cells)
+	 *   cells 4+5 or 5+6:	the size of the range
+	 */
+	rlen = 0;
+	hose->io_base_phys = 0;
+	ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
+	while ((rlen -= np * sizeof(unsigned int)) >= 0) {
+		res = NULL;
+		pci_space = ranges[0];
+		pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
+
+		cpu_phys_addr = ranges[3];
+		if (na >= 2)
+			cpu_phys_addr = (cpu_phys_addr << 32) | ranges[4];
+
+		size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
+		ranges += np;
+		if (size == 0)
+			continue;
+
+		/* Now consume following elements while they are contiguous */
+		while (rlen >= np * sizeof(unsigned int)) {
+			unsigned long addr, phys;
+
+			if (ranges[0] != pci_space)
+				break;
+			addr = ((unsigned long)ranges[1] << 32) | ranges[2];
+			phys = ranges[3];
+			if (na >= 2)
+				phys = (phys << 32) | ranges[4];
+			if (addr != pci_addr + size ||
+			    phys != cpu_phys_addr + size)
+				break;
+
+			size += ((unsigned long)ranges[na+3] << 32)
+				| ranges[na+4];
+			ranges += np;
+			rlen -= np * sizeof(unsigned int);
+		}
+
+		switch ((pci_space >> 24) & 0x3) {
+		case 1:		/* I/O space */
+			hose->io_base_phys = cpu_phys_addr;
+			hose->pci_io_size = size;
+
+			res = &hose->io_resource;
+			res->flags = IORESOURCE_IO;
+			res->start = pci_addr;
+			DBG("phb%d: IO 0x%lx -> 0x%lx\n", hose->global_number,
+				    res->start, res->start + size - 1);
+			break;
+		case 2:		/* memory space */
+			memno = 0;
+			while (memno < 3 && hose->mem_resources[memno].flags)
+				++memno;
+
+			if (memno == 0)
+				hose->pci_mem_offset = cpu_phys_addr - pci_addr;
+			if (memno < 3) {
+				res = &hose->mem_resources[memno];
+				res->flags = IORESOURCE_MEM;
+				res->start = cpu_phys_addr;
+				DBG("phb%d: MEM 0x%lx -> 0x%lx\n", hose->global_number,
+					    res->start, res->start + size - 1);
+			}
+			break;
+		}
+		if (res != NULL) {
+			res->name = dev->full_name;
+			res->end = res->start + size - 1;
+			res->parent = NULL;
+			res->sibling = NULL;
+			res->child = NULL;
+		}
+	}
+}
+
+void __init pci_setup_phb_io(struct pci_controller *hose, int primary)
+{
+	unsigned long size = hose->pci_io_size;
+	unsigned long io_virt_offset;
+	struct resource *res;
+	struct device_node *isa_dn;
+
+	hose->io_base_virt = reserve_phb_iospace(size);
+	DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
+		hose->global_number, hose->io_base_phys,
+		(unsigned long) hose->io_base_virt);
+
+	if (primary) {
+		pci_io_base = (unsigned long)hose->io_base_virt;
+		isa_dn = of_find_node_by_type(NULL, "isa");
+		if (isa_dn) {
+			isa_io_base = pci_io_base;
+			pci_process_ISA_OF_ranges(isa_dn, hose->io_base_phys,
+						hose->io_base_virt);
+			of_node_put(isa_dn);
+			/* Allow all IO */
+			io_page_mask = -1;
+		}
+	}
+
+	io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base;
+	res = &hose->io_resource;
+	res->start += io_virt_offset;
+	res->end += io_virt_offset;
+}
+
+void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose,
+					int primary)
+{
+	unsigned long size = hose->pci_io_size;
+	unsigned long io_virt_offset;
+	struct resource *res;
+
+	hose->io_base_virt = __ioremap(hose->io_base_phys, size,
+					_PAGE_NO_CACHE | _PAGE_GUARDED);
+	DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
+		hose->global_number, hose->io_base_phys,
+		(unsigned long) hose->io_base_virt);
+
+	if (primary)
+		pci_io_base = (unsigned long)hose->io_base_virt;
+
+	io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base;
+	res = &hose->io_resource;
+	res->start += io_virt_offset;
+	res->end += io_virt_offset;
+}
+
+
+static int get_bus_io_range(struct pci_bus *bus, unsigned long *start_phys,
+				unsigned long *start_virt, unsigned long *size)
+{
+	struct pci_controller *hose = pci_bus_to_host(bus);
+	struct pci_bus_region region;
+	struct resource *res;
+
+	if (bus->self) {
+		res = bus->resource[0];
+		pcibios_resource_to_bus(bus->self, &region, res);
+		*start_phys = hose->io_base_phys + region.start;
+		*start_virt = (unsigned long) hose->io_base_virt + 
+				region.start;
+		if (region.end > region.start) 
+			*size = region.end - region.start + 1;
+		else {
+			printk("%s(): unexpected region 0x%lx->0x%lx\n", 
+					__FUNCTION__, region.start, region.end);
+			return 1;
+		}
+		
+	} else {
+		/* Root Bus */
+		res = &hose->io_resource;
+		*start_phys = hose->io_base_phys;
+		*start_virt = (unsigned long) hose->io_base_virt;
+		if (res->end > res->start)
+			*size = res->end - res->start + 1;
+		else {
+			printk("%s(): unexpected region 0x%lx->0x%lx\n", 
+					__FUNCTION__, res->start, res->end);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+int unmap_bus_range(struct pci_bus *bus)
+{
+	unsigned long start_phys;
+	unsigned long start_virt;
+	unsigned long size;
+
+	if (!bus) {
+		printk(KERN_ERR "%s() expected bus\n", __FUNCTION__);
+		return 1;
+	}
+	
+	if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
+		return 1;
+	if (iounmap_explicit((void __iomem *) start_virt, size))
+		return 1;
+
+	return 0;
+}
+EXPORT_SYMBOL(unmap_bus_range);
+
+int remap_bus_range(struct pci_bus *bus)
+{
+	unsigned long start_phys;
+	unsigned long start_virt;
+	unsigned long size;
+
+	if (!bus) {
+		printk(KERN_ERR "%s() expected bus\n", __FUNCTION__);
+		return 1;
+	}
+	
+	
+	if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
+		return 1;
+	printk("mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, size);
+	if (__ioremap_explicit(start_phys, start_virt, size,
+			       _PAGE_NO_CACHE | _PAGE_GUARDED))
+		return 1;
+
+	return 0;
+}
+EXPORT_SYMBOL(remap_bus_range);
+
+void phbs_remap_io(void)
+{
+	struct pci_controller *hose, *tmp;
+
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+		remap_bus_range(hose->bus);
+}
+
+/*
+ * ppc64 can have multifunction devices that do not respond to function 0.
+ * In this case we must scan all functions.
+ * XXX this can go now, we use the OF device tree in all the
+ * cases that caused problems. -- paulus
+ */
+int pcibios_scan_all_fns(struct pci_bus *bus, int devfn)
+{
+       return 0;
+}
+
+static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
+{
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	unsigned long start, end, mask, offset;
+
+	if (res->flags & IORESOURCE_IO) {
+		offset = (unsigned long)hose->io_base_virt - pci_io_base;
+
+		start = res->start += offset;
+		end = res->end += offset;
+
+		/* Need to allow IO access to pages that are in the
+		   ISA range */
+		if (start < MAX_ISA_PORT) {
+			if (end > MAX_ISA_PORT)
+				end = MAX_ISA_PORT;
+
+			start >>= PAGE_SHIFT;
+			end >>= PAGE_SHIFT;
+
+			/* get the range of pages for the map */
+			mask = ((1 << (end+1)) - 1) ^ ((1 << start) - 1);
+			io_page_mask |= mask;
+		}
+	} else if (res->flags & IORESOURCE_MEM) {
+		res->start += hose->pci_mem_offset;
+		res->end += hose->pci_mem_offset;
+	}
+}
+
+void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
+					      struct pci_bus *bus)
+{
+	/* Update device resources.  */
+	int i;
+
+	for (i = 0; i < PCI_NUM_RESOURCES; i++)
+		if (dev->resource[i].flags)
+			fixup_resource(&dev->resource[i], dev);
+}
+EXPORT_SYMBOL(pcibios_fixup_device_resources);
+
+static void __devinit do_bus_setup(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+
+	ppc_md.iommu_bus_setup(bus);
+
+	list_for_each_entry(dev, &bus->devices, bus_list)
+		ppc_md.iommu_dev_setup(dev);
+
+	if (ppc_md.irq_bus_setup)
+		ppc_md.irq_bus_setup(bus);
+}
+
+void __devinit pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_dev *dev = bus->self;
+
+	if (dev && pci_probe_only &&
+	    (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+		/* This is a subordinate bridge */
+
+		pci_read_bridge_bases(bus);
+		pcibios_fixup_device_resources(dev, bus);
+	}
+
+	do_bus_setup(bus);
+
+	if (!pci_probe_only)
+		return;
+
+	list_for_each_entry(dev, &bus->devices, bus_list)
+		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+			pcibios_fixup_device_resources(dev, bus);
+}
+EXPORT_SYMBOL(pcibios_fixup_bus);
+
+/*
+ * Reads the interrupt pin to determine if interrupt is use by card.
+ * If the interrupt is used, then gets the interrupt line from the 
+ * openfirmware and sets it in the pci_dev and pci_config line.
+ */
+int pci_read_irq_line(struct pci_dev *pci_dev)
+{
+	u8 intpin;
+	struct device_node *node;
+
+    	pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &intpin);
+	if (intpin == 0)
+		return 0;
+
+	node = pci_device_to_OF_node(pci_dev);
+	if (node == NULL)
+		return -1;
+
+	if (node->n_intrs == 0)
+		return -1;
+
+	pci_dev->irq = node->intrs[0].line;
+
+	pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, pci_dev->irq);
+
+	return 0;
+}
+EXPORT_SYMBOL(pci_read_irq_line);
+
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+			  const struct resource *rsrc,
+			  u64 *start, u64 *end)
+{
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	unsigned long offset = 0;
+
+	if (hose == NULL)
+		return;
+
+	if (rsrc->flags & IORESOURCE_IO)
+		offset = pci_io_base - (unsigned long)hose->io_base_virt +
+			hose->io_base_phys;
+
+	*start = rsrc->start + offset;
+	*end = rsrc->end + offset;
+}
+
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+
+#define IOBASE_BRIDGE_NUMBER	0
+#define IOBASE_MEMORY		1
+#define IOBASE_IO		2
+#define IOBASE_ISA_IO		3
+#define IOBASE_ISA_MEM		4
+
+long sys_pciconfig_iobase(long which, unsigned long in_bus,
+			  unsigned long in_devfn)
+{
+	struct pci_controller* hose;
+	struct list_head *ln;
+	struct pci_bus *bus = NULL;
+	struct device_node *hose_node;
+
+	/* Argh ! Please forgive me for that hack, but that's the
+	 * simplest way to get existing XFree to not lockup on some
+	 * G5 machines... So when something asks for bus 0 io base
+	 * (bus 0 is HT root), we return the AGP one instead.
+	 */
+	if (machine_is_compatible("MacRISC4"))
+		if (in_bus == 0)
+			in_bus = 0xf0;
+
+	/* That syscall isn't quite compatible with PCI domains, but it's
+	 * used on pre-domains setup. We return the first match
+	 */
+
+	for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
+		bus = pci_bus_b(ln);
+		if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate))
+			break;
+		bus = NULL;
+	}
+	if (bus == NULL || bus->sysdata == NULL)
+		return -ENODEV;
+
+	hose_node = (struct device_node *)bus->sysdata;
+	hose = PCI_DN(hose_node)->phb;
+
+	switch (which) {
+	case IOBASE_BRIDGE_NUMBER:
+		return (long)hose->first_busno;
+	case IOBASE_MEMORY:
+		return (long)hose->pci_mem_offset;
+	case IOBASE_IO:
+		return (long)hose->io_base_phys;
+	case IOBASE_ISA_IO:
+		return (long)isa_io_base;
+	case IOBASE_ISA_MEM:
+		return -EINVAL;
+	}
+
+	return -EOPNOTSUPP;
+}
diff --git a/arch/powerpc/kernel/pci_direct_iommu.c b/arch/powerpc/kernel/pci_direct_iommu.c
new file mode 100644
index 0000000..e1a32f8
--- /dev/null
+++ b/arch/powerpc/kernel/pci_direct_iommu.c
@@ -0,0 +1,94 @@
+/*
+ * Support for DMA from PCI devices to main memory on
+ * machines without an iommu or with directly addressable
+ * RAM (typically a pmac with 2Gb of RAM or less)
+ *
+ * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/abs_addr.h>
+#include <asm/ppc-pci.h>
+
+static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size,
+				   dma_addr_t *dma_handle, gfp_t flag)
+{
+	void *ret;
+
+	ret = (void *)__get_free_pages(flag, get_order(size));
+	if (ret != NULL) {
+		memset(ret, 0, size);
+		*dma_handle = virt_to_abs(ret);
+	}
+	return ret;
+}
+
+static void pci_direct_free_coherent(struct device *hwdev, size_t size,
+				 void *vaddr, dma_addr_t dma_handle)
+{
+	free_pages((unsigned long)vaddr, get_order(size));
+}
+
+static dma_addr_t pci_direct_map_single(struct device *hwdev, void *ptr,
+		size_t size, enum dma_data_direction direction)
+{
+	return virt_to_abs(ptr);
+}
+
+static void pci_direct_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
+		size_t size, enum dma_data_direction direction)
+{
+}
+
+static int pci_direct_map_sg(struct device *hwdev, struct scatterlist *sg,
+		int nents, enum dma_data_direction direction)
+{
+	int i;
+
+	for (i = 0; i < nents; i++, sg++) {
+		sg->dma_address = page_to_phys(sg->page) + sg->offset;
+		sg->dma_length = sg->length;
+	}
+
+	return nents;
+}
+
+static void pci_direct_unmap_sg(struct device *hwdev, struct scatterlist *sg,
+		int nents, enum dma_data_direction direction)
+{
+}
+
+static int pci_direct_dma_supported(struct device *dev, u64 mask)
+{
+	return mask < 0x100000000ull;
+}
+
+void __init pci_direct_iommu_init(void)
+{
+	pci_dma_ops.alloc_coherent = pci_direct_alloc_coherent;
+	pci_dma_ops.free_coherent = pci_direct_free_coherent;
+	pci_dma_ops.map_single = pci_direct_map_single;
+	pci_dma_ops.unmap_single = pci_direct_unmap_single;
+	pci_dma_ops.map_sg = pci_direct_map_sg;
+	pci_dma_ops.unmap_sg = pci_direct_unmap_sg;
+	pci_dma_ops.dma_supported = pci_direct_dma_supported;
+}
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
new file mode 100644
index 0000000..12c4c9e
--- /dev/null
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -0,0 +1,230 @@
+/*
+ * pci_dn.c
+ *
+ * Copyright (C) 2001 Todd Inglett, IBM Corporation
+ *
+ * PCI manipulation via device_nodes.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *    
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/bootmem.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/pSeries_reconfig.h>
+#include <asm/ppc-pci.h>
+
+/*
+ * Traverse_func that inits the PCI fields of the device node.
+ * NOTE: this *must* be done before read/write config to the device.
+ */
+static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
+{
+	struct pci_controller *phb = data;
+	int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL);
+	u32 *regs;
+	struct pci_dn *pdn;
+
+	if (mem_init_done)
+		pdn = kmalloc(sizeof(*pdn), GFP_KERNEL);
+	else
+		pdn = alloc_bootmem(sizeof(*pdn));
+	if (pdn == NULL)
+		return NULL;
+	memset(pdn, 0, sizeof(*pdn));
+	dn->data = pdn;
+	pdn->node = dn;
+	pdn->phb = phb;
+	regs = (u32 *)get_property(dn, "reg", NULL);
+	if (regs) {
+		/* First register entry is addr (00BBSS00)  */
+		pdn->busno = (regs[0] >> 16) & 0xff;
+		pdn->devfn = (regs[0] >> 8) & 0xff;
+	}
+
+	pdn->pci_ext_config_space = (type && *type == 1);
+	return NULL;
+}
+
+/*
+ * Traverse a device tree stopping each PCI device in the tree.
+ * This is done depth first.  As each node is processed, a "pre"
+ * function is called and the children are processed recursively.
+ *
+ * The "pre" func returns a value.  If non-zero is returned from
+ * the "pre" func, the traversal stops and this value is returned.
+ * This return value is useful when using traverse as a method of
+ * finding a device.
+ *
+ * NOTE: we do not run the func for devices that do not appear to
+ * be PCI except for the start node which we assume (this is good
+ * because the start node is often a phb which may be missing PCI
+ * properties).
+ * We use the class-code as an indicator. If we run into
+ * one of these nodes we also assume its siblings are non-pci for
+ * performance.
+ */
+void *traverse_pci_devices(struct device_node *start, traverse_func pre,
+		void *data)
+{
+	struct device_node *dn, *nextdn;
+	void *ret;
+
+	/* We started with a phb, iterate all childs */
+	for (dn = start->child; dn; dn = nextdn) {
+		u32 *classp, class;
+
+		nextdn = NULL;
+		classp = (u32 *)get_property(dn, "class-code", NULL);
+		class = classp ? *classp : 0;
+
+		if (pre && ((ret = pre(dn, data)) != NULL))
+			return ret;
+
+		/* If we are a PCI bridge, go down */
+		if (dn->child && ((class >> 8) == PCI_CLASS_BRIDGE_PCI ||
+				  (class >> 8) == PCI_CLASS_BRIDGE_CARDBUS))
+			/* Depth first...do children */
+			nextdn = dn->child;
+		else if (dn->sibling)
+			/* ok, try next sibling instead. */
+			nextdn = dn->sibling;
+		if (!nextdn) {
+			/* Walk up to next valid sibling. */
+			do {
+				dn = dn->parent;
+				if (dn == start)
+					return NULL;
+			} while (dn->sibling == NULL);
+			nextdn = dn->sibling;
+		}
+	}
+	return NULL;
+}
+
+/** 
+ * pci_devs_phb_init_dynamic - setup pci devices under this PHB
+ * phb: pci-to-host bridge (top-level bridge connecting to cpu)
+ *
+ * This routine is called both during boot, (before the memory
+ * subsystem is set up, before kmalloc is valid) and during the 
+ * dynamic lpar operation of adding a PHB to a running system.
+ */
+void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
+{
+	struct device_node * dn = (struct device_node *) phb->arch_data;
+	struct pci_dn *pdn;
+
+	/* PHB nodes themselves must not match */
+	update_dn_pci_info(dn, phb);
+	pdn = dn->data;
+	if (pdn) {
+		pdn->devfn = pdn->busno = -1;
+		pdn->phb = phb;
+	}
+
+	/* Update dn->phb ptrs for new phb and children devices */
+	traverse_pci_devices(dn, update_dn_pci_info, phb);
+}
+
+/*
+ * Traversal func that looks for a <busno,devfcn> value.
+ * If found, the pci_dn is returned (thus terminating the traversal).
+ */
+static void *is_devfn_node(struct device_node *dn, void *data)
+{
+	int busno = ((unsigned long)data >> 8) & 0xff;
+	int devfn = ((unsigned long)data) & 0xff;
+	struct pci_dn *pci = dn->data;
+
+	if (pci && (devfn == pci->devfn) && (busno == pci->busno))
+		return dn;
+	return NULL;
+}
+
+/*
+ * This is the "slow" path for looking up a device_node from a
+ * pci_dev.  It will hunt for the device under its parent's
+ * phb and then update sysdata for a future fastpath.
+ *
+ * It may also do fixups on the actual device since this happens
+ * on the first read/write.
+ *
+ * Note that it also must deal with devices that don't exist.
+ * In this case it may probe for real hardware ("just in case")
+ * and add a device_node to the device tree if necessary.
+ *
+ */
+struct device_node *fetch_dev_dn(struct pci_dev *dev)
+{
+	struct device_node *orig_dn = dev->sysdata;
+	struct device_node *dn;
+	unsigned long searchval = (dev->bus->number << 8) | dev->devfn;
+
+	dn = traverse_pci_devices(orig_dn, is_devfn_node, (void *)searchval);
+	if (dn)
+		dev->sysdata = dn;
+	return dn;
+}
+EXPORT_SYMBOL(fetch_dev_dn);
+
+static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
+{
+	struct device_node *np = node;
+	struct pci_dn *pci = NULL;
+	int err = NOTIFY_OK;
+
+	switch (action) {
+	case PSERIES_RECONFIG_ADD:
+		pci = np->parent->data;
+		if (pci)
+			update_dn_pci_info(np, pci->phb);
+		break;
+	default:
+		err = NOTIFY_DONE;
+		break;
+	}
+	return err;
+}
+
+static struct notifier_block pci_dn_reconfig_nb = {
+	.notifier_call = pci_dn_reconfig_notifier,
+};
+
+/** 
+ * pci_devs_phb_init - Initialize phbs and pci devs under them.
+ * 
+ * This routine walks over all phb's (pci-host bridges) on the
+ * system, and sets up assorted pci-related structures 
+ * (including pci info in the device node structs) for each
+ * pci device found underneath.  This routine runs once,
+ * early in the boot sequence.
+ */
+void __init pci_devs_phb_init(void)
+{
+	struct pci_controller *phb, *tmp;
+
+	/* This must be done first so the device nodes have valid pci info! */
+	list_for_each_entry_safe(phb, tmp, &hose_list, list_node)
+		pci_devs_phb_init_dynamic(phb);
+
+	pSeries_reconfig_notifier_register(&pci_dn_reconfig_nb);
+}
diff --git a/arch/powerpc/kernel/pci_iommu.c b/arch/powerpc/kernel/pci_iommu.c
new file mode 100644
index 0000000..bdf15db
--- /dev/null
+++ b/arch/powerpc/kernel/pci_iommu.c
@@ -0,0 +1,128 @@
+/*
+ * arch/ppc64/kernel/pci_iommu.c
+ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
+ *
+ * Rewrite, cleanup, new allocation schemes:
+ * Copyright (C) 2004 Olof Johansson, IBM Corporation
+ *
+ * Dynamic DMA mapping support, platform-independent parts.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/iommu.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/ppc-pci.h>
+
+/*
+ * We can use ->sysdata directly and avoid the extra work in
+ * pci_device_to_OF_node since ->sysdata will have been initialised
+ * in the iommu init code for all devices.
+ */
+#define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata))
+
+static inline struct iommu_table *devnode_table(struct device *dev)
+{
+	struct pci_dev *pdev;
+
+	if (!dev) {
+		pdev = ppc64_isabridge_dev;
+		if (!pdev)
+			return NULL;
+	} else
+		pdev = to_pci_dev(dev);
+
+	return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
+}
+
+
+/* Allocates a contiguous real buffer and creates mappings over it.
+ * Returns the virtual address of the buffer and sets dma_handle
+ * to the dma address (mapping) of the first page.
+ */
+static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size,
+			   dma_addr_t *dma_handle, gfp_t flag)
+{
+	return iommu_alloc_coherent(devnode_table(hwdev), size, dma_handle,
+			flag);
+}
+
+static void pci_iommu_free_coherent(struct device *hwdev, size_t size,
+			 void *vaddr, dma_addr_t dma_handle)
+{
+	iommu_free_coherent(devnode_table(hwdev), size, vaddr, dma_handle);
+}
+
+/* Creates TCEs for a user provided buffer.  The user buffer must be 
+ * contiguous real kernel storage (not vmalloc).  The address of the buffer
+ * passed here is the kernel (virtual) address of the buffer.  The buffer
+ * need not be page aligned, the dma_addr_t returned will point to the same
+ * byte within the page as vaddr.
+ */
+static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr,
+		size_t size, enum dma_data_direction direction)
+{
+	return iommu_map_single(devnode_table(hwdev), vaddr, size, direction);
+}
+
+
+static void pci_iommu_unmap_single(struct device *hwdev, dma_addr_t dma_handle,
+		size_t size, enum dma_data_direction direction)
+{
+	iommu_unmap_single(devnode_table(hwdev), dma_handle, size, direction);
+}
+
+
+static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist,
+		int nelems, enum dma_data_direction direction)
+{
+	return iommu_map_sg(pdev, devnode_table(pdev), sglist,
+			nelems, direction);
+}
+
+static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist,
+		int nelems, enum dma_data_direction direction)
+{
+	iommu_unmap_sg(devnode_table(pdev), sglist, nelems, direction);
+}
+
+/* We support DMA to/from any memory page via the iommu */
+static int pci_iommu_dma_supported(struct device *dev, u64 mask)
+{
+	return 1;
+}
+
+void pci_iommu_init(void)
+{
+	pci_dma_ops.alloc_coherent = pci_iommu_alloc_coherent;
+	pci_dma_ops.free_coherent = pci_iommu_free_coherent;
+	pci_dma_ops.map_single = pci_iommu_map_single;
+	pci_dma_ops.unmap_single = pci_iommu_unmap_single;
+	pci_dma_ops.map_sg = pci_iommu_map_sg;
+	pci_dma_ops.unmap_sg = pci_iommu_unmap_sg;
+	pci_dma_ops.dma_supported = pci_iommu_dma_supported;
+}
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 5dcf4ba..59846b4 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -105,6 +105,13 @@ EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(__strncpy_from_user);
 EXPORT_SYMBOL(__strnlen_user);
 
+#ifndef  __powerpc64__
+EXPORT_SYMBOL(__ide_mm_insl);
+EXPORT_SYMBOL(__ide_mm_outsw);
+EXPORT_SYMBOL(__ide_mm_insw);
+EXPORT_SYMBOL(__ide_mm_outsl);
+#endif
+
 EXPORT_SYMBOL(_insb);
 EXPORT_SYMBOL(_outsb);
 EXPORT_SYMBOL(_insw);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 6a5b468..3bf968e 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1368,6 +1368,7 @@ prom_n_addr_cells(struct device_node* np
 	/* No #address-cells property for the root node, default to 1 */
 	return 1;
 }
+EXPORT_SYMBOL(prom_n_addr_cells);
 
 int
 prom_n_size_cells(struct device_node* np)
@@ -1383,6 +1384,7 @@ prom_n_size_cells(struct device_node* np
 	/* No #size-cells property for the root node, default to 1 */
 	return 1;
 }
+EXPORT_SYMBOL(prom_n_size_cells);
 
 /**
  * Work out the sense (active-low level / active-high edge)
diff --git a/arch/powerpc/kernel/rtas-rtc.c b/arch/powerpc/kernel/rtas-rtc.c
new file mode 100644
index 0000000..7b94866
--- /dev/null
+++ b/arch/powerpc/kernel/rtas-rtc.c
@@ -0,0 +1,105 @@
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/rtc.h>
+#include <linux/delay.h>
+#include <asm/prom.h>
+#include <asm/rtas.h>
+#include <asm/time.h>
+
+
+#define MAX_RTC_WAIT 5000	/* 5 sec */
+#define RTAS_CLOCK_BUSY (-2)
+unsigned long __init rtas_get_boot_time(void)
+{
+	int ret[8];
+	int error, wait_time;
+	unsigned long max_wait_tb;
+
+	max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
+	do {
+		error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
+		if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
+			wait_time = rtas_extended_busy_delay_time(error);
+			/* This is boot time so we spin. */
+			udelay(wait_time*1000);
+			error = RTAS_CLOCK_BUSY;
+		}
+	} while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
+
+	if (error != 0 && printk_ratelimit()) {
+		printk(KERN_WARNING "error: reading the clock failed (%d)\n",
+			error);
+		return 0;
+	}
+
+	return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]);
+}
+
+/* NOTE: get_rtc_time will get an error if executed in interrupt context
+ * and if a delay is needed to read the clock.  In this case we just
+ * silently return without updating rtc_tm.
+ */
+void rtas_get_rtc_time(struct rtc_time *rtc_tm)
+{
+        int ret[8];
+	int error, wait_time;
+	unsigned long max_wait_tb;
+
+	max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
+	do {
+		error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
+		if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
+			if (in_interrupt() && printk_ratelimit()) {
+				memset(&rtc_tm, 0, sizeof(struct rtc_time));
+				printk(KERN_WARNING "error: reading clock"
+				       " would delay interrupt\n");
+				return;	/* delay not allowed */
+			}
+			wait_time = rtas_extended_busy_delay_time(error);
+			msleep(wait_time);
+			error = RTAS_CLOCK_BUSY;
+		}
+	} while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
+
+        if (error != 0 && printk_ratelimit()) {
+                printk(KERN_WARNING "error: reading the clock failed (%d)\n",
+		       error);
+		return;
+        }
+
+	rtc_tm->tm_sec = ret[5];
+	rtc_tm->tm_min = ret[4];
+	rtc_tm->tm_hour = ret[3];
+	rtc_tm->tm_mday = ret[2];
+	rtc_tm->tm_mon = ret[1] - 1;
+	rtc_tm->tm_year = ret[0] - 1900;
+}
+
+int rtas_set_rtc_time(struct rtc_time *tm)
+{
+	int error, wait_time;
+	unsigned long max_wait_tb;
+
+	max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
+	do {
+	        error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
+				  tm->tm_year + 1900, tm->tm_mon + 1,
+				  tm->tm_mday, tm->tm_hour, tm->tm_min,
+				  tm->tm_sec, 0);
+		if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
+			if (in_interrupt())
+				return 1;	/* probably decrementer */
+			wait_time = rtas_extended_busy_delay_time(error);
+			msleep(wait_time);
+			error = RTAS_CLOCK_BUSY;
+		}
+	} while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
+
+        if (error != 0 && printk_ratelimit())
+                printk(KERN_WARNING "error: setting the clock failed (%d)\n",
+		       error);
+
+        return 0;
+}
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index c98cfcc..e569433 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -57,10 +57,6 @@ extern void power4_idle(void);
 boot_infos_t *boot_infos;
 struct ide_machdep_calls ppc_ide_md;
 
-/* XXX should go elsewhere */
-int __irq_offset_value;
-EXPORT_SYMBOL(__irq_offset_value);
-
 int boot_cpuid;
 EXPORT_SYMBOL_GPL(boot_cpuid);
 int boot_cpuid_phys;
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index fdbd9f9..608fee7 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -59,6 +59,7 @@
 #include <asm/firmware.h>
 #include <asm/xmon.h>
 #include <asm/udbg.h>
+#include <asm/kexec.h>
 
 #include "setup.h"
 
@@ -415,6 +416,10 @@ void __init setup_system(void)
 	 */
 	unflatten_device_tree();
 
+#ifdef CONFIG_KEXEC
+	kexec_setup();	/* requires unflattened device tree. */
+#endif
+
 	/*
 	 * Fill the ppc64_caches & systemcfg structures with informations
 	 * retreived from the device-tree. Need to be called before
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 8bdf95b..5a2eba6 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -403,8 +403,6 @@ static int save_user_regs(struct pt_regs
 		    ELF_NFPREG * sizeof(double)))
 		return 1;
 
-	current->thread.fpscr.val = 0;	/* turn off all fp exceptions */
-
 #ifdef CONFIG_ALTIVEC
 	/* save altivec registers */
 	if (current->thread.used_vr) {
@@ -818,6 +816,9 @@ static int handle_rt_signal(unsigned lon
 			goto badframe;
 		regs->link = (unsigned long) frame->tramp;
 	}
+
+	current->thread.fpscr.val = 0;	/* turn off all fp exceptions */
+
 	if (put_user(regs->gpr[1], (u32 __user *)newsp))
 		goto badframe;
 	regs->gpr[1] = newsp;
@@ -1097,6 +1098,8 @@ static int handle_signal(unsigned long s
 		regs->link = (unsigned long) frame->mctx.tramp;
 	}
 
+	current->thread.fpscr.val = 0;	/* turn off all fp exceptions */
+
 	if (put_user(regs->gpr[1], (u32 __user *)newsp))
 		goto badframe;
 	regs->gpr[1] = newsp;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 58194e1..1decf27 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -131,9 +131,6 @@ static long setup_sigcontext(struct sigc
 
 	flush_fp_to_thread(current);
 
-	/* Make sure signal doesn't get spurrious FP exceptions */
-	current->thread.fpscr.val = 0;
-
 #ifdef CONFIG_ALTIVEC
 	err |= __put_user(v_regs, &sc->v_regs);
 
@@ -423,6 +420,9 @@ static int setup_rt_frame(int signr, str
 	if (err)
 		goto badframe;
 
+	/* Make sure signal handler doesn't get spurious FP exceptions */
+	current->thread.fpscr.val = 0;
+
 	/* Set up to return from userspace. */
 	if (vdso64_rt_sigtramp && current->thread.vdso_base) {
 		regs->link = current->thread.vdso_base + vdso64_rt_sigtramp;
diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S
index a08c26e..f6b3847 100644
--- a/arch/powerpc/kernel/vdso32/datapage.S
+++ b/arch/powerpc/kernel/vdso32/datapage.S
@@ -77,8 +77,9 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
 	mflr	r12
   .cfi_register lr,r12
 	bl	__get_datapage@local
-	lwz	r3,CFG_TB_TICKS_PER_SEC(r3)
 	lwz	r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
+	lwz	r3,CFG_TB_TICKS_PER_SEC(r3)
 	mtlr	r12
+	blr
   .cfi_endproc
 V_FUNCTION_END(__kernel_get_tbfreq)
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S
index aeb5fc9..0a32a41 100644
--- a/arch/powerpc/kernel/vdso32/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso32/gettimeofday.S
@@ -83,7 +83,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
 	/* Check for supported clock IDs */
 	cmpli	cr0,r3,CLOCK_REALTIME
 	cmpli	cr1,r3,CLOCK_MONOTONIC
-	cror	cr0,cr0,cr1
+	cror	cr0*4+eq,cr0*4+eq,cr1*4+eq
 	bne	cr0,99f
 
 	mflr	r12			/* r12 saves lr */
@@ -91,7 +91,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
 	mr	r10,r3			/* r10 saves id */
 	mr	r11,r4			/* r11 saves tp */
 	bl	__get_datapage@local	/* get data page */
-	mr	r9, r3			/* datapage ptr in r9 */
+	mr	r9,r3			/* datapage ptr in r9 */
 	beq	cr1,50f			/* if monotonic -> jump there */
 
 	/*
@@ -173,10 +173,14 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
 	add	r4,r4,r7
 	lis	r5,NSEC_PER_SEC@h
 	ori	r5,r5,NSEC_PER_SEC@l
-	cmpli	cr0,r4,r5
+	cmpl	cr0,r4,r5
+	cmpli	cr1,r4,0
 	blt	1f
 	subf	r4,r5,r4
 	addi	r3,r3,1
+1:	bge	cr1,1f
+	addi	r3,r3,-1
+	add	r4,r4,r5
 1:	stw	r3,TSPC32_TV_SEC(r11)
 	stw	r4,TSPC32_TV_NSEC(r11)
 
@@ -210,7 +214,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
 	/* Check for supported clock IDs */
 	cmpwi	cr0,r3,CLOCK_REALTIME
 	cmpwi	cr1,r3,CLOCK_MONOTONIC
-	cror	cr0,cr0,cr1
+	cror	cr0*4+eq,cr0*4+eq,cr1*4+eq
 	bne	cr0,99f
 
 	li	r3,0
diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S
index e67eda0..6393e41 100644
--- a/arch/powerpc/kernel/vdso64/datapage.S
+++ b/arch/powerpc/kernel/vdso64/datapage.S
@@ -80,5 +80,6 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
 	bl	V_LOCAL_FUNC(__get_datapage)
 	ld	r3,CFG_TB_TICKS_PER_SEC(r3)
 	mtlr	r12
+	blr
   .cfi_endproc
 V_FUNCTION_END(__kernel_get_tbfreq)
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S
index d371c02..1a89094 100644
--- a/arch/powerpc/kernel/vdso64/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
@@ -1,4 +1,5 @@
-/*
+
+	/*
  * Userland implementation of gettimeofday() for 64 bits processes in a
  * ppc64 kernel for use in the vDSO
  *
@@ -68,7 +69,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
 	/* Check for supported clock IDs */
 	cmpwi	cr0,r3,CLOCK_REALTIME
 	cmpwi	cr1,r3,CLOCK_MONOTONIC
-	cror	cr0,cr0,cr1
+	cror	cr0*4+eq,cr0*4+eq,cr1*4+eq
 	bne	cr0,99f
 
 	mflr	r12			/* r12 saves lr */
@@ -84,16 +85,17 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
 
 	bl	V_LOCAL_FUNC(__do_get_xsec)	/* get xsec from tb & kernel */
 
-	lis     r7,0x3b9a		/* r7 = 1000000000 = NSEC_PER_SEC */
-	ori     r7,r7,0xca00
+	lis     r7,15			/* r7 = 1000000 = USEC_PER_SEC */
+	ori     r7,r7,16960
 	rldicl  r5,r4,44,20		/* r5 = sec = xsec / XSEC_PER_SEC */
 	rldicr  r6,r5,20,43		/* r6 = sec * XSEC_PER_SEC */
 	std	r5,TSPC64_TV_SEC(r11)	/* store sec in tv */
 	subf	r0,r6,r4		/* r0 = xsec = (xsec - r6) */
-	mulld   r0,r0,r7		/* nsec = (xsec * NSEC_PER_SEC) /
+	mulld   r0,r0,r7		/* usec = (xsec * USEC_PER_SEC) /
 					 * XSEC_PER_SEC
 					 */
 	rldicl  r0,r0,44,20
+	mulli	r0,r0,1000		/* nsec = usec * 1000 */
 	std	r0,TSPC64_TV_NSEC(r11)	/* store nsec in tp */
 
 	mtlr	r12
@@ -106,15 +108,16 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
 
 50:	bl	V_LOCAL_FUNC(__do_get_xsec)	/* get xsec from tb & kernel */
 
-	lis     r7,0x3b9a		/* r7 = 1000000000 = NSEC_PER_SEC */
-	ori     r7,r7,0xca00
+	lis     r7,15			/* r7 = 1000000 = USEC_PER_SEC */
+	ori     r7,r7,16960
 	rldicl  r5,r4,44,20		/* r5 = sec = xsec / XSEC_PER_SEC */
 	rldicr  r6,r5,20,43		/* r6 = sec * XSEC_PER_SEC */
 	subf	r0,r6,r4		/* r0 = xsec = (xsec - r6) */
-	mulld   r0,r0,r7		/* nsec = (xsec * NSEC_PER_SEC) /
+	mulld   r0,r0,r7		/* usec = (xsec * USEC_PER_SEC) /
 					 * XSEC_PER_SEC
 					 */
 	rldicl  r6,r0,44,20
+	mulli	r6,r6,1000		/* nsec = usec * 1000 */
 
 	/* now we must fixup using wall to monotonic. We need to snapshot
 	 * that value and do the counter trick again. Fortunately, we still
@@ -123,8 +126,8 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
 	 * can be used
 	 */
 
-	lwz	r4,WTOM_CLOCK_SEC(r9)
-	lwz	r7,WTOM_CLOCK_NSEC(r9)
+	lwa	r4,WTOM_CLOCK_SEC(r3)
+	lwa	r7,WTOM_CLOCK_NSEC(r3)
 
 	/* We now have our result in r4,r7. We create a fake dependency
 	 * on that result and re-check the counter
@@ -144,10 +147,14 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
 	add	r7,r7,r6
 	lis	r9,NSEC_PER_SEC@h
 	ori	r9,r9,NSEC_PER_SEC@l
-	cmpli	cr0,r7,r9
+	cmpl	cr0,r7,r9
+	cmpli	cr1,r7,0
 	blt	1f
 	subf	r7,r9,r7
 	addi	r4,r4,1
+1:	bge	cr1,1f
+	addi	r4,r4,-1
+	add	r7,r7,r9
 1:	std	r4,TSPC64_TV_SEC(r11)
 	std	r7,TSPC64_TV_NSEC(r11)
 
@@ -181,7 +188,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
 	/* Check for supported clock IDs */
 	cmpwi	cr0,r3,CLOCK_REALTIME
 	cmpwi	cr1,r3,CLOCK_MONOTONIC
-	cror	cr0,cr0,cr1
+	cror	cr0*4+eq,cr0*4+eq,cr1*4+eq
 	bne	cr0,99f
 
 	li	r3,0
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index af9ca0e..5d581bb 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -1,5 +1,5 @@
 /*
- * Modifications by Kumar Gala (kumar.gala@freescale.com) to support
+ * Modifications by Kumar Gala (galak@kernel.crashing.org) to support
  * E500 Book E processors.
  *
  * Copyright 2004 Freescale Semiconductor, Inc
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index e2c95fc..4bd7b0a 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -200,6 +200,8 @@ void show_mem(void)
 		unsigned long flags;
 		pgdat_resize_lock(pgdat, &flags);
 		for (i = 0; i < pgdat->node_spanned_pages; i++) {
+			if (!pfn_valid(pgdat->node_start_pfn + i))
+				continue;
 			page = pgdat_page_nr(pgdat, i);
 			total++;
 			if (PageHighMem(page))
@@ -336,7 +338,7 @@ void __init mem_init(void)
 	struct page *page;
 	unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize;
 
-	num_physpages = max_pfn;	/* RAM is assumed contiguous */
+	num_physpages = lmb.memory.size >> PAGE_SHIFT;
 	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
 
 #ifdef CONFIG_NEED_MULTIPLE_NODES
@@ -348,11 +350,13 @@ void __init mem_init(void)
 		}
 	}
 #else
-	max_mapnr = num_physpages;
+	max_mapnr = max_pfn;
 	totalram_pages += free_all_bootmem();
 #endif
 	for_each_pgdat(pgdat) {
 		for (i = 0; i < pgdat->node_spanned_pages; i++) {
+			if (!pfn_valid(pgdat->node_start_pfn + i))
+				continue;
 			page = pgdat_page_nr(pgdat, i);
 			if (PageReserved(page))
 				reservedpages++;
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index bd2cf13..f72cf87 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -483,6 +483,7 @@ static void __init setup_nonnuma(void)
 {
 	unsigned long top_of_ram = lmb_end_of_DRAM();
 	unsigned long total_ram = lmb_phys_mem_size();
+	unsigned int i;
 
 	printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
 	       top_of_ram, total_ram);
@@ -490,7 +491,9 @@ static void __init setup_nonnuma(void)
 	       (top_of_ram - total_ram) >> 20);
 
 	map_cpu_to_node(boot_cpuid, 0);
-	add_region(0, 0, lmb_end_of_DRAM() >> PAGE_SHIFT);
+	for (i = 0; i < lmb.memory.cnt; ++i)
+		add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT,
+			   lmb_size_pages(&lmb.memory, i));
 	node_set_online(0);
 }
 
diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c
index 86124a9..26539cd 100644
--- a/arch/powerpc/oprofile/op_model_fsl_booke.c
+++ b/arch/powerpc/oprofile/op_model_fsl_booke.c
@@ -7,7 +7,7 @@
  * Copyright (c) 2004 Freescale Semiconductor, Inc
  *
  * Author: Andy Fleming
- * Maintainer: Kumar Gala <Kumar.Gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 01090e9..a58daa1 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -42,13 +42,6 @@
 #include "irq.h"
 #include "call_pci.h"
 
-/* This maps virtual irq numbers to real irqs */
-unsigned int virt_irq_to_real_map[NR_IRQS];
-
-/* The next available virtual irq number */
-/* Note: the pcnet32 driver assumes irq numbers < 2 aren't valid. :( */
-static int next_virtual_irq = 2;
-
 static long Pci_Interrupt_Count;
 static long Pci_Event_Count;
 
@@ -350,26 +343,14 @@ static hw_irq_controller iSeries_IRQ_han
 int __init iSeries_allocate_IRQ(HvBusNumber busNumber,
 		HvSubBusNumber subBusNumber, HvAgentId deviceId)
 {
-	unsigned int realirq, virtirq;
+	int virtirq;
+	unsigned int realirq;
 	u8 idsel = (deviceId >> 4);
 	u8 function = deviceId & 7;
 
-	virtirq = next_virtual_irq++;
 	realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function;
-	virt_irq_to_real_map[virtirq] = realirq;
+	virtirq = virt_irq_create_mapping(realirq);
 
 	irq_desc[virtirq].handler = &iSeries_IRQ_handler;
 	return virtirq;
 }
-
-int virt_irq_create_mapping(unsigned int real_irq)
-{
-	BUG(); /* Don't call this on iSeries, yet */
-
-	return 0;
-}
-
-void virt_irq_init(void)
-{
-	return;
-}
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 6a29f30..da26639 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -39,7 +39,6 @@
 #include <asm/sections.h>
 #include <asm/iommu.h>
 #include <asm/firmware.h>
-#include <asm/systemcfg.h>
 #include <asm/system.h>
 #include <asm/time.h>
 #include <asm/paca.h>
@@ -548,8 +547,6 @@ static unsigned long __init build_iSerie
  */
 static void __init iSeries_setup_arch(void)
 {
-	unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index;
-
 	if (get_paca()->lppaca.shared_proc) {
 		ppc_md.idle_loop = iseries_shared_idle;
 		printk(KERN_INFO "Using shared processor idle loop\n");
@@ -565,9 +562,6 @@ static void __init iSeries_setup_arch(vo
 			itVpdAreas.xSlicMaxLogicalProcs);
 	printk("Max physical processors = %d\n",
 			itVpdAreas.xSlicMaxPhysicalProcs);
-
-	_systemcfg->processor = xIoHriProcessorVpd[procIx].xPVR;
-	printk("Processor version = %x\n", _systemcfg->processor);
 }
 
 static void iSeries_show_cpuinfo(struct seq_file *m)
diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c
index 5947b21..feb0a94 100644
--- a/arch/powerpc/platforms/powermac/time.c
+++ b/arch/powerpc/platforms/powermac/time.c
@@ -102,7 +102,7 @@ static unsigned long from_rtc_time(struc
 static unsigned long cuda_get_time(void)
 {
 	struct adb_request req;
-	unsigned long now;
+	unsigned int now;
 
 	if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
 		return 0;
@@ -113,7 +113,7 @@ static unsigned long cuda_get_time(void)
 		       req.reply_len);
 	now = (req.reply[3] << 24) + (req.reply[4] << 16)
 		+ (req.reply[5] << 8) + req.reply[6];
-	return now - RTC_OFFSET;
+	return ((unsigned long)now) - RTC_OFFSET;
 }
 
 #define cuda_get_rtc_time(tm)	to_rtc_time(cuda_get_time(), (tm))
@@ -146,7 +146,7 @@ static int cuda_set_rtc_time(struct rtc_
 static unsigned long pmu_get_time(void)
 {
 	struct adb_request req;
-	unsigned long now;
+	unsigned int now;
 
 	if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
 		return 0;
@@ -156,7 +156,7 @@ static unsigned long pmu_get_time(void)
 		       req.reply_len);
 	now = (req.reply[0] << 24) + (req.reply[1] << 16)
 		+ (req.reply[2] << 8) + req.reply[3];
-	return now - RTC_OFFSET;
+	return ((unsigned long)now) - RTC_OFFSET;
 }
 
 #define pmu_get_rtc_time(tm)	to_rtc_time(pmu_get_time(), (tm))
@@ -199,6 +199,7 @@ static unsigned long smu_get_time(void)
 #define smu_set_rtc_time(tm, spin)	0
 #endif
 
+/* Can't be __init, it's called when suspending and resuming */
 unsigned long pmac_get_boot_time(void)
 {
 	/* Get the time from the RTC, used only at boot time */
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index e7ca5b1..06d5ef5 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -4,4 +4,7 @@ obj-$(CONFIG_SMP)	+= smp.o
 obj-$(CONFIG_IBMVIO)	+= vio.o
 obj-$(CONFIG_XICS)	+= xics.o
 obj-$(CONFIG_SCANLOG)	+= scanlog.o
-obj-$(CONFIG_EEH)    += eeh.o eeh_event.o
+obj-$(CONFIG_EEH)	+= eeh.o eeh_event.o
+
+obj-$(CONFIG_HVC_CONSOLE)	+= hvconsole.o
+obj-$(CONFIG_HVCS)		+= hvcserver.o
diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c
new file mode 100644
index 0000000..138e128
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/hvconsole.c
@@ -0,0 +1,74 @@
+/*
+ * hvconsole.c
+ * Copyright (C) 2004 Hollis Blanchard, IBM Corporation
+ * Copyright (C) 2004 IBM Corporation
+ *
+ * Additional Author(s):
+ *  Ryan S. Arnold <rsa@us.ibm.com>
+ *
+ * LPAR console support.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/hvcall.h>
+#include <asm/hvconsole.h>
+
+/**
+ * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper
+ * @vtermno: The vtermno or unit_address of the adapter from which to fetch the
+ *	data.
+ * @buf: The character buffer into which to put the character data fetched from
+ *	firmware.
+ * @count: not used?
+ */
+int hvc_get_chars(uint32_t vtermno, char *buf, int count)
+{
+	unsigned long got;
+
+	if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got,
+		(unsigned long *)buf, (unsigned long *)buf+1) == H_Success)
+		return got;
+	return 0;
+}
+
+EXPORT_SYMBOL(hvc_get_chars);
+
+
+/**
+ * hvc_put_chars: send characters to firmware for denoted vterm adapter
+ * @vtermno: The vtermno or unit_address of the adapter from which the data
+ *	originated.
+ * @buf: The character buffer that contains the character data to send to
+ *	firmware.
+ * @count: Send this number of characters.
+ */
+int hvc_put_chars(uint32_t vtermno, const char *buf, int count)
+{
+	unsigned long *lbuf = (unsigned long *) buf;
+	long ret;
+
+	ret = plpar_hcall_norets(H_PUT_TERM_CHAR, vtermno, count, lbuf[0],
+				 lbuf[1]);
+	if (ret == H_Success)
+		return count;
+	if (ret == H_Busy)
+		return 0;
+	return -EIO;
+}
+
+EXPORT_SYMBOL(hvc_put_chars);
diff --git a/arch/powerpc/platforms/pseries/hvcserver.c b/arch/powerpc/platforms/pseries/hvcserver.c
new file mode 100644
index 0000000..4d58417
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/hvcserver.c
@@ -0,0 +1,251 @@
+/*
+ * hvcserver.c
+ * Copyright (C) 2004 Ryan S Arnold, IBM Corporation
+ *
+ * PPC64 virtual I/O console server support.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <asm/hvcall.h>
+#include <asm/hvcserver.h>
+#include <asm/io.h>
+
+#define HVCS_ARCH_VERSION "1.0.0"
+
+MODULE_AUTHOR("Ryan S. Arnold <rsa@us.ibm.com>");
+MODULE_DESCRIPTION("IBM hvcs ppc64 API");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(HVCS_ARCH_VERSION);
+
+/*
+ * Convert arch specific return codes into relevant errnos.  The hvcs
+ * functions aren't performance sensitive, so this conversion isn't an
+ * issue.
+ */
+int hvcs_convert(long to_convert)
+{
+	switch (to_convert) {
+		case H_Success:
+			return 0;
+		case H_Parameter:
+			return -EINVAL;
+		case H_Hardware:
+			return -EIO;
+		case H_Busy:
+		case H_LongBusyOrder1msec:
+		case H_LongBusyOrder10msec:
+		case H_LongBusyOrder100msec:
+		case H_LongBusyOrder1sec:
+		case H_LongBusyOrder10sec:
+		case H_LongBusyOrder100sec:
+			return -EBUSY;
+		case H_Function: /* fall through */
+		default:
+			return -EPERM;
+	}
+}
+
+/**
+ * hvcs_free_partner_info - free pi allocated by hvcs_get_partner_info
+ * @head: list_head pointer for an allocated list of partner info structs to
+ *	free.
+ *
+ * This function is used to free the partner info list that was returned by
+ * calling hvcs_get_partner_info().
+ */
+int hvcs_free_partner_info(struct list_head *head)
+{
+	struct hvcs_partner_info *pi;
+	struct list_head *element;
+
+	if (!head)
+		return -EINVAL;
+
+	while (!list_empty(head)) {
+		element = head->next;
+		pi = list_entry(element, struct hvcs_partner_info, node);
+		list_del(element);
+		kfree(pi);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(hvcs_free_partner_info);
+
+/* Helper function for hvcs_get_partner_info */
+int hvcs_next_partner(uint32_t unit_address,
+		unsigned long last_p_partition_ID,
+		unsigned long last_p_unit_address, unsigned long *pi_buff)
+
+{
+	long retval;
+	retval = plpar_hcall_norets(H_VTERM_PARTNER_INFO, unit_address,
+			last_p_partition_ID,
+				last_p_unit_address, virt_to_phys(pi_buff));
+	return hvcs_convert(retval);
+}
+
+/**
+ * hvcs_get_partner_info - Get all of the partner info for a vty-server adapter
+ * @unit_address: The unit_address of the vty-server adapter for which this
+ *	function is fetching partner info.
+ * @head: An initialized list_head pointer to an empty list to use to return the
+ *	list of partner info fetched from the hypervisor to the caller.
+ * @pi_buff: A page sized buffer pre-allocated prior to calling this function
+ *	that is to be used to be used by firmware as an iterator to keep track
+ *	of the partner info retrieval.
+ *
+ * This function returns non-zero on success, or if there is no partner info.
+ *
+ * The pi_buff is pre-allocated prior to calling this function because this
+ * function may be called with a spin_lock held and kmalloc of a page is not
+ * recommended as GFP_ATOMIC.
+ *
+ * The first long of this buffer is used to store a partner unit address.  The
+ * second long is used to store a partner partition ID and starting at
+ * pi_buff[2] is the 79 character Converged Location Code (diff size than the
+ * unsigned longs, hence the casting mumbo jumbo you see later).
+ *
+ * Invocation of this function should always be followed by an invocation of
+ * hvcs_free_partner_info() using a pointer to the SAME list head instance
+ * that was passed as a parameter to this function.
+ */
+int hvcs_get_partner_info(uint32_t unit_address, struct list_head *head,
+		unsigned long *pi_buff)
+{
+	/*
+	 * Dealt with as longs because of the hcall interface even though the
+	 * values are uint32_t.
+	 */
+	unsigned long	last_p_partition_ID;
+	unsigned long	last_p_unit_address;
+	struct hvcs_partner_info *next_partner_info = NULL;
+	int more = 1;
+	int retval;
+
+	memset(pi_buff, 0x00, PAGE_SIZE);
+	/* invalid parameters */
+	if (!head || !pi_buff)
+		return -EINVAL;
+
+	last_p_partition_ID = last_p_unit_address = ~0UL;
+	INIT_LIST_HEAD(head);
+
+	do {
+		retval = hvcs_next_partner(unit_address, last_p_partition_ID,
+				last_p_unit_address, pi_buff);
+		if (retval) {
+			/*
+			 * Don't indicate that we've failed if we have
+			 * any list elements.
+			 */
+			if (!list_empty(head))
+				return 0;
+			return retval;
+		}
+
+		last_p_partition_ID = pi_buff[0];
+		last_p_unit_address = pi_buff[1];
+
+		/* This indicates that there are no further partners */
+		if (last_p_partition_ID == ~0UL
+				&& last_p_unit_address == ~0UL)
+			break;
+
+		/* This is a very small struct and will be freed soon in
+		 * hvcs_free_partner_info(). */
+		next_partner_info = kmalloc(sizeof(struct hvcs_partner_info),
+				GFP_ATOMIC);
+
+		if (!next_partner_info) {
+			printk(KERN_WARNING "HVCONSOLE: kmalloc() failed to"
+				" allocate partner info struct.\n");
+			hvcs_free_partner_info(head);
+			return -ENOMEM;
+		}
+
+		next_partner_info->unit_address
+			= (unsigned int)last_p_unit_address;
+		next_partner_info->partition_ID
+			= (unsigned int)last_p_partition_ID;
+
+		/* copy the Null-term char too */
+		strncpy(&next_partner_info->location_code[0],
+			(char *)&pi_buff[2],
+			strlen((char *)&pi_buff[2]) + 1);
+
+		list_add_tail(&(next_partner_info->node), head);
+		next_partner_info = NULL;
+
+	} while (more);
+
+	return 0;
+}
+EXPORT_SYMBOL(hvcs_get_partner_info);
+
+/**
+ * hvcs_register_connection - establish a connection between this vty-server and
+ *	a vty.
+ * @unit_address: The unit address of the vty-server adapter that is to be
+ *	establish a connection.
+ * @p_partition_ID: The partition ID of the vty adapter that is to be connected.
+ * @p_unit_address: The unit address of the vty adapter to which the vty-server
+ *	is to be connected.
+ *
+ * If this function is called once and -EINVAL is returned it may
+ * indicate that the partner info needs to be refreshed for the
+ * target unit address at which point the caller must invoke
+ * hvcs_get_partner_info() and then call this function again.  If,
+ * for a second time, -EINVAL is returned then it indicates that
+ * there is probably already a partner connection registered to a
+ * different vty-server adapter.  It is also possible that a second
+ * -EINVAL may indicate that one of the parms is not valid, for
+ * instance if the link was removed between the vty-server adapter
+ * and the vty adapter that you are trying to open.  Don't shoot the
+ * messenger.  Firmware implemented it this way.
+ */
+int hvcs_register_connection( uint32_t unit_address,
+		uint32_t p_partition_ID, uint32_t p_unit_address)
+{
+	long retval;
+	retval = plpar_hcall_norets(H_REGISTER_VTERM, unit_address,
+				p_partition_ID, p_unit_address);
+	return hvcs_convert(retval);
+}
+EXPORT_SYMBOL(hvcs_register_connection);
+
+/**
+ * hvcs_free_connection - free the connection between a vty-server and vty
+ * @unit_address: The unit address of the vty-server that is to have its
+ *	connection severed.
+ *
+ * This function is used to free the partner connection between a vty-server
+ * adapter and a vty adapter.
+ *
+ * If -EBUSY is returned continue to call this function until 0 is returned.
+ */
+int hvcs_free_connection(uint32_t unit_address)
+{
+	long retval;
+	retval = plpar_hcall_norets(H_FREE_VTERM, unit_address);
+	return hvcs_convert(retval);
+}
+EXPORT_SYMBOL(hvcs_free_connection);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 3199082..b9d9732 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -200,14 +200,12 @@ static void __init pSeries_setup_arch(vo
 	if (ppc64_interrupt_controller == IC_OPEN_PIC) {
 		ppc_md.init_IRQ       = pSeries_init_mpic;
 		ppc_md.get_irq        = mpic_get_irq;
-	 	ppc_md.cpu_irq_down   = mpic_teardown_this_cpu;
 		/* Allocate the mpic now, so that find_and_init_phbs() can
 		 * fill the ISUs */
 		pSeries_setup_mpic();
 	} else {
 		ppc_md.init_IRQ       = xics_init_IRQ;
 		ppc_md.get_irq        = xics_get_irq;
-		ppc_md.cpu_irq_down   = xics_teardown_cpu;
 	}
 
 #ifdef CONFIG_SMP
@@ -595,6 +593,27 @@ static int pSeries_pci_probe_mode(struct
 	return PCI_PROBE_NORMAL;
 }
 
+#ifdef CONFIG_KEXEC
+static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
+{
+	/* Don't risk a hypervisor call if we're crashing */
+	if (!crash_shutdown) {
+		unsigned long vpa = __pa(&get_paca()->lppaca);
+
+		if (unregister_vpa(hard_smp_processor_id(), vpa)) {
+			printk("VPA deregistration of cpu %u (hw_cpu_id %d) "
+					"failed\n", smp_processor_id(),
+					hard_smp_processor_id());
+		}
+	}
+
+	if (ppc64_interrupt_controller == IC_OPEN_PIC)
+		mpic_teardown_this_cpu(secondary);
+	else
+		xics_teardown_cpu(secondary);
+}
+#endif
+
 struct machdep_calls __initdata pSeries_md = {
 	.probe			= pSeries_probe,
 	.setup_arch		= pSeries_setup_arch,
@@ -617,4 +636,7 @@ struct machdep_calls __initdata pSeries_
 	.check_legacy_ioport	= pSeries_check_legacy_ioport,
 	.system_reset_exception = pSeries_system_reset_exception,
 	.machine_check_exception = pSeries_machine_check_exception,
+#ifdef CONFIG_KEXEC
+	.kexec_cpu_down		= pseries_kexec_cpu_down,
+#endif
 };
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index ef4356b..c45a6ad 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -19,6 +19,7 @@
 #include <linux/cpumask.h>
 #include <linux/module.h>
 #include <linux/sysrq.h>
+#include <linux/interrupt.h>
 
 #include <asm/ptrace.h>
 #include <asm/string.h>
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S
index 5063c60..8d60fa9 100644
--- a/arch/ppc/kernel/head_fsl_booke.S
+++ b/arch/ppc/kernel/head_fsl_booke.S
@@ -24,7 +24,7 @@
  *    Copyright 2002-2004 MontaVista Software, Inc.
  *      PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org>
  *    Copyright 2004 Freescale Semiconductor, Inc
- *      PowerPC e500 modifications, Kumar Gala <kumar.gala@freescale.com>
+ *      PowerPC e500 modifications, Kumar Gala <galak@kernel.crashing.org>
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
diff --git a/arch/ppc/mm/fsl_booke_mmu.c b/arch/ppc/mm/fsl_booke_mmu.c
index af9ca0e..5d581bb 100644
--- a/arch/ppc/mm/fsl_booke_mmu.c
+++ b/arch/ppc/mm/fsl_booke_mmu.c
@@ -1,5 +1,5 @@
 /*
- * Modifications by Kumar Gala (kumar.gala@freescale.com) to support
+ * Modifications by Kumar Gala (galak@kernel.crashing.org) to support
  * E500 Book E processors.
  *
  * Copyright 2004 Freescale Semiconductor, Inc
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
index 98edc75..04bdc39 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -3,7 +3,7 @@
  *
  * MPC834x SYS board specific routines
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
@@ -73,12 +73,19 @@ mpc83xx_map_irq(struct pci_dev *dev, uns
 	     *       A      B      C      D
 	     */
 	{
-		{PIRQA, PIRQB,  PIRQC,  PIRQD}, /* idsel 0x11 */
-		{PIRQC, PIRQD,  PIRQA,  PIRQB}, /* idsel 0x12 */
-		{PIRQD, PIRQA,  PIRQB,  PIRQC}  /* idsel 0x13 */
+		{PIRQA, PIRQB, PIRQC, PIRQD},	/* idsel 0x11 */
+		{PIRQC, PIRQD, PIRQA, PIRQB},	/* idsel 0x12 */
+		{PIRQD, PIRQA, PIRQB, PIRQC},	/* idsel 0x13 */
+		{0, 0, 0, 0},
+		{PIRQA, PIRQB, PIRQC, PIRQD},	/* idsel 0x15 */
+		{PIRQD, PIRQA, PIRQB, PIRQC},	/* idsel 0x16 */
+		{PIRQC, PIRQD, PIRQA, PIRQB},	/* idsel 0x17 */
+		{PIRQB, PIRQC, PIRQD, PIRQA},	/* idsel 0x18 */
+		{0, 0, 0, 0},			/* idsel 0x19 */
+		{0, 0, 0, 0},			/* idsel 0x20 */
 	};
 
-	const long min_idsel = 0x11, max_idsel = 0x13, irqs_per_slot = 4;
+	const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4;
 	return PCI_IRQ_TABLE_LOOKUP;
 }
 
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h
index 58e44c0..2e514d3 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.h
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
@@ -3,7 +3,7 @@
  *
  * MPC834X SYS common board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor, Inc.
  *
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
index 7e952c1..c5cde97 100644
--- a/arch/ppc/platforms/85xx/mpc8540_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.c
@@ -3,7 +3,7 @@
  *
  * MPC8540ADS board specific routines
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.h b/arch/ppc/platforms/85xx/mpc8540_ads.h
index 3d05d7c..e48ca3a 100644
--- a/arch/ppc/platforms/85xx/mpc8540_ads.h
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.h
@@ -3,7 +3,7 @@
  *
  * MPC8540ADS board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/platforms/85xx/mpc8555_cds.h b/arch/ppc/platforms/85xx/mpc8555_cds.h
index e0e7556..1a8e6c6 100644
--- a/arch/ppc/platforms/85xx/mpc8555_cds.h
+++ b/arch/ppc/platforms/85xx/mpc8555_cds.h
@@ -3,7 +3,7 @@
  *
  * MPC8555CDS board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c
index 208433f..8e39a55 100644
--- a/arch/ppc/platforms/85xx/mpc8560_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.c
@@ -3,7 +3,7 @@
  *
  * MPC8560ADS board specific routines
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.h b/arch/ppc/platforms/85xx/mpc8560_ads.h
index 7df885d..143ae7e 100644
--- a/arch/ppc/platforms/85xx/mpc8560_ads.h
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.h
@@ -3,7 +3,7 @@
  *
  * MPC8540ADS board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
index 16ad092..17ce48f 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
@@ -3,7 +3,7 @@
  *
  * MPC85xx ADS board common routines
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
index 84acf6e..7b26bcc 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
@@ -3,7 +3,7 @@
  *
  * MPC85XX ADS common board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index a211569..d8991b8 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -3,7 +3,7 @@
  *
  * MPC85xx CDS board specific routines
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor, Inc
  *
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
index 12b292c..5b588cf 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
@@ -3,7 +3,7 @@
  *
  * MPC85xx CDS board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor, Inc
  *
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c
index b4ee170..45a5b81 100644
--- a/arch/ppc/platforms/85xx/sbc8560.c
+++ b/arch/ppc/platforms/85xx/sbc8560.c
@@ -3,7 +3,7 @@
  * 
  * Wind River SBC8560 board specific routines
  * 
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  * 
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
index 58884a6..1e69b05 100644
--- a/arch/ppc/platforms/pmac_feature.c
+++ b/arch/ppc/platforms/pmac_feature.c
@@ -2317,6 +2317,14 @@ static struct pmac_mb_def pmac_mb_defs[]
 		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
 		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
 	},
+	{	"PowerBook5,8",			"PowerBook G4 15\"",
+		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+	},
+	{	"PowerBook5,9",			"PowerBook G4 17\"",
+		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
+		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
+	},
 	{	"PowerBook6,1",			"PowerBook G4 12\"",
 		PMAC_TYPE_UNKNOWN_INTREPID,	intrepid_features,
 		PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
diff --git a/arch/ppc/platforms/pq2ads.c b/arch/ppc/platforms/pq2ads.c
index 6a1475c..71c9fca 100644
--- a/arch/ppc/platforms/pq2ads.c
+++ b/arch/ppc/platforms/pq2ads.c
@@ -3,7 +3,7 @@
  *
  * PQ2ADS platform support
  *
- * Author: Kumar Gala <kumar.gala@freescale.com>
+ * Author: Kumar Gala <galak@kernel.crashing.org>
  * Derived from: est8260_setup.c by Allen Curtis
  *
  * Copyright 2004 Freescale Semiconductor, Inc.
diff --git a/arch/ppc/syslib/ipic.h b/arch/ppc/syslib/ipic.h
index 2b56a4f..a7ce7da 100644
--- a/arch/ppc/syslib/ipic.h
+++ b/arch/ppc/syslib/ipic.h
@@ -3,7 +3,7 @@
  *
  * IPIC private definitions and structure.
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor, Inc
  *
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
index f43fbf9..847df44 100644
--- a/arch/ppc/syslib/mpc83xx_devices.c
+++ b/arch/ppc/syslib/mpc83xx_devices.c
@@ -3,7 +3,7 @@
  *
  * MPC83xx Device descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/syslib/mpc83xx_sys.c b/arch/ppc/syslib/mpc83xx_sys.c
index da74344..a152398 100644
--- a/arch/ppc/syslib/mpc83xx_sys.c
+++ b/arch/ppc/syslib/mpc83xx_sys.c
@@ -3,7 +3,7 @@
  *
  * MPC83xx System descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c
index 2ede677..69949d2 100644
--- a/arch/ppc/syslib/mpc85xx_devices.c
+++ b/arch/ppc/syslib/mpc85xx_devices.c
@@ -3,7 +3,7 @@
  *
  * MPC85xx Device descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/syslib/mpc85xx_sys.c b/arch/ppc/syslib/mpc85xx_sys.c
index cb68d8c..397cfbc 100644
--- a/arch/ppc/syslib/mpc85xx_sys.c
+++ b/arch/ppc/syslib/mpc85xx_sys.c
@@ -3,7 +3,7 @@
  *
  * MPC85xx System descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/syslib/mpc8xx_devices.c b/arch/ppc/syslib/mpc8xx_devices.c
index 2b5f0e7..92dc98b 100644
--- a/arch/ppc/syslib/mpc8xx_devices.c
+++ b/arch/ppc/syslib/mpc8xx_devices.c
@@ -3,7 +3,7 @@
  *
  * MPC8xx Device descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 MontaVista Software, Inc. by Vitaly Bordug<vbordug@ru.mvista.com>
  *
diff --git a/arch/ppc/syslib/mpc8xx_sys.c b/arch/ppc/syslib/mpc8xx_sys.c
index 3cc27d2..d3c6175 100644
--- a/arch/ppc/syslib/mpc8xx_sys.c
+++ b/arch/ppc/syslib/mpc8xx_sys.c
@@ -3,7 +3,7 @@
  *
  * MPC8xx System descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
  *
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c
index 4da168a..1b5fe9e 100644
--- a/arch/ppc/syslib/ppc83xx_setup.c
+++ b/arch/ppc/syslib/ppc83xx_setup.c
@@ -3,7 +3,7 @@
  *
  * MPC83XX common board code
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/syslib/ppc83xx_setup.h b/arch/ppc/syslib/ppc83xx_setup.h
index c766c1a..a122a73 100644
--- a/arch/ppc/syslib/ppc83xx_setup.h
+++ b/arch/ppc/syslib/ppc83xx_setup.h
@@ -3,7 +3,7 @@
  *
  * MPC83XX common board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/syslib/ppc85xx_common.c b/arch/ppc/syslib/ppc85xx_common.c
index da841da..19ad537 100644
--- a/arch/ppc/syslib/ppc85xx_common.c
+++ b/arch/ppc/syslib/ppc85xx_common.c
@@ -3,7 +3,7 @@
  *
  * MPC85xx support routines
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/syslib/ppc85xx_common.h b/arch/ppc/syslib/ppc85xx_common.h
index 2c8f304..94edf32 100644
--- a/arch/ppc/syslib/ppc85xx_common.h
+++ b/arch/ppc/syslib/ppc85xx_common.h
@@ -3,7 +3,7 @@
  *
  * MPC85xx support routines
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c
index de2f905..1a47ff4 100644
--- a/arch/ppc/syslib/ppc85xx_setup.c
+++ b/arch/ppc/syslib/ppc85xx_setup.c
@@ -3,7 +3,7 @@
  *
  * MPC85XX common board code
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/syslib/ppc85xx_setup.h b/arch/ppc/syslib/ppc85xx_setup.h
index 6e6cfe1..e340b05 100644
--- a/arch/ppc/syslib/ppc85xx_setup.h
+++ b/arch/ppc/syslib/ppc85xx_setup.h
@@ -3,7 +3,7 @@
  *
  * MPC85XX common board definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor Inc.
  *
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index 603f011..c0b93c4 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -3,7 +3,7 @@
  *
  * PPC System library functions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  * Copyright 2005 MontaVista, Inc. by Vitaly Bordug <vbordug@ru.mvista.com>
diff --git a/arch/ppc/syslib/pq2_devices.c b/arch/ppc/syslib/pq2_devices.c
index e960fe9..6ff3aab 100644
--- a/arch/ppc/syslib/pq2_devices.c
+++ b/arch/ppc/syslib/pq2_devices.c
@@ -3,7 +3,7 @@
  *
  * PQ2 Device descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * This file is licensed under the terms of the GNU General Public License
  * version 2. This program is licensed "as is" without any warranty of any
diff --git a/arch/ppc/syslib/pq2_sys.c b/arch/ppc/syslib/pq2_sys.c
index 7b6c9eb..36d6e21 100644
--- a/arch/ppc/syslib/pq2_sys.c
+++ b/arch/ppc/syslib/pq2_sys.c
@@ -3,7 +3,7 @@
  *
  * PQ2 System descriptions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * This file is licensed under the terms of the GNU General Public License
  * version 2. This program is licensed "as is" without any warranty of any
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
deleted file mode 100644
index 9d10c12..0000000
--- a/arch/ppc64/Kconfig
+++ /dev/null
@@ -1,520 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/kconfig-language.txt.
-#
-
-config 64BIT
-	def_bool y
-
-config MMU
-	bool
-	default y
-
-config PPC_STD_MMU
-	def_bool y
-
-config UID16
-	bool
-
-config RWSEM_GENERIC_SPINLOCK
-	bool
-
-config RWSEM_XCHGADD_ALGORITHM
-	bool
-	default y
-
-config GENERIC_CALIBRATE_DELAY
-	bool
-	default y
-
-config GENERIC_ISA_DMA
-	bool
-	default y
-
-config EARLY_PRINTK
-	bool
-	default y
-
-config COMPAT
-	bool
-	default y
-
-config SCHED_NO_NO_OMIT_FRAME_POINTER
-	bool
-	default y
-
-config ARCH_MAY_HAVE_PC_FDC
-	bool
-	default y
-
-config PPC_STD_MMU
-	bool
-	default y
-
-# We optimistically allocate largepages from the VM, so make the limit
-# large enough (16MB). This badly named config option is actually
-# max order + 1
-config FORCE_MAX_ZONEORDER
-	int
-	default "9" if PPC_64K_PAGES
-	default "13"
-
-source "init/Kconfig"
-
-config SYSVIPC_COMPAT
-	bool
-	depends on COMPAT && SYSVIPC
-	default y
-
-menu "Platform support"
-
-choice
-	prompt "Platform Type"
-	default PPC_MULTIPLATFORM
-
-config PPC_ISERIES
-	bool "IBM Legacy iSeries"
-
-config PPC_MULTIPLATFORM
-	bool "Generic"
-
-endchoice
-
-config PPC_PSERIES
-	depends on PPC_MULTIPLATFORM
-	bool "  IBM pSeries & new iSeries"
-	default y
-
-config PPC_BPA
-	bool "  Broadband Processor Architecture"
-	depends on PPC_MULTIPLATFORM
-
-config PPC_PMAC
-	depends on PPC_MULTIPLATFORM
-	bool "  Apple G5 based machines"
-	default y
-	select U3_DART
-	select GENERIC_TBSYNC
-
-config PPC_MAPLE
-	depends on PPC_MULTIPLATFORM
-	bool "  Maple 970FX Evaluation Board"
-	select U3_DART
-	select MPIC_BROKEN_U3
-	select GENERIC_TBSYNC
-	default n
-	help
-          This option enables support for the Maple 970FX Evaluation Board.
-	  For more informations, refer to <http://www.970eval.com>
-
-config PPC
-	bool
-	default y
-
-config PPC64
-	bool
-	default y
-
-config PPC_OF
-	depends on PPC_MULTIPLATFORM
-	bool
-	default y
-
-config XICS
-	depends on PPC_PSERIES
-	bool
-	default y
-
-config MPIC
-	depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE
-	bool
-	default y
-
-config PPC_I8259
-	depends on PPC_PSERIES
-	bool
-	default y
-
-config BPA_IIC
-	depends on PPC_BPA
-	bool
-	default y
-
-# VMX is pSeries only for now until somebody writes the iSeries
-# exception vectors for it
-config ALTIVEC
-	bool "Support for VMX (Altivec) vector unit"
-	depends on PPC_MULTIPLATFORM
-	default y
-
-config PPC_SPLPAR
-	depends on PPC_PSERIES
-	bool "Support for shared-processor logical partitions"
-	default n
-	help
-	  Enabling this option will make the kernel run more efficiently
-	  on logically-partitioned pSeries systems which use shared
-	  processors, that is, which share physical processors between
-	  two or more partitions.
-
-config KEXEC
-	bool "kexec system call (EXPERIMENTAL)"
-	depends on PPC_MULTIPLATFORM && EXPERIMENTAL
-	help
-	  kexec is a system call that implements the ability to shutdown your
-	  current kernel, and to start another kernel.  It is like a reboot
-	  but it is indepedent of the system firmware.  And like a reboot
-	  you can start any kernel with it, not just Linux.
-
-	  The name comes from the similiarity to the exec system call.
-
-	  It is an ongoing process to be certain the hardware in a machine
-	  is properly shutdown, so do not be surprised if this code does not
-	  initially work for you.  It may help to enable device hotplugging
-	  support.  As of this writing the exact hardware interface is
-	  strongly in flux, so no good recommendation can be made.
-
-source "drivers/cpufreq/Kconfig"
-
-config CPU_FREQ_PMAC64
-	bool "Support for some Apple G5s"
-	depends on CPU_FREQ && PMAC_SMU && PPC64
-	select CPU_FREQ_TABLE
-	help
-	  This adds support for frequency switching on Apple iMac G5,
-	  and some of the more recent desktop G5 machines as well.
-
-config IBMVIO
-	depends on PPC_PSERIES || PPC_ISERIES
-	bool
-	default y
-
-config U3_DART
-	bool 
-	depends on PPC_MULTIPLATFORM
-	default n
-
-config MPIC_BROKEN_U3
-	bool
-	depends on PPC_MAPLE
-	default y
-
-config GENERIC_TBSYNC
-	def_bool n
-
-config PPC_PMAC64
-	bool
-	depends on PPC_PMAC
-	default y
-
-config BOOTX_TEXT
-	bool "Support for early boot text console"
-	depends PPC_OF
-	help
-	  Say Y here to see progress messages from the boot firmware in text
-	  mode. Requires an Open Firmware compatible video card.
-
-config POWER4
-	def_bool y
-
-config PPC_FPU
-	def_bool y
-
-config POWER4_ONLY
-	bool "Optimize for POWER4"
-	default n
-	---help---
-	  Cause the compiler to optimize for POWER4 processors. The resulting
-	  binary will not work on POWER3 or RS64 processors when compiled with
-	  binutils 2.15 or later.
-
-config IOMMU_VMERGE
-	bool "Enable IOMMU virtual merging (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
-	default n
-	help
-	  Cause IO segments sent to a device for DMA to be merged virtually
-	  by the IOMMU when they happen to have been allocated contiguously.
-	  This doesn't add pressure to the IOMMU allocator. However, some
-	  drivers don't support getting large merged segments coming back
-	  from *_map_sg(). Say Y if you know the drivers you are using are
-	  properly handling this case.
-
-config SMP
-	bool "Symmetric multi-processing support"
-	---help---
-	  This enables support for systems with more than one CPU. If you have
-	  a system with only one CPU, say N. If you have a system with more
-	  than one CPU, say Y.
-
-	  If you say N here, the kernel will run on single and multiprocessor
-	  machines, but will use only one CPU of a multiprocessor machine. If
-	  you say Y here, the kernel will run on single-processor machines.
-	  On a single-processor machine, the kernel will run faster if you say
-	  N here.
-
-	  If you don't know what to do here, say Y.
-
-config NR_CPUS
-	int "Maximum number of CPUs (2-128)"
-	range 2 128
-	depends on SMP
-	default "32"
-
-config HMT
-	bool "Hardware multithreading"
-	depends on SMP && PPC_PSERIES && BROKEN
-	help
-	  This option enables hardware multithreading on RS64 cpus.
-	  pSeries systems p620 and p660 have such a cpu type.
-
-config NUMA
-	bool "NUMA support"
-	default y if SMP && PPC_PSERIES
-
-config ARCH_SELECT_MEMORY_MODEL
-	def_bool y
-
-config ARCH_FLATMEM_ENABLE
-       def_bool y
-       depends on !NUMA
-
-config ARCH_SPARSEMEM_ENABLE
-	def_bool y
-
-config ARCH_SPARSEMEM_DEFAULT
-	def_bool y
-	depends on NUMA
-
-source "mm/Kconfig"
-
-config HAVE_ARCH_EARLY_PFN_TO_NID
-	def_bool y
-	depends on NEED_MULTIPLE_NODES
-
-config ARCH_MEMORY_PROBE
-	def_bool y
-	depends on MEMORY_HOTPLUG
-
-# Some NUMA nodes have memory ranges that span
-# other nodes.  Even though a pfn is valid and
-# between a node's start and end pfns, it may not
-# reside on that node.
-#
-# This is a relatively temporary hack that should
-# be able to go away when sparsemem is fully in
-# place
-config NODES_SPAN_OTHER_NODES
-	def_bool y
-	depends on NEED_MULTIPLE_NODES
-
-config PPC_64K_PAGES
-	bool "64k page size"
-	help
-	  This option changes the kernel logical page size to 64k. On machines
-          without processor support for 64k pages, the kernel will simulate
-          them by loading each individual 4k page on demand transparently,
-          while on hardware with such support, it will be used to map
-          normal application pages.
-
-config SCHED_SMT
-	bool "SMT (Hyperthreading) scheduler support"
-	depends on SMP
-	default off
-	help
-	  SMT scheduler support improves the CPU scheduler's decision making
-	  when dealing with POWER5 cpus at a cost of slightly increased
-	  overhead in some places. If unsure say N here.
-
-source "kernel/Kconfig.preempt"
-source kernel/Kconfig.hz
-
-config EEH
-	bool "PCI Extended Error Handling (EEH)" if EMBEDDED
-	depends on PPC_PSERIES
-	default y if !EMBEDDED
-
-#
-# Use the generic interrupt handling code in kernel/irq/:
-#
-config GENERIC_HARDIRQS
-	bool
-	default y
-
-config PPC_RTAS
-	bool
-	depends on PPC_PSERIES || PPC_BPA
-	default y
-
-config RTAS_ERROR_LOGGING
-	bool
-	depends on PPC_RTAS
-	default y
-
-config RTAS_PROC
-	bool "Proc interface to RTAS"
-	depends on PPC_RTAS
-	default y
-
-config RTAS_FLASH
-	tristate "Firmware flash interface"
-	depends on RTAS_PROC
-
-config SCANLOG
-	tristate "Scanlog dump interface"
-	depends on RTAS_PROC && PPC_PSERIES
-
-config LPARCFG
-	tristate "LPAR Configuration Data"
-	depends on PPC_PSERIES || PPC_ISERIES
-	help
-	Provide system capacity information via human readable
-	<key word>=<value> pairs through a /proc/ppc64/lparcfg interface.
-
-config SECCOMP
-	bool "Enable seccomp to safely compute untrusted bytecode"
-	depends on PROC_FS
-	default y
-	help
-	  This kernel feature is useful for number crunching applications
-	  that may need to compute untrusted bytecode during their
-	  execution. By using pipes or other transports made available to
-	  the process as file descriptors supporting the read/write
-	  syscalls, it's possible to isolate those applications in
-	  their own address space using seccomp. Once seccomp is
-	  enabled via /proc/<pid>/seccomp, it cannot be disabled
-	  and the task is only allowed to execute a few safe syscalls
-	  defined by each seccomp mode.
-
-	  If unsure, say Y. Only embedded should say N here.
-
-source "fs/Kconfig.binfmt"
-
-config HOTPLUG_CPU
-	bool "Support for hot-pluggable CPUs"
-	depends on SMP && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC)
-	select HOTPLUG
-	---help---
-	  Say Y here to be able to turn CPUs off and on.
-
-	  Say N if you are unsure.
-
-config PROC_DEVICETREE
-	bool "Support for Open Firmware device tree in /proc"
-	help
-	  This option adds a device-tree directory under /proc which contains
-	  an image of the device tree that the kernel copies from Open
-	  Firmware. If unsure, say Y here.
-
-config CMDLINE_BOOL
-	bool "Default bootloader kernel arguments"
-	depends on !PPC_ISERIES
-
-config CMDLINE
-	string "Initial kernel command string"
-	depends on CMDLINE_BOOL
-	default "console=ttyS0,9600 console=tty0 root=/dev/sda2"
-	help
-	  On some platforms, there is currently no way for the boot loader to
-	  pass arguments to the kernel. For these platforms, you can supply
-	  some command-line options at build time by entering them here.  In
-	  most cases you will need to specify the root device here.
-
-endmenu
-
-config ISA_DMA_API
-	bool
-	default y
-
-menu "Bus Options"
-
-config ISA
-	bool
-	help
-	  Find out whether you have ISA slots on your motherboard.  ISA is the
-	  name of a bus system, i.e. the way the CPU talks to the other stuff
-	  inside your box.  If you have an Apple machine, say N here; if you
-	  have an IBM RS/6000 or pSeries machine or a PReP machine, say Y.  If
-	  you have an embedded board, consult your board documentation.
-
-config SBUS
-	bool
-
-config MCA
-	bool
-
-config EISA
-	bool
-
-config PCI
-	bool "support for PCI devices" if (EMBEDDED && PPC_ISERIES)
-	default y
-	help
-	  Find out whether your system includes a PCI bus. PCI is the name of
-	  a bus system, i.e. the way the CPU talks to the other stuff inside
-	  your box.  If you say Y here, the kernel will include drivers and
-	  infrastructure code to support PCI bus devices.
-
-config PCI_DOMAINS
-	bool
-	default PCI
-
-source "drivers/pci/Kconfig"
-
-source "drivers/pcmcia/Kconfig"
-
-source "drivers/pci/hotplug/Kconfig"
-
-endmenu
-
-source "net/Kconfig"
-
-source "drivers/Kconfig"
-
-source "fs/Kconfig"
-
-menu "iSeries device drivers"
-	depends on PPC_ISERIES
-
-config VIOCONS
-	tristate "iSeries Virtual Console Support"
-
-config VIODASD
-	tristate "iSeries Virtual I/O disk support"
-	help
-	  If you are running on an iSeries system and you want to use
- 	  virtual disks created and managed by OS/400, say Y.
-
-config VIOCD
-	tristate "iSeries Virtual I/O CD support"
-	help
-	  If you are running Linux on an IBM iSeries system and you want to
-	  read a CD drive owned by OS/400, say Y here.
-
-config VIOTAPE
-	tristate "iSeries Virtual Tape Support"
-	help
-	  If you are running Linux on an iSeries system and you want Linux
-	  to read and/or write a tape drive owned by OS/400, say Y here.
-
-endmenu
-
-config VIOPATH
-	bool
-	depends on VIOCONS || VIODASD || VIOCD || VIOTAPE || VETH
-	default y
-
-source "arch/powerpc/oprofile/Kconfig"
-
-source "arch/ppc64/Kconfig.debug"
-
-source "security/Kconfig"
-
-config KEYS_COMPAT
-	bool
-	depends on COMPAT && KEYS
-	default y
-
-source "crypto/Kconfig"
-
-source "lib/Kconfig"
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
index dac4cc2..e876c21 100644
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -2,45 +2,6 @@
 # Makefile for the linux ppc64 kernel.
 #
 
-ifneq ($(CONFIG_PPC_MERGE),y)
-
-EXTRA_CFLAGS	+= -mno-minimal-toc
-extra-y		:= head.o vmlinux.lds
-
-obj-y               :=	misc.o prom.o
-
-endif
-
-obj-y               +=	idle.o dma.o \
-			align.o \
-			rtc.o \
-			iommu.o
-
-pci-obj-$(CONFIG_PPC_MULTIPLATFORM)	+= pci_dn.o pci_direct_iommu.o
-
-obj-$(CONFIG_PCI)	+= pci.o pci_iommu.o iomap.o $(pci-obj-y)
+obj-y               +=	idle.o align.o
 
 obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o
-ifneq ($(CONFIG_PPC_MERGE),y)
-obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
-endif
-
-obj-$(CONFIG_KEXEC)		+= machine_kexec.o
-obj-$(CONFIG_MODULES)		+= module.o
-ifneq ($(CONFIG_PPC_MERGE),y)
-obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
-endif
-obj-$(CONFIG_HVC_CONSOLE)	+= hvconsole.o
-ifneq ($(CONFIG_PPC_MERGE),y)
-obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
-endif
-obj-$(CONFIG_HVCS)		+= hvcserver.o
-
-obj-$(CONFIG_KPROBES)		+= kprobes.o
-
-ifneq ($(CONFIG_PPC_MERGE),y)
-ifeq ($(CONFIG_PPC_ISERIES),y)
-arch/ppc64/kernel/head.o: arch/powerpc/kernel/lparmap.s
-AFLAGS_head.o += -Iarch/powerpc/kernel
-endif
-endif
diff --git a/arch/ppc64/kernel/asm-offsets.c b/arch/ppc64/kernel/asm-offsets.c
deleted file mode 100644
index 84ab5c1..0000000
--- a/arch/ppc64/kernel/asm-offsets.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * This program is used to generate definitions needed by
- * assembly language modules.
- *
- * We use the technique used in the OSF Mach kernel code:
- * generate asm statements containing #defines,
- * compile this file to assembler, and then extract the
- * #defines from the assembly-language output.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/config.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/time.h>
-#include <linux/hardirq.h>
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-
-#include <asm/paca.h>
-#include <asm/lppaca.h>
-#include <asm/iseries/hv_lp_event.h>
-#include <asm/rtas.h>
-#include <asm/cputable.h>
-#include <asm/cache.h>
-#include <asm/systemcfg.h>
-#include <asm/compat.h>
-
-#define DEFINE(sym, val) \
-	asm volatile("\n->" #sym " %0 " #val : : "i" (val))
-
-#define BLANK() asm volatile("\n->" : : )
-
-int main(void)
-{
-	/* thread struct on stack */
-	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
-	DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
-	DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror));
-
-	/* task_struct->thread */
-	DEFINE(THREAD, offsetof(struct task_struct, thread));
-	DEFINE(PT_REGS, offsetof(struct thread_struct, regs));
-	DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode));
-	DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
-	DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr));
-	DEFINE(KSP, offsetof(struct thread_struct, ksp));
-	DEFINE(KSP_VSID, offsetof(struct thread_struct, ksp_vsid));
-
-#ifdef CONFIG_ALTIVEC
-	DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0]));
-	DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
-	DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
-	DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
-#endif /* CONFIG_ALTIVEC */
-	DEFINE(MM, offsetof(struct task_struct, mm));
-	DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
-
-	DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
-	DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
-	DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, dlines_per_page));
-	DEFINE(ICACHEL1LINESIZE, offsetof(struct ppc64_caches, iline_size));
-	DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_iline_size));
-	DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct ppc64_caches, ilines_per_page));
-	DEFINE(PLATFORM_LPAR, PLATFORM_LPAR);
-
-	/* paca */
-        DEFINE(PACA_SIZE, sizeof(struct paca_struct));
-        DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index));
-        DEFINE(PACAPROCSTART, offsetof(struct paca_struct, cpu_start));
-        DEFINE(PACAKSAVE, offsetof(struct paca_struct, kstack));
-	DEFINE(PACACURRENT, offsetof(struct paca_struct, __current));
-        DEFINE(PACASAVEDMSR, offsetof(struct paca_struct, saved_msr));
-        DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real));
-        DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr));
-	DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr));
-        DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1));
-	DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc));
-	DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, proc_enabled));
-	DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
-	DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
-	DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
-#ifdef CONFIG_PPC_64K_PAGES
-	DEFINE(PACAPGDIR, offsetof(struct paca_struct, pgdir));
-#endif
-#ifdef CONFIG_HUGETLB_PAGE
-	DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas));
-	DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas));
-#endif /* CONFIG_HUGETLB_PAGE */
-	DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr));
-        DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
-        DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
-        DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
-        DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi));
-        DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
-	DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca));
-	DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
-	DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
-	DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
-	DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
-	DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
-
-	/* RTAS */
-	DEFINE(RTASBASE, offsetof(struct rtas_t, base));
-	DEFINE(RTASENTRY, offsetof(struct rtas_t, entry));
-
-	/* Interrupt register frame */
-	DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
-
-	DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs));
-
-	/* 288 = # of volatile regs, int & fp, for leaf routines */
-	/* which do not stack a frame.  See the PPC64 ABI.       */
-	DEFINE(INT_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 288);
-	/* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
-	DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
-	DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
-	DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0]));
-	DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1]));
-	DEFINE(GPR2, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[2]));
-	DEFINE(GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[3]));
-	DEFINE(GPR4, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[4]));
-	DEFINE(GPR5, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[5]));
-	DEFINE(GPR6, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[6]));
-	DEFINE(GPR7, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[7]));
-	DEFINE(GPR8, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[8]));
-	DEFINE(GPR9, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[9]));
-	DEFINE(GPR10, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[10]));
-	DEFINE(GPR11, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[11]));
-	DEFINE(GPR12, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[12]));
-	DEFINE(GPR13, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[13]));
-	/*
-	 * Note: these symbols include _ because they overlap with special
-	 * register names
-	 */
-	DEFINE(_NIP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, nip));
-	DEFINE(_MSR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, msr));
-	DEFINE(_CTR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ctr));
-	DEFINE(_LINK, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, link));
-	DEFINE(_CCR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ccr));
-	DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer));
-	DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
-	DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
-	DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3));
-	DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result));
-	DEFINE(_TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
-	DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe));
-
-	/* These _only_ to be used with {PROM,RTAS}_FRAME_SIZE!!! */
-	DEFINE(_SRR0, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs));
-	DEFINE(_SRR1, STACK_FRAME_OVERHEAD+sizeof(struct pt_regs)+8);
-
-	DEFINE(CLONE_VM, CLONE_VM);
-	DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
-
-	/* About the CPU features table */
-	DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec));
-	DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask));
-	DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
-	DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
-	DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
-
-	/* systemcfg offsets for use by vdso */
-	DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct systemcfg, tb_orig_stamp));
-	DEFINE(CFG_TB_TICKS_PER_SEC, offsetof(struct systemcfg, tb_ticks_per_sec));
-	DEFINE(CFG_TB_TO_XS, offsetof(struct systemcfg, tb_to_xs));
-	DEFINE(CFG_STAMP_XSEC, offsetof(struct systemcfg, stamp_xsec));
-	DEFINE(CFG_TB_UPDATE_COUNT, offsetof(struct systemcfg, tb_update_count));
-	DEFINE(CFG_TZ_MINUTEWEST, offsetof(struct systemcfg, tz_minuteswest));
-	DEFINE(CFG_TZ_DSTTIME, offsetof(struct systemcfg, tz_dsttime));
-	DEFINE(CFG_SYSCALL_MAP32, offsetof(struct systemcfg, syscall_map_32));
-	DEFINE(CFG_SYSCALL_MAP64, offsetof(struct systemcfg, syscall_map_64));
-
-	/* timeval/timezone offsets for use by vdso */
-	DEFINE(TVAL64_TV_SEC, offsetof(struct timeval, tv_sec));
-	DEFINE(TVAL64_TV_USEC, offsetof(struct timeval, tv_usec));
-	DEFINE(TVAL32_TV_SEC, offsetof(struct compat_timeval, tv_sec));
-	DEFINE(TVAL32_TV_USEC, offsetof(struct compat_timeval, tv_usec));
-	DEFINE(TZONE_TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
-	DEFINE(TZONE_TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
-
-	return 0;
-}
diff --git a/arch/ppc64/kernel/btext.c b/arch/ppc64/kernel/btext.c
deleted file mode 100644
index 506a378..0000000
--- a/arch/ppc64/kernel/btext.c
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- * Procedures for drawing on the screen early on in the boot process.
- *
- * Benjamin Herrenschmidt <benh@kernel.crashing.org>
- */
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/init.h>
-
-#include <asm/sections.h>
-#include <asm/prom.h>
-#include <asm/btext.h>
-#include <asm/prom.h>
-#include <asm/page.h>
-#include <asm/mmu.h>
-#include <asm/pgtable.h>
-#include <asm/io.h>
-#include <asm/lmb.h>
-#include <asm/processor.h>
-#include <asm/udbg.h>
-
-#undef NO_SCROLL
-
-#ifndef NO_SCROLL
-static void scrollscreen(void);
-#endif
-
-static void draw_byte(unsigned char c, long locX, long locY);
-static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
-static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb);
-static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
-
-static int g_loc_X;
-static int g_loc_Y;
-static int g_max_loc_X;
-static int g_max_loc_Y;
-
-static int dispDeviceRowBytes;
-static int dispDeviceDepth;
-static int dispDeviceRect[4];
-static unsigned char *dispDeviceBase, *logicalDisplayBase;
-
-unsigned long disp_BAT[2] __initdata = {0, 0};
-
-#define cmapsz	(16*256)
-
-static unsigned char vga_font[cmapsz];
-
-int boot_text_mapped;
-int force_printk_to_btext = 0;
-
-
-/* Here's a small text engine to use during early boot
- * or for debugging purposes
- *
- * todo:
- *
- *  - build some kind of vgacon with it to enable early printk
- *  - move to a separate file
- *  - add a few video driver hooks to keep in sync with display
- *    changes.
- */
-
-void map_boot_text(void)
-{
-	unsigned long base, offset, size;
-	unsigned char *vbase;
-
-	/* By default, we are no longer mapped */
-	boot_text_mapped = 0;
-	if (dispDeviceBase == 0)
-		return;
-	base = ((unsigned long) dispDeviceBase) & 0xFFFFF000UL;
-	offset = ((unsigned long) dispDeviceBase) - base;
-	size = dispDeviceRowBytes * dispDeviceRect[3] + offset
-		+ dispDeviceRect[0];
-	vbase = __ioremap(base, size, _PAGE_NO_CACHE);
-	if (vbase == 0)
-		return;
-	logicalDisplayBase = vbase + offset;
-	boot_text_mapped = 1;
-}
-
-int btext_initialize(struct device_node *np)
-{
-	unsigned int width, height, depth, pitch;
-	unsigned long address = 0;
-	u32 *prop;
-
-	prop = (u32 *)get_property(np, "width", NULL);
-	if (prop == NULL)
-		return -EINVAL;
-	width = *prop;
-	prop = (u32 *)get_property(np, "height", NULL);
-	if (prop == NULL)
-		return -EINVAL;
-	height = *prop;
-	prop = (u32 *)get_property(np, "depth", NULL);
-	if (prop == NULL)
-		return -EINVAL;
-	depth = *prop;
-	pitch = width * ((depth + 7) / 8);
-	prop = (u32 *)get_property(np, "linebytes", NULL);
-	if (prop)
-		pitch = *prop;
-	if (pitch == 1)
-		pitch = 0x1000;
-	prop = (u32 *)get_property(np, "address", NULL);
-	if (prop)
-		address = *prop;
-
-	/* FIXME: Add support for PCI reg properties */
-
-	if (address == 0)
-		return -EINVAL;
-
-	g_loc_X = 0;
-	g_loc_Y = 0;
-	g_max_loc_X = width / 8;
-	g_max_loc_Y = height / 16;
-	logicalDisplayBase = (unsigned char *)address;
-	dispDeviceBase = (unsigned char *)address;
-	dispDeviceRowBytes = pitch;
-	dispDeviceDepth = depth;
-	dispDeviceRect[0] = dispDeviceRect[1] = 0;
-	dispDeviceRect[2] = width;
-	dispDeviceRect[3] = height;
-
-	map_boot_text();
-
-	return 0;
-}
-
-static void btext_putc(unsigned char c)
-{
-	btext_drawchar(c);
-}
-
-void __init init_boot_display(void)
-{
-	char *name;
-	struct device_node *np = NULL; 
-	int rc = -ENODEV;
-
-	printk("trying to initialize btext ...\n");
-
-	name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
-	if (name != NULL) {
-		np = of_find_node_by_path(name);
-		if (np != NULL) {
-			if (strcmp(np->type, "display") != 0) {
-				printk("boot stdout isn't a display !\n");
-				of_node_put(np);
-				np = NULL;
-			}
-		}
-	}
-	if (np)
-		rc = btext_initialize(np);
-	if (rc) {
-		for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
-			if (get_property(np, "linux,opened", NULL)) {
-				printk("trying %s ...\n", np->full_name);
-				rc = btext_initialize(np);
-				printk("result: %d\n", rc);
-			}
-			if (rc == 0)
-				break;
-		}
-	}
-	if (rc == 0 && udbg_putc == NULL)
-		udbg_putc = btext_putc;
-}
-
-
-/* Calc the base address of a given point (x,y) */
-static unsigned char * calc_base(int x, int y)
-{
-	unsigned char *base;
-
-	base = logicalDisplayBase;
-	if (base == 0)
-		base = dispDeviceBase;
-	base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3);
-	base += (y + dispDeviceRect[1]) * dispDeviceRowBytes;
-	return base;
-}
-
-/* Adjust the display to a new resolution */
-void btext_update_display(unsigned long phys, int width, int height,
-			  int depth, int pitch)
-{
-	if (dispDeviceBase == 0)
-		return;
-
-	/* check it's the same frame buffer (within 256MB) */
-	if ((phys ^ (unsigned long)dispDeviceBase) & 0xf0000000)
-		return;
-
-	dispDeviceBase = (__u8 *) phys;
-	dispDeviceRect[0] = 0;
-	dispDeviceRect[1] = 0;
-	dispDeviceRect[2] = width;
-	dispDeviceRect[3] = height;
-	dispDeviceDepth = depth;
-	dispDeviceRowBytes = pitch;
-	if (boot_text_mapped) {
-		iounmap(logicalDisplayBase);
-		boot_text_mapped = 0;
-	}
-	map_boot_text();
-	g_loc_X = 0;
-	g_loc_Y = 0;
-	g_max_loc_X = width / 8;
-	g_max_loc_Y = height / 16;
-}
-
-void btext_clearscreen(void)
-{
-	unsigned long *base	= (unsigned long *)calc_base(0, 0);
-	unsigned long width 	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
-					(dispDeviceDepth >> 3)) >> 3;
-	int i,j;
-
-	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
-	{
-		unsigned long *ptr = base;
-		for(j=width; j; --j)
-			*(ptr++) = 0;
-		base += (dispDeviceRowBytes >> 3);
-	}
-}
-
-#ifndef NO_SCROLL
-static void scrollscreen(void)
-{
-	unsigned long *src     	= (unsigned long *)calc_base(0,16);
-	unsigned long *dst     	= (unsigned long *)calc_base(0,0);
-	unsigned long width    	= ((dispDeviceRect[2] - dispDeviceRect[0]) *
-				   (dispDeviceDepth >> 3)) >> 3;
-	int i,j;
-
-	for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
-	{
-		unsigned long *src_ptr = src;
-		unsigned long *dst_ptr = dst;
-		for(j=width; j; --j)
-			*(dst_ptr++) = *(src_ptr++);
-		src += (dispDeviceRowBytes >> 3);
-		dst += (dispDeviceRowBytes >> 3);
-	}
-	for (i=0; i<16; i++)
-	{
-		unsigned long *dst_ptr = dst;
-		for(j=width; j; --j)
-			*(dst_ptr++) = 0;
-		dst += (dispDeviceRowBytes >> 3);
-	}
-}
-#endif /* ndef NO_SCROLL */
-
-void btext_drawchar(char c)
-{
-	int cline = 0;
-#ifdef NO_SCROLL
-	int x;
-#endif
-	if (!boot_text_mapped)
-		return;
-
-	switch (c) {
-	case '\b':
-		if (g_loc_X > 0)
-			--g_loc_X;
-		break;
-	case '\t':
-		g_loc_X = (g_loc_X & -8) + 8;
-		break;
-	case '\r':
-		g_loc_X = 0;
-		break;
-	case '\n':
-		g_loc_X = 0;
-		g_loc_Y++;
-		cline = 1;
-		break;
-	default:
-		draw_byte(c, g_loc_X++, g_loc_Y);
-	}
-	if (g_loc_X >= g_max_loc_X) {
-		g_loc_X = 0;
-		g_loc_Y++;
-		cline = 1;
-	}
-#ifndef NO_SCROLL
-	while (g_loc_Y >= g_max_loc_Y) {
-		scrollscreen();
-		g_loc_Y--;
-	}
-#else
-	/* wrap around from bottom to top of screen so we don't
-	   waste time scrolling each line.  -- paulus. */
-	if (g_loc_Y >= g_max_loc_Y)
-		g_loc_Y = 0;
-	if (cline) {
-		for (x = 0; x < g_max_loc_X; ++x)
-			draw_byte(' ', x, g_loc_Y);
-	}
-#endif
-}
-
-void btext_drawstring(const char *c)
-{
-	if (!boot_text_mapped)
-		return;
-	while (*c)
-		btext_drawchar(*c++);
-}
-
-void btext_drawhex(unsigned long v)
-{
-	char *hex_table = "0123456789abcdef";
-
-	if (!boot_text_mapped)
-		return;
-	btext_drawchar(hex_table[(v >> 60) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >> 56) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >> 52) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >> 48) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >> 44) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >> 40) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >> 36) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >> 32) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >> 28) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >> 24) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >> 20) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >> 16) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >> 12) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >>  8) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >>  4) & 0x0000000FUL]);
-	btext_drawchar(hex_table[(v >>  0) & 0x0000000FUL]);
-	btext_drawchar(' ');
-}
-
-static void draw_byte(unsigned char c, long locX, long locY)
-{
-	unsigned char *base	= calc_base(locX << 3, locY << 4);
-	unsigned char *font	= &vga_font[((unsigned int)c) * 16];
-	int rb			= dispDeviceRowBytes;
-
-	switch(dispDeviceDepth) {
-	case 24:
-	case 32:
-		draw_byte_32(font, (unsigned int *)base, rb);
-		break;
-	case 15:
-	case 16:
-		draw_byte_16(font, (unsigned int *)base, rb);
-		break;
-	case 8:
-		draw_byte_8(font, (unsigned int *)base, rb);
-		break;
-	}
-}
-
-static unsigned int expand_bits_8[16] = {
-	0x00000000,
-	0x000000ff,
-	0x0000ff00,
-	0x0000ffff,
-	0x00ff0000,
-	0x00ff00ff,
-	0x00ffff00,
-	0x00ffffff,
-	0xff000000,
-	0xff0000ff,
-	0xff00ff00,
-	0xff00ffff,
-	0xffff0000,
-	0xffff00ff,
-	0xffffff00,
-	0xffffffff
-};
-
-static unsigned int expand_bits_16[4] = {
-	0x00000000,
-	0x0000ffff,
-	0xffff0000,
-	0xffffffff
-};
-
-
-static void draw_byte_32(unsigned char *font, unsigned int *base, int rb)
-{
-	int l, bits;
-	int fg = 0xFFFFFFFFUL;
-	int bg = 0x00000000UL;
-
-	for (l = 0; l < 16; ++l)
-	{
-		bits = *font++;
-		base[0] = (-(bits >> 7) & fg) ^ bg;
-		base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
-		base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
-		base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
-		base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
-		base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
-		base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
-		base[7] = (-(bits & 1) & fg) ^ bg;
-		base = (unsigned int *) ((char *)base + rb);
-	}
-}
-
-static void draw_byte_16(unsigned char *font, unsigned int *base, int rb)
-{
-	int l, bits;
-	int fg = 0xFFFFFFFFUL;
-	int bg = 0x00000000UL;
-	unsigned int *eb = (int *)expand_bits_16;
-
-	for (l = 0; l < 16; ++l)
-	{
-		bits = *font++;
-		base[0] = (eb[bits >> 6] & fg) ^ bg;
-		base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
-		base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
-		base[3] = (eb[bits & 3] & fg) ^ bg;
-		base = (unsigned int *) ((char *)base + rb);
-	}
-}
-
-static void draw_byte_8(unsigned char *font, unsigned int *base, int rb)
-{
-	int l, bits;
-	int fg = 0x0F0F0F0FUL;
-	int bg = 0x00000000UL;
-	unsigned int *eb = (int *)expand_bits_8;
-
-	for (l = 0; l < 16; ++l)
-	{
-		bits = *font++;
-		base[0] = (eb[bits >> 4] & fg) ^ bg;
-		base[1] = (eb[bits & 0xf] & fg) ^ bg;
-		base = (unsigned int *) ((char *)base + rb);
-	}
-}
-
-static unsigned char vga_font[cmapsz] = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
-0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
-0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
-0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
-0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
-0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
-0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
-0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
-0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
-0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
-0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
-0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
-0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
-0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
-0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
-0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
-0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
-0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
-0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
-0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
-0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
-0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
-0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
-0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
-0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
-0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
-0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
-0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
-0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
-0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
-0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
-0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
-0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
-0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde,
-0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
-0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
-0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
-0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
-0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
-0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
-0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
-0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7,
-0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
-0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
-0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
-0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
-0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
-0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18,
-0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
-0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
-0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
-0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
-0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
-0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
-0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
-0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
-0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
-0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb,
-0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
-0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
-0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
-0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3,
-0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
-0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
-0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
-0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
-0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
-0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
-0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
-0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
-0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
-0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
-0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
-0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
-0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
-0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
-0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
-0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b,
-0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
-0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
-0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
-0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
-0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
-0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
-0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18,
-0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66,
-0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
-0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
-0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
-0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
-0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
-0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
-0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
-0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06,
-0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
-0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
-0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
-0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
-0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
-0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
-0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
-0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
-0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
-0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
-0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
-0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
-0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
-0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
-0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8,
-0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66,
-0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
-0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
-0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
-0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
-0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
-0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
-0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
-0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
-0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c,
-0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00,
-};
diff --git a/arch/ppc64/kernel/dma.c b/arch/ppc64/kernel/dma.c
deleted file mode 100644
index 7c34196..0000000
--- a/arch/ppc64/kernel/dma.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2004 IBM Corporation
- *
- * Implements the generic device dma API for ppc64. Handles
- * the pci and vio busses
- */
-
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-/* Include the busses we support */
-#include <linux/pci.h>
-#include <asm/vio.h>
-#include <asm/scatterlist.h>
-#include <asm/bug.h>
-
-static struct dma_mapping_ops *get_dma_ops(struct device *dev)
-{
-#ifdef CONFIG_PCI
-	if (dev->bus == &pci_bus_type)
-		return &pci_dma_ops;
-#endif
-#ifdef CONFIG_IBMVIO
-	if (dev->bus == &vio_bus_type)
-		return &vio_dma_ops;
-#endif
-	return NULL;
-}
-
-int dma_supported(struct device *dev, u64 mask)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	if (dma_ops)
-		return dma_ops->dma_supported(dev, mask);
-	BUG();
-	return 0;
-}
-EXPORT_SYMBOL(dma_supported);
-
-int dma_set_mask(struct device *dev, u64 dma_mask)
-{
-#ifdef CONFIG_PCI
-	if (dev->bus == &pci_bus_type)
-		return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
-#endif
-#ifdef CONFIG_IBMVIO
-	if (dev->bus == &vio_bus_type)
-		return -EIO;
-#endif /* CONFIG_IBMVIO */
-	BUG();
-	return 0;
-}
-EXPORT_SYMBOL(dma_set_mask);
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
-		dma_addr_t *dma_handle, gfp_t flag)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	if (dma_ops)
-		return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
-	BUG();
-	return NULL;
-}
-EXPORT_SYMBOL(dma_alloc_coherent);
-
-void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-		dma_addr_t dma_handle)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	if (dma_ops)
-		dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
-	else
-		BUG();
-}
-EXPORT_SYMBOL(dma_free_coherent);
-
-dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size,
-		enum dma_data_direction direction)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	if (dma_ops)
-		return dma_ops->map_single(dev, cpu_addr, size, direction);
-	BUG();
-	return (dma_addr_t)0;
-}
-EXPORT_SYMBOL(dma_map_single);
-
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
-		enum dma_data_direction direction)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	if (dma_ops)
-		dma_ops->unmap_single(dev, dma_addr, size, direction);
-	else
-		BUG();
-}
-EXPORT_SYMBOL(dma_unmap_single);
-
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
-		unsigned long offset, size_t size,
-		enum dma_data_direction direction)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	if (dma_ops)
-		return dma_ops->map_single(dev,
-				(page_address(page) + offset), size, direction);
-	BUG();
-	return (dma_addr_t)0;
-}
-EXPORT_SYMBOL(dma_map_page);
-
-void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
-		enum dma_data_direction direction)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	if (dma_ops)
-		dma_ops->unmap_single(dev, dma_address, size, direction);
-	else
-		BUG();
-}
-EXPORT_SYMBOL(dma_unmap_page);
-
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		enum dma_data_direction direction)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	if (dma_ops)
-		return dma_ops->map_sg(dev, sg, nents, direction);
-	BUG();
-	return 0;
-}
-EXPORT_SYMBOL(dma_map_sg);
-
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
-		enum dma_data_direction direction)
-{
-	struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
-	if (dma_ops)
-		dma_ops->unmap_sg(dev, sg, nhwentries, direction);
-	else
-		BUG();
-}
-EXPORT_SYMBOL(dma_unmap_sg);
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S
deleted file mode 100644
index 1c869ea..0000000
--- a/arch/ppc64/kernel/head.S
+++ /dev/null
@@ -1,2007 +0,0 @@
-/*
- *  arch/ppc64/kernel/head.S
- *
- *  PowerPC version
- *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
- *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
- *  Adapted for Power Macintosh by Paul Mackerras.
- *  Low-level exception handlers and MMU support
- *  rewritten by Paul Mackerras.
- *    Copyright (C) 1996 Paul Mackerras.
- *
- *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
- *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
- *
- *  This file contains the low-level support and setup for the
- *  PowerPC-64 platform, including trap and interrupt dispatch.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- */
-
-#include <linux/config.h>
-#include <linux/threads.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/mmu.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-#include <asm/bug.h>
-#include <asm/cputable.h>
-#include <asm/setup.h>
-#include <asm/hvcall.h>
-#include <asm/iseries/lpar_map.h>
-#include <asm/thread_info.h>
-
-#ifdef CONFIG_PPC_ISERIES
-#define DO_SOFT_DISABLE
-#endif
-
-/*
- * We layout physical memory as follows:
- * 0x0000 - 0x00ff : Secondary processor spin code
- * 0x0100 - 0x2fff : pSeries Interrupt prologs
- * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs
- * 0x6000 - 0x6fff : Initial (CPU0) segment table
- * 0x7000 - 0x7fff : FWNMI data area
- * 0x8000 -        : Early init and support code
- */
-
-/*
- *   SPRG Usage
- *
- *   Register	Definition
- *
- *   SPRG0	reserved for hypervisor
- *   SPRG1	temp - used to save gpr
- *   SPRG2	temp - used to save gpr
- *   SPRG3	virt addr of paca
- */
-
-/*
- * Entering into this code we make the following assumptions:
- *  For pSeries:
- *   1. The MMU is off & open firmware is running in real mode.
- *   2. The kernel is entered at __start
- *
- *  For iSeries:
- *   1. The MMU is on (as it always is for iSeries)
- *   2. The kernel is entered at system_reset_iSeries
- */
-
-	.text
-	.globl  _stext
-_stext:
-#ifdef CONFIG_PPC_MULTIPLATFORM
-_GLOBAL(__start)
-	/* NOP this out unconditionally */
-BEGIN_FTR_SECTION
-	b	.__start_initialization_multiplatform
-END_FTR_SECTION(0, 1)
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
-	/* Catch branch to 0 in real mode */
-	trap
-
-#ifdef CONFIG_PPC_ISERIES
-	/*
-	 * At offset 0x20, there is a pointer to iSeries LPAR data.
-	 * This is required by the hypervisor
-	 */
-	. = 0x20
-	.llong hvReleaseData-KERNELBASE
-
-	/*
-	 * At offset 0x28 and 0x30 are offsets to the mschunks_map
-	 * array (used by the iSeries LPAR debugger to do translation
-	 * between physical addresses and absolute addresses) and
-	 * to the pidhash table (also used by the debugger)
-	 */
-	.llong mschunks_map-KERNELBASE
-	.llong 0	/* pidhash-KERNELBASE SFRXXX */
-
-	/* Offset 0x38 - Pointer to start of embedded System.map */
-	.globl	embedded_sysmap_start
-embedded_sysmap_start:
-	.llong	0
-	/* Offset 0x40 - Pointer to end of embedded System.map */
-	.globl	embedded_sysmap_end
-embedded_sysmap_end:
-	.llong	0
-
-#endif /* CONFIG_PPC_ISERIES */
-
-	/* Secondary processors spin on this value until it goes to 1. */
-	.globl  __secondary_hold_spinloop
-__secondary_hold_spinloop:
-	.llong	0x0
-
-	/* Secondary processors write this value with their cpu # */
-	/* after they enter the spin loop immediately below.	  */
-	.globl	__secondary_hold_acknowledge
-__secondary_hold_acknowledge:
-	.llong	0x0
-
-	. = 0x60
-/*
- * The following code is used on pSeries to hold secondary processors
- * in a spin loop after they have been freed from OpenFirmware, but
- * before the bulk of the kernel has been relocated.  This code
- * is relocated to physical address 0x60 before prom_init is run.
- * All of it must fit below the first exception vector at 0x100.
- */
-_GLOBAL(__secondary_hold)
-	mfmsr	r24
-	ori	r24,r24,MSR_RI
-	mtmsrd	r24			/* RI on */
-
-	/* Grab our linux cpu number */
-	mr	r24,r3
-
-	/* Tell the master cpu we're here */
-	/* Relocation is off & we are located at an address less */
-	/* than 0x100, so only need to grab low order offset.    */
-	std	r24,__secondary_hold_acknowledge@l(0)
-	sync
-
-	/* All secondary cpus wait here until told to start. */
-100:	ld	r4,__secondary_hold_spinloop@l(0)
-	cmpdi	0,r4,1
-	bne	100b
-
-#ifdef CONFIG_HMT
-	b	.hmt_init
-#else
-#ifdef CONFIG_SMP
-	mr	r3,r24
-	b	.pSeries_secondary_smp_init
-#else
-	BUG_OPCODE
-#endif
-#endif
-
-/* This value is used to mark exception frames on the stack. */
-	.section ".toc","aw"
-exception_marker:
-	.tc	ID_72656773_68657265[TC],0x7265677368657265
-	.text
-
-/*
- * The following macros define the code that appears as
- * the prologue to each of the exception handlers.  They
- * are split into two parts to allow a single kernel binary
- * to be used for pSeries and iSeries.
- * LOL.  One day... - paulus
- */
-
-/*
- * We make as much of the exception code common between native
- * exception handlers (including pSeries LPAR) and iSeries LPAR
- * implementations as possible.
- */
-
-/*
- * This is the start of the interrupt handlers for pSeries
- * This code runs with relocation off.
- */
-#define EX_R9		0
-#define EX_R10		8
-#define EX_R11		16
-#define EX_R12		24
-#define EX_R13		32
-#define EX_SRR0		40
-#define EX_DAR		48
-#define EX_DSISR	56
-#define EX_CCR		60
-#define EX_R3		64
-#define EX_LR		72
-
-#define EXCEPTION_PROLOG_PSERIES(area, label)				\
-	mfspr	r13,SPRN_SPRG3;		/* get paca address into r13 */	\
-	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
-	std	r10,area+EX_R10(r13);					\
-	std	r11,area+EX_R11(r13);					\
-	std	r12,area+EX_R12(r13);					\
-	mfspr	r9,SPRN_SPRG1;						\
-	std	r9,area+EX_R13(r13);					\
-	mfcr	r9;							\
-	clrrdi	r12,r13,32;		/* get high part of &label */	\
-	mfmsr	r10;							\
-	mfspr	r11,SPRN_SRR0;		/* save SRR0 */			\
-	ori	r12,r12,(label)@l;	/* virt addr of handler */	\
-	ori	r10,r10,MSR_IR|MSR_DR|MSR_RI;				\
-	mtspr	SPRN_SRR0,r12;						\
-	mfspr	r12,SPRN_SRR1;		/* and SRR1 */			\
-	mtspr	SPRN_SRR1,r10;						\
-	rfid;								\
-	b	.	/* prevent speculative execution */
-
-/*
- * This is the start of the interrupt handlers for iSeries
- * This code runs with relocation on.
- */
-#define EXCEPTION_PROLOG_ISERIES_1(area)				\
-	mfspr	r13,SPRN_SPRG3;		/* get paca address into r13 */	\
-	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
-	std	r10,area+EX_R10(r13);					\
-	std	r11,area+EX_R11(r13);					\
-	std	r12,area+EX_R12(r13);					\
-	mfspr	r9,SPRN_SPRG1;						\
-	std	r9,area+EX_R13(r13);					\
-	mfcr	r9
-
-#define EXCEPTION_PROLOG_ISERIES_2					\
-	mfmsr	r10;							\
-	ld	r11,PACALPPACA+LPPACASRR0(r13);				\
-	ld	r12,PACALPPACA+LPPACASRR1(r13);				\
-	ori	r10,r10,MSR_RI;						\
-	mtmsrd	r10,1
-
-/*
- * The common exception prolog is used for all except a few exceptions
- * such as a segment miss on a kernel address.  We have to be prepared
- * to take another exception from the point where we first touch the
- * kernel stack onwards.
- *
- * On entry r13 points to the paca, r9-r13 are saved in the paca,
- * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
- * SRR1, and relocation is on.
- */
-#define EXCEPTION_PROLOG_COMMON(n, area)				   \
-	andi.	r10,r12,MSR_PR;		/* See if coming from user	*/ \
-	mr	r10,r1;			/* Save r1			*/ \
-	subi	r1,r1,INT_FRAME_SIZE;	/* alloc frame on kernel stack	*/ \
-	beq-	1f;							   \
-	ld	r1,PACAKSAVE(r13);	/* kernel stack to use		*/ \
-1:	cmpdi	cr1,r1,0;		/* check if r1 is in userspace	*/ \
-	bge-	cr1,bad_stack;		/* abort if it is		*/ \
-	std	r9,_CCR(r1);		/* save CR in stackframe	*/ \
-	std	r11,_NIP(r1);		/* save SRR0 in stackframe	*/ \
-	std	r12,_MSR(r1);		/* save SRR1 in stackframe	*/ \
-	std	r10,0(r1);		/* make stack chain pointer	*/ \
-	std	r0,GPR0(r1);		/* save r0 in stackframe	*/ \
-	std	r10,GPR1(r1);		/* save r1 in stackframe	*/ \
-	std	r2,GPR2(r1);		/* save r2 in stackframe	*/ \
-	SAVE_4GPRS(3, r1);		/* save r3 - r6 in stackframe	*/ \
-	SAVE_2GPRS(7, r1);		/* save r7, r8 in stackframe	*/ \
-	ld	r9,area+EX_R9(r13);	/* move r9, r10 to stackframe	*/ \
-	ld	r10,area+EX_R10(r13);					   \
-	std	r9,GPR9(r1);						   \
-	std	r10,GPR10(r1);						   \
-	ld	r9,area+EX_R11(r13);	/* move r11 - r13 to stackframe	*/ \
-	ld	r10,area+EX_R12(r13);					   \
-	ld	r11,area+EX_R13(r13);					   \
-	std	r9,GPR11(r1);						   \
-	std	r10,GPR12(r1);						   \
-	std	r11,GPR13(r1);						   \
-	ld	r2,PACATOC(r13);	/* get kernel TOC into r2	*/ \
-	mflr	r9;			/* save LR in stackframe	*/ \
-	std	r9,_LINK(r1);						   \
-	mfctr	r10;			/* save CTR in stackframe	*/ \
-	std	r10,_CTR(r1);						   \
-	mfspr	r11,SPRN_XER;		/* save XER in stackframe	*/ \
-	std	r11,_XER(r1);						   \
-	li	r9,(n)+1;						   \
-	std	r9,_TRAP(r1);		/* set trap number		*/ \
-	li	r10,0;							   \
-	ld	r11,exception_marker@toc(r2);				   \
-	std	r10,RESULT(r1);		/* clear regs->result		*/ \
-	std	r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame	*/
-
-/*
- * Exception vectors.
- */
-#define STD_EXCEPTION_PSERIES(n, label)			\
-	. = n;						\
-	.globl label##_pSeries;				\
-label##_pSeries:					\
-	HMT_MEDIUM;					\
-	mtspr	SPRN_SPRG1,r13;		/* save r13 */	\
-	RUNLATCH_ON(r13);				\
-	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
-
-#define STD_EXCEPTION_ISERIES(n, label, area)		\
-	.globl label##_iSeries;				\
-label##_iSeries:					\
-	HMT_MEDIUM;					\
-	mtspr	SPRN_SPRG1,r13;		/* save r13 */	\
-	RUNLATCH_ON(r13);				\
-	EXCEPTION_PROLOG_ISERIES_1(area);		\
-	EXCEPTION_PROLOG_ISERIES_2;			\
-	b	label##_common
-
-#define MASKABLE_EXCEPTION_ISERIES(n, label)				\
-	.globl label##_iSeries;						\
-label##_iSeries:							\
-	HMT_MEDIUM;							\
-	mtspr	SPRN_SPRG1,r13;		/* save r13 */			\
-	RUNLATCH_ON(r13);						\
-	EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN);				\
-	lbz	r10,PACAPROCENABLED(r13);				\
-	cmpwi	0,r10,0;						\
-	beq-	label##_iSeries_masked;					\
-	EXCEPTION_PROLOG_ISERIES_2;					\
-	b	label##_common;						\
-
-#ifdef DO_SOFT_DISABLE
-#define DISABLE_INTS				\
-	lbz	r10,PACAPROCENABLED(r13);	\
-	li	r11,0;				\
-	std	r10,SOFTE(r1);			\
-	mfmsr	r10;				\
-	stb	r11,PACAPROCENABLED(r13);	\
-	ori	r10,r10,MSR_EE;			\
-	mtmsrd	r10,1
-
-#define ENABLE_INTS				\
-	lbz	r10,PACAPROCENABLED(r13);	\
-	mfmsr	r11;				\
-	std	r10,SOFTE(r1);			\
-	ori	r11,r11,MSR_EE;			\
-	mtmsrd	r11,1
-
-#else	/* hard enable/disable interrupts */
-#define DISABLE_INTS
-
-#define ENABLE_INTS				\
-	ld	r12,_MSR(r1);			\
-	mfmsr	r11;				\
-	rlwimi	r11,r12,0,MSR_EE;		\
-	mtmsrd	r11,1
-
-#endif
-
-#define STD_EXCEPTION_COMMON(trap, label, hdlr)		\
-	.align	7;					\
-	.globl label##_common;				\
-label##_common:						\
-	EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);	\
-	DISABLE_INTS;					\
-	bl	.save_nvgprs;				\
-	addi	r3,r1,STACK_FRAME_OVERHEAD;		\
-	bl	hdlr;					\
-	b	.ret_from_except
-
-#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr)	\
-	.align	7;					\
-	.globl label##_common;				\
-label##_common:						\
-	EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);	\
-	DISABLE_INTS;					\
-	addi	r3,r1,STACK_FRAME_OVERHEAD;		\
-	bl	hdlr;					\
-	b	.ret_from_except_lite
-
-/*
- * Start of pSeries system interrupt routines
- */
-	. = 0x100
-	.globl __start_interrupts
-__start_interrupts:
-
-	STD_EXCEPTION_PSERIES(0x100, system_reset)
-
-	. = 0x200
-_machine_check_pSeries:
-	HMT_MEDIUM
-	mtspr	SPRN_SPRG1,r13		/* save r13 */
-	RUNLATCH_ON(r13)
-	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
-
-	. = 0x300
-	.globl data_access_pSeries
-data_access_pSeries:
-	HMT_MEDIUM
-	mtspr	SPRN_SPRG1,r13
-BEGIN_FTR_SECTION
-	mtspr	SPRN_SPRG2,r12
-	mfspr	r13,SPRN_DAR
-	mfspr	r12,SPRN_DSISR
-	srdi	r13,r13,60
-	rlwimi	r13,r12,16,0x20
-	mfcr	r12
-	cmpwi	r13,0x2c
-	beq	.do_stab_bolted_pSeries
-	mtcrf	0x80,r12
-	mfspr	r12,SPRN_SPRG2
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
-
-	. = 0x380
-	.globl data_access_slb_pSeries
-data_access_slb_pSeries:
-	HMT_MEDIUM
-	mtspr	SPRN_SPRG1,r13
-	RUNLATCH_ON(r13)
-	mfspr	r13,SPRN_SPRG3		/* get paca address into r13 */
-	std	r3,PACA_EXSLB+EX_R3(r13)
-	mfspr	r3,SPRN_DAR
-	std	r9,PACA_EXSLB+EX_R9(r13)	/* save r9 - r12 */
-	mfcr	r9
-#ifdef __DISABLED__
-	/* Keep that around for when we re-implement dynamic VSIDs */
-	cmpdi	r3,0
-	bge	slb_miss_user_pseries
-#endif /* __DISABLED__ */
-	std	r10,PACA_EXSLB+EX_R10(r13)
-	std	r11,PACA_EXSLB+EX_R11(r13)
-	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG1
-	std	r10,PACA_EXSLB+EX_R13(r13)
-	mfspr	r12,SPRN_SRR1		/* and SRR1 */
-	b	.slb_miss_realmode	/* Rel. branch works in real mode */
-
-	STD_EXCEPTION_PSERIES(0x400, instruction_access)
-
-	. = 0x480
-	.globl instruction_access_slb_pSeries
-instruction_access_slb_pSeries:
-	HMT_MEDIUM
-	mtspr	SPRN_SPRG1,r13
-	RUNLATCH_ON(r13)
-	mfspr	r13,SPRN_SPRG3		/* get paca address into r13 */
-	std	r3,PACA_EXSLB+EX_R3(r13)
-	mfspr	r3,SPRN_SRR0		/* SRR0 is faulting address */
-	std	r9,PACA_EXSLB+EX_R9(r13)	/* save r9 - r12 */
-	mfcr	r9
-#ifdef __DISABLED__
-	/* Keep that around for when we re-implement dynamic VSIDs */
-	cmpdi	r3,0
-	bge	slb_miss_user_pseries
-#endif /* __DISABLED__ */
-	std	r10,PACA_EXSLB+EX_R10(r13)
-	std	r11,PACA_EXSLB+EX_R11(r13)
-	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG1
-	std	r10,PACA_EXSLB+EX_R13(r13)
-	mfspr	r12,SPRN_SRR1		/* and SRR1 */
-	b	.slb_miss_realmode	/* Rel. branch works in real mode */
-
-	STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
-	STD_EXCEPTION_PSERIES(0x600, alignment)
-	STD_EXCEPTION_PSERIES(0x700, program_check)
-	STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
-	STD_EXCEPTION_PSERIES(0x900, decrementer)
-	STD_EXCEPTION_PSERIES(0xa00, trap_0a)
-	STD_EXCEPTION_PSERIES(0xb00, trap_0b)
-
-	. = 0xc00
-	.globl	system_call_pSeries
-system_call_pSeries:
-	HMT_MEDIUM
-	RUNLATCH_ON(r9)
-	mr	r9,r13
-	mfmsr	r10
-	mfspr	r13,SPRN_SPRG3
-	mfspr	r11,SPRN_SRR0
-	clrrdi	r12,r13,32
-	oris	r12,r12,system_call_common@h
-	ori	r12,r12,system_call_common@l
-	mtspr	SPRN_SRR0,r12
-	ori	r10,r10,MSR_IR|MSR_DR|MSR_RI
-	mfspr	r12,SPRN_SRR1
-	mtspr	SPRN_SRR1,r10
-	rfid
-	b	.	/* prevent speculative execution */
-
-	STD_EXCEPTION_PSERIES(0xd00, single_step)
-	STD_EXCEPTION_PSERIES(0xe00, trap_0e)
-
-	/* We need to deal with the Altivec unavailable exception
-	 * here which is at 0xf20, thus in the middle of the
-	 * prolog code of the PerformanceMonitor one. A little
-	 * trickery is thus necessary
-	 */
-	. = 0xf00
-	b	performance_monitor_pSeries
-
-	STD_EXCEPTION_PSERIES(0xf20, altivec_unavailable)
-
-	STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
-	STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
-
-	. = 0x3000
-
-/*** pSeries interrupt support ***/
-
-	/* moved from 0xf00 */
-	STD_EXCEPTION_PSERIES(., performance_monitor)
-
-	.align	7
-_GLOBAL(do_stab_bolted_pSeries)
-	mtcrf	0x80,r12
-	mfspr	r12,SPRN_SPRG2
-	EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
-
-/*
- * We have some room here  we use that to put
- * the peries slb miss user trampoline code so it's reasonably
- * away from slb_miss_user_common to avoid problems with rfid
- *
- * This is used for when the SLB miss handler has to go virtual,
- * which doesn't happen for now anymore but will once we re-implement
- * dynamic VSIDs for shared page tables
- */
-#ifdef __DISABLED__
-slb_miss_user_pseries:
-	std	r10,PACA_EXGEN+EX_R10(r13)
-	std	r11,PACA_EXGEN+EX_R11(r13)
-	std	r12,PACA_EXGEN+EX_R12(r13)
-	mfspr	r10,SPRG1
-	ld	r11,PACA_EXSLB+EX_R9(r13)
-	ld	r12,PACA_EXSLB+EX_R3(r13)
-	std	r10,PACA_EXGEN+EX_R13(r13)
-	std	r11,PACA_EXGEN+EX_R9(r13)
-	std	r12,PACA_EXGEN+EX_R3(r13)
-	clrrdi	r12,r13,32
-	mfmsr	r10
-	mfspr	r11,SRR0			/* save SRR0 */
-	ori	r12,r12,slb_miss_user_common@l	/* virt addr of handler */
-	ori	r10,r10,MSR_IR|MSR_DR|MSR_RI
-	mtspr	SRR0,r12
-	mfspr	r12,SRR1			/* and SRR1 */
-	mtspr	SRR1,r10
-	rfid
-	b	.				/* prevent spec. execution */
-#endif /* __DISABLED__ */
-
-/*
- * Vectors for the FWNMI option.  Share common code.
- */
-	.globl system_reset_fwnmi
-system_reset_fwnmi:
-	HMT_MEDIUM
-	mtspr	SPRN_SPRG1,r13		/* save r13 */
-	RUNLATCH_ON(r13)
-	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
-
-	.globl machine_check_fwnmi
-machine_check_fwnmi:
-	HMT_MEDIUM
-	mtspr	SPRN_SPRG1,r13		/* save r13 */
-	RUNLATCH_ON(r13)
-	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
-
-#ifdef CONFIG_PPC_ISERIES
-/***  ISeries-LPAR interrupt handlers ***/
-
-	STD_EXCEPTION_ISERIES(0x200, machine_check, PACA_EXMC)
-
-	.globl data_access_iSeries
-data_access_iSeries:
-	mtspr	SPRN_SPRG1,r13
-BEGIN_FTR_SECTION
-	mtspr	SPRN_SPRG2,r12
-	mfspr	r13,SPRN_DAR
-	mfspr	r12,SPRN_DSISR
-	srdi	r13,r13,60
-	rlwimi	r13,r12,16,0x20
-	mfcr	r12
-	cmpwi	r13,0x2c
-	beq	.do_stab_bolted_iSeries
-	mtcrf	0x80,r12
-	mfspr	r12,SPRN_SPRG2
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-	EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN)
-	EXCEPTION_PROLOG_ISERIES_2
-	b	data_access_common
-
-.do_stab_bolted_iSeries:
-	mtcrf	0x80,r12
-	mfspr	r12,SPRN_SPRG2
-	EXCEPTION_PROLOG_ISERIES_1(PACA_EXSLB)
-	EXCEPTION_PROLOG_ISERIES_2
-	b	.do_stab_bolted
-
-	.globl	data_access_slb_iSeries
-data_access_slb_iSeries:
-	mtspr	SPRN_SPRG1,r13		/* save r13 */
-	mfspr	r13,SPRN_SPRG3		/* get paca address into r13 */
-	std	r3,PACA_EXSLB+EX_R3(r13)
-	mfspr	r3,SPRN_DAR
-	std	r9,PACA_EXSLB+EX_R9(r13)
-	mfcr	r9
-#ifdef __DISABLED__
-	cmpdi	r3,0
-	bge	slb_miss_user_iseries
-#endif
-	std	r10,PACA_EXSLB+EX_R10(r13)
-	std	r11,PACA_EXSLB+EX_R11(r13)
-	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG1
-	std	r10,PACA_EXSLB+EX_R13(r13)
-	ld	r12,PACALPPACA+LPPACASRR1(r13);
-	b	.slb_miss_realmode
-
-	STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
-
-	.globl	instruction_access_slb_iSeries
-instruction_access_slb_iSeries:
-	mtspr	SPRN_SPRG1,r13		/* save r13 */
-	mfspr	r13,SPRN_SPRG3		/* get paca address into r13 */
-	std	r3,PACA_EXSLB+EX_R3(r13)
-	ld	r3,PACALPPACA+LPPACASRR0(r13)	/* get SRR0 value */
-	std	r9,PACA_EXSLB+EX_R9(r13)
-	mfcr	r9
-#ifdef __DISABLED__
-	cmpdi	r3,0
-	bge	.slb_miss_user_iseries
-#endif
-	std	r10,PACA_EXSLB+EX_R10(r13)
-	std	r11,PACA_EXSLB+EX_R11(r13)
-	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG1
-	std	r10,PACA_EXSLB+EX_R13(r13)
-	ld	r12,PACALPPACA+LPPACASRR1(r13);
-	b	.slb_miss_realmode
-
-#ifdef __DISABLED__
-slb_miss_user_iseries:
-	std	r10,PACA_EXGEN+EX_R10(r13)
-	std	r11,PACA_EXGEN+EX_R11(r13)
-	std	r12,PACA_EXGEN+EX_R12(r13)
-	mfspr	r10,SPRG1
-	ld	r11,PACA_EXSLB+EX_R9(r13)
-	ld	r12,PACA_EXSLB+EX_R3(r13)
-	std	r10,PACA_EXGEN+EX_R13(r13)
-	std	r11,PACA_EXGEN+EX_R9(r13)
-	std	r12,PACA_EXGEN+EX_R3(r13)
-	EXCEPTION_PROLOG_ISERIES_2
-	b	slb_miss_user_common
-#endif
-
-	MASKABLE_EXCEPTION_ISERIES(0x500, hardware_interrupt)
-	STD_EXCEPTION_ISERIES(0x600, alignment, PACA_EXGEN)
-	STD_EXCEPTION_ISERIES(0x700, program_check, PACA_EXGEN)
-	STD_EXCEPTION_ISERIES(0x800, fp_unavailable, PACA_EXGEN)
-	MASKABLE_EXCEPTION_ISERIES(0x900, decrementer)
-	STD_EXCEPTION_ISERIES(0xa00, trap_0a, PACA_EXGEN)
-	STD_EXCEPTION_ISERIES(0xb00, trap_0b, PACA_EXGEN)
-
-	.globl	system_call_iSeries
-system_call_iSeries:
-	mr	r9,r13
-	mfspr	r13,SPRN_SPRG3
-	EXCEPTION_PROLOG_ISERIES_2
-	b	system_call_common
-
-	STD_EXCEPTION_ISERIES( 0xd00, single_step, PACA_EXGEN)
-	STD_EXCEPTION_ISERIES( 0xe00, trap_0e, PACA_EXGEN)
-	STD_EXCEPTION_ISERIES( 0xf00, performance_monitor, PACA_EXGEN)
-
-	.globl system_reset_iSeries
-system_reset_iSeries:
-	mfspr	r13,SPRN_SPRG3		/* Get paca address */
-	mfmsr	r24
-	ori	r24,r24,MSR_RI
-	mtmsrd	r24			/* RI on */
-	lhz	r24,PACAPACAINDEX(r13)	/* Get processor # */
-	cmpwi	0,r24,0			/* Are we processor 0? */
-	beq	.__start_initialization_iSeries	/* Start up the first processor */
-	mfspr	r4,SPRN_CTRLF
-	li	r5,CTRL_RUNLATCH	/* Turn off the run light */
-	andc	r4,r4,r5
-	mtspr	SPRN_CTRLT,r4
-
-1:
-	HMT_LOW
-#ifdef CONFIG_SMP
-	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor
-					 * should start */
-	sync
-	LOADADDR(r3,current_set)
-	sldi	r28,r24,3		/* get current_set[cpu#] */
-	ldx	r3,r3,r28
-	addi	r1,r3,THREAD_SIZE
-	subi	r1,r1,STACK_FRAME_OVERHEAD
-
-	cmpwi	0,r23,0
-	beq	iSeries_secondary_smp_loop	/* Loop until told to go */
-	bne	.__secondary_start		/* Loop until told to go */
-iSeries_secondary_smp_loop:
-	/* Let the Hypervisor know we are alive */
-	/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
-	lis	r3,0x8002
-	rldicr	r3,r3,32,15		/* r0 = (r3 << 32) & 0xffff000000000000 */
-#else /* CONFIG_SMP */
-	/* Yield the processor.  This is required for non-SMP kernels
-		which are running on multi-threaded machines. */
-	lis	r3,0x8000
-	rldicr	r3,r3,32,15		/* r3 = (r3 << 32) & 0xffff000000000000 */
-	addi	r3,r3,18		/* r3 = 0x8000000000000012 which is "yield" */
-	li	r4,0			/* "yield timed" */
-	li	r5,-1			/* "yield forever" */
-#endif /* CONFIG_SMP */
-	li	r0,-1			/* r0=-1 indicates a Hypervisor call */
-	sc				/* Invoke the hypervisor via a system call */
-	mfspr	r13,SPRN_SPRG3		/* Put r13 back ???? */
-	b	1b			/* If SMP not configured, secondaries
-					 * loop forever */
-
-	.globl decrementer_iSeries_masked
-decrementer_iSeries_masked:
-	li	r11,1
-	stb	r11,PACALPPACA+LPPACADECRINT(r13)
-	lwz	r12,PACADEFAULTDECR(r13)
-	mtspr	SPRN_DEC,r12
-	/* fall through */
-
-	.globl hardware_interrupt_iSeries_masked
-hardware_interrupt_iSeries_masked:
-	mtcrf	0x80,r9		/* Restore regs */
-	ld	r11,PACALPPACA+LPPACASRR0(r13)
-	ld	r12,PACALPPACA+LPPACASRR1(r13)
-	mtspr	SPRN_SRR0,r11
-	mtspr	SPRN_SRR1,r12
-	ld	r9,PACA_EXGEN+EX_R9(r13)
-	ld	r10,PACA_EXGEN+EX_R10(r13)
-	ld	r11,PACA_EXGEN+EX_R11(r13)
-	ld	r12,PACA_EXGEN+EX_R12(r13)
-	ld	r13,PACA_EXGEN+EX_R13(r13)
-	rfid
-	b	.	/* prevent speculative execution */
-#endif /* CONFIG_PPC_ISERIES */
-
-/*** Common interrupt handlers ***/
-
-	STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
-
-	/*
-	 * Machine check is different because we use a different
-	 * save area: PACA_EXMC instead of PACA_EXGEN.
-	 */
-	.align	7
-	.globl machine_check_common
-machine_check_common:
-	EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
-	DISABLE_INTS
-	bl	.save_nvgprs
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	bl	.machine_check_exception
-	b	.ret_from_except
-
-	STD_EXCEPTION_COMMON_LITE(0x900, decrementer, .timer_interrupt)
-	STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
-	STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
-	STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
-	STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
-	STD_EXCEPTION_COMMON(0xf00, performance_monitor, .performance_monitor_exception)
-	STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
-#ifdef CONFIG_ALTIVEC
-	STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
-#else
-	STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
-#endif
-
-/*
- * Here we have detected that the kernel stack pointer is bad.
- * R9 contains the saved CR, r13 points to the paca,
- * r10 contains the (bad) kernel stack pointer,
- * r11 and r12 contain the saved SRR0 and SRR1.
- * We switch to using an emergency stack, save the registers there,
- * and call kernel_bad_stack(), which panics.
- */
-bad_stack:
-	ld	r1,PACAEMERGSP(r13)
-	subi	r1,r1,64+INT_FRAME_SIZE
-	std	r9,_CCR(r1)
-	std	r10,GPR1(r1)
-	std	r11,_NIP(r1)
-	std	r12,_MSR(r1)
-	mfspr	r11,SPRN_DAR
-	mfspr	r12,SPRN_DSISR
-	std	r11,_DAR(r1)
-	std	r12,_DSISR(r1)
-	mflr	r10
-	mfctr	r11
-	mfxer	r12
-	std	r10,_LINK(r1)
-	std	r11,_CTR(r1)
-	std	r12,_XER(r1)
-	SAVE_GPR(0,r1)
-	SAVE_GPR(2,r1)
-	SAVE_4GPRS(3,r1)
-	SAVE_2GPRS(7,r1)
-	SAVE_10GPRS(12,r1)
-	SAVE_10GPRS(22,r1)
-	addi	r11,r1,INT_FRAME_SIZE
-	std	r11,0(r1)
-	li	r12,0
-	std	r12,0(r11)
-	ld	r2,PACATOC(r13)
-1:	addi	r3,r1,STACK_FRAME_OVERHEAD
-	bl	.kernel_bad_stack
-	b	1b
-
-/*
- * Return from an exception with minimal checks.
- * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
- * If interrupts have been enabled, or anything has been
- * done that might have changed the scheduling status of
- * any task or sent any task a signal, you should use
- * ret_from_except or ret_from_except_lite instead of this.
- */
-	.globl	fast_exception_return
-fast_exception_return:
-	ld	r12,_MSR(r1)
-	ld	r11,_NIP(r1)
-	andi.	r3,r12,MSR_RI		/* check if RI is set */
-	beq-	unrecov_fer
-	ld	r3,_CCR(r1)
-	ld	r4,_LINK(r1)
-	ld	r5,_CTR(r1)
-	ld	r6,_XER(r1)
-	mtcr	r3
-	mtlr	r4
-	mtctr	r5
-	mtxer	r6
-	REST_GPR(0, r1)
-	REST_8GPRS(2, r1)
-
-	mfmsr	r10
-	clrrdi	r10,r10,2		/* clear RI (LE is 0 already) */
-	mtmsrd	r10,1
-
-	mtspr	SPRN_SRR1,r12
-	mtspr	SPRN_SRR0,r11
-	REST_4GPRS(10, r1)
-	ld	r1,GPR1(r1)
-	rfid
-	b	.	/* prevent speculative execution */
-
-unrecov_fer:
-	bl	.save_nvgprs
-1:	addi	r3,r1,STACK_FRAME_OVERHEAD
-	bl	.unrecoverable_exception
-	b	1b
-
-/*
- * Here r13 points to the paca, r9 contains the saved CR,
- * SRR0 and SRR1 are saved in r11 and r12,
- * r9 - r13 are saved in paca->exgen.
- */
-	.align	7
-	.globl data_access_common
-data_access_common:
-	RUNLATCH_ON(r10)		/* It wont fit in the 0x300 handler */
-	mfspr	r10,SPRN_DAR
-	std	r10,PACA_EXGEN+EX_DAR(r13)
-	mfspr	r10,SPRN_DSISR
-	stw	r10,PACA_EXGEN+EX_DSISR(r13)
-	EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
-	ld	r3,PACA_EXGEN+EX_DAR(r13)
-	lwz	r4,PACA_EXGEN+EX_DSISR(r13)
-	li	r5,0x300
-	b	.do_hash_page	 	/* Try to handle as hpte fault */
-
-	.align	7
-	.globl instruction_access_common
-instruction_access_common:
-	EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
-	ld	r3,_NIP(r1)
-	andis.	r4,r12,0x5820
-	li	r5,0x400
-	b	.do_hash_page		/* Try to handle as hpte fault */
-
-/*
- * Here is the common SLB miss user that is used when going to virtual
- * mode for SLB misses, that is currently not used
- */
-#ifdef __DISABLED__
-	.align	7
-	.globl	slb_miss_user_common
-slb_miss_user_common:
-	mflr	r10
-	std	r3,PACA_EXGEN+EX_DAR(r13)
-	stw	r9,PACA_EXGEN+EX_CCR(r13)
-	std	r10,PACA_EXGEN+EX_LR(r13)
-	std	r11,PACA_EXGEN+EX_SRR0(r13)
-	bl	.slb_allocate_user
-
-	ld	r10,PACA_EXGEN+EX_LR(r13)
-	ld	r3,PACA_EXGEN+EX_R3(r13)
-	lwz	r9,PACA_EXGEN+EX_CCR(r13)
-	ld	r11,PACA_EXGEN+EX_SRR0(r13)
-	mtlr	r10
-	beq-	slb_miss_fault
-
-	andi.	r10,r12,MSR_RI		/* check for unrecoverable exception */
-	beq-	unrecov_user_slb
-	mfmsr	r10
-
-.machine push
-.machine "power4"
-	mtcrf	0x80,r9
-.machine pop
-
-	clrrdi	r10,r10,2		/* clear RI before setting SRR0/1 */
-	mtmsrd	r10,1
-
-	mtspr	SRR0,r11
-	mtspr	SRR1,r12
-
-	ld	r9,PACA_EXGEN+EX_R9(r13)
-	ld	r10,PACA_EXGEN+EX_R10(r13)
-	ld	r11,PACA_EXGEN+EX_R11(r13)
-	ld	r12,PACA_EXGEN+EX_R12(r13)
-	ld	r13,PACA_EXGEN+EX_R13(r13)
-	rfid
-	b	.
-
-slb_miss_fault:
-	EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
-	ld	r4,PACA_EXGEN+EX_DAR(r13)
-	li	r5,0
-	std	r4,_DAR(r1)
-	std	r5,_DSISR(r1)
-	b	.handle_page_fault
-
-unrecov_user_slb:
-	EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
-	DISABLE_INTS
-	bl	.save_nvgprs
-1:	addi	r3,r1,STACK_FRAME_OVERHEAD
-	bl	.unrecoverable_exception
-	b	1b
-
-#endif /* __DISABLED__ */
-
-
-/*
- * r13 points to the PACA, r9 contains the saved CR,
- * r12 contain the saved SRR1, SRR0 is still ready for return
- * r3 has the faulting address
- * r9 - r13 are saved in paca->exslb.
- * r3 is saved in paca->slb_r3
- * We assume we aren't going to take any exceptions during this procedure.
- */
-_GLOBAL(slb_miss_realmode)
-	mflr	r10
-
-	stw	r9,PACA_EXSLB+EX_CCR(r13)	/* save CR in exc. frame */
-	std	r10,PACA_EXSLB+EX_LR(r13)	/* save LR */
-
-	bl	.slb_allocate_realmode
-
-	/* All done -- return from exception. */
-
-	ld	r10,PACA_EXSLB+EX_LR(r13)
-	ld	r3,PACA_EXSLB+EX_R3(r13)
-	lwz	r9,PACA_EXSLB+EX_CCR(r13)	/* get saved CR */
-#ifdef CONFIG_PPC_ISERIES
-	ld	r11,PACALPPACA+LPPACASRR0(r13)	/* get SRR0 value */
-#endif /* CONFIG_PPC_ISERIES */
-
-	mtlr	r10
-
-	andi.	r10,r12,MSR_RI	/* check for unrecoverable exception */
-	beq-	unrecov_slb
-
-.machine	push
-.machine	"power4"
-	mtcrf	0x80,r9
-	mtcrf	0x01,r9		/* slb_allocate uses cr0 and cr7 */
-.machine	pop
-
-#ifdef CONFIG_PPC_ISERIES
-	mtspr	SPRN_SRR0,r11
-	mtspr	SPRN_SRR1,r12
-#endif /* CONFIG_PPC_ISERIES */
-	ld	r9,PACA_EXSLB+EX_R9(r13)
-	ld	r10,PACA_EXSLB+EX_R10(r13)
-	ld	r11,PACA_EXSLB+EX_R11(r13)
-	ld	r12,PACA_EXSLB+EX_R12(r13)
-	ld	r13,PACA_EXSLB+EX_R13(r13)
-	rfid
-	b	.	/* prevent speculative execution */
-
-unrecov_slb:
-	EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
-	DISABLE_INTS
-	bl	.save_nvgprs
-1:	addi	r3,r1,STACK_FRAME_OVERHEAD
-	bl	.unrecoverable_exception
-	b	1b
-
-	.align	7
-	.globl hardware_interrupt_common
-	.globl hardware_interrupt_entry
-hardware_interrupt_common:
-	EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
-hardware_interrupt_entry:
-	DISABLE_INTS
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	bl	.do_IRQ
-	b	.ret_from_except_lite
-
-	.align	7
-	.globl alignment_common
-alignment_common:
-	mfspr	r10,SPRN_DAR
-	std	r10,PACA_EXGEN+EX_DAR(r13)
-	mfspr	r10,SPRN_DSISR
-	stw	r10,PACA_EXGEN+EX_DSISR(r13)
-	EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
-	ld	r3,PACA_EXGEN+EX_DAR(r13)
-	lwz	r4,PACA_EXGEN+EX_DSISR(r13)
-	std	r3,_DAR(r1)
-	std	r4,_DSISR(r1)
-	bl	.save_nvgprs
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	ENABLE_INTS
-	bl	.alignment_exception
-	b	.ret_from_except
-
-	.align	7
-	.globl program_check_common
-program_check_common:
-	EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
-	bl	.save_nvgprs
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	ENABLE_INTS
-	bl	.program_check_exception
-	b	.ret_from_except
-
-	.align	7
-	.globl fp_unavailable_common
-fp_unavailable_common:
-	EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
-	bne	.load_up_fpu		/* if from user, just load it up */
-	bl	.save_nvgprs
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	ENABLE_INTS
-	bl	.kernel_fp_unavailable_exception
-	BUG_OPCODE
-
-	.align	7
-	.globl altivec_unavailable_common
-altivec_unavailable_common:
-	EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
-#ifdef CONFIG_ALTIVEC
-BEGIN_FTR_SECTION
-	bne	.load_up_altivec	/* if from user, just load it up */
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-#endif
-	bl	.save_nvgprs
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	ENABLE_INTS
-	bl	.altivec_unavailable_exception
-	b	.ret_from_except
-
-#ifdef CONFIG_ALTIVEC
-/*
- * load_up_altivec(unused, unused, tsk)
- * Disable VMX for the task which had it previously,
- * and save its vector registers in its thread_struct.
- * Enables the VMX for use in the kernel on return.
- * On SMP we know the VMX is free, since we give it up every
- * switch (ie, no lazy save of the vector registers).
- * On entry: r13 == 'current' && last_task_used_altivec != 'current'
- */
-_STATIC(load_up_altivec)
-	mfmsr	r5			/* grab the current MSR */
-	oris	r5,r5,MSR_VEC@h
-	mtmsrd	r5			/* enable use of VMX now */
-	isync
-
-/*
- * For SMP, we don't do lazy VMX switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another.  Instead we call giveup_altvec in switch_to.
- * VRSAVE isn't dealt with here, that is done in the normal context
- * switch code. Note that we could rely on vrsave value to eventually
- * avoid saving all of the VREGs here...
- */
-#ifndef CONFIG_SMP
-	ld	r3,last_task_used_altivec@got(r2)
-	ld	r4,0(r3)
-	cmpdi	0,r4,0
-	beq	1f
-	/* Save VMX state to last_task_used_altivec's THREAD struct */
-	addi	r4,r4,THREAD
-	SAVE_32VRS(0,r5,r4)
-	mfvscr	vr0
-	li	r10,THREAD_VSCR
-	stvx	vr0,r10,r4
-	/* Disable VMX for last_task_used_altivec */
-	ld	r5,PT_REGS(r4)
-	ld	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-	lis	r6,MSR_VEC@h
-	andc	r4,r4,r6
-	std	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
-	/* Hack: if we get an altivec unavailable trap with VRSAVE
-	 * set to all zeros, we assume this is a broken application
-	 * that fails to set it properly, and thus we switch it to
-	 * all 1's
-	 */
-	mfspr	r4,SPRN_VRSAVE
-	cmpdi	0,r4,0
-	bne+	1f
-	li	r4,-1
-	mtspr	SPRN_VRSAVE,r4
-1:
-	/* enable use of VMX after return */
-	ld	r4,PACACURRENT(r13)
-	addi	r5,r4,THREAD		/* Get THREAD */
-	oris	r12,r12,MSR_VEC@h
-	std	r12,_MSR(r1)
-	li	r4,1
-	li	r10,THREAD_VSCR
-	stw	r4,THREAD_USED_VR(r5)
-	lvx	vr0,r10,r5
-	mtvscr	vr0
-	REST_32VRS(0,r4,r5)
-#ifndef CONFIG_SMP
-	/* Update last_task_used_math to 'current' */
-	subi	r4,r5,THREAD		/* Back to 'current' */
-	std	r4,0(r3)
-#endif /* CONFIG_SMP */
-	/* restore registers and return */
-	b	fast_exception_return
-#endif /* CONFIG_ALTIVEC */
-
-/*
- * Hash table stuff
- */
-	.align	7
-_GLOBAL(do_hash_page)
-	std	r3,_DAR(r1)
-	std	r4,_DSISR(r1)
-
-	andis.	r0,r4,0xa450		/* weird error? */
-	bne-	.handle_page_fault	/* if not, try to insert a HPTE */
-BEGIN_FTR_SECTION
-	andis.	r0,r4,0x0020		/* Is it a segment table fault? */
-	bne-	.do_ste_alloc		/* If so handle it */
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-
-	/*
-	 * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
-	 * accessing a userspace segment (even from the kernel). We assume
-	 * kernel addresses always have the high bit set.
-	 */
-	rlwinm	r4,r4,32-25+9,31-9,31-9	/* DSISR_STORE -> _PAGE_RW */
-	rotldi	r0,r3,15		/* Move high bit into MSR_PR posn */
-	orc	r0,r12,r0		/* MSR_PR | ~high_bit */
-	rlwimi	r4,r0,32-13,30,30	/* becomes _PAGE_USER access bit */
-	ori	r4,r4,1			/* add _PAGE_PRESENT */
-	rlwimi	r4,r5,22+2,31-2,31-2	/* Set _PAGE_EXEC if trap is 0x400 */
-
-	/*
-	 * On iSeries, we soft-disable interrupts here, then
-	 * hard-enable interrupts so that the hash_page code can spin on
-	 * the hash_table_lock without problems on a shared processor.
-	 */
-	DISABLE_INTS
-
-	/*
-	 * r3 contains the faulting address
-	 * r4 contains the required access permissions
-	 * r5 contains the trap number
-	 *
-	 * at return r3 = 0 for success
-	 */
-	bl	.hash_page		/* build HPTE if possible */
-	cmpdi	r3,0			/* see if hash_page succeeded */
-
-#ifdef DO_SOFT_DISABLE
-	/*
-	 * If we had interrupts soft-enabled at the point where the
-	 * DSI/ISI occurred, and an interrupt came in during hash_page,
-	 * handle it now.
-	 * We jump to ret_from_except_lite rather than fast_exception_return
-	 * because ret_from_except_lite will check for and handle pending
-	 * interrupts if necessary.
-	 */
-	beq	.ret_from_except_lite
-	/* For a hash failure, we don't bother re-enabling interrupts */
-	ble-	12f
-
-	/*
-	 * hash_page couldn't handle it, set soft interrupt enable back
-	 * to what it was before the trap.  Note that .local_irq_restore
-	 * handles any interrupts pending at this point.
-	 */
-	ld	r3,SOFTE(r1)
-	bl	.local_irq_restore
-	b	11f
-#else
-	beq	fast_exception_return   /* Return from exception on success */
-	ble-	12f			/* Failure return from hash_page */
-
-	/* fall through */
-#endif
-
-/* Here we have a page fault that hash_page can't handle. */
-_GLOBAL(handle_page_fault)
-	ENABLE_INTS
-11:	ld	r4,_DAR(r1)
-	ld	r5,_DSISR(r1)
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	bl	.do_page_fault
-	cmpdi	r3,0
-	beq+	.ret_from_except_lite
-	bl	.save_nvgprs
-	mr	r5,r3
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	lwz	r4,_DAR(r1)
-	bl	.bad_page_fault
-	b	.ret_from_except
-
-/* We have a page fault that hash_page could handle but HV refused
- * the PTE insertion
- */
-12:	bl	.save_nvgprs
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	lwz	r4,_DAR(r1)
-	bl	.low_hash_fault
-	b	.ret_from_except
-
-	/* here we have a segment miss */
-_GLOBAL(do_ste_alloc)
-	bl	.ste_allocate		/* try to insert stab entry */
-	cmpdi	r3,0
-	beq+	fast_exception_return
-	b	.handle_page_fault
-
-/*
- * r13 points to the PACA, r9 contains the saved CR,
- * r11 and r12 contain the saved SRR0 and SRR1.
- * r9 - r13 are saved in paca->exslb.
- * We assume we aren't going to take any exceptions during this procedure.
- * We assume (DAR >> 60) == 0xc.
- */
-	.align	7
-_GLOBAL(do_stab_bolted)
-	stw	r9,PACA_EXSLB+EX_CCR(r13)	/* save CR in exc. frame */
-	std	r11,PACA_EXSLB+EX_SRR0(r13)	/* save SRR0 in exc. frame */
-
-	/* Hash to the primary group */
-	ld	r10,PACASTABVIRT(r13)
-	mfspr	r11,SPRN_DAR
-	srdi	r11,r11,28
-	rldimi	r10,r11,7,52	/* r10 = first ste of the group */
-
-	/* Calculate VSID */
-	/* This is a kernel address, so protovsid = ESID */
-	ASM_VSID_SCRAMBLE(r11, r9)
-	rldic	r9,r11,12,16	/* r9 = vsid << 12 */
-
-	/* Search the primary group for a free entry */
-1:	ld	r11,0(r10)	/* Test valid bit of the current ste	*/
-	andi.	r11,r11,0x80
-	beq	2f
-	addi	r10,r10,16
-	andi.	r11,r10,0x70
-	bne	1b
-
-	/* Stick for only searching the primary group for now.		*/
-	/* At least for now, we use a very simple random castout scheme */
-	/* Use the TB as a random number ;  OR in 1 to avoid entry 0	*/
-	mftb	r11
-	rldic	r11,r11,4,57	/* r11 = (r11 << 4) & 0x70 */
-	ori	r11,r11,0x10
-
-	/* r10 currently points to an ste one past the group of interest */
-	/* make it point to the randomly selected entry			*/
-	subi	r10,r10,128
-	or 	r10,r10,r11	/* r10 is the entry to invalidate	*/
-
-	isync			/* mark the entry invalid		*/
-	ld	r11,0(r10)
-	rldicl	r11,r11,56,1	/* clear the valid bit */
-	rotldi	r11,r11,8
-	std	r11,0(r10)
-	sync
-
-	clrrdi	r11,r11,28	/* Get the esid part of the ste		*/
-	slbie	r11
-
-2:	std	r9,8(r10)	/* Store the vsid part of the ste	*/
-	eieio
-
-	mfspr	r11,SPRN_DAR		/* Get the new esid			*/
-	clrrdi	r11,r11,28	/* Permits a full 32b of ESID		*/
-	ori	r11,r11,0x90	/* Turn on valid and kp			*/
-	std	r11,0(r10)	/* Put new entry back into the stab	*/
-
-	sync
-
-	/* All done -- return from exception. */
-	lwz	r9,PACA_EXSLB+EX_CCR(r13)	/* get saved CR */
-	ld	r11,PACA_EXSLB+EX_SRR0(r13)	/* get saved SRR0 */
-
-	andi.	r10,r12,MSR_RI
-	beq-	unrecov_slb
-
-	mtcrf	0x80,r9			/* restore CR */
-
-	mfmsr	r10
-	clrrdi	r10,r10,2
-	mtmsrd	r10,1
-
-	mtspr	SPRN_SRR0,r11
-	mtspr	SPRN_SRR1,r12
-	ld	r9,PACA_EXSLB+EX_R9(r13)
-	ld	r10,PACA_EXSLB+EX_R10(r13)
-	ld	r11,PACA_EXSLB+EX_R11(r13)
-	ld	r12,PACA_EXSLB+EX_R12(r13)
-	ld	r13,PACA_EXSLB+EX_R13(r13)
-	rfid
-	b	.	/* prevent speculative execution */
-
-/*
- * Space for CPU0's segment table.
- *
- * On iSeries, the hypervisor must fill in at least one entry before
- * we get control (with relocate on).  The address is give to the hv
- * as a page number (see xLparMap in lpardata.c), so this must be at a
- * fixed address (the linker can't compute (u64)&initial_stab >>
- * PAGE_SHIFT).
- */
-	. = STAB0_PHYS_ADDR	/* 0x6000 */
-	.globl initial_stab
-initial_stab:
-	.space	4096
-
-/*
- * Data area reserved for FWNMI option.
- * This address (0x7000) is fixed by the RPA.
- */
-	.= 0x7000
-	.globl fwnmi_data_area
-fwnmi_data_area:
-
-	/* iSeries does not use the FWNMI stuff, so it is safe to put
-	 * this here, even if we later allow kernels that will boot on
-	 * both pSeries and iSeries */
-#ifdef CONFIG_PPC_ISERIES
-        . = LPARMAP_PHYS
-#include "lparmap.s"
-/*
- * This ".text" is here for old compilers that generate a trailing
- * .note section when compiling .c files to .s
- */
-	.text
-#endif /* CONFIG_PPC_ISERIES */
-
-        . = 0x8000
-
-/*
- * On pSeries, secondary processors spin in the following code.
- * At entry, r3 = this processor's number (physical cpu id)
- */
-_GLOBAL(pSeries_secondary_smp_init)
-	mr	r24,r3
-	
-	/* turn on 64-bit mode */
-	bl	.enable_64b_mode
-	isync
-
-	/* Copy some CPU settings from CPU 0 */
-	bl	.__restore_cpu_setup
-
-	/* Set up a paca value for this processor. Since we have the
-	 * physical cpu id in r24, we need to search the pacas to find
-	 * which logical id maps to our physical one.
-	 */
-	LOADADDR(r13, paca) 		/* Get base vaddr of paca array	 */
-	li	r5,0			/* logical cpu id                */
-1:	lhz	r6,PACAHWCPUID(r13)	/* Load HW procid from paca      */
-	cmpw	r6,r24			/* Compare to our id             */
-	beq	2f
-	addi	r13,r13,PACA_SIZE	/* Loop to next PACA on miss     */
-	addi	r5,r5,1
-	cmpwi	r5,NR_CPUS
-	blt	1b
-
-	mr	r3,r24			/* not found, copy phys to r3	 */
-	b	.kexec_wait		/* next kernel might do better	 */
-
-2:	mtspr	SPRN_SPRG3,r13		/* Save vaddr of paca in SPRG3	 */
-	/* From now on, r24 is expected to be logical cpuid */
-	mr	r24,r5
-3:	HMT_LOW
-	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor should */
-					/* start.			 */
-	sync
-
-	/* Create a temp kernel stack for use before relocation is on.	*/
-	ld	r1,PACAEMERGSP(r13)
-	subi	r1,r1,STACK_FRAME_OVERHEAD
-
-	cmpwi	0,r23,0
-#ifdef CONFIG_SMP
-	bne	.__secondary_start
-#endif
-	b 	3b			/* Loop until told to go	 */
-
-#ifdef CONFIG_PPC_ISERIES
-_STATIC(__start_initialization_iSeries)
-	/* Clear out the BSS */
-	LOADADDR(r11,__bss_stop)
-	LOADADDR(r8,__bss_start)
-	sub	r11,r11,r8		/* bss size			*/
-	addi	r11,r11,7		/* round up to an even double word */
-	rldicl. r11,r11,61,3		/* shift right by 3		*/
-	beq	4f
-	addi	r8,r8,-8
-	li	r0,0
-	mtctr	r11			/* zero this many doublewords	*/
-3:	stdu	r0,8(r8)
-	bdnz	3b
-4:
-	LOADADDR(r1,init_thread_union)
-	addi	r1,r1,THREAD_SIZE
-	li	r0,0
-	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
-
-	LOADADDR(r3,cpu_specs)
-	LOADADDR(r4,cur_cpu_spec)
-	li	r5,0
-	bl	.identify_cpu
-
-	LOADADDR(r2,__toc_start)
-	addi	r2,r2,0x4000
-	addi	r2,r2,0x4000
-
-	bl	.iSeries_early_setup
-	bl	.early_setup
-
-	/* relocation is on at this point */
-
-	b	.start_here_common
-#endif /* CONFIG_PPC_ISERIES */
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
-
-_STATIC(__mmu_off)
-	mfmsr	r3
-	andi.	r0,r3,MSR_IR|MSR_DR
-	beqlr
-	andc	r3,r3,r0
-	mtspr	SPRN_SRR0,r4
-	mtspr	SPRN_SRR1,r3
-	sync
-	rfid
-	b	.	/* prevent speculative execution */
-
-
-/*
- * Here is our main kernel entry point. We support currently 2 kind of entries
- * depending on the value of r5.
- *
- *   r5 != NULL -> OF entry, we go to prom_init, "legacy" parameter content
- *                 in r3...r7
- *   
- *   r5 == NULL -> kexec style entry. r3 is a physical pointer to the
- *                 DT block, r4 is a physical pointer to the kernel itself
- *
- */
-_GLOBAL(__start_initialization_multiplatform)
-	/*
-	 * Are we booted from a PROM Of-type client-interface ?
-	 */
-	cmpldi	cr0,r5,0
-	bne	.__boot_from_prom		/* yes -> prom */
-
-	/* Save parameters */
-	mr	r31,r3
-	mr	r30,r4
-
-	/* Make sure we are running in 64 bits mode */
-	bl	.enable_64b_mode
-
-	/* Setup some critical 970 SPRs before switching MMU off */
-	bl	.__970_cpu_preinit
-
-	/* cpu # */
-	li	r24,0
-
-	/* Switch off MMU if not already */
-	LOADADDR(r4, .__after_prom_start - KERNELBASE)
-	add	r4,r4,r30
-	bl	.__mmu_off
-	b	.__after_prom_start
-
-_STATIC(__boot_from_prom)
-	/* Save parameters */
-	mr	r31,r3
-	mr	r30,r4
-	mr	r29,r5
-	mr	r28,r6
-	mr	r27,r7
-
-	/* Make sure we are running in 64 bits mode */
-	bl	.enable_64b_mode
-
-	/* put a relocation offset into r3 */
-	bl	.reloc_offset
-
-	LOADADDR(r2,__toc_start)
-	addi	r2,r2,0x4000
-	addi	r2,r2,0x4000
-
-	/* Relocate the TOC from a virt addr to a real addr */
-	sub	r2,r2,r3
-
-	/* Restore parameters */
-	mr	r3,r31
-	mr	r4,r30
-	mr	r5,r29
-	mr	r6,r28
-	mr	r7,r27
-
-	/* Do all of the interaction with OF client interface */
-	bl	.prom_init
-	/* We never return */
-	trap
-
-/*
- * At this point, r3 contains the physical address we are running at,
- * returned by prom_init()
- */
-_STATIC(__after_prom_start)
-
-/*
- * We need to run with __start at physical address 0.
- * This will leave some code in the first 256B of
- * real memory, which are reserved for software use.
- * The remainder of the first page is loaded with the fixed
- * interrupt vectors.  The next two pages are filled with
- * unknown exception placeholders.
- *
- * Note: This process overwrites the OF exception vectors.
- *	r26 == relocation offset
- *	r27 == KERNELBASE
- */
-	bl	.reloc_offset
-	mr	r26,r3
-	SET_REG_TO_CONST(r27,KERNELBASE)
-
-	li	r3,0			/* target addr */
-
-	// XXX FIXME: Use phys returned by OF (r30)
-	sub	r4,r27,r26 		/* source addr			 */
-					/* current address of _start	 */
-					/*   i.e. where we are running	 */
-					/*	the source addr		 */
-
-	LOADADDR(r5,copy_to_here)	/* # bytes of memory to copy	 */
-	sub	r5,r5,r27
-
-	li	r6,0x100		/* Start offset, the first 0x100 */
-					/* bytes were copied earlier.	 */
-
-	bl	.copy_and_flush		/* copy the first n bytes	 */
-					/* this includes the code being	 */
-					/* executed here.		 */
-
-	LOADADDR(r0, 4f)		/* Jump to the copy of this code */
-	mtctr	r0			/* that we just made/relocated	 */
-	bctr
-
-4:	LOADADDR(r5,klimit)
-	sub	r5,r5,r26
-	ld	r5,0(r5)		/* get the value of klimit */
-	sub	r5,r5,r27
-	bl	.copy_and_flush		/* copy the rest */
-	b	.start_here_multiplatform
-
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
-/*
- * Copy routine used to copy the kernel to start at physical address 0
- * and flush and invalidate the caches as needed.
- * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
- * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
- *
- * Note: this routine *only* clobbers r0, r6 and lr
- */
-_GLOBAL(copy_and_flush)
-	addi	r5,r5,-8
-	addi	r6,r6,-8
-4:	li	r0,16			/* Use the least common		*/
-					/* denominator cache line	*/
-					/* size.  This results in	*/
-					/* extra cache line flushes	*/
-					/* but operation is correct.	*/
-					/* Can't get cache line size	*/
-					/* from NACA as it is being	*/
-					/* moved too.			*/
-
-	mtctr	r0			/* put # words/line in ctr	*/
-3:	addi	r6,r6,8			/* copy a cache line		*/
-	ldx	r0,r6,r4
-	stdx	r0,r6,r3
-	bdnz	3b
-	dcbst	r6,r3			/* write it to memory		*/
-	sync
-	icbi	r6,r3			/* flush the icache line	*/
-	cmpld	0,r6,r5
-	blt	4b
-	sync
-	addi	r5,r5,8
-	addi	r6,r6,8
-	blr
-
-.align 8
-copy_to_here:
-
-#ifdef CONFIG_SMP
-#ifdef CONFIG_PPC_PMAC
-/*
- * On PowerMac, secondary processors starts from the reset vector, which
- * is temporarily turned into a call to one of the functions below.
- */
-	.section ".text";
-	.align 2 ;
-
-	.globl	__secondary_start_pmac_0
-__secondary_start_pmac_0:
-	/* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
-	li	r24,0
-	b	1f
-	li	r24,1
-	b	1f
-	li	r24,2
-	b	1f
-	li	r24,3
-1:
-	
-_GLOBAL(pmac_secondary_start)
-	/* turn on 64-bit mode */
-	bl	.enable_64b_mode
-	isync
-
-	/* Copy some CPU settings from CPU 0 */
-	bl	.__restore_cpu_setup
-
-	/* pSeries do that early though I don't think we really need it */
-	mfmsr	r3
-	ori	r3,r3,MSR_RI
-	mtmsrd	r3			/* RI on */
-
-	/* Set up a paca value for this processor. */
-	LOADADDR(r4, paca) 		 /* Get base vaddr of paca array	*/
-	mulli	r13,r24,PACA_SIZE	 /* Calculate vaddr of right paca */
-	add	r13,r13,r4		/* for this processor.		*/
-	mtspr	SPRN_SPRG3,r13		 /* Save vaddr of paca in SPRG3	*/
-
-	/* Create a temp kernel stack for use before relocation is on.	*/
-	ld	r1,PACAEMERGSP(r13)
-	subi	r1,r1,STACK_FRAME_OVERHEAD
-
-	b	.__secondary_start
-
-#endif /* CONFIG_PPC_PMAC */
-
-/*
- * This function is called after the master CPU has released the
- * secondary processors.  The execution environment is relocation off.
- * The paca for this processor has the following fields initialized at
- * this point:
- *   1. Processor number
- *   2. Segment table pointer (virtual address)
- * On entry the following are set:
- *   r1	= stack pointer.  vaddr for iSeries, raddr (temp stack) for pSeries
- *   r24   = cpu# (in Linux terms)
- *   r13   = paca virtual address
- *   SPRG3 = paca virtual address
- */
-_GLOBAL(__secondary_start)
-
-	HMT_MEDIUM			/* Set thread priority to MEDIUM */
-
-	ld	r2,PACATOC(r13)
-
-	/* Do early setup for that CPU */
-	bl	.early_setup_secondary
-
-	/* Initialize the kernel stack.  Just a repeat for iSeries.	 */
-	LOADADDR(r3,current_set)
-	sldi	r28,r24,3		/* get current_set[cpu#]	 */
-	ldx	r1,r3,r28
-	addi	r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
-	std	r1,PACAKSAVE(r13)
-
-	li	r7,0
-	mtlr	r7
-
-	/* enable MMU and jump to start_secondary */
-	LOADADDR(r3,.start_secondary_prolog)
-	SET_REG_TO_CONST(r4, MSR_KERNEL)
-#ifdef DO_SOFT_DISABLE
-	ori	r4,r4,MSR_EE
-#endif
-	mtspr	SPRN_SRR0,r3
-	mtspr	SPRN_SRR1,r4
-	rfid
-	b	.	/* prevent speculative execution */
-
-/* 
- * Running with relocation on at this point.  All we want to do is
- * zero the stack back-chain pointer before going into C code.
- */
-_GLOBAL(start_secondary_prolog)
-	li	r3,0
-	std	r3,0(r1)		/* Zero the stack frame pointer	*/
-	bl	.start_secondary
-#endif
-
-/*
- * This subroutine clobbers r11 and r12
- */
-_GLOBAL(enable_64b_mode)
-	mfmsr	r11			/* grab the current MSR */
-	li	r12,1
-	rldicr	r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
-	or	r11,r11,r12
-	li	r12,1
-	rldicr	r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
-	or	r11,r11,r12
-	mtmsrd	r11
-	isync
-	blr
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
-/*
- * This is where the main kernel code starts.
- */
-_STATIC(start_here_multiplatform)
-	/* get a new offset, now that the kernel has moved. */
-	bl	.reloc_offset
-	mr	r26,r3
-
-	/* Clear out the BSS. It may have been done in prom_init,
-	 * already but that's irrelevant since prom_init will soon
-	 * be detached from the kernel completely. Besides, we need
-	 * to clear it now for kexec-style entry.
-	 */
-	LOADADDR(r11,__bss_stop)
-	LOADADDR(r8,__bss_start)
-	sub	r11,r11,r8		/* bss size			*/
-	addi	r11,r11,7		/* round up to an even double word */
-	rldicl. r11,r11,61,3		/* shift right by 3		*/
-	beq	4f
-	addi	r8,r8,-8
-	li	r0,0
-	mtctr	r11			/* zero this many doublewords	*/
-3:	stdu	r0,8(r8)
-	bdnz	3b
-4:
-
-	mfmsr	r6
-	ori	r6,r6,MSR_RI
-	mtmsrd	r6			/* RI on */
-
-#ifdef CONFIG_HMT
-	/* Start up the second thread on cpu 0 */
-	mfspr	r3,SPRN_PVR
-	srwi	r3,r3,16
-	cmpwi	r3,0x34			/* Pulsar  */
-	beq	90f
-	cmpwi	r3,0x36			/* Icestar */
-	beq	90f
-	cmpwi	r3,0x37			/* SStar   */
-	beq	90f
-	b	91f			/* HMT not supported */
-90:	li	r3,0
-	bl	.hmt_start_secondary
-91:
-#endif
-
-	/* The following gets the stack and TOC set up with the regs */
-	/* pointing to the real addr of the kernel stack.  This is   */
-	/* all done to support the C function call below which sets  */
-	/* up the htab.  This is done because we have relocated the  */
-	/* kernel but are still running in real mode. */
-
-	LOADADDR(r3,init_thread_union)
-	sub	r3,r3,r26
-
-	/* set up a stack pointer (physical address) */
-	addi	r1,r3,THREAD_SIZE
-	li	r0,0
-	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
-
-	/* set up the TOC (physical address) */
-	LOADADDR(r2,__toc_start)
-	addi	r2,r2,0x4000
-	addi	r2,r2,0x4000
-	sub	r2,r2,r26
-
-	LOADADDR(r3,cpu_specs)
-	sub	r3,r3,r26
-	LOADADDR(r4,cur_cpu_spec)
-	sub	r4,r4,r26
-	mr	r5,r26
-	bl	.identify_cpu
-
-	/* Save some low level config HIDs of CPU0 to be copied to
-	 * other CPUs later on, or used for suspend/resume
-	 */
-	bl	.__save_cpu_setup
-	sync
-
-	/* Setup a valid physical PACA pointer in SPRG3 for early_setup
-	 * note that boot_cpuid can always be 0 nowadays since there is
-	 * nowhere it can be initialized differently before we reach this
-	 * code
-	 */
-	LOADADDR(r27, boot_cpuid)
-	sub	r27,r27,r26
-	lwz	r27,0(r27)
-
-	LOADADDR(r24, paca) 		/* Get base vaddr of paca array	 */
-	mulli	r13,r27,PACA_SIZE	/* Calculate vaddr of right paca */
-	add	r13,r13,r24		/* for this processor.		 */
-	sub	r13,r13,r26		/* convert to physical addr	 */
-	mtspr	SPRN_SPRG3,r13		/* PPPBBB: Temp... -Peter */
-	
-	/* Do very early kernel initializations, including initial hash table,
-	 * stab and slb setup before we turn on relocation.	*/
-
-	/* Restore parameters passed from prom_init/kexec */
-	mr	r3,r31
- 	bl	.early_setup
-
-	LOADADDR(r3,.start_here_common)
-	SET_REG_TO_CONST(r4, MSR_KERNEL)
-	mtspr	SPRN_SRR0,r3
-	mtspr	SPRN_SRR1,r4
-	rfid
-	b	.	/* prevent speculative execution */
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-	
-	/* This is where all platforms converge execution */
-_STATIC(start_here_common)
-	/* relocation is on at this point */
-
-	/* The following code sets up the SP and TOC now that we are */
-	/* running with translation enabled. */
-
-	LOADADDR(r3,init_thread_union)
-
-	/* set up the stack */
-	addi	r1,r3,THREAD_SIZE
-	li	r0,0
-	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
-
-	/* Apply the CPUs-specific fixups (nop out sections not relevant
-	 * to this CPU
-	 */
-	li	r3,0
-	bl	.do_cpu_ftr_fixups
-
-	LOADADDR(r26, boot_cpuid)
-	lwz	r26,0(r26)
-
-	LOADADDR(r24, paca) 		/* Get base vaddr of paca array  */
-	mulli	r13,r26,PACA_SIZE	/* Calculate vaddr of right paca */
-	add	r13,r13,r24		/* for this processor.		 */
-	mtspr	SPRN_SPRG3,r13
-
-	/* ptr to current */
-	LOADADDR(r4,init_task)
-	std	r4,PACACURRENT(r13)
-
-	/* Load the TOC */
-	ld	r2,PACATOC(r13)
-	std	r1,PACAKSAVE(r13)
-
-	bl	.setup_system
-
-	/* Load up the kernel context */
-5:
-#ifdef DO_SOFT_DISABLE
-	li	r5,0
-	stb	r5,PACAPROCENABLED(r13)	/* Soft Disabled */
-	mfmsr	r5
-	ori	r5,r5,MSR_EE		/* Hard Enabled */
-	mtmsrd	r5
-#endif
-
-	bl .start_kernel
-
-_GLOBAL(hmt_init)
-#ifdef CONFIG_HMT
-	LOADADDR(r5, hmt_thread_data)
-	mfspr	r7,SPRN_PVR
-	srwi	r7,r7,16
-	cmpwi	r7,0x34			/* Pulsar  */
-	beq	90f
-	cmpwi	r7,0x36			/* Icestar */
-	beq	91f
-	cmpwi	r7,0x37			/* SStar   */
-	beq	91f
-	b	101f
-90:	mfspr	r6,SPRN_PIR
-	andi.	r6,r6,0x1f
-	b	92f
-91:	mfspr	r6,SPRN_PIR
-	andi.	r6,r6,0x3ff
-92:	sldi	r4,r24,3
-	stwx	r6,r5,r4
-	bl	.hmt_start_secondary
-	b	101f
-
-__hmt_secondary_hold:
-	LOADADDR(r5, hmt_thread_data)
-	clrldi	r5,r5,4
-	li	r7,0
-	mfspr	r6,SPRN_PIR
-	mfspr	r8,SPRN_PVR
-	srwi	r8,r8,16
-	cmpwi	r8,0x34
-	bne	93f
-	andi.	r6,r6,0x1f
-	b	103f
-93:	andi.	r6,r6,0x3f
-
-103:	lwzx	r8,r5,r7
-	cmpw	r8,r6
-	beq	104f
-	addi	r7,r7,8
-	b	103b
-
-104:	addi	r7,r7,4
-	lwzx	r9,r5,r7
-	mr	r24,r9
-101:
-#endif
-	mr	r3,r24
-	b	.pSeries_secondary_smp_init
-
-#ifdef CONFIG_HMT
-_GLOBAL(hmt_start_secondary)
-	LOADADDR(r4,__hmt_secondary_hold)
-	clrldi	r4,r4,4
-	mtspr	SPRN_NIADORM, r4
-	mfspr	r4, SPRN_MSRDORM
-	li	r5, -65
-	and	r4, r4, r5
-	mtspr	SPRN_MSRDORM, r4
-	lis	r4,0xffef
-	ori	r4,r4,0x7403
-	mtspr	SPRN_TSC, r4
-	li	r4,0x1f4
-	mtspr	SPRN_TST, r4
-	mfspr	r4, SPRN_HID0
-	ori	r4, r4, 0x1
-	mtspr	SPRN_HID0, r4
-	mfspr	r4, SPRN_CTRLF
-	oris	r4, r4, 0x40
-	mtspr	SPRN_CTRLT, r4
-	blr
-#endif
-
-/*
- * We put a few things here that have to be page-aligned.
- * This stuff goes at the beginning of the bss, which is page-aligned.
- */
-	.section ".bss"
-
-	.align	PAGE_SHIFT
-
-	.globl	empty_zero_page
-empty_zero_page:
-	.space	PAGE_SIZE
-
-	.globl	swapper_pg_dir
-swapper_pg_dir:
-	.space	PAGE_SIZE
-
-/*
- * This space gets a copy of optional info passed to us by the bootstrap
- * Used to pass parameters into the kernel like root=/dev/sda1, etc.
- */
-	.globl	cmd_line
-cmd_line:
-	.space	COMMAND_LINE_SIZE
diff --git a/arch/ppc64/kernel/hvconsole.c b/arch/ppc64/kernel/hvconsole.c
deleted file mode 100644
index 138e128..0000000
--- a/arch/ppc64/kernel/hvconsole.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * hvconsole.c
- * Copyright (C) 2004 Hollis Blanchard, IBM Corporation
- * Copyright (C) 2004 IBM Corporation
- *
- * Additional Author(s):
- *  Ryan S. Arnold <rsa@us.ibm.com>
- *
- * LPAR console support.
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <asm/hvcall.h>
-#include <asm/hvconsole.h>
-
-/**
- * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper
- * @vtermno: The vtermno or unit_address of the adapter from which to fetch the
- *	data.
- * @buf: The character buffer into which to put the character data fetched from
- *	firmware.
- * @count: not used?
- */
-int hvc_get_chars(uint32_t vtermno, char *buf, int count)
-{
-	unsigned long got;
-
-	if (plpar_hcall(H_GET_TERM_CHAR, vtermno, 0, 0, 0, &got,
-		(unsigned long *)buf, (unsigned long *)buf+1) == H_Success)
-		return got;
-	return 0;
-}
-
-EXPORT_SYMBOL(hvc_get_chars);
-
-
-/**
- * hvc_put_chars: send characters to firmware for denoted vterm adapter
- * @vtermno: The vtermno or unit_address of the adapter from which the data
- *	originated.
- * @buf: The character buffer that contains the character data to send to
- *	firmware.
- * @count: Send this number of characters.
- */
-int hvc_put_chars(uint32_t vtermno, const char *buf, int count)
-{
-	unsigned long *lbuf = (unsigned long *) buf;
-	long ret;
-
-	ret = plpar_hcall_norets(H_PUT_TERM_CHAR, vtermno, count, lbuf[0],
-				 lbuf[1]);
-	if (ret == H_Success)
-		return count;
-	if (ret == H_Busy)
-		return 0;
-	return -EIO;
-}
-
-EXPORT_SYMBOL(hvc_put_chars);
diff --git a/arch/ppc64/kernel/hvcserver.c b/arch/ppc64/kernel/hvcserver.c
deleted file mode 100644
index 4d58417..0000000
--- a/arch/ppc64/kernel/hvcserver.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * hvcserver.c
- * Copyright (C) 2004 Ryan S Arnold, IBM Corporation
- *
- * PPC64 virtual I/O console server support.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-
-#include <asm/hvcall.h>
-#include <asm/hvcserver.h>
-#include <asm/io.h>
-
-#define HVCS_ARCH_VERSION "1.0.0"
-
-MODULE_AUTHOR("Ryan S. Arnold <rsa@us.ibm.com>");
-MODULE_DESCRIPTION("IBM hvcs ppc64 API");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(HVCS_ARCH_VERSION);
-
-/*
- * Convert arch specific return codes into relevant errnos.  The hvcs
- * functions aren't performance sensitive, so this conversion isn't an
- * issue.
- */
-int hvcs_convert(long to_convert)
-{
-	switch (to_convert) {
-		case H_Success:
-			return 0;
-		case H_Parameter:
-			return -EINVAL;
-		case H_Hardware:
-			return -EIO;
-		case H_Busy:
-		case H_LongBusyOrder1msec:
-		case H_LongBusyOrder10msec:
-		case H_LongBusyOrder100msec:
-		case H_LongBusyOrder1sec:
-		case H_LongBusyOrder10sec:
-		case H_LongBusyOrder100sec:
-			return -EBUSY;
-		case H_Function: /* fall through */
-		default:
-			return -EPERM;
-	}
-}
-
-/**
- * hvcs_free_partner_info - free pi allocated by hvcs_get_partner_info
- * @head: list_head pointer for an allocated list of partner info structs to
- *	free.
- *
- * This function is used to free the partner info list that was returned by
- * calling hvcs_get_partner_info().
- */
-int hvcs_free_partner_info(struct list_head *head)
-{
-	struct hvcs_partner_info *pi;
-	struct list_head *element;
-
-	if (!head)
-		return -EINVAL;
-
-	while (!list_empty(head)) {
-		element = head->next;
-		pi = list_entry(element, struct hvcs_partner_info, node);
-		list_del(element);
-		kfree(pi);
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(hvcs_free_partner_info);
-
-/* Helper function for hvcs_get_partner_info */
-int hvcs_next_partner(uint32_t unit_address,
-		unsigned long last_p_partition_ID,
-		unsigned long last_p_unit_address, unsigned long *pi_buff)
-
-{
-	long retval;
-	retval = plpar_hcall_norets(H_VTERM_PARTNER_INFO, unit_address,
-			last_p_partition_ID,
-				last_p_unit_address, virt_to_phys(pi_buff));
-	return hvcs_convert(retval);
-}
-
-/**
- * hvcs_get_partner_info - Get all of the partner info for a vty-server adapter
- * @unit_address: The unit_address of the vty-server adapter for which this
- *	function is fetching partner info.
- * @head: An initialized list_head pointer to an empty list to use to return the
- *	list of partner info fetched from the hypervisor to the caller.
- * @pi_buff: A page sized buffer pre-allocated prior to calling this function
- *	that is to be used to be used by firmware as an iterator to keep track
- *	of the partner info retrieval.
- *
- * This function returns non-zero on success, or if there is no partner info.
- *
- * The pi_buff is pre-allocated prior to calling this function because this
- * function may be called with a spin_lock held and kmalloc of a page is not
- * recommended as GFP_ATOMIC.
- *
- * The first long of this buffer is used to store a partner unit address.  The
- * second long is used to store a partner partition ID and starting at
- * pi_buff[2] is the 79 character Converged Location Code (diff size than the
- * unsigned longs, hence the casting mumbo jumbo you see later).
- *
- * Invocation of this function should always be followed by an invocation of
- * hvcs_free_partner_info() using a pointer to the SAME list head instance
- * that was passed as a parameter to this function.
- */
-int hvcs_get_partner_info(uint32_t unit_address, struct list_head *head,
-		unsigned long *pi_buff)
-{
-	/*
-	 * Dealt with as longs because of the hcall interface even though the
-	 * values are uint32_t.
-	 */
-	unsigned long	last_p_partition_ID;
-	unsigned long	last_p_unit_address;
-	struct hvcs_partner_info *next_partner_info = NULL;
-	int more = 1;
-	int retval;
-
-	memset(pi_buff, 0x00, PAGE_SIZE);
-	/* invalid parameters */
-	if (!head || !pi_buff)
-		return -EINVAL;
-
-	last_p_partition_ID = last_p_unit_address = ~0UL;
-	INIT_LIST_HEAD(head);
-
-	do {
-		retval = hvcs_next_partner(unit_address, last_p_partition_ID,
-				last_p_unit_address, pi_buff);
-		if (retval) {
-			/*
-			 * Don't indicate that we've failed if we have
-			 * any list elements.
-			 */
-			if (!list_empty(head))
-				return 0;
-			return retval;
-		}
-
-		last_p_partition_ID = pi_buff[0];
-		last_p_unit_address = pi_buff[1];
-
-		/* This indicates that there are no further partners */
-		if (last_p_partition_ID == ~0UL
-				&& last_p_unit_address == ~0UL)
-			break;
-
-		/* This is a very small struct and will be freed soon in
-		 * hvcs_free_partner_info(). */
-		next_partner_info = kmalloc(sizeof(struct hvcs_partner_info),
-				GFP_ATOMIC);
-
-		if (!next_partner_info) {
-			printk(KERN_WARNING "HVCONSOLE: kmalloc() failed to"
-				" allocate partner info struct.\n");
-			hvcs_free_partner_info(head);
-			return -ENOMEM;
-		}
-
-		next_partner_info->unit_address
-			= (unsigned int)last_p_unit_address;
-		next_partner_info->partition_ID
-			= (unsigned int)last_p_partition_ID;
-
-		/* copy the Null-term char too */
-		strncpy(&next_partner_info->location_code[0],
-			(char *)&pi_buff[2],
-			strlen((char *)&pi_buff[2]) + 1);
-
-		list_add_tail(&(next_partner_info->node), head);
-		next_partner_info = NULL;
-
-	} while (more);
-
-	return 0;
-}
-EXPORT_SYMBOL(hvcs_get_partner_info);
-
-/**
- * hvcs_register_connection - establish a connection between this vty-server and
- *	a vty.
- * @unit_address: The unit address of the vty-server adapter that is to be
- *	establish a connection.
- * @p_partition_ID: The partition ID of the vty adapter that is to be connected.
- * @p_unit_address: The unit address of the vty adapter to which the vty-server
- *	is to be connected.
- *
- * If this function is called once and -EINVAL is returned it may
- * indicate that the partner info needs to be refreshed for the
- * target unit address at which point the caller must invoke
- * hvcs_get_partner_info() and then call this function again.  If,
- * for a second time, -EINVAL is returned then it indicates that
- * there is probably already a partner connection registered to a
- * different vty-server adapter.  It is also possible that a second
- * -EINVAL may indicate that one of the parms is not valid, for
- * instance if the link was removed between the vty-server adapter
- * and the vty adapter that you are trying to open.  Don't shoot the
- * messenger.  Firmware implemented it this way.
- */
-int hvcs_register_connection( uint32_t unit_address,
-		uint32_t p_partition_ID, uint32_t p_unit_address)
-{
-	long retval;
-	retval = plpar_hcall_norets(H_REGISTER_VTERM, unit_address,
-				p_partition_ID, p_unit_address);
-	return hvcs_convert(retval);
-}
-EXPORT_SYMBOL(hvcs_register_connection);
-
-/**
- * hvcs_free_connection - free the connection between a vty-server and vty
- * @unit_address: The unit address of the vty-server that is to have its
- *	connection severed.
- *
- * This function is used to free the partner connection between a vty-server
- * adapter and a vty adapter.
- *
- * If -EBUSY is returned continue to call this function until 0 is returned.
- */
-int hvcs_free_connection(uint32_t unit_address)
-{
-	long retval;
-	retval = plpar_hcall_norets(H_FREE_VTERM, unit_address);
-	return hvcs_convert(retval);
-}
-EXPORT_SYMBOL(hvcs_free_connection);
diff --git a/arch/ppc64/kernel/iomap.c b/arch/ppc64/kernel/iomap.c
deleted file mode 100644
index 6160c8d..0000000
--- a/arch/ppc64/kernel/iomap.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * arch/ppc64/kernel/iomap.c
- *
- * ppc64 "iomap" interface implementation.
- *
- * (C) Copyright 2004 Linus Torvalds
- */
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/mm.h>
-#include <asm/io.h>
-
-/*
- * Here comes the ppc64 implementation of the IOMAP 
- * interfaces.
- */
-unsigned int fastcall ioread8(void __iomem *addr)
-{
-	return readb(addr);
-}
-unsigned int fastcall ioread16(void __iomem *addr)
-{
-	return readw(addr);
-}
-unsigned int fastcall ioread16be(void __iomem *addr)
-{
-	return in_be16(addr);
-}
-unsigned int fastcall ioread32(void __iomem *addr)
-{
-	return readl(addr);
-}
-unsigned int fastcall ioread32be(void __iomem *addr)
-{
-	return in_be32(addr);
-}
-EXPORT_SYMBOL(ioread8);
-EXPORT_SYMBOL(ioread16);
-EXPORT_SYMBOL(ioread16be);
-EXPORT_SYMBOL(ioread32);
-EXPORT_SYMBOL(ioread32be);
-
-void fastcall iowrite8(u8 val, void __iomem *addr)
-{
-	writeb(val, addr);
-}
-void fastcall iowrite16(u16 val, void __iomem *addr)
-{
-	writew(val, addr);
-}
-void fastcall iowrite16be(u16 val, void __iomem *addr)
-{
-	out_be16(addr, val);
-}
-void fastcall iowrite32(u32 val, void __iomem *addr)
-{
-	writel(val, addr);
-}
-void fastcall iowrite32be(u32 val, void __iomem *addr)
-{
-	out_be32(addr, val);
-}
-EXPORT_SYMBOL(iowrite8);
-EXPORT_SYMBOL(iowrite16);
-EXPORT_SYMBOL(iowrite16be);
-EXPORT_SYMBOL(iowrite32);
-EXPORT_SYMBOL(iowrite32be);
-
-/*
- * These are the "repeat read/write" functions. Note the
- * non-CPU byte order. We do things in "IO byteorder"
- * here.
- *
- * FIXME! We could make these do EEH handling if we really
- * wanted. Not clear if we do.
- */
-void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
-{
-	_insb((u8 __iomem *) addr, dst, count);
-}
-void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
-{
-	_insw_ns((u16 __iomem *) addr, dst, count);
-}
-void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
-{
-	_insl_ns((u32 __iomem *) addr, dst, count);
-}
-EXPORT_SYMBOL(ioread8_rep);
-EXPORT_SYMBOL(ioread16_rep);
-EXPORT_SYMBOL(ioread32_rep);
-
-void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
-{
-	_outsb((u8 __iomem *) addr, src, count);
-}
-void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
-{
-	_outsw_ns((u16 __iomem *) addr, src, count);
-}
-void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
-{
-	_outsl_ns((u32 __iomem *) addr, src, count);
-}
-EXPORT_SYMBOL(iowrite8_rep);
-EXPORT_SYMBOL(iowrite16_rep);
-EXPORT_SYMBOL(iowrite32_rep);
-
-void __iomem *ioport_map(unsigned long port, unsigned int len)
-{
-	if (!_IO_IS_VALID(port))
-		return NULL;
-	return (void __iomem *) (port+pci_io_base);
-}
-
-void ioport_unmap(void __iomem *addr)
-{
-	/* Nothing to do */
-}
-EXPORT_SYMBOL(ioport_map);
-EXPORT_SYMBOL(ioport_unmap);
-
-void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
-{
-	unsigned long start = pci_resource_start(dev, bar);
-	unsigned long len = pci_resource_len(dev, bar);
-	unsigned long flags = pci_resource_flags(dev, bar);
-
-	if (!len)
-		return NULL;
-	if (max && len > max)
-		len = max;
-	if (flags & IORESOURCE_IO)
-		return ioport_map(start, len);
-	if (flags & IORESOURCE_MEM)
-		return ioremap(start, len);
-	/* What? */
-	return NULL;
-}
-
-void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
-{
-	/* Nothing to do */
-}
-EXPORT_SYMBOL(pci_iomap);
-EXPORT_SYMBOL(pci_iounmap);
diff --git a/arch/ppc64/kernel/iommu.c b/arch/ppc64/kernel/iommu.c
deleted file mode 100644
index 4d9b438..0000000
--- a/arch/ppc64/kernel/iommu.c
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * arch/ppc64/kernel/iommu.c
- * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
- * 
- * Rewrite, cleanup, new allocation schemes, virtual merging: 
- * Copyright (C) 2004 Olof Johansson, IBM Corporation
- *               and  Ben. Herrenschmidt, IBM Corporation
- *
- * Dynamic DMA mapping support, bus-independent parts.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/iommu.h>
-#include <asm/pci-bridge.h>
-#include <asm/machdep.h>
-
-#define DBG(...)
-
-#ifdef CONFIG_IOMMU_VMERGE
-static int novmerge = 0;
-#else
-static int novmerge = 1;
-#endif
-
-static int __init setup_iommu(char *str)
-{
-	if (!strcmp(str, "novmerge"))
-		novmerge = 1;
-	else if (!strcmp(str, "vmerge"))
-		novmerge = 0;
-	return 1;
-}
-
-__setup("iommu=", setup_iommu);
-
-static unsigned long iommu_range_alloc(struct iommu_table *tbl,
-                                       unsigned long npages,
-                                       unsigned long *handle,
-                                       unsigned int align_order)
-{ 
-	unsigned long n, end, i, start;
-	unsigned long limit;
-	int largealloc = npages > 15;
-	int pass = 0;
-	unsigned long align_mask;
-
-	align_mask = 0xffffffffffffffffl >> (64 - align_order);
-
-	/* This allocator was derived from x86_64's bit string search */
-
-	/* Sanity check */
-	if (unlikely(npages) == 0) {
-		if (printk_ratelimit())
-			WARN_ON(1);
-		return DMA_ERROR_CODE;
-	}
-
-	if (handle && *handle)
-		start = *handle;
-	else
-		start = largealloc ? tbl->it_largehint : tbl->it_hint;
-
-	/* Use only half of the table for small allocs (15 pages or less) */
-	limit = largealloc ? tbl->it_size : tbl->it_halfpoint;
-
-	if (largealloc && start < tbl->it_halfpoint)
-		start = tbl->it_halfpoint;
-
-	/* The case below can happen if we have a small segment appended
-	 * to a large, or when the previous alloc was at the very end of
-	 * the available space. If so, go back to the initial start.
-	 */
-	if (start >= limit)
-		start = largealloc ? tbl->it_largehint : tbl->it_hint;
-	
- again:
-
-	n = find_next_zero_bit(tbl->it_map, limit, start);
-
-	/* Align allocation */
-	n = (n + align_mask) & ~align_mask;
-
-	end = n + npages;
-
-	if (unlikely(end >= limit)) {
-		if (likely(pass < 2)) {
-			/* First failure, just rescan the half of the table.
-			 * Second failure, rescan the other half of the table.
-			 */
-			start = (largealloc ^ pass) ? tbl->it_halfpoint : 0;
-			limit = pass ? tbl->it_size : limit;
-			pass++;
-			goto again;
-		} else {
-			/* Third failure, give up */
-			return DMA_ERROR_CODE;
-		}
-	}
-
-	for (i = n; i < end; i++)
-		if (test_bit(i, tbl->it_map)) {
-			start = i+1;
-			goto again;
-		}
-
-	for (i = n; i < end; i++)
-		__set_bit(i, tbl->it_map);
-
-	/* Bump the hint to a new block for small allocs. */
-	if (largealloc) {
-		/* Don't bump to new block to avoid fragmentation */
-		tbl->it_largehint = end;
-	} else {
-		/* Overflow will be taken care of at the next allocation */
-		tbl->it_hint = (end + tbl->it_blocksize - 1) &
-		                ~(tbl->it_blocksize - 1);
-	}
-
-	/* Update handle for SG allocations */
-	if (handle)
-		*handle = end;
-
-	return n;
-}
-
-static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page,
-		       unsigned int npages, enum dma_data_direction direction,
-		       unsigned int align_order)
-{
-	unsigned long entry, flags;
-	dma_addr_t ret = DMA_ERROR_CODE;
-	
-	spin_lock_irqsave(&(tbl->it_lock), flags);
-
-	entry = iommu_range_alloc(tbl, npages, NULL, align_order);
-
-	if (unlikely(entry == DMA_ERROR_CODE)) {
-		spin_unlock_irqrestore(&(tbl->it_lock), flags);
-		return DMA_ERROR_CODE;
-	}
-
-	entry += tbl->it_offset;	/* Offset into real TCE table */
-	ret = entry << PAGE_SHIFT;	/* Set the return dma address */
-
-	/* Put the TCEs in the HW table */
-	ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & PAGE_MASK,
-			 direction);
-
-
-	/* Flush/invalidate TLB caches if necessary */
-	if (ppc_md.tce_flush)
-		ppc_md.tce_flush(tbl);
-
-	spin_unlock_irqrestore(&(tbl->it_lock), flags);
-
-	/* Make sure updates are seen by hardware */
-	mb();
-
-	return ret;
-}
-
-static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, 
-			 unsigned int npages)
-{
-	unsigned long entry, free_entry;
-	unsigned long i;
-
-	entry = dma_addr >> PAGE_SHIFT;
-	free_entry = entry - tbl->it_offset;
-
-	if (((free_entry + npages) > tbl->it_size) ||
-	    (entry < tbl->it_offset)) {
-		if (printk_ratelimit()) {
-			printk(KERN_INFO "iommu_free: invalid entry\n");
-			printk(KERN_INFO "\tentry     = 0x%lx\n", entry); 
-			printk(KERN_INFO "\tdma_addr  = 0x%lx\n", (u64)dma_addr);
-			printk(KERN_INFO "\tTable     = 0x%lx\n", (u64)tbl);
-			printk(KERN_INFO "\tbus#      = 0x%lx\n", (u64)tbl->it_busno);
-			printk(KERN_INFO "\tsize      = 0x%lx\n", (u64)tbl->it_size);
-			printk(KERN_INFO "\tstartOff  = 0x%lx\n", (u64)tbl->it_offset);
-			printk(KERN_INFO "\tindex     = 0x%lx\n", (u64)tbl->it_index);
-			WARN_ON(1);
-		}
-		return;
-	}
-
-	ppc_md.tce_free(tbl, entry, npages);
-	
-	for (i = 0; i < npages; i++)
-		__clear_bit(free_entry+i, tbl->it_map);
-}
-
-static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
-		unsigned int npages)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&(tbl->it_lock), flags);
-
-	__iommu_free(tbl, dma_addr, npages);
-
-	/* Make sure TLB cache is flushed if the HW needs it. We do
-	 * not do an mb() here on purpose, it is not needed on any of
-	 * the current platforms.
-	 */
-	if (ppc_md.tce_flush)
-		ppc_md.tce_flush(tbl);
-
-	spin_unlock_irqrestore(&(tbl->it_lock), flags);
-}
-
-int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
-		struct scatterlist *sglist, int nelems,
-		enum dma_data_direction direction)
-{
-	dma_addr_t dma_next = 0, dma_addr;
-	unsigned long flags;
-	struct scatterlist *s, *outs, *segstart;
-	int outcount, incount;
-	unsigned long handle;
-
-	BUG_ON(direction == DMA_NONE);
-
-	if ((nelems == 0) || !tbl)
-		return 0;
-
-	outs = s = segstart = &sglist[0];
-	outcount = 1;
-	incount = nelems;
-	handle = 0;
-
-	/* Init first segment length for backout at failure */
-	outs->dma_length = 0;
-
-	DBG("mapping %d elements:\n", nelems);
-
-	spin_lock_irqsave(&(tbl->it_lock), flags);
-
-	for (s = outs; nelems; nelems--, s++) {
-		unsigned long vaddr, npages, entry, slen;
-
-		slen = s->length;
-		/* Sanity check */
-		if (slen == 0) {
-			dma_next = 0;
-			continue;
-		}
-		/* Allocate iommu entries for that segment */
-		vaddr = (unsigned long)page_address(s->page) + s->offset;
-		npages = PAGE_ALIGN(vaddr + slen) - (vaddr & PAGE_MASK);
-		npages >>= PAGE_SHIFT;
-		entry = iommu_range_alloc(tbl, npages, &handle, 0);
-
-		DBG("  - vaddr: %lx, size: %lx\n", vaddr, slen);
-
-		/* Handle failure */
-		if (unlikely(entry == DMA_ERROR_CODE)) {
-			if (printk_ratelimit())
-				printk(KERN_INFO "iommu_alloc failed, tbl %p vaddr %lx"
-				       " npages %lx\n", tbl, vaddr, npages);
-			goto failure;
-		}
-
-		/* Convert entry to a dma_addr_t */
-		entry += tbl->it_offset;
-		dma_addr = entry << PAGE_SHIFT;
-		dma_addr |= s->offset;
-
-		DBG("  - %lx pages, entry: %lx, dma_addr: %lx\n",
-			    npages, entry, dma_addr);
-
-		/* Insert into HW table */
-		ppc_md.tce_build(tbl, entry, npages, vaddr & PAGE_MASK, direction);
-
-		/* If we are in an open segment, try merging */
-		if (segstart != s) {
-			DBG("  - trying merge...\n");
-			/* We cannot merge if:
-			 * - allocated dma_addr isn't contiguous to previous allocation
-			 */
-			if (novmerge || (dma_addr != dma_next)) {
-				/* Can't merge: create a new segment */
-				segstart = s;
-				outcount++; outs++;
-				DBG("    can't merge, new segment.\n");
-			} else {
-				outs->dma_length += s->length;
-				DBG("    merged, new len: %lx\n", outs->dma_length);
-			}
-		}
-
-		if (segstart == s) {
-			/* This is a new segment, fill entries */
-			DBG("  - filling new segment.\n");
-			outs->dma_address = dma_addr;
-			outs->dma_length = slen;
-		}
-
-		/* Calculate next page pointer for contiguous check */
-		dma_next = dma_addr + slen;
-
-		DBG("  - dma next is: %lx\n", dma_next);
-	}
-
-	/* Flush/invalidate TLB caches if necessary */
-	if (ppc_md.tce_flush)
-		ppc_md.tce_flush(tbl);
-
-	spin_unlock_irqrestore(&(tbl->it_lock), flags);
-
-	/* Make sure updates are seen by hardware */
-	mb();
-
-	DBG("mapped %d elements:\n", outcount);
-
-	/* For the sake of iommu_unmap_sg, we clear out the length in the
-	 * next entry of the sglist if we didn't fill the list completely
-	 */
-	if (outcount < incount) {
-		outs++;
-		outs->dma_address = DMA_ERROR_CODE;
-		outs->dma_length = 0;
-	}
-	return outcount;
-
- failure:
-	for (s = &sglist[0]; s <= outs; s++) {
-		if (s->dma_length != 0) {
-			unsigned long vaddr, npages;
-
-			vaddr = s->dma_address & PAGE_MASK;
-			npages = (PAGE_ALIGN(s->dma_address + s->dma_length) - vaddr)
-				>> PAGE_SHIFT;
-			__iommu_free(tbl, vaddr, npages);
-		}
-	}
-	spin_unlock_irqrestore(&(tbl->it_lock), flags);
-	return 0;
-}
-
-
-void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
-		int nelems, enum dma_data_direction direction)
-{
-	unsigned long flags;
-
-	BUG_ON(direction == DMA_NONE);
-
-	if (!tbl)
-		return;
-
-	spin_lock_irqsave(&(tbl->it_lock), flags);
-
-	while (nelems--) {
-		unsigned int npages;
-		dma_addr_t dma_handle = sglist->dma_address;
-
-		if (sglist->dma_length == 0)
-			break;
-		npages = (PAGE_ALIGN(dma_handle + sglist->dma_length)
-			  - (dma_handle & PAGE_MASK)) >> PAGE_SHIFT;
-		__iommu_free(tbl, dma_handle, npages);
-		sglist++;
-	}
-
-	/* Flush/invalidate TLBs if necessary. As for iommu_free(), we
-	 * do not do an mb() here, the affected platforms do not need it
-	 * when freeing.
-	 */
-	if (ppc_md.tce_flush)
-		ppc_md.tce_flush(tbl);
-
-	spin_unlock_irqrestore(&(tbl->it_lock), flags);
-}
-
-/*
- * Build a iommu_table structure.  This contains a bit map which
- * is used to manage allocation of the tce space.
- */
-struct iommu_table *iommu_init_table(struct iommu_table *tbl)
-{
-	unsigned long sz;
-	static int welcomed = 0;
-
-	/* Set aside 1/4 of the table for large allocations. */
-	tbl->it_halfpoint = tbl->it_size * 3 / 4;
-
-	/* number of bytes needed for the bitmap */
-	sz = (tbl->it_size + 7) >> 3;
-
-	tbl->it_map = (unsigned long *)__get_free_pages(GFP_ATOMIC, get_order(sz));
-	if (!tbl->it_map)
-		panic("iommu_init_table: Can't allocate %ld bytes\n", sz);
-
-	memset(tbl->it_map, 0, sz);
-
-	tbl->it_hint = 0;
-	tbl->it_largehint = tbl->it_halfpoint;
-	spin_lock_init(&tbl->it_lock);
-
-	/* Clear the hardware table in case firmware left allocations in it */
-	ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
-
-	if (!welcomed) {
-		printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n",
-		       novmerge ? "disabled" : "enabled");
-		welcomed = 1;
-	}
-
-	return tbl;
-}
-
-void iommu_free_table(struct device_node *dn)
-{
-	struct pci_dn *pdn = dn->data;
-	struct iommu_table *tbl = pdn->iommu_table;
-	unsigned long bitmap_sz, i;
-	unsigned int order;
-
-	if (!tbl || !tbl->it_map) {
-		printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__,
-				dn->full_name);
-		return;
-	}
-
-	/* verify that table contains no entries */
-	/* it_size is in entries, and we're examining 64 at a time */
-	for (i = 0; i < (tbl->it_size/64); i++) {
-		if (tbl->it_map[i] != 0) {
-			printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
-				__FUNCTION__, dn->full_name);
-			break;
-		}
-	}
-
-	/* calculate bitmap size in bytes */
-	bitmap_sz = (tbl->it_size + 7) / 8;
-
-	/* free bitmap */
-	order = get_order(bitmap_sz);
-	free_pages((unsigned long) tbl->it_map, order);
-
-	/* free table */
-	kfree(tbl);
-}
-
-/* Creates TCEs for a user provided buffer.  The user buffer must be
- * contiguous real kernel storage (not vmalloc).  The address of the buffer
- * passed here is the kernel (virtual) address of the buffer.  The buffer
- * need not be page aligned, the dma_addr_t returned will point to the same
- * byte within the page as vaddr.
- */
-dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
-		size_t size, enum dma_data_direction direction)
-{
-	dma_addr_t dma_handle = DMA_ERROR_CODE;
-	unsigned long uaddr;
-	unsigned int npages;
-
-	BUG_ON(direction == DMA_NONE);
-
-	uaddr = (unsigned long)vaddr;
-	npages = PAGE_ALIGN(uaddr + size) - (uaddr & PAGE_MASK);
-	npages >>= PAGE_SHIFT;
-
-	if (tbl) {
-		dma_handle = iommu_alloc(tbl, vaddr, npages, direction, 0);
-		if (dma_handle == DMA_ERROR_CODE) {
-			if (printk_ratelimit())  {
-				printk(KERN_INFO "iommu_alloc failed, "
-						"tbl %p vaddr %p npages %d\n",
-						tbl, vaddr, npages);
-			}
-		} else
-			dma_handle |= (uaddr & ~PAGE_MASK);
-	}
-
-	return dma_handle;
-}
-
-void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
-		size_t size, enum dma_data_direction direction)
-{
-	BUG_ON(direction == DMA_NONE);
-
-	if (tbl)
-		iommu_free(tbl, dma_handle, (PAGE_ALIGN(dma_handle + size) -
-					(dma_handle & PAGE_MASK)) >> PAGE_SHIFT);
-}
-
-/* Allocates a contiguous real buffer and creates mappings over it.
- * Returns the virtual address of the buffer and sets dma_handle
- * to the dma address (mapping) of the first page.
- */
-void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
-		dma_addr_t *dma_handle, gfp_t flag)
-{
-	void *ret = NULL;
-	dma_addr_t mapping;
-	unsigned int npages, order;
-
-	size = PAGE_ALIGN(size);
-	npages = size >> PAGE_SHIFT;
-	order = get_order(size);
-
- 	/*
-	 * Client asked for way too much space.  This is checked later
-	 * anyway.  It is easier to debug here for the drivers than in
-	 * the tce tables.
-	 */
-	if (order >= IOMAP_MAX_ORDER) {
-		printk("iommu_alloc_consistent size too large: 0x%lx\n", size);
-		return NULL;
-	}
-
-	if (!tbl)
-		return NULL;
-
-	/* Alloc enough pages (and possibly more) */
-	ret = (void *)__get_free_pages(flag, order);
-	if (!ret)
-		return NULL;
-	memset(ret, 0, size);
-
-	/* Set up tces to cover the allocated range */
-	mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL, order);
-	if (mapping == DMA_ERROR_CODE) {
-		free_pages((unsigned long)ret, order);
-		ret = NULL;
-	} else
-		*dma_handle = mapping;
-	return ret;
-}
-
-void iommu_free_coherent(struct iommu_table *tbl, size_t size,
-			 void *vaddr, dma_addr_t dma_handle)
-{
-	unsigned int npages;
-
-	if (tbl) {
-		size = PAGE_ALIGN(size);
-		npages = size >> PAGE_SHIFT;
-		iommu_free(tbl, dma_handle, npages);
-		free_pages((unsigned long)vaddr, get_order(size));
-	}
-}
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
deleted file mode 100644
index 511af54..0000000
--- a/arch/ppc64/kernel/kprobes.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- *  Kernel Probes (KProbes)
- *  arch/ppc64/kernel/kprobes.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Copyright (C) IBM Corporation, 2002, 2004
- *
- * 2002-Oct	Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel
- *		Probes initial implementation ( includes contributions from
- *		Rusty Russell).
- * 2004-July	Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes
- *		interface to access function arguments.
- * 2004-Nov	Ananth N Mavinakayanahalli <ananth@in.ibm.com> kprobes port
- *		for PPC64
- */
-
-#include <linux/config.h>
-#include <linux/kprobes.h>
-#include <linux/ptrace.h>
-#include <linux/preempt.h>
-#include <asm/cacheflush.h>
-#include <asm/kdebug.h>
-#include <asm/sstep.h>
-
-static DECLARE_MUTEX(kprobe_mutex);
-DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
-DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
-
-int __kprobes arch_prepare_kprobe(struct kprobe *p)
-{
-	int ret = 0;
-	kprobe_opcode_t insn = *p->addr;
-
-	if ((unsigned long)p->addr & 0x03) {
-		printk("Attempt to register kprobe at an unaligned address\n");
-		ret = -EINVAL;
-	} else if (IS_MTMSRD(insn) || IS_RFID(insn)) {
-		printk("Cannot register a kprobe on rfid or mtmsrd\n");
-		ret = -EINVAL;
-	}
-
-	/* insn must be on a special executable page on ppc64 */
-	if (!ret) {
-		down(&kprobe_mutex);
-		p->ainsn.insn = get_insn_slot();
-		up(&kprobe_mutex);
-		if (!p->ainsn.insn)
-			ret = -ENOMEM;
-	}
-	return ret;
-}
-
-void __kprobes arch_copy_kprobe(struct kprobe *p)
-{
-	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
-	p->opcode = *p->addr;
-}
-
-void __kprobes arch_arm_kprobe(struct kprobe *p)
-{
-	*p->addr = BREAKPOINT_INSTRUCTION;
-	flush_icache_range((unsigned long) p->addr,
-			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
-}
-
-void __kprobes arch_disarm_kprobe(struct kprobe *p)
-{
-	*p->addr = p->opcode;
-	flush_icache_range((unsigned long) p->addr,
-			   (unsigned long) p->addr + sizeof(kprobe_opcode_t));
-}
-
-void __kprobes arch_remove_kprobe(struct kprobe *p)
-{
-	down(&kprobe_mutex);
-	free_insn_slot(p->ainsn.insn);
-	up(&kprobe_mutex);
-}
-
-static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
-{
-	kprobe_opcode_t insn = *p->ainsn.insn;
-
-	regs->msr |= MSR_SE;
-
-	/* single step inline if it is a trap variant */
-	if (is_trap(insn))
-		regs->nip = (unsigned long)p->addr;
-	else
-		regs->nip = (unsigned long)p->ainsn.insn;
-}
-
-static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
-{
-	kcb->prev_kprobe.kp = kprobe_running();
-	kcb->prev_kprobe.status = kcb->kprobe_status;
-	kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr;
-}
-
-static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
-{
-	__get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
-	kcb->kprobe_status = kcb->prev_kprobe.status;
-	kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr;
-}
-
-static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
-				struct kprobe_ctlblk *kcb)
-{
-	__get_cpu_var(current_kprobe) = p;
-	kcb->kprobe_saved_msr = regs->msr;
-}
-
-/* Called with kretprobe_lock held */
-void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
-				      struct pt_regs *regs)
-{
-	struct kretprobe_instance *ri;
-
-	if ((ri = get_free_rp_inst(rp)) != NULL) {
-		ri->rp = rp;
-		ri->task = current;
-		ri->ret_addr = (kprobe_opcode_t *)regs->link;
-
-		/* Replace the return addr with trampoline addr */
-		regs->link = (unsigned long)kretprobe_trampoline;
-		add_rp_inst(ri);
-	} else {
-		rp->nmissed++;
-	}
-}
-
-static inline int kprobe_handler(struct pt_regs *regs)
-{
-	struct kprobe *p;
-	int ret = 0;
-	unsigned int *addr = (unsigned int *)regs->nip;
-	struct kprobe_ctlblk *kcb;
-
-	/*
-	 * We don't want to be preempted for the entire
-	 * duration of kprobe processing
-	 */
-	preempt_disable();
-	kcb = get_kprobe_ctlblk();
-
-	/* Check we're not actually recursing */
-	if (kprobe_running()) {
-		p = get_kprobe(addr);
-		if (p) {
-			kprobe_opcode_t insn = *p->ainsn.insn;
-			if (kcb->kprobe_status == KPROBE_HIT_SS &&
-					is_trap(insn)) {
-				regs->msr &= ~MSR_SE;
-				regs->msr |= kcb->kprobe_saved_msr;
-				goto no_kprobe;
-			}
-			/* We have reentered the kprobe_handler(), since
-			 * another probe was hit while within the handler.
-			 * We here save the original kprobes variables and
-			 * just single step on the instruction of the new probe
-			 * without calling any user handlers.
-			 */
-			save_previous_kprobe(kcb);
-			set_current_kprobe(p, regs, kcb);
-			kcb->kprobe_saved_msr = regs->msr;
-			p->nmissed++;
-			prepare_singlestep(p, regs);
-			kcb->kprobe_status = KPROBE_REENTER;
-			return 1;
-		} else {
-			p = __get_cpu_var(current_kprobe);
-			if (p->break_handler && p->break_handler(p, regs)) {
-				goto ss_probe;
-			}
-		}
-		goto no_kprobe;
-	}
-
-	p = get_kprobe(addr);
-	if (!p) {
-		if (*addr != BREAKPOINT_INSTRUCTION) {
-			/*
-			 * PowerPC has multiple variants of the "trap"
-			 * instruction. If the current instruction is a
-			 * trap variant, it could belong to someone else
-			 */
-			kprobe_opcode_t cur_insn = *addr;
-			if (is_trap(cur_insn))
-		       		goto no_kprobe;
-			/*
-			 * The breakpoint instruction was removed right
-			 * after we hit it.  Another cpu has removed
-			 * either a probepoint or a debugger breakpoint
-			 * at this address.  In either case, no further
-			 * handling of this interrupt is appropriate.
-			 */
-			ret = 1;
-		}
-		/* Not one of ours: let kernel handle it */
-		goto no_kprobe;
-	}
-
-	kcb->kprobe_status = KPROBE_HIT_ACTIVE;
-	set_current_kprobe(p, regs, kcb);
-	if (p->pre_handler && p->pre_handler(p, regs))
-		/* handler has already set things up, so skip ss setup */
-		return 1;
-
-ss_probe:
-	prepare_singlestep(p, regs);
-	kcb->kprobe_status = KPROBE_HIT_SS;
-	return 1;
-
-no_kprobe:
-	preempt_enable_no_resched();
-	return ret;
-}
-
-/*
- * Function return probe trampoline:
- * 	- init_kprobes() establishes a probepoint here
- * 	- When the probed function returns, this probe
- * 		causes the handlers to fire
- */
-void kretprobe_trampoline_holder(void)
-{
-	asm volatile(".global kretprobe_trampoline\n"
-			"kretprobe_trampoline:\n"
-			"nop\n");
-}
-
-/*
- * Called when the probe at kretprobe trampoline is hit
- */
-int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
-{
-        struct kretprobe_instance *ri = NULL;
-        struct hlist_head *head;
-        struct hlist_node *node, *tmp;
-	unsigned long flags, orig_ret_address = 0;
-	unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
-
-	spin_lock_irqsave(&kretprobe_lock, flags);
-        head = kretprobe_inst_table_head(current);
-
-	/*
-	 * It is possible to have multiple instances associated with a given
-	 * task either because an multiple functions in the call path
-	 * have a return probe installed on them, and/or more then one return
-	 * return probe was registered for a target function.
-	 *
-	 * We can handle this because:
-	 *     - instances are always inserted at the head of the list
-	 *     - when multiple return probes are registered for the same
-         *       function, the first instance's ret_addr will point to the
-	 *       real return address, and all the rest will point to
-	 *       kretprobe_trampoline
-	 */
-	hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
-                if (ri->task != current)
-			/* another task is sharing our hash bucket */
-                        continue;
-
-		if (ri->rp && ri->rp->handler)
-			ri->rp->handler(ri, regs);
-
-		orig_ret_address = (unsigned long)ri->ret_addr;
-		recycle_rp_inst(ri);
-
-		if (orig_ret_address != trampoline_address)
-			/*
-			 * This is the real return address. Any other
-			 * instances associated with this task are for
-			 * other calls deeper on the call stack
-			 */
-			break;
-	}
-
-	BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
-	regs->nip = orig_ret_address;
-
-	reset_current_kprobe();
-	spin_unlock_irqrestore(&kretprobe_lock, flags);
-	preempt_enable_no_resched();
-
-        /*
-         * By returning a non-zero value, we are telling
-         * kprobe_handler() that we don't want the post_handler
-         * to run (and have re-enabled preemption)
-         */
-        return 1;
-}
-
-/*
- * Called after single-stepping.  p->addr is the address of the
- * instruction whose first byte has been replaced by the "breakpoint"
- * instruction.  To avoid the SMP problems that can occur when we
- * temporarily put back the original opcode to single-step, we
- * single-stepped a copy of the instruction.  The address of this
- * copy is p->ainsn.insn.
- */
-static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
-{
-	int ret;
-	unsigned int insn = *p->ainsn.insn;
-
-	regs->nip = (unsigned long)p->addr;
-	ret = emulate_step(regs, insn);
-	if (ret == 0)
-		regs->nip = (unsigned long)p->addr + 4;
-}
-
-static inline int post_kprobe_handler(struct pt_regs *regs)
-{
-	struct kprobe *cur = kprobe_running();
-	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
-
-	if (!cur)
-		return 0;
-
-	if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
-		kcb->kprobe_status = KPROBE_HIT_SSDONE;
-		cur->post_handler(cur, regs, 0);
-	}
-
-	resume_execution(cur, regs);
-	regs->msr |= kcb->kprobe_saved_msr;
-
-	/*Restore back the original saved kprobes variables and continue. */
-	if (kcb->kprobe_status == KPROBE_REENTER) {
-		restore_previous_kprobe(kcb);
-		goto out;
-	}
-	reset_current_kprobe();
-out:
-	preempt_enable_no_resched();
-
-	/*
-	 * if somebody else is singlestepping across a probe point, msr
-	 * will have SE set, in which case, continue the remaining processing
-	 * of do_debug, as if this is not a probe hit.
-	 */
-	if (regs->msr & MSR_SE)
-		return 0;
-
-	return 1;
-}
-
-static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
-{
-	struct kprobe *cur = kprobe_running();
-	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
-
-	if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
-		return 1;
-
-	if (kcb->kprobe_status & KPROBE_HIT_SS) {
-		resume_execution(cur, regs);
-		regs->msr &= ~MSR_SE;
-		regs->msr |= kcb->kprobe_saved_msr;
-
-		reset_current_kprobe();
-		preempt_enable_no_resched();
-	}
-	return 0;
-}
-
-/*
- * Wrapper routine to for handling exceptions.
- */
-int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
-				       unsigned long val, void *data)
-{
-	struct die_args *args = (struct die_args *)data;
-	int ret = NOTIFY_DONE;
-
-	switch (val) {
-	case DIE_BPT:
-		if (kprobe_handler(args->regs))
-			ret = NOTIFY_STOP;
-		break;
-	case DIE_SSTEP:
-		if (post_kprobe_handler(args->regs))
-			ret = NOTIFY_STOP;
-		break;
-	case DIE_PAGE_FAULT:
-		/* kprobe_running() needs smp_processor_id() */
-		preempt_disable();
-		if (kprobe_running() &&
-		    kprobe_fault_handler(args->regs, args->trapnr))
-			ret = NOTIFY_STOP;
-		preempt_enable();
-		break;
-	default:
-		break;
-	}
-	return ret;
-}
-
-int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
-{
-	struct jprobe *jp = container_of(p, struct jprobe, kp);
-	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
-
-	memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
-
-	/* setup return addr to the jprobe handler routine */
-	regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry);
-	regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
-
-	return 1;
-}
-
-void __kprobes jprobe_return(void)
-{
-	asm volatile("trap" ::: "memory");
-}
-
-void __kprobes jprobe_return_end(void)
-{
-};
-
-int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
-{
-	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
-
-	/*
-	 * FIXME - we should ideally be validating that we got here 'cos
-	 * of the "trap" in jprobe_return() above, before restoring the
-	 * saved regs...
-	 */
-	memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
-	preempt_enable_no_resched();
-	return 1;
-}
-
-static struct kprobe trampoline_p = {
-	.addr = (kprobe_opcode_t *) &kretprobe_trampoline,
-	.pre_handler = trampoline_probe_handler
-};
-
-int __init arch_init_kprobes(void)
-{
-	return register_kprobe(&trampoline_p);
-}
diff --git a/arch/ppc64/kernel/machine_kexec.c b/arch/ppc64/kernel/machine_kexec.c
deleted file mode 100644
index 07ea035..0000000
--- a/arch/ppc64/kernel/machine_kexec.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * machine_kexec.c - handle transition of Linux booting another kernel
- *
- * Copyright (C) 2004-2005, IBM Corp.
- *
- * Created by: Milton D Miller II
- *
- * This source code is licensed under the GNU General Public License,
- * Version 2.  See the file COPYING for more details.
- */
-
-
-#include <linux/cpumask.h>
-#include <linux/kexec.h>
-#include <linux/smp.h>
-#include <linux/thread_info.h>
-#include <linux/errno.h>
-
-#include <asm/page.h>
-#include <asm/current.h>
-#include <asm/machdep.h>
-#include <asm/cacheflush.h>
-#include <asm/paca.h>
-#include <asm/mmu.h>
-#include <asm/sections.h>	/* _end */
-#include <asm/prom.h>
-#include <asm/smp.h>
-
-#define HASH_GROUP_SIZE 0x80	/* size of each hash group, asm/mmu.h */
-
-/* Have this around till we move it into crash specific file */
-note_buf_t crash_notes[NR_CPUS];
-
-/* Dummy for now. Not sure if we need to have a crash shutdown in here
- * and if what it will achieve. Letting it be now to compile the code
- * in generic kexec environment
- */
-void machine_crash_shutdown(struct pt_regs *regs)
-{
-	/* do nothing right now */
-	/* smp_relase_cpus() if we want smp on panic kernel */
-	/* cpu_irq_down to isolate us until we are ready */
-}
-
-int machine_kexec_prepare(struct kimage *image)
-{
-	int i;
-	unsigned long begin, end;	/* limits of segment */
-	unsigned long low, high;	/* limits of blocked memory range */
-	struct device_node *node;
-	unsigned long *basep;
-	unsigned int *sizep;
-
-	if (!ppc_md.hpte_clear_all)
-		return -ENOENT;
-
-	/*
-	 * Since we use the kernel fault handlers and paging code to
-	 * handle the virtual mode, we must make sure no destination
-	 * overlaps kernel static data or bss.
-	 */
-	for (i = 0; i < image->nr_segments; i++)
-		if (image->segment[i].mem < __pa(_end))
-			return -ETXTBSY;
-
-	/*
-	 * For non-LPAR, we absolutely can not overwrite the mmu hash
-	 * table, since we are still using the bolted entries in it to
-	 * do the copy.  Check that here.
-	 *
-	 * It is safe if the end is below the start of the blocked
-	 * region (end <= low), or if the beginning is after the
-	 * end of the blocked region (begin >= high).  Use the
-	 * boolean identity !(a || b)  === (!a && !b).
-	 */
-	if (htab_address) {
-		low = __pa(htab_address);
-		high = low + (htab_hash_mask + 1) * HASH_GROUP_SIZE;
-
-		for (i = 0; i < image->nr_segments; i++) {
-			begin = image->segment[i].mem;
-			end = begin + image->segment[i].memsz;
-
-			if ((begin < high) && (end > low))
-				return -ETXTBSY;
-		}
-	}
-
-	/* We also should not overwrite the tce tables */
-	for (node = of_find_node_by_type(NULL, "pci"); node != NULL;
-			node = of_find_node_by_type(node, "pci")) {
-		basep = (unsigned long *)get_property(node, "linux,tce-base",
-							NULL);
-		sizep = (unsigned int *)get_property(node, "linux,tce-size",
-							NULL);
-		if (basep == NULL || sizep == NULL)
-			continue;
-
-		low = *basep;
-		high = low + (*sizep);
-
-		for (i = 0; i < image->nr_segments; i++) {
-			begin = image->segment[i].mem;
-			end = begin + image->segment[i].memsz;
-
-			if ((begin < high) && (end > low))
-				return -ETXTBSY;
-		}
-	}
-
-	return 0;
-}
-
-void machine_kexec_cleanup(struct kimage *image)
-{
-	/* we do nothing in prepare that needs to be undone */
-}
-
-#define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE)
-
-static void copy_segments(unsigned long ind)
-{
-	unsigned long entry;
-	unsigned long *ptr;
-	void *dest;
-	void *addr;
-
-	/*
-	 * We rely on kexec_load to create a lists that properly
-	 * initializes these pointers before they are used.
-	 * We will still crash if the list is wrong, but at least
-	 * the compiler will be quiet.
-	 */
-	ptr = NULL;
-	dest = NULL;
-
-	for (entry = ind; !(entry & IND_DONE); entry = *ptr++) {
-		addr = __va(entry & PAGE_MASK);
-
-		switch (entry & IND_FLAGS) {
-		case IND_DESTINATION:
-			dest = addr;
-			break;
-		case IND_INDIRECTION:
-			ptr = addr;
-			break;
-		case IND_SOURCE:
-			copy_page(dest, addr);
-			dest += PAGE_SIZE;
-		}
-	}
-}
-
-void kexec_copy_flush(struct kimage *image)
-{
-	long i, nr_segments = image->nr_segments;
-	struct  kexec_segment ranges[KEXEC_SEGMENT_MAX];
-
-	/* save the ranges on the stack to efficiently flush the icache */
-	memcpy(ranges, image->segment, sizeof(ranges));
-
-	/*
-	 * After this call we may not use anything allocated in dynamic
-	 * memory, including *image.
-	 *
-	 * Only globals and the stack are allowed.
-	 */
-	copy_segments(image->head);
-
-	/*
-	 * we need to clear the icache for all dest pages sometime,
-	 * including ones that were in place on the original copy
-	 */
-	for (i = 0; i < nr_segments; i++)
-		flush_icache_range(ranges[i].mem + KERNELBASE,
-				ranges[i].mem + KERNELBASE +
-				ranges[i].memsz);
-}
-
-#ifdef CONFIG_SMP
-
-/* FIXME: we should schedule this function to be called on all cpus based
- * on calling the interrupts, but we would like to call it off irq level
- * so that the interrupt controller is clean.
- */
-void kexec_smp_down(void *arg)
-{
-	if (ppc_md.cpu_irq_down)
-		ppc_md.cpu_irq_down(1);
-
-	local_irq_disable();
-	kexec_smp_wait();
-	/* NOTREACHED */
-}
-
-static void kexec_prepare_cpus(void)
-{
-	int my_cpu, i, notified=-1;
-
-	smp_call_function(kexec_smp_down, NULL, 0, /* wait */0);
-	my_cpu = get_cpu();
-
-	/* check the others cpus are now down (via paca hw cpu id == -1) */
-	for (i=0; i < NR_CPUS; i++) {
-		if (i == my_cpu)
-			continue;
-
-		while (paca[i].hw_cpu_id != -1) {
-			barrier();
-			if (!cpu_possible(i)) {
-				printk("kexec: cpu %d hw_cpu_id %d is not"
-						" possible, ignoring\n",
-						i, paca[i].hw_cpu_id);
-				break;
-			}
-			if (!cpu_online(i)) {
-				/* Fixme: this can be spinning in
-				 * pSeries_secondary_wait with a paca
-				 * waiting for it to go online.
-				 */
-				printk("kexec: cpu %d hw_cpu_id %d is not"
-						" online, ignoring\n",
-						i, paca[i].hw_cpu_id);
-				break;
-			}
-			if (i != notified) {
-				printk( "kexec: waiting for cpu %d (physical"
-						" %d) to go down\n",
-						i, paca[i].hw_cpu_id);
-				notified = i;
-			}
-		}
-	}
-
-	/* after we tell the others to go down */
-	if (ppc_md.cpu_irq_down)
-		ppc_md.cpu_irq_down(0);
-
-	put_cpu();
-
-	local_irq_disable();
-}
-
-#else /* ! SMP */
-
-static void kexec_prepare_cpus(void)
-{
-	/*
-	 * move the secondarys to us so that we can copy
-	 * the new kernel 0-0x100 safely
-	 *
-	 * do this if kexec in setup.c ?
-	 *
-	 * We need to release the cpus if we are ever going from an
-	 * UP to an SMP kernel.
-	 */
-	smp_release_cpus();
-	if (ppc_md.cpu_irq_down)
-		ppc_md.cpu_irq_down(0);
-	local_irq_disable();
-}
-
-#endif /* SMP */
-
-/*
- * kexec thread structure and stack.
- *
- * We need to make sure that this is 16384-byte aligned due to the
- * way process stacks are handled.  It also must be statically allocated
- * or allocated as part of the kimage, because everything else may be
- * overwritten when we copy the kexec image.  We piggyback on the
- * "init_task" linker section here to statically allocate a stack.
- *
- * We could use a smaller stack if we don't care about anything using
- * current, but that audit has not been performed.
- */
-union thread_union kexec_stack
-	__attribute__((__section__(".data.init_task"))) = { };
-
-/* Our assembly helper, in kexec_stub.S */
-extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start,
-					void *image, void *control,
-					void (*clear_all)(void)) ATTRIB_NORET;
-
-/* too late to fail here */
-void machine_kexec(struct kimage *image)
-{
-
-	/* prepare control code if any */
-
-	/* shutdown other cpus into our wait loop and quiesce interrupts */
-	kexec_prepare_cpus();
-
-	/* switch to a staticly allocated stack.  Based on irq stack code.
-	 * XXX: the task struct will likely be invalid once we do the copy!
-	 */
-	kexec_stack.thread_info.task = current_thread_info()->task;
-	kexec_stack.thread_info.flags = 0;
-
-	/* Some things are best done in assembly.  Finding globals with
-	 * a toc is easier in C, so pass in what we can.
-	 */
-	kexec_sequence(&kexec_stack, image->start, image,
-			page_address(image->control_code_page),
-			ppc_md.hpte_clear_all);
-	/* NOTREACHED */
-}
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
deleted file mode 100644
index 5e089de..0000000
--- a/arch/ppc64/kernel/misc.S
+++ /dev/null
@@ -1,940 +0,0 @@
-/*
- *  arch/ppc/kernel/misc.S
- *
- *  
- *
- * This file contains miscellaneous low-level functions.
- *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
- * and Paul Mackerras.
- * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
- * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) 
- * 
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-#include <linux/config.h>
-#include <linux/sys.h>
-#include <asm/unistd.h>
-#include <asm/errno.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/cache.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-#include <asm/cputable.h>
-#include <asm/thread_info.h>
-
-	.text
-
-/*
- * Returns (address we were linked at) - (address we are running at)
- * for use before the text and data are mapped to KERNELBASE.
- */
-
-_GLOBAL(reloc_offset)
-	mflr	r0
-	bl	1f
-1:	mflr	r3
-	LOADADDR(r4,1b)
-	sub	r3,r4,r3
-	mtlr	r0
-	blr
-
-_GLOBAL(get_msr)
-	mfmsr	r3
-	blr
-
-_GLOBAL(get_dar)
-	mfdar	r3
-	blr
-
-_GLOBAL(get_srr0)
-	mfsrr0  r3
-	blr
-
-_GLOBAL(get_srr1)
-	mfsrr1  r3
-	blr
-	
-_GLOBAL(get_sp)
-	mr	r3,r1
-	blr
-
-#ifdef CONFIG_IRQSTACKS
-_GLOBAL(call_do_softirq)
-	mflr	r0
-	std	r0,16(r1)
-	stdu	r1,THREAD_SIZE-112(r3)
-	mr	r1,r3
-	bl	.__do_softirq
-	ld	r1,0(r1)
-	ld	r0,16(r1)
-	mtlr	r0
-	blr
-
-_GLOBAL(call___do_IRQ)
-	mflr	r0
-	std	r0,16(r1)
-	stdu	r1,THREAD_SIZE-112(r5)
-	mr	r1,r5
-	bl	.__do_IRQ
-	ld	r1,0(r1)
-	ld	r0,16(r1)
-	mtlr	r0
-	blr
-#endif /* CONFIG_IRQSTACKS */
-
-	/*
- * To be called by C code which needs to do some operations with MMU
- * disabled. Note that interrupts have to be disabled by the caller
- * prior to calling us. The code called _MUST_ be in the RMO of course
- * and part of the linear mapping as we don't attempt to translate the
- * stack pointer at all. The function is called with the stack switched
- * to this CPU emergency stack
- *
- * prototype is void *call_with_mmu_off(void *func, void *data);
- *
- * the called function is expected to be of the form
- *
- * void *called(void *data); 
- */
-_GLOBAL(call_with_mmu_off)
-	mflr	r0			/* get link, save it on stackframe */
-	std	r0,16(r1)
-	mr	r1,r5			/* save old stack ptr */
-	ld	r1,PACAEMERGSP(r13)	/* get emerg. stack */
-	subi	r1,r1,STACK_FRAME_OVERHEAD
-	std	r0,16(r1)		/* save link on emerg. stack */
-	std	r5,0(r1)		/* save old stack ptr in backchain */
-	ld	r3,0(r3)		/* get to real function ptr (assume same TOC) */
-	bl	2f			/* we need LR to return, continue at label 2 */
-
-	ld	r0,16(r1)		/* we return here from the call, get LR and */
-	ld	r1,0(r1)		/* .. old stack ptr */
-	mtspr	SPRN_SRR0,r0		/* and get back to virtual mode with these */
-	mfmsr	r4
-	ori	r4,r4,MSR_IR|MSR_DR
-	mtspr	SPRN_SRR1,r4
-	rfid
-
-2:	mtspr	SPRN_SRR0,r3		/* coming from above, enter real mode */
-	mr	r3,r4			/* get parameter */
-	mfmsr	r0
-	ori	r0,r0,MSR_IR|MSR_DR
-	xori	r0,r0,MSR_IR|MSR_DR
-	mtspr	SPRN_SRR1,r0
-	rfid
-
-
-	.section	".toc","aw"
-PPC64_CACHES:
-	.tc		ppc64_caches[TC],ppc64_caches
-	.section	".text"
-
-/*
- * Write any modified data cache blocks out to memory
- * and invalidate the corresponding instruction cache blocks.
- *
- * flush_icache_range(unsigned long start, unsigned long stop)
- *
- *   flush all bytes from start through stop-1 inclusive
- */
-
-_KPROBE(__flush_icache_range)
-
-/*
- * Flush the data cache to memory 
- * 
- * Different systems have different cache line sizes
- * and in some cases i-cache and d-cache line sizes differ from
- * each other.
- */
- 	ld	r10,PPC64_CACHES@toc(r2)
-	lwz	r7,DCACHEL1LINESIZE(r10)/* Get cache line size */
-	addi	r5,r7,-1
-	andc	r6,r3,r5		/* round low to line bdy */
-	subf	r8,r6,r4		/* compute length */
-	add	r8,r8,r5		/* ensure we get enough */
-	lwz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of cache line size */
-	srw.	r8,r8,r9		/* compute line count */
-	beqlr				/* nothing to do? */
-	mtctr	r8
-1:	dcbst	0,r6
-	add	r6,r6,r7
-	bdnz	1b
-	sync
-
-/* Now invalidate the instruction cache */
-	
-	lwz	r7,ICACHEL1LINESIZE(r10)	/* Get Icache line size */
-	addi	r5,r7,-1
-	andc	r6,r3,r5		/* round low to line bdy */
-	subf	r8,r6,r4		/* compute length */
-	add	r8,r8,r5
-	lwz	r9,ICACHEL1LOGLINESIZE(r10)	/* Get log-2 of Icache line size */
-	srw.	r8,r8,r9		/* compute line count */
-	beqlr				/* nothing to do? */
-	mtctr	r8
-2:	icbi	0,r6
-	add	r6,r6,r7
-	bdnz	2b
-	isync
-	blr
-
-	.text
-/*
- * Like above, but only do the D-cache.
- *
- * flush_dcache_range(unsigned long start, unsigned long stop)
- *
- *    flush all bytes from start to stop-1 inclusive
- */
-_GLOBAL(flush_dcache_range)
-
-/*
- * Flush the data cache to memory 
- * 
- * Different systems have different cache line sizes
- */
- 	ld	r10,PPC64_CACHES@toc(r2)
-	lwz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */
-	addi	r5,r7,-1
-	andc	r6,r3,r5		/* round low to line bdy */
-	subf	r8,r6,r4		/* compute length */
-	add	r8,r8,r5		/* ensure we get enough */
-	lwz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of dcache line size */
-	srw.	r8,r8,r9		/* compute line count */
-	beqlr				/* nothing to do? */
-	mtctr	r8
-0:	dcbst	0,r6
-	add	r6,r6,r7
-	bdnz	0b
-	sync
-	blr
-
-/*
- * Like above, but works on non-mapped physical addresses.
- * Use only for non-LPAR setups ! It also assumes real mode
- * is cacheable. Used for flushing out the DART before using
- * it as uncacheable memory 
- *
- * flush_dcache_phys_range(unsigned long start, unsigned long stop)
- *
- *    flush all bytes from start to stop-1 inclusive
- */
-_GLOBAL(flush_dcache_phys_range)
- 	ld	r10,PPC64_CACHES@toc(r2)
-	lwz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */
-	addi	r5,r7,-1
-	andc	r6,r3,r5		/* round low to line bdy */
-	subf	r8,r6,r4		/* compute length */
-	add	r8,r8,r5		/* ensure we get enough */
-	lwz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of dcache line size */
-	srw.	r8,r8,r9		/* compute line count */
-	beqlr				/* nothing to do? */
-	mfmsr	r5			/* Disable MMU Data Relocation */
-	ori	r0,r5,MSR_DR
-	xori	r0,r0,MSR_DR
-	sync
-	mtmsr	r0
-	sync
-	isync
-	mtctr	r8
-0:	dcbst	0,r6
-	add	r6,r6,r7
-	bdnz	0b
-	sync
-	isync
-	mtmsr	r5			/* Re-enable MMU Data Relocation */
-	sync
-	isync
-	blr
-
-_GLOBAL(flush_inval_dcache_range)
- 	ld	r10,PPC64_CACHES@toc(r2)
-	lwz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */
-	addi	r5,r7,-1
-	andc	r6,r3,r5		/* round low to line bdy */
-	subf	r8,r6,r4		/* compute length */
-	add	r8,r8,r5		/* ensure we get enough */
-	lwz	r9,DCACHEL1LOGLINESIZE(r10)/* Get log-2 of dcache line size */
-	srw.	r8,r8,r9		/* compute line count */
-	beqlr				/* nothing to do? */
-	sync
-	isync
-	mtctr	r8
-0:	dcbf	0,r6
-	add	r6,r6,r7
-	bdnz	0b
-	sync
-	isync
-	blr
-
-
-/*
- * Flush a particular page from the data cache to RAM.
- * Note: this is necessary because the instruction cache does *not*
- * snoop from the data cache.
- *
- *	void __flush_dcache_icache(void *page)
- */
-_GLOBAL(__flush_dcache_icache)
-/*
- * Flush the data cache to memory 
- * 
- * Different systems have different cache line sizes
- */
-
-/* Flush the dcache */
- 	ld	r7,PPC64_CACHES@toc(r2)
-	clrrdi	r3,r3,PAGE_SHIFT           	    /* Page align */
-	lwz	r4,DCACHEL1LINESPERPAGE(r7)	/* Get # dcache lines per page */
-	lwz	r5,DCACHEL1LINESIZE(r7)		/* Get dcache line size */
-	mr	r6,r3
-	mtctr	r4
-0:	dcbst	0,r6
-	add	r6,r6,r5
-	bdnz	0b
-	sync
-
-/* Now invalidate the icache */	
-
-	lwz	r4,ICACHEL1LINESPERPAGE(r7)	/* Get # icache lines per page */
-	lwz	r5,ICACHEL1LINESIZE(r7)		/* Get icache line size */
-	mtctr	r4
-1:	icbi	0,r3
-	add	r3,r3,r5
-	bdnz	1b
-	isync
-	blr
-	
-/*
- * I/O string operations
- *
- * insb(port, buf, len)
- * outsb(port, buf, len)
- * insw(port, buf, len)
- * outsw(port, buf, len)
- * insl(port, buf, len)
- * outsl(port, buf, len)
- * insw_ns(port, buf, len)
- * outsw_ns(port, buf, len)
- * insl_ns(port, buf, len)
- * outsl_ns(port, buf, len)
- *
- * The *_ns versions don't do byte-swapping.
- */
-_GLOBAL(_insb)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,1
-	blelr-
-00:	lbz	r5,0(r3)
-	eieio
-	stbu	r5,1(r4)
-	bdnz	00b
-	twi	0,r5,0
-	isync
-	blr
-
-_GLOBAL(_outsb)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,1
-	blelr-
-00:	lbzu	r5,1(r4)
-	stb	r5,0(r3)
-	bdnz	00b
-	sync
-	blr	
-
-_GLOBAL(_insw)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,2
-	blelr-
-00:	lhbrx	r5,0,r3
-	eieio
-	sthu	r5,2(r4)
-	bdnz	00b
-	twi	0,r5,0
-	isync
-	blr
-
-_GLOBAL(_outsw)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,2
-	blelr-
-00:	lhzu	r5,2(r4)
-	sthbrx	r5,0,r3	
-	bdnz	00b
-	sync
-	blr	
-
-_GLOBAL(_insl)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,4
-	blelr-
-00:	lwbrx	r5,0,r3
-	eieio
-	stwu	r5,4(r4)
-	bdnz	00b
-	twi	0,r5,0
-	isync
-	blr
-
-_GLOBAL(_outsl)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,4
-	blelr-
-00:	lwzu	r5,4(r4)
-	stwbrx	r5,0,r3
-	bdnz	00b
-	sync
-	blr	
-
-/* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */
-_GLOBAL(_insw_ns)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,2
-	blelr-
-00:	lhz	r5,0(r3)
-	eieio
-	sthu	r5,2(r4)
-	bdnz	00b
-	twi	0,r5,0
-	isync
-	blr
-
-/* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */
-_GLOBAL(_outsw_ns)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,2
-	blelr-
-00:	lhzu	r5,2(r4)
-	sth	r5,0(r3)
-	bdnz	00b
-	sync
-	blr	
-
-_GLOBAL(_insl_ns)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,4
-	blelr-
-00:	lwz	r5,0(r3)
-	eieio
-	stwu	r5,4(r4)
-	bdnz	00b
-	twi	0,r5,0
-	isync
-	blr
-
-_GLOBAL(_outsl_ns)
-	cmpwi	0,r5,0
-	mtctr	r5
-	subi	r4,r4,4
-	blelr-
-00:	lwzu	r5,4(r4)
-	stw	r5,0(r3)
-	bdnz	00b
-	sync
-	blr	
-
-/*
- * identify_cpu and calls setup_cpu
- * In:	r3 = base of the cpu_specs array
- *	r4 = address of cur_cpu_spec
- *	r5 = relocation offset
- */
-_GLOBAL(identify_cpu)
-	mfpvr	r7
-1:
-	lwz	r8,CPU_SPEC_PVR_MASK(r3)
-	and	r8,r8,r7
-	lwz	r9,CPU_SPEC_PVR_VALUE(r3)
-	cmplw	0,r9,r8
-	beq	1f
-	addi	r3,r3,CPU_SPEC_ENTRY_SIZE
-	b	1b
-1:
-	add	r0,r3,r5
-	std	r0,0(r4)
-	ld	r4,CPU_SPEC_SETUP(r3)
-	sub	r4,r4,r5
-	ld	r4,0(r4)
-	sub	r4,r4,r5
-	mtctr	r4
-	/* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */
-	mr	r4,r3
-	mr	r3,r5
-	bctr
-
-/*
- * do_cpu_ftr_fixups - goes through the list of CPU feature fixups
- * and writes nop's over sections of code that don't apply for this cpu.
- * r3 = data offset (not changed)
- */
-_GLOBAL(do_cpu_ftr_fixups)
-	/* Get CPU 0 features */
-	LOADADDR(r6,cur_cpu_spec)
-	sub	r6,r6,r3
-	ld	r4,0(r6)
-	sub	r4,r4,r3
-	ld	r4,CPU_SPEC_FEATURES(r4)
-	/* Get the fixup table */
-	LOADADDR(r6,__start___ftr_fixup)
-	sub	r6,r6,r3
-	LOADADDR(r7,__stop___ftr_fixup)
-	sub	r7,r7,r3
-	/* Do the fixup */
-1:	cmpld	r6,r7
-	bgelr
-	addi	r6,r6,32
-	ld	r8,-32(r6)	/* mask */
-	and	r8,r8,r4
-	ld	r9,-24(r6)	/* value */
-	cmpld	r8,r9
-	beq	1b
-	ld	r8,-16(r6)	/* section begin */
-	ld	r9,-8(r6)	/* section end */
-	subf.	r9,r8,r9
-	beq	1b
-	/* write nops over the section of code */
-	/* todo: if large section, add a branch at the start of it */
-	srwi	r9,r9,2
-	mtctr	r9
-	sub	r8,r8,r3
-	lis	r0,0x60000000@h	/* nop */
-3:	stw	r0,0(r8)
-	andi.	r10,r4,CPU_FTR_SPLIT_ID_CACHE@l
-	beq	2f
-	dcbst	0,r8		/* suboptimal, but simpler */
-	sync
-	icbi	0,r8
-2:	addi	r8,r8,4
-	bdnz	3b
-	sync			/* additional sync needed on g4 */
-	isync
-	b	1b
-
-#if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE)
-/*
- * Do an IO access in real mode
- */
-_GLOBAL(real_readb)
-	mfmsr	r7
-	ori	r0,r7,MSR_DR
-	xori	r0,r0,MSR_DR
-	sync
-	mtmsrd	r0
-	sync
-	isync
-	mfspr	r6,SPRN_HID4
-	rldicl	r5,r6,32,0
-	ori	r5,r5,0x100
-	rldicl	r5,r5,32,0
-	sync
-	mtspr	SPRN_HID4,r5
-	isync
-	slbia
-	isync
-	lbz	r3,0(r3)
-	sync
-	mtspr	SPRN_HID4,r6
-	isync
-	slbia
-	isync
-	mtmsrd	r7
-	sync
-	isync
-	blr
-
-/*
- * Do an IO access in real mode
- */
-_GLOBAL(real_writeb)
-	mfmsr	r7
-	ori	r0,r7,MSR_DR
-	xori	r0,r0,MSR_DR
-	sync
-	mtmsrd	r0
-	sync
-	isync
-	mfspr	r6,SPRN_HID4
-	rldicl	r5,r6,32,0
-	ori	r5,r5,0x100
-	rldicl	r5,r5,32,0
-	sync
-	mtspr	SPRN_HID4,r5
-	isync
-	slbia
-	isync
-	stb	r3,0(r4)
-	sync
-	mtspr	SPRN_HID4,r6
-	isync
-	slbia
-	isync
-	mtmsrd	r7
-	sync
-	isync
-	blr
-#endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */
-
-/*
- * SCOM access functions for 970 (FX only for now)
- *
- * unsigned long scom970_read(unsigned int address);
- * void scom970_write(unsigned int address, unsigned long value);
- *
- * The address passed in is the 24 bits register address. This code
- * is 970 specific and will not check the status bits, so you should
- * know what you are doing.
- */
-_GLOBAL(scom970_read)
-	/* interrupts off */
-	mfmsr	r4
-	ori	r0,r4,MSR_EE
-	xori	r0,r0,MSR_EE
-	mtmsrd	r0,1
-
-	/* rotate 24 bits SCOM address 8 bits left and mask out it's low 8 bits
-	 * (including parity). On current CPUs they must be 0'd,
-	 * and finally or in RW bit
-	 */
-	rlwinm	r3,r3,8,0,15
-	ori	r3,r3,0x8000
-
-	/* do the actual scom read */
-	sync
-	mtspr	SPRN_SCOMC,r3
-	isync
-	mfspr	r3,SPRN_SCOMD
-	isync
-	mfspr	r0,SPRN_SCOMC
-	isync
-
-	/* XXX:	fixup result on some buggy 970's (ouch ! we lost a bit, bah
-	 * that's the best we can do). Not implemented yet as we don't use
-	 * the scom on any of the bogus CPUs yet, but may have to be done
-	 * ultimately
-	 */
-
-	/* restore interrupts */
-	mtmsrd	r4,1
-	blr
-
-
-_GLOBAL(scom970_write)
-	/* interrupts off */
-	mfmsr	r5
-	ori	r0,r5,MSR_EE
-	xori	r0,r0,MSR_EE
-	mtmsrd	r0,1
-
-	/* rotate 24 bits SCOM address 8 bits left and mask out it's low 8 bits
-	 * (including parity). On current CPUs they must be 0'd.
-	 */
-
-	rlwinm	r3,r3,8,0,15
-
-	sync
-	mtspr	SPRN_SCOMD,r4      /* write data */
-	isync
-	mtspr	SPRN_SCOMC,r3      /* write command */
-	isync
-	mfspr	3,SPRN_SCOMC
-	isync
-
-	/* restore interrupts */
-	mtmsrd	r5,1
-	blr
-
-
-/*
- * Create a kernel thread
- *   kernel_thread(fn, arg, flags)
- */
-_GLOBAL(kernel_thread)
-	std	r29,-24(r1)
-	std	r30,-16(r1)
-	stdu	r1,-STACK_FRAME_OVERHEAD(r1)
-	mr	r29,r3
-	mr	r30,r4
-	ori	r3,r5,CLONE_VM	/* flags */
-	oris	r3,r3,(CLONE_UNTRACED>>16)
-	li	r4,0		/* new sp (unused) */
-	li	r0,__NR_clone
-	sc
-	cmpdi	0,r3,0		/* parent or child? */
-	bne	1f		/* return if parent */
-	li	r0,0
-	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
-	ld	r2,8(r29)
-	ld	r29,0(r29)
-	mtlr	r29              /* fn addr in lr */
-	mr	r3,r30	        /* load arg and call fn */
-	blrl
-	li	r0,__NR_exit	/* exit after child exits */
-        li	r3,0
-	sc
-1:	addi	r1,r1,STACK_FRAME_OVERHEAD	
-	ld	r29,-24(r1)
-	ld	r30,-16(r1)
-	blr
-
-/*
- * disable_kernel_fp()
- * Disable the FPU.
- */
-_GLOBAL(disable_kernel_fp)
-	mfmsr	r3
-	rldicl	r0,r3,(63-MSR_FP_LG),1
-	rldicl	r3,r0,(MSR_FP_LG+1),0
-	mtmsrd	r3			/* disable use of fpu now */
-	isync
-	blr
-
-#ifdef CONFIG_ALTIVEC
-
-#if 0 /* this has no callers for now */
-/*
- * disable_kernel_altivec()
- * Disable the VMX.
- */
-_GLOBAL(disable_kernel_altivec)
-	mfmsr	r3
-	rldicl	r0,r3,(63-MSR_VEC_LG),1
-	rldicl	r3,r0,(MSR_VEC_LG+1),0
-	mtmsrd	r3			/* disable use of VMX now */
-	isync
-	blr
-#endif /* 0 */
-
-/*
- * giveup_altivec(tsk)
- * Disable VMX for the task given as the argument,
- * and save the vector registers in its thread_struct.
- * Enables the VMX for use in the kernel on return.
- */
-_GLOBAL(giveup_altivec)
-	mfmsr	r5
-	oris	r5,r5,MSR_VEC@h
-	mtmsrd	r5			/* enable use of VMX now */
-	isync
-	cmpdi	0,r3,0
-	beqlr-				/* if no previous owner, done */
-	addi	r3,r3,THREAD		/* want THREAD of task */
-	ld	r5,PT_REGS(r3)
-	cmpdi	0,r5,0
-	SAVE_32VRS(0,r4,r3)
-	mfvscr	vr0
-	li	r4,THREAD_VSCR
-	stvx	vr0,r4,r3
-	beq	1f
-	ld	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-	lis	r3,MSR_VEC@h
-	andc	r4,r4,r3		/* disable FP for previous task */
-	std	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
-	li	r5,0
-	ld	r4,last_task_used_altivec@got(r2)
-	std	r5,0(r4)
-#endif /* CONFIG_SMP */
-	blr
-
-#endif /* CONFIG_ALTIVEC */
-
-_GLOBAL(__setup_cpu_power3)
-	blr
-
-_GLOBAL(execve)
-	li	r0,__NR_execve
-	sc
-	bnslr
-	neg	r3,r3
-	blr
-
-/* kexec_wait(phys_cpu)
- *
- * wait for the flag to change, indicating this kernel is going away but
- * the slave code for the next one is at addresses 0 to 100.
- *
- * This is used by all slaves.
- *
- * Physical (hardware) cpu id should be in r3.
- */
-_GLOBAL(kexec_wait)
-	bl	1f
-1:	mflr	r5
-	addi	r5,r5,kexec_flag-1b
-
-99:	HMT_LOW
-#ifdef CONFIG_KEXEC		/* use no memory without kexec */
-	lwz	r4,0(r5)
-	cmpwi	0,r4,0
-	bnea	0x60
-#endif
-	b	99b
-
-/* this can be in text because we won't change it until we are
- * running in real anyways
- */
-kexec_flag:
-	.long	0
-
-
-#ifdef CONFIG_KEXEC
-
-/* kexec_smp_wait(void)
- *
- * call with interrupts off
- * note: this is a terminal routine, it does not save lr
- *
- * get phys id from paca
- * set paca id to -1 to say we got here
- * switch to real mode
- * join other cpus in kexec_wait(phys_id)
- */
-_GLOBAL(kexec_smp_wait)
-	lhz	r3,PACAHWCPUID(r13)
-	li	r4,-1
-	sth	r4,PACAHWCPUID(r13)	/* let others know we left */
-	bl	real_mode
-	b	.kexec_wait
-
-/*
- * switch to real mode (turn mmu off)
- * we use the early kernel trick that the hardware ignores bits
- * 0 and 1 (big endian) of the effective address in real mode
- *
- * don't overwrite r3 here, it is live for kexec_wait above.
- */
-real_mode:	/* assume normal blr return */
-1:	li	r9,MSR_RI
-	li	r10,MSR_DR|MSR_IR
-	mflr	r11		/* return address to SRR0 */
-	mfmsr	r12
-	andc	r9,r12,r9
-	andc	r10,r12,r10
-
-	mtmsrd	r9,1
-	mtspr	SPRN_SRR1,r10
-	mtspr	SPRN_SRR0,r11
-	rfid
-
-
-/*
- * kexec_sequence(newstack, start, image, control, clear_all())
- *
- * does the grungy work with stack switching and real mode switches
- * also does simple calls to other code
- */
-
-_GLOBAL(kexec_sequence)
-	mflr	r0
-	std	r0,16(r1)
-
-	/* switch stacks to newstack -- &kexec_stack.stack */
-	stdu	r1,THREAD_SIZE-112(r3)
-	mr	r1,r3
-
-	li	r0,0
-	std	r0,16(r1)
-
-	/* save regs for local vars on new stack.
-	 * yes, we won't go back, but ...
-	 */
-	std	r31,-8(r1)
-	std	r30,-16(r1)
-	std	r29,-24(r1)
-	std	r28,-32(r1)
-	std	r27,-40(r1)
-	std	r26,-48(r1)
-	std	r25,-56(r1)
-
-	stdu	r1,-112-64(r1)
-
-	/* save args into preserved regs */
-	mr	r31,r3			/* newstack (both) */
-	mr	r30,r4			/* start (real) */
-	mr	r29,r5			/* image (virt) */
-	mr	r28,r6			/* control, unused */
-	mr	r27,r7			/* clear_all() fn desc */
-	mr	r26,r8			/* spare */
-	lhz	r25,PACAHWCPUID(r13)	/* get our phys cpu from paca */
-
-	/* disable interrupts, we are overwriting kernel data next */
-	mfmsr	r3
-	rlwinm	r3,r3,0,17,15
-	mtmsrd	r3,1
-
-	/* copy dest pages, flush whole dest image */
-	mr	r3,r29
-	bl	.kexec_copy_flush	/* (image) */
-
-	/* turn off mmu */
-	bl	real_mode
-
-	/* clear out hardware hash page table and tlb */
-	ld	r5,0(r27)		/* deref function descriptor */
-	mtctr	r5
-	bctrl				/* ppc_md.hash_clear_all(void); */
-
-/*
- *   kexec image calling is:
- *      the first 0x100 bytes of the entry point are copied to 0
- *
- *      all slaves branch to slave = 0x60 (absolute)
- *              slave(phys_cpu_id);
- *
- *      master goes to start = entry point
- *              start(phys_cpu_id, start, 0);
- *
- *
- *   a wrapper is needed to call existing kernels, here is an approximate
- *   description of one method:
- *
- * v2: (2.6.10)
- *   start will be near the boot_block (maybe 0x100 bytes before it?)
- *   it will have a 0x60, which will b to boot_block, where it will wait
- *   and 0 will store phys into struct boot-block and load r3 from there,
- *   copy kernel 0-0x100 and tell slaves to back down to 0x60 again
- *
- * v1: (2.6.9)
- *    boot block will have all cpus scanning device tree to see if they
- *    are the boot cpu ?????
- *    other device tree differences (prop sizes, va vs pa, etc)...
- */
-
-	/* copy  0x100 bytes starting at start to 0 */
-	li	r3,0
-	mr	r4,r30
-	li	r5,0x100
-	li	r6,0
-	bl	.copy_and_flush	/* (dest, src, copy limit, start offset) */
-1:	/* assume normal blr return */
-
-	/* release other cpus to the new kernel secondary start at 0x60 */
-	mflr	r5
-	li	r6,1
-	stw	r6,kexec_flag-1b(5)
-	mr	r3,r25	# my phys cpu
-	mr	r4,r30	# start, aka phys mem offset
-	mtlr	4
-	li	r5,0
-	blr	/* image->start(physid, image->start, 0); */
-#endif /* CONFIG_KEXEC */
diff --git a/arch/ppc64/kernel/module.c b/arch/ppc64/kernel/module.c
deleted file mode 100644
index 928b858..0000000
--- a/arch/ppc64/kernel/module.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/*  Kernel module help for PPC64.
-    Copyright (C) 2001, 2003 Rusty Russell IBM Corporation.
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-#include <linux/module.h>
-#include <linux/elf.h>
-#include <linux/moduleloader.h>
-#include <linux/err.h>
-#include <linux/vmalloc.h>
-#include <asm/module.h>
-#include <asm/uaccess.h>
-
-/* FIXME: We don't do .init separately.  To do this, we'd need to have
-   a separate r2 value in the init and core section, and stub between
-   them, too.
-
-   Using a magic allocator which places modules within 32MB solves
-   this, and makes other things simpler.  Anton?
-   --RR.  */
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(fmt , ...)
-#endif
-
-/* There's actually a third entry here, but it's unused */
-struct ppc64_opd_entry
-{
-	unsigned long funcaddr;
-	unsigned long r2;
-};
-
-/* Like PPC32, we need little trampolines to do > 24-bit jumps (into
-   the kernel itself).  But on PPC64, these need to be used for every
-   jump, actually, to reset r2 (TOC+0x8000). */
-struct ppc64_stub_entry
-{
-	/* 28 byte jump instruction sequence (7 instructions) */
-	unsigned char jump[28];
-	unsigned char unused[4];
-	/* Data for the above code */
-	struct ppc64_opd_entry opd;
-};
-
-/* We use a stub to fix up r2 (TOC ptr) and to jump to the (external)
-   function which may be more than 24-bits away.  We could simply
-   patch the new r2 value and function pointer into the stub, but it's
-   significantly shorter to put these values at the end of the stub
-   code, and patch the stub address (32-bits relative to the TOC ptr,
-   r2) into the stub. */
-static struct ppc64_stub_entry ppc64_stub =
-{ .jump = {
-	0x3d, 0x82, 0x00, 0x00, /* addis   r12,r2, <high> */
-	0x39, 0x8c, 0x00, 0x00, /* addi    r12,r12, <low> */
-	/* Save current r2 value in magic place on the stack. */
-	0xf8, 0x41, 0x00, 0x28, /* std     r2,40(r1) */
-	0xe9, 0x6c, 0x00, 0x20, /* ld      r11,32(r12) */
-	0xe8, 0x4c, 0x00, 0x28, /* ld      r2,40(r12) */
-	0x7d, 0x69, 0x03, 0xa6, /* mtctr   r11 */
-	0x4e, 0x80, 0x04, 0x20  /* bctr */
-} };
-
-/* Count how many different 24-bit relocations (different symbol,
-   different addend) */
-static unsigned int count_relocs(const Elf64_Rela *rela, unsigned int num)
-{
-	unsigned int i, j, ret = 0;
-
-	/* FIXME: Only count external ones --RR */
-	/* Sure, this is order(n^2), but it's usually short, and not
-           time critical */
-	for (i = 0; i < num; i++) {
-		/* Only count 24-bit relocs, others don't need stubs */
-		if (ELF64_R_TYPE(rela[i].r_info) != R_PPC_REL24)
-			continue;
-		for (j = 0; j < i; j++) {
-			/* If this addend appeared before, it's
-                           already been counted */
-			if (rela[i].r_info == rela[j].r_info
-			    && rela[i].r_addend == rela[j].r_addend)
-				break;
-		}
-		if (j == i) ret++;
-	}
-	return ret;
-}
-
-void *module_alloc(unsigned long size)
-{
-	if (size == 0)
-		return NULL;
-
-	return vmalloc_exec(size);
-}
-
-/* Free memory returned from module_alloc */
-void module_free(struct module *mod, void *module_region)
-{
-	vfree(module_region);
-	/* FIXME: If module_region == mod->init_region, trim exception
-           table entries. */
-}
-
-/* Get size of potential trampolines required. */
-static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
-				    const Elf64_Shdr *sechdrs)
-{
-	/* One extra reloc so it's always 0-funcaddr terminated */
-	unsigned long relocs = 1;
-	unsigned i;
-
-	/* Every relocated section... */
-	for (i = 1; i < hdr->e_shnum; i++) {
-		if (sechdrs[i].sh_type == SHT_RELA) {
-			DEBUGP("Found relocations in section %u\n", i);
-			DEBUGP("Ptr: %p.  Number: %lu\n",
-			       (void *)sechdrs[i].sh_addr,
-			       sechdrs[i].sh_size / sizeof(Elf64_Rela));
-			relocs += count_relocs((void *)sechdrs[i].sh_addr,
-					       sechdrs[i].sh_size
-					       / sizeof(Elf64_Rela));
-		}
-	}
-
-	DEBUGP("Looks like a total of %lu stubs, max\n", relocs);
-	return relocs * sizeof(struct ppc64_stub_entry);
-}
-
-static void dedotify_versions(struct modversion_info *vers,
-			      unsigned long size)
-{
-	struct modversion_info *end;
-
-	for (end = (void *)vers + size; vers < end; vers++)
-		if (vers->name[0] == '.')
-			memmove(vers->name, vers->name+1, strlen(vers->name));
-}
-
-/* Undefined symbols which refer to .funcname, hack to funcname */
-static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab)
-{
-	unsigned int i;
-
-	for (i = 1; i < numsyms; i++) {
-		if (syms[i].st_shndx == SHN_UNDEF) {
-			char *name = strtab + syms[i].st_name;
-			if (name[0] == '.')
-				memmove(name, name+1, strlen(name));
-		}
-	}
-}
-
-int module_frob_arch_sections(Elf64_Ehdr *hdr,
-			      Elf64_Shdr *sechdrs,
-			      char *secstrings,
-			      struct module *me)
-{
-	unsigned int i;
-
-	/* Find .toc and .stubs sections, symtab and strtab */
-	for (i = 1; i < hdr->e_shnum; i++) {
-		char *p;
-		if (strcmp(secstrings + sechdrs[i].sh_name, ".stubs") == 0)
-			me->arch.stubs_section = i;
-		else if (strcmp(secstrings + sechdrs[i].sh_name, ".toc") == 0)
-			me->arch.toc_section = i;
-		else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0)
-			dedotify_versions((void *)hdr + sechdrs[i].sh_offset,
-					  sechdrs[i].sh_size);
-
-		/* We don't handle .init for the moment: rename to _init */
-		while ((p = strstr(secstrings + sechdrs[i].sh_name, ".init")))
-			p[0] = '_';
-
-		if (sechdrs[i].sh_type == SHT_SYMTAB)
-			dedotify((void *)hdr + sechdrs[i].sh_offset,
-				 sechdrs[i].sh_size / sizeof(Elf64_Sym),
-				 (void *)hdr
-				 + sechdrs[sechdrs[i].sh_link].sh_offset);
-	}
-	if (!me->arch.stubs_section || !me->arch.toc_section) {
-		printk("%s: doesn't contain .toc or .stubs.\n", me->name);
-		return -ENOEXEC;
-	}
-
-	/* Override the stubs size */
-	sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs);
-	return 0;
-}
-
-int apply_relocate(Elf64_Shdr *sechdrs,
-		   const char *strtab,
-		   unsigned int symindex,
-		   unsigned int relsec,
-		   struct module *me)
-{
-	printk(KERN_ERR "%s: Non-ADD RELOCATION unsupported\n", me->name);
-	return -ENOEXEC;
-}
-
-/* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this
-   gives the value maximum span in an instruction which uses a signed
-   offset) */
-static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me)
-{
-	return sechdrs[me->arch.toc_section].sh_addr + 0x8000;
-}
-
-/* Both low and high 16 bits are added as SIGNED additions, so if low
-   16 bits has high bit set, high 16 bits must be adjusted.  These
-   macros do that (stolen from binutils). */
-#define PPC_LO(v) ((v) & 0xffff)
-#define PPC_HI(v) (((v) >> 16) & 0xffff)
-#define PPC_HA(v) PPC_HI ((v) + 0x8000)
-
-/* Patch stub to reference function and correct r2 value. */
-static inline int create_stub(Elf64_Shdr *sechdrs,
-			      struct ppc64_stub_entry *entry,
-			      struct ppc64_opd_entry *opd,
-			      struct module *me)
-{
-	Elf64_Half *loc1, *loc2;
-	long reladdr;
-
-	*entry = ppc64_stub;
-
-	loc1 = (Elf64_Half *)&entry->jump[2];
-	loc2 = (Elf64_Half *)&entry->jump[6];
-
-	/* Stub uses address relative to r2. */
-	reladdr = (unsigned long)entry - my_r2(sechdrs, me);
-	if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) {
-		printk("%s: Address %p of stub out of range of %p.\n",
-		       me->name, (void *)reladdr, (void *)my_r2);
-		return 0;
-	}
-	DEBUGP("Stub %p get data from reladdr %li\n", entry, reladdr);
-
-	*loc1 = PPC_HA(reladdr);
-	*loc2 = PPC_LO(reladdr);
-	entry->opd.funcaddr = opd->funcaddr;
-	entry->opd.r2 = opd->r2;
-	return 1;
-}
-
-/* Create stub to jump to function described in this OPD: we need the
-   stub to set up the TOC ptr (r2) for the function. */
-static unsigned long stub_for_addr(Elf64_Shdr *sechdrs,
-				   unsigned long opdaddr,
-				   struct module *me)
-{
-	struct ppc64_stub_entry *stubs;
-	struct ppc64_opd_entry *opd = (void *)opdaddr;
-	unsigned int i, num_stubs;
-
-	num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*stubs);
-
-	/* Find this stub, or if that fails, the next avail. entry */
-	stubs = (void *)sechdrs[me->arch.stubs_section].sh_addr;
-	for (i = 0; stubs[i].opd.funcaddr; i++) {
-		BUG_ON(i >= num_stubs);
-
-		if (stubs[i].opd.funcaddr == opd->funcaddr)
-			return (unsigned long)&stubs[i];
-	}
-
-	if (!create_stub(sechdrs, &stubs[i], opd, me))
-		return 0;
-
-	return (unsigned long)&stubs[i];
-}
-
-/* We expect a noop next: if it is, replace it with instruction to
-   restore r2. */
-static int restore_r2(u32 *instruction, struct module *me)
-{
-	if (*instruction != 0x60000000) {
-		printk("%s: Expect noop after relocate, got %08x\n",
-		       me->name, *instruction);
-		return 0;
-	}
-	*instruction = 0xe8410028;	/* ld r2,40(r1) */
-	return 1;
-}
-
-int apply_relocate_add(Elf64_Shdr *sechdrs,
-		       const char *strtab,
-		       unsigned int symindex,
-		       unsigned int relsec,
-		       struct module *me)
-{
-	unsigned int i;
-	Elf64_Rela *rela = (void *)sechdrs[relsec].sh_addr;
-	Elf64_Sym *sym;
-	unsigned long *location;
-	unsigned long value;
-
-	DEBUGP("Applying ADD relocate section %u to %u\n", relsec,
-	       sechdrs[relsec].sh_info);
-	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
-		/* This is where to make the change */
-		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
-			+ rela[i].r_offset;
-		/* This is the symbol it is referring to */
-		sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
-			+ ELF64_R_SYM(rela[i].r_info);
-
-		DEBUGP("RELOC at %p: %li-type as %s (%lu) + %li\n",
-		       location, (long)ELF64_R_TYPE(rela[i].r_info),
-		       strtab + sym->st_name, (unsigned long)sym->st_value,
-		       (long)rela[i].r_addend);
-
-		/* `Everything is relative'. */
-		value = sym->st_value + rela[i].r_addend;
-
-		switch (ELF64_R_TYPE(rela[i].r_info)) {
-		case R_PPC64_ADDR32:
-			/* Simply set it */
-			*(u32 *)location = value;
-			break;
-			
-		case R_PPC64_ADDR64:
-			/* Simply set it */
-			*(unsigned long *)location = value;
-			break;
-
-		case R_PPC64_TOC:
-			*(unsigned long *)location = my_r2(sechdrs, me);
-			break;
-
-		case R_PPC64_TOC16:
-			/* Subtact TOC pointer */
-			value -= my_r2(sechdrs, me);
-			if (value + 0x8000 > 0xffff) {
-				printk("%s: bad TOC16 relocation (%lu)\n",
-				       me->name, value);
-				return -ENOEXEC;
-			}
-			*((uint16_t *) location)
-				= (*((uint16_t *) location) & ~0xffff)
-				| (value & 0xffff);
-			break;
-
-		case R_PPC64_TOC16_DS:
-			/* Subtact TOC pointer */
-			value -= my_r2(sechdrs, me);
-			if ((value & 3) != 0 || value + 0x8000 > 0xffff) {
-				printk("%s: bad TOC16_DS relocation (%lu)\n",
-				       me->name, value);
-				return -ENOEXEC;
-			}
-			*((uint16_t *) location)
-				= (*((uint16_t *) location) & ~0xfffc)
-				| (value & 0xfffc);
-			break;
-
-		case R_PPC_REL24:
-			/* FIXME: Handle weak symbols here --RR */
-			if (sym->st_shndx == SHN_UNDEF) {
-				/* External: go via stub */
-				value = stub_for_addr(sechdrs, value, me);
-				if (!value)
-					return -ENOENT;
-				if (!restore_r2((u32 *)location + 1, me))
-					return -ENOEXEC;
-			}
-
-			/* Convert value to relative */
-			value -= (unsigned long)location;
-			if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0){
-				printk("%s: REL24 %li out of range!\n",
-				       me->name, (long int)value);
-				return -ENOEXEC;
-			}
-
-			/* Only replace bits 2 through 26 */
-			*(uint32_t *)location 
-				= (*(uint32_t *)location & ~0x03fffffc)
-				| (value & 0x03fffffc);
-			break;
-
-		default:
-			printk("%s: Unknown ADD relocation: %lu\n",
-			       me->name,
-			       (unsigned long)ELF64_R_TYPE(rela[i].r_info));
-			return -ENOEXEC;
-		}
-	}
-
-	return 0;
-}
-
-LIST_HEAD(module_bug_list);
-
-int module_finalize(const Elf_Ehdr *hdr,
-		const Elf_Shdr *sechdrs, struct module *me)
-{
-	char *secstrings;
-	unsigned int i;
-
-	me->arch.bug_table = NULL;
-	me->arch.num_bugs = 0;
-
-	/* Find the __bug_table section, if present */
-	secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
-	for (i = 1; i < hdr->e_shnum; i++) {
-		if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table"))
-			continue;
-		me->arch.bug_table = (void *) sechdrs[i].sh_addr;
-		me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry);
-		break;
-	}
-
-	/*
-	 * Strictly speaking this should have a spinlock to protect against
-	 * traversals, but since we only traverse on BUG()s, a spinlock
-	 * could potentially lead to deadlock and thus be counter-productive.
-	 */
-	list_add(&me->arch.bug_list, &module_bug_list);
-
-	return 0;
-}
-
-void module_arch_cleanup(struct module *mod)
-{
-	list_del(&mod->arch.bug_list);
-}
-
-struct bug_entry *module_find_bug(unsigned long bugaddr)
-{
-	struct mod_arch_specific *mod;
-	unsigned int i;
-	struct bug_entry *bug;
-
-	list_for_each_entry(mod, &module_bug_list, bug_list) {
-		bug = mod->bug_table;
-		for (i = 0; i < mod->num_bugs; ++i, ++bug)
-			if (bugaddr == bug->bug_addr)
-				return bug;
-	}
-	return NULL;
-}
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
deleted file mode 100644
index 3cef1b8..0000000
--- a/arch/ppc64/kernel/pci.c
+++ /dev/null
@@ -1,1319 +0,0 @@
-/*
- * Port for PPC64 David Engebretsen, IBM Corp.
- * Contains common pci routines for ppc64 platform, pSeries and iSeries brands.
- * 
- * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
- *   Rework, based on alpha PCI code.
- *
- *      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.
- */
-
-#undef DEBUG
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/mm.h>
-#include <linux/list.h>
-#include <linux/syscalls.h>
-
-#include <asm/processor.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <asm/byteorder.h>
-#include <asm/irq.h>
-#include <asm/machdep.h>
-#include <asm/udbg.h>
-#include <asm/ppc-pci.h>
-
-#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-unsigned long pci_probe_only = 1;
-unsigned long pci_assign_all_buses = 0;
-
-/*
- * legal IO pages under MAX_ISA_PORT.  This is to ensure we don't touch
- * devices we don't have access to.
- */
-unsigned long io_page_mask;
-
-EXPORT_SYMBOL(io_page_mask);
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
-static void fixup_resource(struct resource *res, struct pci_dev *dev);
-static void do_bus_setup(struct pci_bus *bus);
-#endif
-
-unsigned int pcibios_assign_all_busses(void)
-{
-	return pci_assign_all_buses;
-}
-
-/* pci_io_base -- the base address from which io bars are offsets.
- * This is the lowest I/O base address (so bar values are always positive),
- * and it *must* be the start of ISA space if an ISA bus exists because
- * ISA drivers use hard coded offsets.  If no ISA bus exists a dummy
- * page is mapped and isa_io_limit prevents access to it.
- */
-unsigned long isa_io_base;	/* NULL if no ISA bus */
-EXPORT_SYMBOL(isa_io_base);
-unsigned long pci_io_base;
-EXPORT_SYMBOL(pci_io_base);
-
-void iSeries_pcibios_init(void);
-
-LIST_HEAD(hose_list);
-
-struct dma_mapping_ops pci_dma_ops;
-EXPORT_SYMBOL(pci_dma_ops);
-
-int global_phb_number;		/* Global phb counter */
-
-/* Cached ISA bridge dev. */
-struct pci_dev *ppc64_isabridge_dev = NULL;
-
-static void fixup_broken_pcnet32(struct pci_dev* dev)
-{
-	if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
-		dev->vendor = PCI_VENDOR_ID_AMD;
-		pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
-	}
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32);
-
-void  pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			      struct resource *res)
-{
-	unsigned long offset = 0;
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-
-	if (!hose)
-		return;
-
-	if (res->flags & IORESOURCE_IO)
-	        offset = (unsigned long)hose->io_base_virt - pci_io_base;
-
-	if (res->flags & IORESOURCE_MEM)
-		offset = hose->pci_mem_offset;
-
-	region->start = res->start - offset;
-	region->end = res->end - offset;
-}
-
-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			      struct pci_bus_region *region)
-{
-	unsigned long offset = 0;
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-
-	if (!hose)
-		return;
-
-	if (res->flags & IORESOURCE_IO)
-	        offset = (unsigned long)hose->io_base_virt - pci_io_base;
-
-	if (res->flags & IORESOURCE_MEM)
-		offset = hose->pci_mem_offset;
-
-	res->start = region->start + offset;
-	res->end = region->end + offset;
-}
-
-#ifdef CONFIG_HOTPLUG
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-#endif
-
-/*
- * We need to avoid collisions with `mirrored' VGA ports
- * and other strange ISA hardware, so we always want the
- * addresses to be allocated in the 0x000-0x0ff region
- * modulo 0x400.
- *
- * Why? Because some silly external IO cards only decode
- * the low 10 bits of the IO address. The 0x00-0xff region
- * is reserved for motherboard devices that decode all 16
- * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
- * but we want to try to avoid allocating at 0x2900-0x2bff
- * which might have be mirrored at 0x0100-0x03ff..
- */
-void pcibios_align_resource(void *data, struct resource *res,
-			    unsigned long size, unsigned long align)
-{
-	struct pci_dev *dev = data;
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-	unsigned long start = res->start;
-	unsigned long alignto;
-
-	if (res->flags & IORESOURCE_IO) {
-	        unsigned long offset = (unsigned long)hose->io_base_virt -
-					pci_io_base;
-		/* Make sure we start at our min on all hoses */
-		if (start - offset < PCIBIOS_MIN_IO)
-			start = PCIBIOS_MIN_IO + offset;
-
-		/*
-		 * Put everything into 0x00-0xff region modulo 0x400
-		 */
-		if (start & 0x300)
-			start = (start + 0x3ff) & ~0x3ff;
-
-	} else if (res->flags & IORESOURCE_MEM) {
-		/* Make sure we start at our min on all hoses */
-		if (start - hose->pci_mem_offset < PCIBIOS_MIN_MEM)
-			start = PCIBIOS_MIN_MEM + hose->pci_mem_offset;
-
-		/* Align to multiple of size of minimum base.  */
-		alignto = max(0x1000UL, align);
-		start = ALIGN(start, alignto);
-	}
-
-	res->start = start;
-}
-
-static DEFINE_SPINLOCK(hose_spinlock);
-
-/*
- * pci_controller(phb) initialized common variables.
- */
-void __devinit pci_setup_pci_controller(struct pci_controller *hose)
-{
-	memset(hose, 0, sizeof(struct pci_controller));
-
-	spin_lock(&hose_spinlock);
-	hose->global_number = global_phb_number++;
-	list_add_tail(&hose->list_node, &hose_list);
-	spin_unlock(&hose_spinlock);
-}
-
-static void __init pcibios_claim_one_bus(struct pci_bus *b)
-{
-	struct pci_dev *dev;
-	struct pci_bus *child_bus;
-
-	list_for_each_entry(dev, &b->devices, bus_list) {
-		int i;
-
-		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-			struct resource *r = &dev->resource[i];
-
-			if (r->parent || !r->start || !r->flags)
-				continue;
-			pci_claim_resource(dev, i);
-		}
-	}
-
-	list_for_each_entry(child_bus, &b->children, node)
-		pcibios_claim_one_bus(child_bus);
-}
-
-#ifndef CONFIG_PPC_ISERIES
-static void __init pcibios_claim_of_setup(void)
-{
-	struct pci_bus *b;
-
-	list_for_each_entry(b, &pci_root_buses, node)
-		pcibios_claim_one_bus(b);
-}
-#endif
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
-static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
-{
-	u32 *prop;
-	int len;
-
-	prop = (u32 *) get_property(np, name, &len);
-	if (prop && len >= 4)
-		return *prop;
-	return def;
-}
-
-static unsigned int pci_parse_of_flags(u32 addr0)
-{
-	unsigned int flags = 0;
-
-	if (addr0 & 0x02000000) {
-		flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
-		flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
-		flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
-		if (addr0 & 0x40000000)
-			flags |= IORESOURCE_PREFETCH
-				 | PCI_BASE_ADDRESS_MEM_PREFETCH;
-	} else if (addr0 & 0x01000000)
-		flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
-	return flags;
-}
-
-#define GET_64BIT(prop, i)	((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1])
-
-static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
-{
-	u64 base, size;
-	unsigned int flags;
-	struct resource *res;
-	u32 *addrs, i;
-	int proplen;
-
-	addrs = (u32 *) get_property(node, "assigned-addresses", &proplen);
-	if (!addrs)
-		return;
-	for (; proplen >= 20; proplen -= 20, addrs += 5) {
-		flags = pci_parse_of_flags(addrs[0]);
-		if (!flags)
-			continue;
-		base = GET_64BIT(addrs, 1);
-		size = GET_64BIT(addrs, 3);
-		if (!size)
-			continue;
-		i = addrs[0] & 0xff;
-		if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
-			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
-		} else if (i == dev->rom_base_reg) {
-			res = &dev->resource[PCI_ROM_RESOURCE];
-			flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
-		} else {
-			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
-			continue;
-		}
-		res->start = base;
-		res->end = base + size - 1;
-		res->flags = flags;
-		res->name = pci_name(dev);
-		fixup_resource(res, dev);
-	}
-}
-
-struct pci_dev *of_create_pci_dev(struct device_node *node,
-				 struct pci_bus *bus, int devfn)
-{
-	struct pci_dev *dev;
-	const char *type;
-
-	dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
-	if (!dev)
-		return NULL;
-	type = get_property(node, "device_type", NULL);
-	if (type == NULL)
-		type = "";
-
-	memset(dev, 0, sizeof(struct pci_dev));
-	dev->bus = bus;
-	dev->sysdata = node;
-	dev->dev.parent = bus->bridge;
-	dev->dev.bus = &pci_bus_type;
-	dev->devfn = devfn;
-	dev->multifunction = 0;		/* maybe a lie? */
-
-	dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
-	dev->device = get_int_prop(node, "device-id", 0xffff);
-	dev->subsystem_vendor = get_int_prop(node, "subsystem-vendor-id", 0);
-	dev->subsystem_device = get_int_prop(node, "subsystem-id", 0);
-
-	dev->cfg_size = 256; /*pci_cfg_space_size(dev);*/
-
-	sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
-		dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
-	dev->class = get_int_prop(node, "class-code", 0);
-
-	dev->current_state = 4;		/* unknown power state */
-
-	if (!strcmp(type, "pci")) {
-		/* a PCI-PCI bridge */
-		dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
-		dev->rom_base_reg = PCI_ROM_ADDRESS1;
-	} else if (!strcmp(type, "cardbus")) {
-		dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
-	} else {
-		dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
-		dev->rom_base_reg = PCI_ROM_ADDRESS;
-		dev->irq = NO_IRQ;
-		if (node->n_intrs > 0) {
-			dev->irq = node->intrs[0].line;
-			pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
-					      dev->irq);
-		}
-	}
-
-	pci_parse_of_addrs(node, dev);
-
-	pci_device_add(dev, bus);
-
-	/* XXX pci_scan_msi_device(dev); */
-
-	return dev;
-}
-EXPORT_SYMBOL(of_create_pci_dev);
-
-void __devinit of_scan_bus(struct device_node *node,
-				  struct pci_bus *bus)
-{
-	struct device_node *child = NULL;
-	u32 *reg;
-	int reglen, devfn;
-	struct pci_dev *dev;
-
-	while ((child = of_get_next_child(node, child)) != NULL) {
-		reg = (u32 *) get_property(child, "reg", &reglen);
-		if (reg == NULL || reglen < 20)
-			continue;
-		devfn = (reg[0] >> 8) & 0xff;
-		/* create a new pci_dev for this device */
-		dev = of_create_pci_dev(child, bus, devfn);
-		if (!dev)
-			continue;
-		if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
-		    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
-			of_scan_pci_bridge(child, dev);
-	}
-
-	do_bus_setup(bus);
-}
-EXPORT_SYMBOL(of_scan_bus);
-
-void __devinit of_scan_pci_bridge(struct device_node *node,
-			 	struct pci_dev *dev)
-{
-	struct pci_bus *bus;
-	u32 *busrange, *ranges;
-	int len, i, mode;
-	struct resource *res;
-	unsigned int flags;
-	u64 size;
-
-	/* parse bus-range property */
-	busrange = (u32 *) get_property(node, "bus-range", &len);
-	if (busrange == NULL || len != 8) {
-		printk(KERN_ERR "Can't get bus-range for PCI-PCI bridge %s\n",
-		       node->full_name);
-		return;
-	}
-	ranges = (u32 *) get_property(node, "ranges", &len);
-	if (ranges == NULL) {
-		printk(KERN_ERR "Can't get ranges for PCI-PCI bridge %s\n",
-		       node->full_name);
-		return;
-	}
-
-	bus = pci_add_new_bus(dev->bus, dev, busrange[0]);
-	if (!bus) {
-		printk(KERN_ERR "Failed to create pci bus for %s\n",
-		       node->full_name);
-		return;
-	}
-
-	bus->primary = dev->bus->number;
-	bus->subordinate = busrange[1];
-	bus->bridge_ctl = 0;
-	bus->sysdata = node;
-
-	/* parse ranges property */
-	/* PCI #address-cells == 3 and #size-cells == 2 always */
-	res = &dev->resource[PCI_BRIDGE_RESOURCES];
-	for (i = 0; i < PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES; ++i) {
-		res->flags = 0;
-		bus->resource[i] = res;
-		++res;
-	}
-	i = 1;
-	for (; len >= 32; len -= 32, ranges += 8) {
-		flags = pci_parse_of_flags(ranges[0]);
-		size = GET_64BIT(ranges, 6);
-		if (flags == 0 || size == 0)
-			continue;
-		if (flags & IORESOURCE_IO) {
-			res = bus->resource[0];
-			if (res->flags) {
-				printk(KERN_ERR "PCI: ignoring extra I/O range"
-				       " for bridge %s\n", node->full_name);
-				continue;
-			}
-		} else {
-			if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
-				printk(KERN_ERR "PCI: too many memory ranges"
-				       " for bridge %s\n", node->full_name);
-				continue;
-			}
-			res = bus->resource[i];
-			++i;
-		}
-		res->start = GET_64BIT(ranges, 1);
-		res->end = res->start + size - 1;
-		res->flags = flags;
-		fixup_resource(res, dev);
-	}
-	sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
-		bus->number);
-
-	mode = PCI_PROBE_NORMAL;
-	if (ppc_md.pci_probe_mode)
-		mode = ppc_md.pci_probe_mode(bus);
-	if (mode == PCI_PROBE_DEVTREE)
-		of_scan_bus(node, bus);
-	else if (mode == PCI_PROBE_NORMAL)
-		pci_scan_child_bus(bus);
-}
-EXPORT_SYMBOL(of_scan_pci_bridge);
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
-void __devinit scan_phb(struct pci_controller *hose)
-{
-	struct pci_bus *bus;
-	struct device_node *node = hose->arch_data;
-	int i, mode;
-	struct resource *res;
-
-	bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node);
-	if (bus == NULL) {
-		printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
-		       hose->global_number);
-		return;
-	}
-	bus->secondary = hose->first_busno;
-	hose->bus = bus;
-
-	bus->resource[0] = res = &hose->io_resource;
-	if (res->flags && request_resource(&ioport_resource, res))
-		printk(KERN_ERR "Failed to request PCI IO region "
-		       "on PCI domain %04x\n", hose->global_number);
-
-	for (i = 0; i < 3; ++i) {
-		res = &hose->mem_resources[i];
-		bus->resource[i+1] = res;
-		if (res->flags && request_resource(&iomem_resource, res))
-			printk(KERN_ERR "Failed to request PCI memory region "
-			       "on PCI domain %04x\n", hose->global_number);
-	}
-
-	mode = PCI_PROBE_NORMAL;
-#ifdef CONFIG_PPC_MULTIPLATFORM
-	if (ppc_md.pci_probe_mode)
-		mode = ppc_md.pci_probe_mode(bus);
-	if (mode == PCI_PROBE_DEVTREE) {
-		bus->subordinate = hose->last_busno;
-		of_scan_bus(node, bus);
-	}
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-	if (mode == PCI_PROBE_NORMAL)
-		hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
-	pci_bus_add_devices(bus);
-}
-
-static int __init pcibios_init(void)
-{
-	struct pci_controller *hose, *tmp;
-
-	/* For now, override phys_mem_access_prot. If we need it,
-	 * later, we may move that initialization to each ppc_md
-	 */
-	ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
-
-#ifdef CONFIG_PPC_ISERIES
-	iSeries_pcibios_init(); 
-#endif
-
-	printk("PCI: Probing PCI hardware\n");
-
-	/* Scan all of the recorded PCI controllers.  */
-	list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
-		scan_phb(hose);
-
-#ifndef CONFIG_PPC_ISERIES
-	if (pci_probe_only)
-		pcibios_claim_of_setup();
-	else
-		/* FIXME: `else' will be removed when
-		   pci_assign_unassigned_resources() is able to work
-		   correctly with [partially] allocated PCI tree. */
-		pci_assign_unassigned_resources();
-#endif /* !CONFIG_PPC_ISERIES */
-
-	/* Call machine dependent final fixup */
-	if (ppc_md.pcibios_fixup)
-		ppc_md.pcibios_fixup();
-
-	/* Cache the location of the ISA bridge (if we have one) */
-	ppc64_isabridge_dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
-	if (ppc64_isabridge_dev != NULL)
-		printk("ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
-	/* map in PCI I/O space */
-	phbs_remap_io();
-#endif
-
-	printk("PCI: Probing PCI hardware done\n");
-
-	return 0;
-}
-
-subsys_initcall(pcibios_init);
-
-char __init *pcibios_setup(char *str)
-{
-	return str;
-}
-
-int pcibios_enable_device(struct pci_dev *dev, int mask)
-{
-	u16 cmd, oldcmd;
-	int i;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	oldcmd = cmd;
-
-	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-		struct resource *res = &dev->resource[i];
-
-		/* Only set up the requested stuff */
-		if (!(mask & (1<<i)))
-			continue;
-
-		if (res->flags & IORESOURCE_IO)
-			cmd |= PCI_COMMAND_IO;
-		if (res->flags & IORESOURCE_MEM)
-			cmd |= PCI_COMMAND_MEMORY;
-	}
-
-	if (cmd != oldcmd) {
-		printk(KERN_DEBUG "PCI: Enabling device: (%s), cmd %x\n",
-		       pci_name(dev), cmd);
-                /* Enable the appropriate bits in the PCI command register.  */
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-	}
-	return 0;
-}
-
-/*
- * Return the domain number for this bus.
- */
-int pci_domain_nr(struct pci_bus *bus)
-{
-#ifdef CONFIG_PPC_ISERIES
-	return 0;
-#else
-	struct pci_controller *hose = pci_bus_to_host(bus);
-
-	return hose->global_number;
-#endif
-}
-
-EXPORT_SYMBOL(pci_domain_nr);
-
-/* Decide whether to display the domain number in /proc */
-int pci_proc_domain(struct pci_bus *bus)
-{
-#ifdef CONFIG_PPC_ISERIES
-	return 0;
-#else
-	struct pci_controller *hose = pci_bus_to_host(bus);
-	return hose->buid;
-#endif
-}
-
-/*
- * Platform support for /proc/bus/pci/X/Y mmap()s,
- * modelled on the sparc64 implementation by Dave Miller.
- *  -- paulus.
- */
-
-/*
- * Adjust vm_pgoff of VMA such that it is the physical page offset
- * corresponding to the 32-bit pci bus offset for DEV requested by the user.
- *
- * Basically, the user finds the base address for his device which he wishes
- * to mmap.  They read the 32-bit value from the config space base register,
- * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
- * offset parameter of mmap on /proc/bus/pci/XXX for that device.
- *
- * Returns negative error code on failure, zero on success.
- */
-static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
-					       unsigned long *offset,
-					       enum pci_mmap_state mmap_state)
-{
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-	unsigned long io_offset = 0;
-	int i, res_bit;
-
-	if (hose == 0)
-		return NULL;		/* should never happen */
-
-	/* If memory, add on the PCI bridge address offset */
-	if (mmap_state == pci_mmap_mem) {
-		*offset += hose->pci_mem_offset;
-		res_bit = IORESOURCE_MEM;
-	} else {
-		io_offset = (unsigned long)hose->io_base_virt - pci_io_base;
-		*offset += io_offset;
-		res_bit = IORESOURCE_IO;
-	}
-
-	/*
-	 * Check that the offset requested corresponds to one of the
-	 * resources of the device.
-	 */
-	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-		struct resource *rp = &dev->resource[i];
-		int flags = rp->flags;
-
-		/* treat ROM as memory (should be already) */
-		if (i == PCI_ROM_RESOURCE)
-			flags |= IORESOURCE_MEM;
-
-		/* Active and same type? */
-		if ((flags & res_bit) == 0)
-			continue;
-
-		/* In the range of this resource? */
-		if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
-			continue;
-
-		/* found it! construct the final physical address */
-		if (mmap_state == pci_mmap_io)
-		       	*offset += hose->io_base_phys - io_offset;
-		return rp;
-	}
-
-	return NULL;
-}
-
-/*
- * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
- * device mapping.
- */
-static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
-				      pgprot_t protection,
-				      enum pci_mmap_state mmap_state,
-				      int write_combine)
-{
-	unsigned long prot = pgprot_val(protection);
-
-	/* Write combine is always 0 on non-memory space mappings. On
-	 * memory space, if the user didn't pass 1, we check for a
-	 * "prefetchable" resource. This is a bit hackish, but we use
-	 * this to workaround the inability of /sysfs to provide a write
-	 * combine bit
-	 */
-	if (mmap_state != pci_mmap_mem)
-		write_combine = 0;
-	else if (write_combine == 0) {
-		if (rp->flags & IORESOURCE_PREFETCH)
-			write_combine = 1;
-	}
-
-	/* XXX would be nice to have a way to ask for write-through */
-	prot |= _PAGE_NO_CACHE;
-	if (write_combine)
-		prot &= ~_PAGE_GUARDED;
-	else
-		prot |= _PAGE_GUARDED;
-
-	printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start,
-	       prot);
-
-	return __pgprot(prot);
-}
-
-/*
- * This one is used by /dev/mem and fbdev who have no clue about the
- * PCI device, it tries to find the PCI device first and calls the
- * above routine
- */
-pgprot_t pci_phys_mem_access_prot(struct file *file,
-				  unsigned long pfn,
-				  unsigned long size,
-				  pgprot_t protection)
-{
-	struct pci_dev *pdev = NULL;
-	struct resource *found = NULL;
-	unsigned long prot = pgprot_val(protection);
-	unsigned long offset = pfn << PAGE_SHIFT;
-	int i;
-
-	if (page_is_ram(pfn))
-		return __pgprot(prot);
-
-	prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
-
-	for_each_pci_dev(pdev) {
-		for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-			struct resource *rp = &pdev->resource[i];
-			int flags = rp->flags;
-
-			/* Active and same type? */
-			if ((flags & IORESOURCE_MEM) == 0)
-				continue;
-			/* In the range of this resource? */
-			if (offset < (rp->start & PAGE_MASK) ||
-			    offset > rp->end)
-				continue;
-			found = rp;
-			break;
-		}
-		if (found)
-			break;
-	}
-	if (found) {
-		if (found->flags & IORESOURCE_PREFETCH)
-			prot &= ~_PAGE_GUARDED;
-		pci_dev_put(pdev);
-	}
-
-	DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
-
-	return __pgprot(prot);
-}
-
-
-/*
- * Perform the actual remap of the pages for a PCI device mapping, as
- * appropriate for this architecture.  The region in the process to map
- * is described by vm_start and vm_end members of VMA, the base physical
- * address is found in vm_pgoff.
- * The pci device structure is provided so that architectures may make mapping
- * decisions on a per-device or per-bus basis.
- *
- * Returns a negative error code on failure, zero on success.
- */
-int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
-			enum pci_mmap_state mmap_state,
-			int write_combine)
-{
-	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-	struct resource *rp;
-	int ret;
-
-	rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
-	if (rp == NULL)
-		return -EINVAL;
-
-	vma->vm_pgoff = offset >> PAGE_SHIFT;
-	vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO;
-	vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
-						  vma->vm_page_prot,
-						  mmap_state, write_combine);
-
-	ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
-			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
-
-	return ret;
-}
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
-static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct pci_dev *pdev;
-	struct device_node *np;
-
-	pdev = to_pci_dev (dev);
-	np = pci_device_to_OF_node(pdev);
-	if (np == NULL || np->full_name == NULL)
-		return 0;
-	return sprintf(buf, "%s", np->full_name);
-}
-static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
-void pcibios_add_platform_entries(struct pci_dev *pdev)
-{
-#ifdef CONFIG_PPC_MULTIPLATFORM
-	device_create_file(&pdev->dev, &dev_attr_devspec);
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-}
-
-#ifdef CONFIG_PPC_MULTIPLATFORM
-
-#define ISA_SPACE_MASK 0x1
-#define ISA_SPACE_IO 0x1
-
-static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
-				      unsigned long phb_io_base_phys,
-				      void __iomem * phb_io_base_virt)
-{
-	struct isa_range *range;
-	unsigned long pci_addr;
-	unsigned int isa_addr;
-	unsigned int size;
-	int rlen = 0;
-
-	range = (struct isa_range *) get_property(isa_node, "ranges", &rlen);
-	if (range == NULL || (rlen < sizeof(struct isa_range))) {
-		printk(KERN_ERR "no ISA ranges or unexpected isa range size,"
-		       "mapping 64k\n");
-		__ioremap_explicit(phb_io_base_phys,
-				   (unsigned long)phb_io_base_virt,
-				   0x10000, _PAGE_NO_CACHE | _PAGE_GUARDED);
-		return;	
-	}
-	
-	/* From "ISA Binding to 1275"
-	 * The ranges property is laid out as an array of elements,
-	 * each of which comprises:
-	 *   cells 0 - 1:	an ISA address
-	 *   cells 2 - 4:	a PCI address 
-	 *			(size depending on dev->n_addr_cells)
-	 *   cell 5:		the size of the range
-	 */
-	if ((range->isa_addr.a_hi && ISA_SPACE_MASK) == ISA_SPACE_IO) {
-		isa_addr = range->isa_addr.a_lo;
-		pci_addr = (unsigned long) range->pci_addr.a_mid << 32 | 
-			range->pci_addr.a_lo;
-
-		/* Assume these are both zero */
-		if ((pci_addr != 0) || (isa_addr != 0)) {
-			printk(KERN_ERR "unexpected isa to pci mapping: %s\n",
-					__FUNCTION__);
-			return;
-		}
-		
-		size = PAGE_ALIGN(range->size);
-
-		__ioremap_explicit(phb_io_base_phys, 
-				   (unsigned long) phb_io_base_virt, 
-				   size, _PAGE_NO_CACHE | _PAGE_GUARDED);
-	}
-}
-
-void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
-					    struct device_node *dev, int prim)
-{
-	unsigned int *ranges, pci_space;
-	unsigned long size;
-	int rlen = 0;
-	int memno = 0;
-	struct resource *res;
-	int np, na = prom_n_addr_cells(dev);
-	unsigned long pci_addr, cpu_phys_addr;
-
-	np = na + 5;
-
-	/* From "PCI Binding to 1275"
-	 * The ranges property is laid out as an array of elements,
-	 * each of which comprises:
-	 *   cells 0 - 2:	a PCI address
-	 *   cells 3 or 3+4:	a CPU physical address
-	 *			(size depending on dev->n_addr_cells)
-	 *   cells 4+5 or 5+6:	the size of the range
-	 */
-	rlen = 0;
-	hose->io_base_phys = 0;
-	ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
-	while ((rlen -= np * sizeof(unsigned int)) >= 0) {
-		res = NULL;
-		pci_space = ranges[0];
-		pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
-
-		cpu_phys_addr = ranges[3];
-		if (na >= 2)
-			cpu_phys_addr = (cpu_phys_addr << 32) | ranges[4];
-
-		size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
-		ranges += np;
-		if (size == 0)
-			continue;
-
-		/* Now consume following elements while they are contiguous */
-		while (rlen >= np * sizeof(unsigned int)) {
-			unsigned long addr, phys;
-
-			if (ranges[0] != pci_space)
-				break;
-			addr = ((unsigned long)ranges[1] << 32) | ranges[2];
-			phys = ranges[3];
-			if (na >= 2)
-				phys = (phys << 32) | ranges[4];
-			if (addr != pci_addr + size ||
-			    phys != cpu_phys_addr + size)
-				break;
-
-			size += ((unsigned long)ranges[na+3] << 32)
-				| ranges[na+4];
-			ranges += np;
-			rlen -= np * sizeof(unsigned int);
-		}
-
-		switch ((pci_space >> 24) & 0x3) {
-		case 1:		/* I/O space */
-			hose->io_base_phys = cpu_phys_addr;
-			hose->pci_io_size = size;
-
-			res = &hose->io_resource;
-			res->flags = IORESOURCE_IO;
-			res->start = pci_addr;
-			DBG("phb%d: IO 0x%lx -> 0x%lx\n", hose->global_number,
-				    res->start, res->start + size - 1);
-			break;
-		case 2:		/* memory space */
-			memno = 0;
-			while (memno < 3 && hose->mem_resources[memno].flags)
-				++memno;
-
-			if (memno == 0)
-				hose->pci_mem_offset = cpu_phys_addr - pci_addr;
-			if (memno < 3) {
-				res = &hose->mem_resources[memno];
-				res->flags = IORESOURCE_MEM;
-				res->start = cpu_phys_addr;
-				DBG("phb%d: MEM 0x%lx -> 0x%lx\n", hose->global_number,
-					    res->start, res->start + size - 1);
-			}
-			break;
-		}
-		if (res != NULL) {
-			res->name = dev->full_name;
-			res->end = res->start + size - 1;
-			res->parent = NULL;
-			res->sibling = NULL;
-			res->child = NULL;
-		}
-	}
-}
-
-void __init pci_setup_phb_io(struct pci_controller *hose, int primary)
-{
-	unsigned long size = hose->pci_io_size;
-	unsigned long io_virt_offset;
-	struct resource *res;
-	struct device_node *isa_dn;
-
-	hose->io_base_virt = reserve_phb_iospace(size);
-	DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
-		hose->global_number, hose->io_base_phys,
-		(unsigned long) hose->io_base_virt);
-
-	if (primary) {
-		pci_io_base = (unsigned long)hose->io_base_virt;
-		isa_dn = of_find_node_by_type(NULL, "isa");
-		if (isa_dn) {
-			isa_io_base = pci_io_base;
-			pci_process_ISA_OF_ranges(isa_dn, hose->io_base_phys,
-						hose->io_base_virt);
-			of_node_put(isa_dn);
-			/* Allow all IO */
-			io_page_mask = -1;
-		}
-	}
-
-	io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base;
-	res = &hose->io_resource;
-	res->start += io_virt_offset;
-	res->end += io_virt_offset;
-}
-
-void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose,
-					int primary)
-{
-	unsigned long size = hose->pci_io_size;
-	unsigned long io_virt_offset;
-	struct resource *res;
-
-	hose->io_base_virt = __ioremap(hose->io_base_phys, size,
-					_PAGE_NO_CACHE | _PAGE_GUARDED);
-	DBG("phb%d io_base_phys 0x%lx io_base_virt 0x%lx\n",
-		hose->global_number, hose->io_base_phys,
-		(unsigned long) hose->io_base_virt);
-
-	if (primary)
-		pci_io_base = (unsigned long)hose->io_base_virt;
-
-	io_virt_offset = (unsigned long)hose->io_base_virt - pci_io_base;
-	res = &hose->io_resource;
-	res->start += io_virt_offset;
-	res->end += io_virt_offset;
-}
-
-
-static int get_bus_io_range(struct pci_bus *bus, unsigned long *start_phys,
-				unsigned long *start_virt, unsigned long *size)
-{
-	struct pci_controller *hose = pci_bus_to_host(bus);
-	struct pci_bus_region region;
-	struct resource *res;
-
-	if (bus->self) {
-		res = bus->resource[0];
-		pcibios_resource_to_bus(bus->self, &region, res);
-		*start_phys = hose->io_base_phys + region.start;
-		*start_virt = (unsigned long) hose->io_base_virt + 
-				region.start;
-		if (region.end > region.start) 
-			*size = region.end - region.start + 1;
-		else {
-			printk("%s(): unexpected region 0x%lx->0x%lx\n", 
-					__FUNCTION__, region.start, region.end);
-			return 1;
-		}
-		
-	} else {
-		/* Root Bus */
-		res = &hose->io_resource;
-		*start_phys = hose->io_base_phys;
-		*start_virt = (unsigned long) hose->io_base_virt;
-		if (res->end > res->start)
-			*size = res->end - res->start + 1;
-		else {
-			printk("%s(): unexpected region 0x%lx->0x%lx\n", 
-					__FUNCTION__, res->start, res->end);
-			return 1;
-		}
-	}
-
-	return 0;
-}
-
-int unmap_bus_range(struct pci_bus *bus)
-{
-	unsigned long start_phys;
-	unsigned long start_virt;
-	unsigned long size;
-
-	if (!bus) {
-		printk(KERN_ERR "%s() expected bus\n", __FUNCTION__);
-		return 1;
-	}
-	
-	if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
-		return 1;
-	if (iounmap_explicit((void __iomem *) start_virt, size))
-		return 1;
-
-	return 0;
-}
-EXPORT_SYMBOL(unmap_bus_range);
-
-int remap_bus_range(struct pci_bus *bus)
-{
-	unsigned long start_phys;
-	unsigned long start_virt;
-	unsigned long size;
-
-	if (!bus) {
-		printk(KERN_ERR "%s() expected bus\n", __FUNCTION__);
-		return 1;
-	}
-	
-	
-	if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
-		return 1;
-	printk("mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, size);
-	if (__ioremap_explicit(start_phys, start_virt, size,
-			       _PAGE_NO_CACHE | _PAGE_GUARDED))
-		return 1;
-
-	return 0;
-}
-EXPORT_SYMBOL(remap_bus_range);
-
-void phbs_remap_io(void)
-{
-	struct pci_controller *hose, *tmp;
-
-	list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
-		remap_bus_range(hose->bus);
-}
-
-/*
- * ppc64 can have multifunction devices that do not respond to function 0.
- * In this case we must scan all functions.
- * XXX this can go now, we use the OF device tree in all the
- * cases that caused problems. -- paulus
- */
-int pcibios_scan_all_fns(struct pci_bus *bus, int devfn)
-{
-       return 0;
-}
-
-static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
-{
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-	unsigned long start, end, mask, offset;
-
-	if (res->flags & IORESOURCE_IO) {
-		offset = (unsigned long)hose->io_base_virt - pci_io_base;
-
-		start = res->start += offset;
-		end = res->end += offset;
-
-		/* Need to allow IO access to pages that are in the
-		   ISA range */
-		if (start < MAX_ISA_PORT) {
-			if (end > MAX_ISA_PORT)
-				end = MAX_ISA_PORT;
-
-			start >>= PAGE_SHIFT;
-			end >>= PAGE_SHIFT;
-
-			/* get the range of pages for the map */
-			mask = ((1 << (end+1)) - 1) ^ ((1 << start) - 1);
-			io_page_mask |= mask;
-		}
-	} else if (res->flags & IORESOURCE_MEM) {
-		res->start += hose->pci_mem_offset;
-		res->end += hose->pci_mem_offset;
-	}
-}
-
-void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
-					      struct pci_bus *bus)
-{
-	/* Update device resources.  */
-	int i;
-
-	for (i = 0; i < PCI_NUM_RESOURCES; i++)
-		if (dev->resource[i].flags)
-			fixup_resource(&dev->resource[i], dev);
-}
-EXPORT_SYMBOL(pcibios_fixup_device_resources);
-
-static void __devinit do_bus_setup(struct pci_bus *bus)
-{
-	struct pci_dev *dev;
-
-	ppc_md.iommu_bus_setup(bus);
-
-	list_for_each_entry(dev, &bus->devices, bus_list)
-		ppc_md.iommu_dev_setup(dev);
-
-	if (ppc_md.irq_bus_setup)
-		ppc_md.irq_bus_setup(bus);
-}
-
-void __devinit pcibios_fixup_bus(struct pci_bus *bus)
-{
-	struct pci_dev *dev = bus->self;
-
-	if (dev && pci_probe_only &&
-	    (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
-		/* This is a subordinate bridge */
-
-		pci_read_bridge_bases(bus);
-		pcibios_fixup_device_resources(dev, bus);
-	}
-
-	do_bus_setup(bus);
-
-	if (!pci_probe_only)
-		return;
-
-	list_for_each_entry(dev, &bus->devices, bus_list)
-		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
-			pcibios_fixup_device_resources(dev, bus);
-}
-EXPORT_SYMBOL(pcibios_fixup_bus);
-
-/*
- * Reads the interrupt pin to determine if interrupt is use by card.
- * If the interrupt is used, then gets the interrupt line from the 
- * openfirmware and sets it in the pci_dev and pci_config line.
- */
-int pci_read_irq_line(struct pci_dev *pci_dev)
-{
-	u8 intpin;
-	struct device_node *node;
-
-    	pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &intpin);
-	if (intpin == 0)
-		return 0;
-
-	node = pci_device_to_OF_node(pci_dev);
-	if (node == NULL)
-		return -1;
-
-	if (node->n_intrs == 0)
-		return -1;
-
-	pci_dev->irq = node->intrs[0].line;
-
-	pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, pci_dev->irq);
-
-	return 0;
-}
-EXPORT_SYMBOL(pci_read_irq_line);
-
-void pci_resource_to_user(const struct pci_dev *dev, int bar,
-			  const struct resource *rsrc,
-			  u64 *start, u64 *end)
-{
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-	unsigned long offset = 0;
-
-	if (hose == NULL)
-		return;
-
-	if (rsrc->flags & IORESOURCE_IO)
-		offset = pci_io_base - (unsigned long)hose->io_base_virt +
-			hose->io_base_phys;
-
-	*start = rsrc->start + offset;
-	*end = rsrc->end + offset;
-}
-
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
-
-#define IOBASE_BRIDGE_NUMBER	0
-#define IOBASE_MEMORY		1
-#define IOBASE_IO		2
-#define IOBASE_ISA_IO		3
-#define IOBASE_ISA_MEM		4
-
-long sys_pciconfig_iobase(long which, unsigned long in_bus,
-			  unsigned long in_devfn)
-{
-	struct pci_controller* hose;
-	struct list_head *ln;
-	struct pci_bus *bus = NULL;
-	struct device_node *hose_node;
-
-	/* Argh ! Please forgive me for that hack, but that's the
-	 * simplest way to get existing XFree to not lockup on some
-	 * G5 machines... So when something asks for bus 0 io base
-	 * (bus 0 is HT root), we return the AGP one instead.
-	 */
-	if (machine_is_compatible("MacRISC4"))
-		if (in_bus == 0)
-			in_bus = 0xf0;
-
-	/* That syscall isn't quite compatible with PCI domains, but it's
-	 * used on pre-domains setup. We return the first match
-	 */
-
-	for (ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
-		bus = pci_bus_b(ln);
-		if (in_bus >= bus->number && in_bus < (bus->number + bus->subordinate))
-			break;
-		bus = NULL;
-	}
-	if (bus == NULL || bus->sysdata == NULL)
-		return -ENODEV;
-
-	hose_node = (struct device_node *)bus->sysdata;
-	hose = PCI_DN(hose_node)->phb;
-
-	switch (which) {
-	case IOBASE_BRIDGE_NUMBER:
-		return (long)hose->first_busno;
-	case IOBASE_MEMORY:
-		return (long)hose->pci_mem_offset;
-	case IOBASE_IO:
-		return (long)hose->io_base_phys;
-	case IOBASE_ISA_IO:
-		return (long)isa_io_base;
-	case IOBASE_ISA_MEM:
-		return -EINVAL;
-	}
-
-	return -EOPNOTSUPP;
-}
diff --git a/arch/ppc64/kernel/pci_direct_iommu.c b/arch/ppc64/kernel/pci_direct_iommu.c
deleted file mode 100644
index e1a32f8..0000000
--- a/arch/ppc64/kernel/pci_direct_iommu.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Support for DMA from PCI devices to main memory on
- * machines without an iommu or with directly addressable
- * RAM (typically a pmac with 2Gb of RAM or less)
- *
- * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/mm.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/abs_addr.h>
-#include <asm/ppc-pci.h>
-
-static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size,
-				   dma_addr_t *dma_handle, gfp_t flag)
-{
-	void *ret;
-
-	ret = (void *)__get_free_pages(flag, get_order(size));
-	if (ret != NULL) {
-		memset(ret, 0, size);
-		*dma_handle = virt_to_abs(ret);
-	}
-	return ret;
-}
-
-static void pci_direct_free_coherent(struct device *hwdev, size_t size,
-				 void *vaddr, dma_addr_t dma_handle)
-{
-	free_pages((unsigned long)vaddr, get_order(size));
-}
-
-static dma_addr_t pci_direct_map_single(struct device *hwdev, void *ptr,
-		size_t size, enum dma_data_direction direction)
-{
-	return virt_to_abs(ptr);
-}
-
-static void pci_direct_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
-		size_t size, enum dma_data_direction direction)
-{
-}
-
-static int pci_direct_map_sg(struct device *hwdev, struct scatterlist *sg,
-		int nents, enum dma_data_direction direction)
-{
-	int i;
-
-	for (i = 0; i < nents; i++, sg++) {
-		sg->dma_address = page_to_phys(sg->page) + sg->offset;
-		sg->dma_length = sg->length;
-	}
-
-	return nents;
-}
-
-static void pci_direct_unmap_sg(struct device *hwdev, struct scatterlist *sg,
-		int nents, enum dma_data_direction direction)
-{
-}
-
-static int pci_direct_dma_supported(struct device *dev, u64 mask)
-{
-	return mask < 0x100000000ull;
-}
-
-void __init pci_direct_iommu_init(void)
-{
-	pci_dma_ops.alloc_coherent = pci_direct_alloc_coherent;
-	pci_dma_ops.free_coherent = pci_direct_free_coherent;
-	pci_dma_ops.map_single = pci_direct_map_single;
-	pci_dma_ops.unmap_single = pci_direct_unmap_single;
-	pci_dma_ops.map_sg = pci_direct_map_sg;
-	pci_dma_ops.unmap_sg = pci_direct_unmap_sg;
-	pci_dma_ops.dma_supported = pci_direct_dma_supported;
-}
diff --git a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c
deleted file mode 100644
index 12c4c9e..0000000
--- a/arch/ppc64/kernel/pci_dn.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * pci_dn.c
- *
- * Copyright (C) 2001 Todd Inglett, IBM Corporation
- *
- * PCI manipulation via device_nodes.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *    
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/bootmem.h>
-
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <asm/pSeries_reconfig.h>
-#include <asm/ppc-pci.h>
-
-/*
- * Traverse_func that inits the PCI fields of the device node.
- * NOTE: this *must* be done before read/write config to the device.
- */
-static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
-{
-	struct pci_controller *phb = data;
-	int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL);
-	u32 *regs;
-	struct pci_dn *pdn;
-
-	if (mem_init_done)
-		pdn = kmalloc(sizeof(*pdn), GFP_KERNEL);
-	else
-		pdn = alloc_bootmem(sizeof(*pdn));
-	if (pdn == NULL)
-		return NULL;
-	memset(pdn, 0, sizeof(*pdn));
-	dn->data = pdn;
-	pdn->node = dn;
-	pdn->phb = phb;
-	regs = (u32 *)get_property(dn, "reg", NULL);
-	if (regs) {
-		/* First register entry is addr (00BBSS00)  */
-		pdn->busno = (regs[0] >> 16) & 0xff;
-		pdn->devfn = (regs[0] >> 8) & 0xff;
-	}
-
-	pdn->pci_ext_config_space = (type && *type == 1);
-	return NULL;
-}
-
-/*
- * Traverse a device tree stopping each PCI device in the tree.
- * This is done depth first.  As each node is processed, a "pre"
- * function is called and the children are processed recursively.
- *
- * The "pre" func returns a value.  If non-zero is returned from
- * the "pre" func, the traversal stops and this value is returned.
- * This return value is useful when using traverse as a method of
- * finding a device.
- *
- * NOTE: we do not run the func for devices that do not appear to
- * be PCI except for the start node which we assume (this is good
- * because the start node is often a phb which may be missing PCI
- * properties).
- * We use the class-code as an indicator. If we run into
- * one of these nodes we also assume its siblings are non-pci for
- * performance.
- */
-void *traverse_pci_devices(struct device_node *start, traverse_func pre,
-		void *data)
-{
-	struct device_node *dn, *nextdn;
-	void *ret;
-
-	/* We started with a phb, iterate all childs */
-	for (dn = start->child; dn; dn = nextdn) {
-		u32 *classp, class;
-
-		nextdn = NULL;
-		classp = (u32 *)get_property(dn, "class-code", NULL);
-		class = classp ? *classp : 0;
-
-		if (pre && ((ret = pre(dn, data)) != NULL))
-			return ret;
-
-		/* If we are a PCI bridge, go down */
-		if (dn->child && ((class >> 8) == PCI_CLASS_BRIDGE_PCI ||
-				  (class >> 8) == PCI_CLASS_BRIDGE_CARDBUS))
-			/* Depth first...do children */
-			nextdn = dn->child;
-		else if (dn->sibling)
-			/* ok, try next sibling instead. */
-			nextdn = dn->sibling;
-		if (!nextdn) {
-			/* Walk up to next valid sibling. */
-			do {
-				dn = dn->parent;
-				if (dn == start)
-					return NULL;
-			} while (dn->sibling == NULL);
-			nextdn = dn->sibling;
-		}
-	}
-	return NULL;
-}
-
-/** 
- * pci_devs_phb_init_dynamic - setup pci devices under this PHB
- * phb: pci-to-host bridge (top-level bridge connecting to cpu)
- *
- * This routine is called both during boot, (before the memory
- * subsystem is set up, before kmalloc is valid) and during the 
- * dynamic lpar operation of adding a PHB to a running system.
- */
-void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
-{
-	struct device_node * dn = (struct device_node *) phb->arch_data;
-	struct pci_dn *pdn;
-
-	/* PHB nodes themselves must not match */
-	update_dn_pci_info(dn, phb);
-	pdn = dn->data;
-	if (pdn) {
-		pdn->devfn = pdn->busno = -1;
-		pdn->phb = phb;
-	}
-
-	/* Update dn->phb ptrs for new phb and children devices */
-	traverse_pci_devices(dn, update_dn_pci_info, phb);
-}
-
-/*
- * Traversal func that looks for a <busno,devfcn> value.
- * If found, the pci_dn is returned (thus terminating the traversal).
- */
-static void *is_devfn_node(struct device_node *dn, void *data)
-{
-	int busno = ((unsigned long)data >> 8) & 0xff;
-	int devfn = ((unsigned long)data) & 0xff;
-	struct pci_dn *pci = dn->data;
-
-	if (pci && (devfn == pci->devfn) && (busno == pci->busno))
-		return dn;
-	return NULL;
-}
-
-/*
- * This is the "slow" path for looking up a device_node from a
- * pci_dev.  It will hunt for the device under its parent's
- * phb and then update sysdata for a future fastpath.
- *
- * It may also do fixups on the actual device since this happens
- * on the first read/write.
- *
- * Note that it also must deal with devices that don't exist.
- * In this case it may probe for real hardware ("just in case")
- * and add a device_node to the device tree if necessary.
- *
- */
-struct device_node *fetch_dev_dn(struct pci_dev *dev)
-{
-	struct device_node *orig_dn = dev->sysdata;
-	struct device_node *dn;
-	unsigned long searchval = (dev->bus->number << 8) | dev->devfn;
-
-	dn = traverse_pci_devices(orig_dn, is_devfn_node, (void *)searchval);
-	if (dn)
-		dev->sysdata = dn;
-	return dn;
-}
-EXPORT_SYMBOL(fetch_dev_dn);
-
-static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
-{
-	struct device_node *np = node;
-	struct pci_dn *pci = NULL;
-	int err = NOTIFY_OK;
-
-	switch (action) {
-	case PSERIES_RECONFIG_ADD:
-		pci = np->parent->data;
-		if (pci)
-			update_dn_pci_info(np, pci->phb);
-		break;
-	default:
-		err = NOTIFY_DONE;
-		break;
-	}
-	return err;
-}
-
-static struct notifier_block pci_dn_reconfig_nb = {
-	.notifier_call = pci_dn_reconfig_notifier,
-};
-
-/** 
- * pci_devs_phb_init - Initialize phbs and pci devs under them.
- * 
- * This routine walks over all phb's (pci-host bridges) on the
- * system, and sets up assorted pci-related structures 
- * (including pci info in the device node structs) for each
- * pci device found underneath.  This routine runs once,
- * early in the boot sequence.
- */
-void __init pci_devs_phb_init(void)
-{
-	struct pci_controller *phb, *tmp;
-
-	/* This must be done first so the device nodes have valid pci info! */
-	list_for_each_entry_safe(phb, tmp, &hose_list, list_node)
-		pci_devs_phb_init_dynamic(phb);
-
-	pSeries_reconfig_notifier_register(&pci_dn_reconfig_nb);
-}
diff --git a/arch/ppc64/kernel/pci_iommu.c b/arch/ppc64/kernel/pci_iommu.c
deleted file mode 100644
index bdf15db..0000000
--- a/arch/ppc64/kernel/pci_iommu.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * arch/ppc64/kernel/pci_iommu.c
- * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
- *
- * Rewrite, cleanup, new allocation schemes:
- * Copyright (C) 2004 Olof Johansson, IBM Corporation
- *
- * Dynamic DMA mapping support, platform-independent parts.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/iommu.h>
-#include <asm/pci-bridge.h>
-#include <asm/machdep.h>
-#include <asm/ppc-pci.h>
-
-/*
- * We can use ->sysdata directly and avoid the extra work in
- * pci_device_to_OF_node since ->sysdata will have been initialised
- * in the iommu init code for all devices.
- */
-#define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata))
-
-static inline struct iommu_table *devnode_table(struct device *dev)
-{
-	struct pci_dev *pdev;
-
-	if (!dev) {
-		pdev = ppc64_isabridge_dev;
-		if (!pdev)
-			return NULL;
-	} else
-		pdev = to_pci_dev(dev);
-
-	return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
-}
-
-
-/* Allocates a contiguous real buffer and creates mappings over it.
- * Returns the virtual address of the buffer and sets dma_handle
- * to the dma address (mapping) of the first page.
- */
-static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size,
-			   dma_addr_t *dma_handle, gfp_t flag)
-{
-	return iommu_alloc_coherent(devnode_table(hwdev), size, dma_handle,
-			flag);
-}
-
-static void pci_iommu_free_coherent(struct device *hwdev, size_t size,
-			 void *vaddr, dma_addr_t dma_handle)
-{
-	iommu_free_coherent(devnode_table(hwdev), size, vaddr, dma_handle);
-}
-
-/* Creates TCEs for a user provided buffer.  The user buffer must be 
- * contiguous real kernel storage (not vmalloc).  The address of the buffer
- * passed here is the kernel (virtual) address of the buffer.  The buffer
- * need not be page aligned, the dma_addr_t returned will point to the same
- * byte within the page as vaddr.
- */
-static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr,
-		size_t size, enum dma_data_direction direction)
-{
-	return iommu_map_single(devnode_table(hwdev), vaddr, size, direction);
-}
-
-
-static void pci_iommu_unmap_single(struct device *hwdev, dma_addr_t dma_handle,
-		size_t size, enum dma_data_direction direction)
-{
-	iommu_unmap_single(devnode_table(hwdev), dma_handle, size, direction);
-}
-
-
-static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist,
-		int nelems, enum dma_data_direction direction)
-{
-	return iommu_map_sg(pdev, devnode_table(pdev), sglist,
-			nelems, direction);
-}
-
-static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist,
-		int nelems, enum dma_data_direction direction)
-{
-	iommu_unmap_sg(devnode_table(pdev), sglist, nelems, direction);
-}
-
-/* We support DMA to/from any memory page via the iommu */
-static int pci_iommu_dma_supported(struct device *dev, u64 mask)
-{
-	return 1;
-}
-
-void pci_iommu_init(void)
-{
-	pci_dma_ops.alloc_coherent = pci_iommu_alloc_coherent;
-	pci_dma_ops.free_coherent = pci_iommu_free_coherent;
-	pci_dma_ops.map_single = pci_iommu_map_single;
-	pci_dma_ops.unmap_single = pci_iommu_unmap_single;
-	pci_dma_ops.map_sg = pci_iommu_map_sg;
-	pci_dma_ops.unmap_sg = pci_iommu_unmap_sg;
-	pci_dma_ops.dma_supported = pci_iommu_dma_supported;
-}
diff --git a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c
deleted file mode 100644
index 84006e2..0000000
--- a/arch/ppc64/kernel/ppc_ksyms.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* 
- * c 2001 PPC 64 Team, IBM Corp
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
- */
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/console.h>
-#include <net/checksum.h>
-
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/hw_irq.h>
-#include <asm/abs_addr.h>
-#include <asm/cacheflush.h>
-
-EXPORT_SYMBOL(strcpy);
-EXPORT_SYMBOL(strncpy);
-EXPORT_SYMBOL(strcat);
-EXPORT_SYMBOL(strncat);
-EXPORT_SYMBOL(strchr);
-EXPORT_SYMBOL(strrchr);
-EXPORT_SYMBOL(strpbrk);
-EXPORT_SYMBOL(strstr);
-EXPORT_SYMBOL(strlen);
-EXPORT_SYMBOL(strnlen);
-EXPORT_SYMBOL(strcmp);
-EXPORT_SYMBOL(strncmp);
-
-EXPORT_SYMBOL(csum_partial);
-EXPORT_SYMBOL(csum_partial_copy_generic);
-EXPORT_SYMBOL(ip_fast_csum);
-EXPORT_SYMBOL(csum_tcpudp_magic);
-
-EXPORT_SYMBOL(__copy_tofrom_user);
-EXPORT_SYMBOL(__clear_user);
-EXPORT_SYMBOL(__strncpy_from_user);
-EXPORT_SYMBOL(__strnlen_user);
-
-EXPORT_SYMBOL(reloc_offset);
-
-EXPORT_SYMBOL(_insb);
-EXPORT_SYMBOL(_outsb);
-EXPORT_SYMBOL(_insw);
-EXPORT_SYMBOL(_outsw);
-EXPORT_SYMBOL(_insl);
-EXPORT_SYMBOL(_outsl);
-EXPORT_SYMBOL(_insw_ns);
-EXPORT_SYMBOL(_outsw_ns);
-EXPORT_SYMBOL(_insl_ns);
-EXPORT_SYMBOL(_outsl_ns);
-
-EXPORT_SYMBOL(kernel_thread);
-
-EXPORT_SYMBOL(giveup_fpu);
-#ifdef CONFIG_ALTIVEC
-EXPORT_SYMBOL(giveup_altivec);
-#endif
-EXPORT_SYMBOL(__flush_icache_range);
-EXPORT_SYMBOL(flush_dcache_range);
-
-EXPORT_SYMBOL(memcpy);
-EXPORT_SYMBOL(memset);
-EXPORT_SYMBOL(memmove);
-EXPORT_SYMBOL(memscan);
-EXPORT_SYMBOL(memcmp);
-EXPORT_SYMBOL(memchr);
-
-EXPORT_SYMBOL(timer_interrupt);
-EXPORT_SYMBOL(console_drivers);
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
deleted file mode 100644
index fbad2c3..0000000
--- a/arch/ppc64/kernel/prom.c
+++ /dev/null
@@ -1,1954 +0,0 @@
-/*
- * 
- *
- * Procedures for interfacing to Open Firmware.
- *
- * Paul Mackerras	August 1996.
- * Copyright (C) 1996 Paul Mackerras.
- * 
- *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
- *    {engebret|bergner}@us.ibm.com 
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
- */
-
-#undef DEBUG
-
-#include <stdarg.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/threads.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/stringify.h>
-#include <linux/delay.h>
-#include <linux/initrd.h>
-#include <linux/bitops.h>
-#include <linux/module.h>
-#include <linux/module.h>
-
-#include <asm/prom.h>
-#include <asm/rtas.h>
-#include <asm/lmb.h>
-#include <asm/abs_addr.h>
-#include <asm/page.h>
-#include <asm/processor.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/system.h>
-#include <asm/mmu.h>
-#include <asm/pgtable.h>
-#include <asm/pci.h>
-#include <asm/iommu.h>
-#include <asm/btext.h>
-#include <asm/sections.h>
-#include <asm/machdep.h>
-#include <asm/pSeries_reconfig.h>
-
-#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-struct pci_reg_property {
-	struct pci_address addr;
-	u32 size_hi;
-	u32 size_lo;
-};
-
-struct isa_reg_property {
-	u32 space;
-	u32 address;
-	u32 size;
-};
-
-
-typedef int interpret_func(struct device_node *, unsigned long *,
-			   int, int, int);
-
-extern struct rtas_t rtas;
-extern struct lmb lmb;
-extern unsigned long klimit;
-extern unsigned long memory_limit;
-
-static int __initdata dt_root_addr_cells;
-static int __initdata dt_root_size_cells;
-static int __initdata iommu_is_off;
-int __initdata iommu_force_on;
-unsigned long tce_alloc_start, tce_alloc_end;
-
-typedef u32 cell_t;
-
-#if 0
-static struct boot_param_header *initial_boot_params __initdata;
-#else
-struct boot_param_header *initial_boot_params;
-#endif
-
-static struct device_node *allnodes = NULL;
-
-/* use when traversing tree through the allnext, child, sibling,
- * or parent members of struct device_node.
- */
-static DEFINE_RWLOCK(devtree_lock);
-
-/* export that to outside world */
-struct device_node *of_chosen;
-
-/*
- * Wrapper for allocating memory for various data that needs to be
- * attached to device nodes as they are processed at boot or when
- * added to the device tree later (e.g. DLPAR).  At boot there is
- * already a region reserved so we just increment *mem_start by size;
- * otherwise we call kmalloc.
- */
-static void * prom_alloc(unsigned long size, unsigned long *mem_start)
-{
-	unsigned long tmp;
-
-	if (!mem_start)
-		return kmalloc(size, GFP_KERNEL);
-
-	tmp = *mem_start;
-	*mem_start += size;
-	return (void *)tmp;
-}
-
-/*
- * Find the device_node with a given phandle.
- */
-static struct device_node * find_phandle(phandle ph)
-{
-	struct device_node *np;
-
-	for (np = allnodes; np != 0; np = np->allnext)
-		if (np->linux_phandle == ph)
-			return np;
-	return NULL;
-}
-
-/*
- * Find the interrupt parent of a node.
- */
-static struct device_node * __devinit intr_parent(struct device_node *p)
-{
-	phandle *parp;
-
-	parp = (phandle *) get_property(p, "interrupt-parent", NULL);
-	if (parp == NULL)
-		return p->parent;
-	return find_phandle(*parp);
-}
-
-/*
- * Find out the size of each entry of the interrupts property
- * for a node.
- */
-int __devinit prom_n_intr_cells(struct device_node *np)
-{
-	struct device_node *p;
-	unsigned int *icp;
-
-	for (p = np; (p = intr_parent(p)) != NULL; ) {
-		icp = (unsigned int *)
-			get_property(p, "#interrupt-cells", NULL);
-		if (icp != NULL)
-			return *icp;
-		if (get_property(p, "interrupt-controller", NULL) != NULL
-		    || get_property(p, "interrupt-map", NULL) != NULL) {
-			printk("oops, node %s doesn't have #interrupt-cells\n",
-			       p->full_name);
-			return 1;
-		}
-	}
-#ifdef DEBUG_IRQ
-	printk("prom_n_intr_cells failed for %s\n", np->full_name);
-#endif
-	return 1;
-}
-
-/*
- * Map an interrupt from a device up to the platform interrupt
- * descriptor.
- */
-static int __devinit map_interrupt(unsigned int **irq, struct device_node **ictrler,
-				   struct device_node *np, unsigned int *ints,
-				   int nintrc)
-{
-	struct device_node *p, *ipar;
-	unsigned int *imap, *imask, *ip;
-	int i, imaplen, match;
-	int newintrc = 0, newaddrc = 0;
-	unsigned int *reg;
-	int naddrc;
-
-	reg = (unsigned int *) get_property(np, "reg", NULL);
-	naddrc = prom_n_addr_cells(np);
-	p = intr_parent(np);
-	while (p != NULL) {
-		if (get_property(p, "interrupt-controller", NULL) != NULL)
-			/* this node is an interrupt controller, stop here */
-			break;
-		imap = (unsigned int *)
-			get_property(p, "interrupt-map", &imaplen);
-		if (imap == NULL) {
-			p = intr_parent(p);
-			continue;
-		}
-		imask = (unsigned int *)
-			get_property(p, "interrupt-map-mask", NULL);
-		if (imask == NULL) {
-			printk("oops, %s has interrupt-map but no mask\n",
-			       p->full_name);
-			return 0;
-		}
-		imaplen /= sizeof(unsigned int);
-		match = 0;
-		ipar = NULL;
-		while (imaplen > 0 && !match) {
-			/* check the child-interrupt field */
-			match = 1;
-			for (i = 0; i < naddrc && match; ++i)
-				match = ((reg[i] ^ imap[i]) & imask[i]) == 0;
-			for (; i < naddrc + nintrc && match; ++i)
-				match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0;
-			imap += naddrc + nintrc;
-			imaplen -= naddrc + nintrc;
-			/* grab the interrupt parent */
-			ipar = find_phandle((phandle) *imap++);
-			--imaplen;
-			if (ipar == NULL) {
-				printk("oops, no int parent %x in map of %s\n",
-				       imap[-1], p->full_name);
-				return 0;
-			}
-			/* find the parent's # addr and intr cells */
-			ip = (unsigned int *)
-				get_property(ipar, "#interrupt-cells", NULL);
-			if (ip == NULL) {
-				printk("oops, no #interrupt-cells on %s\n",
-				       ipar->full_name);
-				return 0;
-			}
-			newintrc = *ip;
-			ip = (unsigned int *)
-				get_property(ipar, "#address-cells", NULL);
-			newaddrc = (ip == NULL)? 0: *ip;
-			imap += newaddrc + newintrc;
-			imaplen -= newaddrc + newintrc;
-		}
-		if (imaplen < 0) {
-			printk("oops, error decoding int-map on %s, len=%d\n",
-			       p->full_name, imaplen);
-			return 0;
-		}
-		if (!match) {
-#ifdef DEBUG_IRQ
-			printk("oops, no match in %s int-map for %s\n",
-			       p->full_name, np->full_name);
-#endif
-			return 0;
-		}
-		p = ipar;
-		naddrc = newaddrc;
-		nintrc = newintrc;
-		ints = imap - nintrc;
-		reg = ints - naddrc;
-	}
-	if (p == NULL) {
-#ifdef DEBUG_IRQ
-		printk("hmmm, int tree for %s doesn't have ctrler\n",
-		       np->full_name);
-#endif
-		return 0;
-	}
-	*irq = ints;
-	*ictrler = p;
-	return nintrc;
-}
-
-static int __devinit finish_node_interrupts(struct device_node *np,
-					    unsigned long *mem_start,
-					    int measure_only)
-{
-	unsigned int *ints;
-	int intlen, intrcells, intrcount;
-	int i, j, n;
-	unsigned int *irq, virq;
-	struct device_node *ic;
-
-	ints = (unsigned int *) get_property(np, "interrupts", &intlen);
-	if (ints == NULL)
-		return 0;
-	intrcells = prom_n_intr_cells(np);
-	intlen /= intrcells * sizeof(unsigned int);
-
-	np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start);
-	if (!np->intrs)
-		return -ENOMEM;
-
-	if (measure_only)
-		return 0;
-
-	intrcount = 0;
-	for (i = 0; i < intlen; ++i, ints += intrcells) {
-		n = map_interrupt(&irq, &ic, np, ints, intrcells);
-		if (n <= 0)
-			continue;
-
-		/* don't map IRQ numbers under a cascaded 8259 controller */
-		if (ic && device_is_compatible(ic, "chrp,iic")) {
-			np->intrs[intrcount].line = irq[0];
-		} else {
-			virq = virt_irq_create_mapping(irq[0]);
-			if (virq == NO_IRQ) {
-				printk(KERN_CRIT "Could not allocate interrupt"
-				       " number for %s\n", np->full_name);
-				continue;
-			}
-			np->intrs[intrcount].line = irq_offset_up(virq);
-		}
-
-		/* We offset irq numbers for the u3 MPIC by 128 in PowerMac */
-		if (_machine == PLATFORM_POWERMAC && ic && ic->parent) {
-			char *name = get_property(ic->parent, "name", NULL);
-			if (name && !strcmp(name, "u3"))
-				np->intrs[intrcount].line += 128;
-			else if (!(name && !strcmp(name, "mac-io")))
-				/* ignore other cascaded controllers, such as
-				   the k2-sata-root */
-				break;
-		}
-		np->intrs[intrcount].sense = 1;
-		if (n > 1)
-			np->intrs[intrcount].sense = irq[1];
-		if (n > 2) {
-			printk("hmmm, got %d intr cells for %s:", n,
-			       np->full_name);
-			for (j = 0; j < n; ++j)
-				printk(" %d", irq[j]);
-			printk("\n");
-		}
-		++intrcount;
-	}
-	np->n_intrs = intrcount;
-
-	return 0;
-}
-
-static int __devinit interpret_pci_props(struct device_node *np,
-					 unsigned long *mem_start,
-					 int naddrc, int nsizec,
-					 int measure_only)
-{
-	struct address_range *adr;
-	struct pci_reg_property *pci_addrs;
-	int i, l, n_addrs;
-
-	pci_addrs = (struct pci_reg_property *)
-		get_property(np, "assigned-addresses", &l);
-	if (!pci_addrs)
-		return 0;
-
-	n_addrs = l / sizeof(*pci_addrs);
-
-	adr = prom_alloc(n_addrs * sizeof(*adr), mem_start);
-	if (!adr)
-		return -ENOMEM;
-
- 	if (measure_only)
- 		return 0;
-
- 	np->addrs = adr;
- 	np->n_addrs = n_addrs;
-
- 	for (i = 0; i < n_addrs; i++) {
- 		adr[i].space = pci_addrs[i].addr.a_hi;
- 		adr[i].address = pci_addrs[i].addr.a_lo |
-			((u64)pci_addrs[i].addr.a_mid << 32);
- 		adr[i].size = pci_addrs[i].size_lo;
-	}
-
-	return 0;
-}
-
-static int __init interpret_dbdma_props(struct device_node *np,
-					unsigned long *mem_start,
-					int naddrc, int nsizec,
-					int measure_only)
-{
-	struct reg_property32 *rp;
-	struct address_range *adr;
-	unsigned long base_address;
-	int i, l;
-	struct device_node *db;
-
-	base_address = 0;
-	if (!measure_only) {
-		for (db = np->parent; db != NULL; db = db->parent) {
-			if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) {
-				base_address = db->addrs[0].address;
-				break;
-			}
-		}
-	}
-
-	rp = (struct reg_property32 *) get_property(np, "reg", &l);
-	if (rp != 0 && l >= sizeof(struct reg_property32)) {
-		i = 0;
-		adr = (struct address_range *) (*mem_start);
-		while ((l -= sizeof(struct reg_property32)) >= 0) {
-			if (!measure_only) {
-				adr[i].space = 2;
-				adr[i].address = rp[i].address + base_address;
-				adr[i].size = rp[i].size;
-			}
-			++i;
-		}
-		np->addrs = adr;
-		np->n_addrs = i;
-		(*mem_start) += i * sizeof(struct address_range);
-	}
-
-	return 0;
-}
-
-static int __init interpret_macio_props(struct device_node *np,
-					unsigned long *mem_start,
-					int naddrc, int nsizec,
-					int measure_only)
-{
-	struct reg_property32 *rp;
-	struct address_range *adr;
-	unsigned long base_address;
-	int i, l;
-	struct device_node *db;
-
-	base_address = 0;
-	if (!measure_only) {
-		for (db = np->parent; db != NULL; db = db->parent) {
-			if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
-				base_address = db->addrs[0].address;
-				break;
-			}
-		}
-	}
-
-	rp = (struct reg_property32 *) get_property(np, "reg", &l);
-	if (rp != 0 && l >= sizeof(struct reg_property32)) {
-		i = 0;
-		adr = (struct address_range *) (*mem_start);
-		while ((l -= sizeof(struct reg_property32)) >= 0) {
-			if (!measure_only) {
-				adr[i].space = 2;
-				adr[i].address = rp[i].address + base_address;
-				adr[i].size = rp[i].size;
-			}
-			++i;
-		}
-		np->addrs = adr;
-		np->n_addrs = i;
-		(*mem_start) += i * sizeof(struct address_range);
-	}
-
-	return 0;
-}
-
-static int __init interpret_isa_props(struct device_node *np,
-				      unsigned long *mem_start,
-				      int naddrc, int nsizec,
-				      int measure_only)
-{
-	struct isa_reg_property *rp;
-	struct address_range *adr;
-	int i, l;
-
-	rp = (struct isa_reg_property *) get_property(np, "reg", &l);
-	if (rp != 0 && l >= sizeof(struct isa_reg_property)) {
-		i = 0;
-		adr = (struct address_range *) (*mem_start);
-		while ((l -= sizeof(struct isa_reg_property)) >= 0) {
-			if (!measure_only) {
-				adr[i].space = rp[i].space;
-				adr[i].address = rp[i].address;
-				adr[i].size = rp[i].size;
-			}
-			++i;
-		}
-		np->addrs = adr;
-		np->n_addrs = i;
-		(*mem_start) += i * sizeof(struct address_range);
-	}
-
-	return 0;
-}
-
-static int __init interpret_root_props(struct device_node *np,
-				       unsigned long *mem_start,
-				       int naddrc, int nsizec,
-				       int measure_only)
-{
-	struct address_range *adr;
-	int i, l;
-	unsigned int *rp;
-	int rpsize = (naddrc + nsizec) * sizeof(unsigned int);
-
-	rp = (unsigned int *) get_property(np, "reg", &l);
-	if (rp != 0 && l >= rpsize) {
-		i = 0;
-		adr = (struct address_range *) (*mem_start);
-		while ((l -= rpsize) >= 0) {
-			if (!measure_only) {
-				adr[i].space = 0;
-				adr[i].address = rp[naddrc - 1];
-				adr[i].size = rp[naddrc + nsizec - 1];
-			}
-			++i;
-			rp += naddrc + nsizec;
-		}
-		np->addrs = adr;
-		np->n_addrs = i;
-		(*mem_start) += i * sizeof(struct address_range);
-	}
-
-	return 0;
-}
-
-static int __devinit finish_node(struct device_node *np,
-				 unsigned long *mem_start,
-				 interpret_func *ifunc,
-				 int naddrc, int nsizec,
-				 int measure_only)
-{
-	struct device_node *child;
-	int *ip, rc = 0;
-
-	/* get the device addresses and interrupts */
-	if (ifunc != NULL)
-		rc = ifunc(np, mem_start, naddrc, nsizec, measure_only);
-	if (rc)
-		goto out;
-
-	rc = finish_node_interrupts(np, mem_start, measure_only);
-	if (rc)
-		goto out;
-
-	/* Look for #address-cells and #size-cells properties. */
-	ip = (int *) get_property(np, "#address-cells", NULL);
-	if (ip != NULL)
-		naddrc = *ip;
-	ip = (int *) get_property(np, "#size-cells", NULL);
-	if (ip != NULL)
-		nsizec = *ip;
-
-	if (!strcmp(np->name, "device-tree") || np->parent == NULL)
-		ifunc = interpret_root_props;
-	else if (np->type == 0)
-		ifunc = NULL;
-	else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci"))
-		ifunc = interpret_pci_props;
-	else if (!strcmp(np->type, "dbdma"))
-		ifunc = interpret_dbdma_props;
-	else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props)
-		ifunc = interpret_macio_props;
-	else if (!strcmp(np->type, "isa"))
-		ifunc = interpret_isa_props;
-	else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3"))
-		ifunc = interpret_root_props;
-	else if (!((ifunc == interpret_dbdma_props
-		    || ifunc == interpret_macio_props)
-		   && (!strcmp(np->type, "escc")
-		       || !strcmp(np->type, "media-bay"))))
-		ifunc = NULL;
-
-	for (child = np->child; child != NULL; child = child->sibling) {
-		rc = finish_node(child, mem_start, ifunc,
-				 naddrc, nsizec, measure_only);
-		if (rc)
-			goto out;
-	}
-out:
-	return rc;
-}
-
-/**
- * finish_device_tree is called once things are running normally
- * (i.e. with text and data mapped to the address they were linked at).
- * It traverses the device tree and fills in some of the additional,
- * fields in each node like {n_}addrs and {n_}intrs, the virt interrupt
- * mapping is also initialized at this point.
- */
-void __init finish_device_tree(void)
-{
-	unsigned long start, end, size = 0;
-
-	DBG(" -> finish_device_tree\n");
-
-	if (ppc64_interrupt_controller == IC_INVALID) {
-		DBG("failed to configure interrupt controller type\n");
-		panic("failed to configure interrupt controller type\n");
-	}
-	
-	/* Initialize virtual IRQ map */
-	virt_irq_init();
-
-	/*
-	 * Finish device-tree (pre-parsing some properties etc...)
-	 * We do this in 2 passes. One with "measure_only" set, which
-	 * will only measure the amount of memory needed, then we can
-	 * allocate that memory, and call finish_node again. However,
-	 * we must be careful as most routines will fail nowadays when
-	 * prom_alloc() returns 0, so we must make sure our first pass
-	 * doesn't start at 0. We pre-initialize size to 16 for that
-	 * reason and then remove those additional 16 bytes
-	 */
-	size = 16;
-	finish_node(allnodes, &size, NULL, 0, 0, 1);
-	size -= 16;
-	end = start = (unsigned long)abs_to_virt(lmb_alloc(size, 128));
-	finish_node(allnodes, &end, NULL, 0, 0, 0);
-	BUG_ON(end != start + size);
-
-	DBG(" <- finish_device_tree\n");
-}
-
-#ifdef DEBUG
-#define printk udbg_printf
-#endif
-
-static inline char *find_flat_dt_string(u32 offset)
-{
-	return ((char *)initial_boot_params) +
-		initial_boot_params->off_dt_strings + offset;
-}
-
-/**
- * This function is used to scan the flattened device-tree, it is
- * used to extract the memory informations at boot before we can
- * unflatten the tree
- */
-int __init of_scan_flat_dt(int (*it)(unsigned long node,
-				     const char *uname, int depth,
-				     void *data),
-			   void *data)
-{
-	unsigned long p = ((unsigned long)initial_boot_params) +
-		initial_boot_params->off_dt_struct;
-	int rc = 0;
-	int depth = -1;
-
-	do {
-		u32 tag = *((u32 *)p);
-		char *pathp;
-		
-		p += 4;
-		if (tag == OF_DT_END_NODE) {
-			depth --;
-			continue;
-		}
-		if (tag == OF_DT_NOP)
-			continue;
-		if (tag == OF_DT_END)
-			break;
-		if (tag == OF_DT_PROP) {
-			u32 sz = *((u32 *)p);
-			p += 8;
-			if (initial_boot_params->version < 0x10)
-				p = _ALIGN(p, sz >= 8 ? 8 : 4);
-			p += sz;
-			p = _ALIGN(p, 4);
-			continue;
-		}
-		if (tag != OF_DT_BEGIN_NODE) {
-			printk(KERN_WARNING "Invalid tag %x scanning flattened"
-			       " device tree !\n", tag);
-			return -EINVAL;
-		}
-		depth++;
-		pathp = (char *)p;
-		p = _ALIGN(p + strlen(pathp) + 1, 4);
-		if ((*pathp) == '/') {
-			char *lp, *np;
-			for (lp = NULL, np = pathp; *np; np++)
-				if ((*np) == '/')
-					lp = np+1;
-			if (lp != NULL)
-				pathp = lp;
-		}
-		rc = it(p, pathp, depth, data);
-		if (rc != 0)
-			break;		
-	} while(1);
-
-	return rc;
-}
-
-/**
- * This  function can be used within scan_flattened_dt callback to get
- * access to properties
- */
-void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
-				 unsigned long *size)
-{
-	unsigned long p = node;
-
-	do {
-		u32 tag = *((u32 *)p);
-		u32 sz, noff;
-		const char *nstr;
-
-		p += 4;
-		if (tag == OF_DT_NOP)
-			continue;
-		if (tag != OF_DT_PROP)
-			return NULL;
-
-		sz = *((u32 *)p);
-		noff = *((u32 *)(p + 4));
-		p += 8;
-		if (initial_boot_params->version < 0x10)
-			p = _ALIGN(p, sz >= 8 ? 8 : 4);
-
-		nstr = find_flat_dt_string(noff);
-		if (nstr == NULL) {
-			printk(KERN_WARNING "Can't find property index"
-			       " name !\n");
-			return NULL;
-		}
-		if (strcmp(name, nstr) == 0) {
-			if (size)
-				*size = sz;
-			return (void *)p;
-		}
-		p += sz;
-		p = _ALIGN(p, 4);
-	} while(1);
-}
-
-static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
-				       unsigned long align)
-{
-	void *res;
-
-	*mem = _ALIGN(*mem, align);
-	res = (void *)*mem;
-	*mem += size;
-
-	return res;
-}
-
-static unsigned long __init unflatten_dt_node(unsigned long mem,
-					      unsigned long *p,
-					      struct device_node *dad,
-					      struct device_node ***allnextpp,
-					      unsigned long fpsize)
-{
-	struct device_node *np;
-	struct property *pp, **prev_pp = NULL;
-	char *pathp;
-	u32 tag;
-	unsigned int l, allocl;
-	int has_name = 0;
-	int new_format = 0;
-
-	tag = *((u32 *)(*p));
-	if (tag != OF_DT_BEGIN_NODE) {
-		printk("Weird tag at start of node: %x\n", tag);
-		return mem;
-	}
-	*p += 4;
-	pathp = (char *)*p;
-	l = allocl = strlen(pathp) + 1;
-	*p = _ALIGN(*p + l, 4);
-
-	/* version 0x10 has a more compact unit name here instead of the full
-	 * path. we accumulate the full path size using "fpsize", we'll rebuild
-	 * it later. We detect this because the first character of the name is
-	 * not '/'.
-	 */
-	if ((*pathp) != '/') {
-		new_format = 1;
-		if (fpsize == 0) {
-			/* root node: special case. fpsize accounts for path
-			 * plus terminating zero. root node only has '/', so
-			 * fpsize should be 2, but we want to avoid the first
-			 * level nodes to have two '/' so we use fpsize 1 here
-			 */
-			fpsize = 1;
-			allocl = 2;
-		} else {
-			/* account for '/' and path size minus terminal 0
-			 * already in 'l'
-			 */
-			fpsize += l;
-			allocl = fpsize;
-		}
-	}
-
-
-	np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
-				__alignof__(struct device_node));
-	if (allnextpp) {
-		memset(np, 0, sizeof(*np));
-		np->full_name = ((char*)np) + sizeof(struct device_node);
-		if (new_format) {
-			char *p = np->full_name;
-			/* rebuild full path for new format */
-			if (dad && dad->parent) {
-				strcpy(p, dad->full_name);
-#ifdef DEBUG
-				if ((strlen(p) + l + 1) != allocl) {
-					DBG("%s: p: %d, l: %d, a: %d\n",
-					    pathp, strlen(p), l, allocl);
-				}
-#endif
-				p += strlen(p);
-			}
-			*(p++) = '/';
-			memcpy(p, pathp, l);
-		} else
-			memcpy(np->full_name, pathp, l);
-		prev_pp = &np->properties;
-		**allnextpp = np;
-		*allnextpp = &np->allnext;
-		if (dad != NULL) {
-			np->parent = dad;
-			/* we temporarily use the next field as `last_child'*/
-			if (dad->next == 0)
-				dad->child = np;
-			else
-				dad->next->sibling = np;
-			dad->next = np;
-		}
-		kref_init(&np->kref);
-	}
-	while(1) {
-		u32 sz, noff;
-		char *pname;
-
-		tag = *((u32 *)(*p));
-		if (tag == OF_DT_NOP) {
-			*p += 4;
-			continue;
-		}
-		if (tag != OF_DT_PROP)
-			break;
-		*p += 4;
-		sz = *((u32 *)(*p));
-		noff = *((u32 *)((*p) + 4));
-		*p += 8;
-		if (initial_boot_params->version < 0x10)
-			*p = _ALIGN(*p, sz >= 8 ? 8 : 4);
-
-		pname = find_flat_dt_string(noff);
-		if (pname == NULL) {
-			printk("Can't find property name in list !\n");
-			break;
-		}
-		if (strcmp(pname, "name") == 0)
-			has_name = 1;
-		l = strlen(pname) + 1;
-		pp = unflatten_dt_alloc(&mem, sizeof(struct property),
-					__alignof__(struct property));
-		if (allnextpp) {
-			if (strcmp(pname, "linux,phandle") == 0) {
-				np->node = *((u32 *)*p);
-				if (np->linux_phandle == 0)
-					np->linux_phandle = np->node;
-			}
-			if (strcmp(pname, "ibm,phandle") == 0)
-				np->linux_phandle = *((u32 *)*p);
-			pp->name = pname;
-			pp->length = sz;
-			pp->value = (void *)*p;
-			*prev_pp = pp;
-			prev_pp = &pp->next;
-		}
-		*p = _ALIGN((*p) + sz, 4);
-	}
-	/* with version 0x10 we may not have the name property, recreate
-	 * it here from the unit name if absent
-	 */
-	if (!has_name) {
-		char *p = pathp, *ps = pathp, *pa = NULL;
-		int sz;
-
-		while (*p) {
-			if ((*p) == '@')
-				pa = p;
-			if ((*p) == '/')
-				ps = p + 1;
-			p++;
-		}
-		if (pa < ps)
-			pa = p;
-		sz = (pa - ps) + 1;
-		pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
-					__alignof__(struct property));
-		if (allnextpp) {
-			pp->name = "name";
-			pp->length = sz;
-			pp->value = (unsigned char *)(pp + 1);
-			*prev_pp = pp;
-			prev_pp = &pp->next;
-			memcpy(pp->value, ps, sz - 1);
-			((char *)pp->value)[sz - 1] = 0;
-			DBG("fixed up name for %s -> %s\n", pathp, pp->value);
-		}
-	}
-	if (allnextpp) {
-		*prev_pp = NULL;
-		np->name = get_property(np, "name", NULL);
-		np->type = get_property(np, "device_type", NULL);
-
-		if (!np->name)
-			np->name = "<NULL>";
-		if (!np->type)
-			np->type = "<NULL>";
-	}
-	while (tag == OF_DT_BEGIN_NODE) {
-		mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
-		tag = *((u32 *)(*p));
-	}
-	if (tag != OF_DT_END_NODE) {
-		printk("Weird tag at end of node: %x\n", tag);
-		return mem;
-	}
-	*p += 4;
-	return mem;
-}
-
-
-/**
- * unflattens the device-tree passed by the firmware, creating the
- * tree of struct device_node. It also fills the "name" and "type"
- * pointers of the nodes so the normal device-tree walking functions
- * can be used (this used to be done by finish_device_tree)
- */
-void __init unflatten_device_tree(void)
-{
-	unsigned long start, mem, size;
-	struct device_node **allnextp = &allnodes;
-	char *p = NULL;
-	int l = 0;
-
-	DBG(" -> unflatten_device_tree()\n");
-
-	/* First pass, scan for size */
-	start = ((unsigned long)initial_boot_params) +
-		initial_boot_params->off_dt_struct;
-	size = unflatten_dt_node(0, &start, NULL, NULL, 0);
-	size = (size | 3) + 1;
-
-	DBG("  size is %lx, allocating...\n", size);
-
-	/* Allocate memory for the expanded device tree */
-	mem = lmb_alloc(size + 4, __alignof__(struct device_node));
-	if (!mem) {
-		DBG("Couldn't allocate memory with lmb_alloc()!\n");
-		panic("Couldn't allocate memory with lmb_alloc()!\n");
-	}
-	mem = (unsigned long)abs_to_virt(mem);
-
-	((u32 *)mem)[size / 4] = 0xdeadbeef;
-
-	DBG("  unflattening...\n", mem);
-
-	/* Second pass, do actual unflattening */
-	start = ((unsigned long)initial_boot_params) +
-		initial_boot_params->off_dt_struct;
-	unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
-	if (*((u32 *)start) != OF_DT_END)
-		printk(KERN_WARNING "Weird tag at end of tree: %08x\n", *((u32 *)start));
-	if (((u32 *)mem)[size / 4] != 0xdeadbeef)
-		printk(KERN_WARNING "End of tree marker overwritten: %08x\n",
-		       ((u32 *)mem)[size / 4] );
-	*allnextp = NULL;
-
-	/* Get pointer to OF "/chosen" node for use everywhere */
-	of_chosen = of_find_node_by_path("/chosen");
-
-	/* Retreive command line */
-	if (of_chosen != NULL) {
-		p = (char *)get_property(of_chosen, "bootargs", &l);
-		if (p != NULL && l > 0)
-			strlcpy(cmd_line, p, min(l, COMMAND_LINE_SIZE));
-	}
-#ifdef CONFIG_CMDLINE
-	if (l == 0 || (l == 1 && (*p) == 0))
-		strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
-#endif /* CONFIG_CMDLINE */
-
-	DBG("Command line is: %s\n", cmd_line);
-
-	DBG(" <- unflatten_device_tree()\n");
-}
-
-
-static int __init early_init_dt_scan_cpus(unsigned long node,
-					  const char *uname, int depth, void *data)
-{
-	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
-	u32 *prop;
-	unsigned long size;
-
-	/* We are scanning "cpu" nodes only */
-	if (type == NULL || strcmp(type, "cpu") != 0)
-		return 0;
-
-	if (initial_boot_params && initial_boot_params->version >= 2) {
-		/* version 2 of the kexec param format adds the phys cpuid
-		 * of booted proc.
-		 */
-		boot_cpuid_phys = initial_boot_params->boot_cpuid_phys;
-		boot_cpuid = 0;
-	} else {
-		/* Check if it's the boot-cpu, set it's hw index in paca now */
-		if (of_get_flat_dt_prop(node, "linux,boot-cpu", NULL)
-		    != NULL) {
-			u32 *prop = of_get_flat_dt_prop(node, "reg", NULL);
-			set_hard_smp_processor_id(0, prop == NULL ? 0 : *prop);
-			boot_cpuid_phys = get_hard_smp_processor_id(0);
-		}
-	}
-
-#ifdef CONFIG_ALTIVEC
-	/* Check if we have a VMX and eventually update CPU features */
-	prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", NULL);
-	if (prop && (*prop) > 0) {
-		cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
-		cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
-	}
-
-	/* Same goes for Apple's "altivec" property */
-	prop = (u32 *)of_get_flat_dt_prop(node, "altivec", NULL);
-	if (prop) {
-		cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
-		cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
-	}
-#endif /* CONFIG_ALTIVEC */
-
-	/*
-	 * Check for an SMT capable CPU and set the CPU feature. We do
-	 * this by looking at the size of the ibm,ppc-interrupt-server#s
-	 * property
-	 */
-	prop = (u32 *)of_get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
-				       &size);
-	cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
-	if (prop && ((size / sizeof(u32)) > 1))
-		cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
-
-	return 0;
-}
-
-static int __init early_init_dt_scan_chosen(unsigned long node,
-					    const char *uname, int depth, void *data)
-{
-	u32 *prop;
-	u64 *prop64;
-
-	DBG("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
-
-	if (depth != 1 || strcmp(uname, "chosen") != 0)
-		return 0;
-
-	/* get platform type */
-	prop = (u32 *)of_get_flat_dt_prop(node, "linux,platform", NULL);
-	if (prop == NULL)
-		return 0;
-	_machine = *prop;
-
-	/* check if iommu is forced on or off */
-	if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
-		iommu_is_off = 1;
-	if (of_get_flat_dt_prop(node, "linux,iommu-force-on", NULL) != NULL)
-		iommu_force_on = 1;
-
- 	prop64 = (u64*)of_get_flat_dt_prop(node, "linux,memory-limit", NULL);
- 	if (prop64)
- 		memory_limit = *prop64;
-
- 	prop64 = (u64*)of_get_flat_dt_prop(node, "linux,tce-alloc-start",NULL);
- 	if (prop64)
- 		tce_alloc_start = *prop64;
-
- 	prop64 = (u64*)of_get_flat_dt_prop(node, "linux,tce-alloc-end", NULL);
- 	if (prop64)
- 		tce_alloc_end = *prop64;
-
-#ifdef CONFIG_PPC_RTAS
-	/* To help early debugging via the front panel, we retreive a minimal
-	 * set of RTAS infos now if available
-	 */
-	{
-		u64 *basep, *entryp;
-
-		basep = (u64*)of_get_flat_dt_prop(node,
-						  "linux,rtas-base", NULL);
-		entryp = (u64*)of_get_flat_dt_prop(node,
-						   "linux,rtas-entry", NULL);
-		prop = (u32*)of_get_flat_dt_prop(node,
-						 "linux,rtas-size", NULL);
-		if (basep && entryp && prop) {
-			rtas.base = *basep;
-			rtas.entry = *entryp;
-			rtas.size = *prop;
-		}
-	}
-#endif /* CONFIG_PPC_RTAS */
-
-	/* break now */
-	return 1;
-}
-
-static int __init early_init_dt_scan_root(unsigned long node,
-					  const char *uname, int depth, void *data)
-{
-	u32 *prop;
-
-	if (depth != 0)
-		return 0;
-
-	prop = (u32 *)of_get_flat_dt_prop(node, "#size-cells", NULL);
-	dt_root_size_cells = (prop == NULL) ? 1 : *prop;
-	DBG("dt_root_size_cells = %x\n", dt_root_size_cells);
-
-	prop = (u32 *)of_get_flat_dt_prop(node, "#address-cells", NULL);
-	dt_root_addr_cells = (prop == NULL) ? 2 : *prop;
-	DBG("dt_root_addr_cells = %x\n", dt_root_addr_cells);
-	
-	/* break now */
-	return 1;
-}
-
-static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
-{
-	cell_t *p = *cellp;
-	unsigned long r = 0;
-
-	/* Ignore more than 2 cells */
-	while (s > 2) {
-		p++;
-		s--;
-	}
-	while (s) {
-		r <<= 32;
-		r |= *(p++);
-		s--;
-	}
-
-	*cellp = p;
-	return r;
-}
-
-
-static int __init early_init_dt_scan_memory(unsigned long node,
-					    const char *uname, int depth, void *data)
-{
-	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
-	cell_t *reg, *endp;
-	unsigned long l;
-
-	/* We are scanning "memory" nodes only */
-	if (type == NULL || strcmp(type, "memory") != 0)
-		return 0;
-
-	reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l);
-	if (reg == NULL)
-		return 0;
-
-	endp = reg + (l / sizeof(cell_t));
-
-	DBG("memory scan node %s ..., reg size %ld, data: %x %x %x %x, ...\n",
-	    uname, l, reg[0], reg[1], reg[2], reg[3]);
-
-	while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) {
-		unsigned long base, size;
-
-		base = dt_mem_next_cell(dt_root_addr_cells, &reg);
-		size = dt_mem_next_cell(dt_root_size_cells, &reg);
-
-		if (size == 0)
-			continue;
-		DBG(" - %lx ,  %lx\n", base, size);
-		if (iommu_is_off) {
-			if (base >= 0x80000000ul)
-				continue;
-			if ((base + size) > 0x80000000ul)
-				size = 0x80000000ul - base;
-		}
-		lmb_add(base, size);
-	}
-	return 0;
-}
-
-static void __init early_reserve_mem(void)
-{
-	u64 base, size;
-	u64 *reserve_map = (u64 *)(((unsigned long)initial_boot_params) +
-				   initial_boot_params->off_mem_rsvmap);
-	while (1) {
-		base = *(reserve_map++);
-		size = *(reserve_map++);
-		if (size == 0)
-			break;
-		DBG("reserving: %lx -> %lx\n", base, size);
-		lmb_reserve(base, size);
-	}
-
-#if 0
-	DBG("memory reserved, lmbs :\n");
-      	lmb_dump_all();
-#endif
-}
-
-void __init early_init_devtree(void *params)
-{
-	DBG(" -> early_init_devtree()\n");
-
-	/* Setup flat device-tree pointer */
-	initial_boot_params = params;
-
-	/* Retreive various informations from the /chosen node of the
-	 * device-tree, including the platform type, initrd location and
-	 * size, TCE reserve, and more ...
-	 */
-	of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
-
-	/* Scan memory nodes and rebuild LMBs */
-	lmb_init();
-	of_scan_flat_dt(early_init_dt_scan_root, NULL);
-	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
-	lmb_enforce_memory_limit(memory_limit);
-	lmb_analyze();
-	lmb_reserve(0, __pa(klimit));
-
-	/* Reserve LMB regions used by kernel, initrd, dt, etc... */
-	early_reserve_mem();
-
-	DBG("Scanning CPUs ...\n");
-
-	/* Retreive hash table size from flattened tree plus other
-	 * CPU related informations (altivec support, boot CPU ID, ...)
-	 */
-	of_scan_flat_dt(early_init_dt_scan_cpus, NULL);
-
-	DBG(" <- early_init_devtree()\n");
-}
-
-#undef printk
-
-int
-prom_n_addr_cells(struct device_node* np)
-{
-	int* ip;
-	do {
-		if (np->parent)
-			np = np->parent;
-		ip = (int *) get_property(np, "#address-cells", NULL);
-		if (ip != NULL)
-			return *ip;
-	} while (np->parent);
-	/* No #address-cells property for the root node, default to 1 */
-	return 1;
-}
-
-int
-prom_n_size_cells(struct device_node* np)
-{
-	int* ip;
-	do {
-		if (np->parent)
-			np = np->parent;
-		ip = (int *) get_property(np, "#size-cells", NULL);
-		if (ip != NULL)
-			return *ip;
-	} while (np->parent);
-	/* No #size-cells property for the root node, default to 1 */
-	return 1;
-}
-
-/**
- * Work out the sense (active-low level / active-high edge)
- * of each interrupt from the device tree.
- */
-void __init prom_get_irq_senses(unsigned char *senses, int off, int max)
-{
-	struct device_node *np;
-	int i, j;
-
-	/* default to level-triggered */
-	memset(senses, 1, max - off);
-
-	for (np = allnodes; np != 0; np = np->allnext) {
-		for (j = 0; j < np->n_intrs; j++) {
-			i = np->intrs[j].line;
-			if (i >= off && i < max)
-				senses[i-off] = np->intrs[j].sense ?
-					IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE :
-					IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE;
-		}
-	}
-}
-
-/**
- * Construct and return a list of the device_nodes with a given name.
- */
-struct device_node *
-find_devices(const char *name)
-{
-	struct device_node *head, **prevp, *np;
-
-	prevp = &head;
-	for (np = allnodes; np != 0; np = np->allnext) {
-		if (np->name != 0 && strcasecmp(np->name, name) == 0) {
-			*prevp = np;
-			prevp = &np->next;
-		}
-	}
-	*prevp = NULL;
-	return head;
-}
-EXPORT_SYMBOL(find_devices);
-
-/**
- * Construct and return a list of the device_nodes with a given type.
- */
-struct device_node *
-find_type_devices(const char *type)
-{
-	struct device_node *head, **prevp, *np;
-
-	prevp = &head;
-	for (np = allnodes; np != 0; np = np->allnext) {
-		if (np->type != 0 && strcasecmp(np->type, type) == 0) {
-			*prevp = np;
-			prevp = &np->next;
-		}
-	}
-	*prevp = NULL;
-	return head;
-}
-EXPORT_SYMBOL(find_type_devices);
-
-/**
- * Returns all nodes linked together
- */
-struct device_node *
-find_all_nodes(void)
-{
-	struct device_node *head, **prevp, *np;
-
-	prevp = &head;
-	for (np = allnodes; np != 0; np = np->allnext) {
-		*prevp = np;
-		prevp = &np->next;
-	}
-	*prevp = NULL;
-	return head;
-}
-EXPORT_SYMBOL(find_all_nodes);
-
-/** Checks if the given "compat" string matches one of the strings in
- * the device's "compatible" property
- */
-int
-device_is_compatible(struct device_node *device, const char *compat)
-{
-	const char* cp;
-	int cplen, l;
-
-	cp = (char *) get_property(device, "compatible", &cplen);
-	if (cp == NULL)
-		return 0;
-	while (cplen > 0) {
-		if (strncasecmp(cp, compat, strlen(compat)) == 0)
-			return 1;
-		l = strlen(cp) + 1;
-		cp += l;
-		cplen -= l;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL(device_is_compatible);
-
-
-/**
- * Indicates whether the root node has a given value in its
- * compatible property.
- */
-int
-machine_is_compatible(const char *compat)
-{
-	struct device_node *root;
-	int rc = 0;
-
-	root = of_find_node_by_path("/");
-	if (root) {
-		rc = device_is_compatible(root, compat);
-		of_node_put(root);
-	}
-	return rc;
-}
-EXPORT_SYMBOL(machine_is_compatible);
-
-/**
- * Construct and return a list of the device_nodes with a given type
- * and compatible property.
- */
-struct device_node *
-find_compatible_devices(const char *type, const char *compat)
-{
-	struct device_node *head, **prevp, *np;
-
-	prevp = &head;
-	for (np = allnodes; np != 0; np = np->allnext) {
-		if (type != NULL
-		    && !(np->type != 0 && strcasecmp(np->type, type) == 0))
-			continue;
-		if (device_is_compatible(np, compat)) {
-			*prevp = np;
-			prevp = &np->next;
-		}
-	}
-	*prevp = NULL;
-	return head;
-}
-EXPORT_SYMBOL(find_compatible_devices);
-
-/**
- * Find the device_node with a given full_name.
- */
-struct device_node *
-find_path_device(const char *path)
-{
-	struct device_node *np;
-
-	for (np = allnodes; np != 0; np = np->allnext)
-		if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0)
-			return np;
-	return NULL;
-}
-EXPORT_SYMBOL(find_path_device);
-
-/*******
- *
- * New implementation of the OF "find" APIs, return a refcounted
- * object, call of_node_put() when done.  The device tree and list
- * are protected by a rw_lock.
- *
- * Note that property management will need some locking as well,
- * this isn't dealt with yet.
- *
- *******/
-
-/**
- *	of_find_node_by_name - Find a node by its "name" property
- *	@from:	The node to start searching from or NULL, the node
- *		you pass will not be searched, only the next one
- *		will; typically, you pass what the previous call
- *		returned. of_node_put() will be called on it
- *	@name:	The name string to match against
- *
- *	Returns a node pointer with refcount incremented, use
- *	of_node_put() on it when done.
- */
-struct device_node *of_find_node_by_name(struct device_node *from,
-	const char *name)
-{
-	struct device_node *np;
-
-	read_lock(&devtree_lock);
-	np = from ? from->allnext : allnodes;
-	for (; np != 0; np = np->allnext)
-		if (np->name != 0 && strcasecmp(np->name, name) == 0
-		    && of_node_get(np))
-			break;
-	if (from)
-		of_node_put(from);
-	read_unlock(&devtree_lock);
-	return np;
-}
-EXPORT_SYMBOL(of_find_node_by_name);
-
-/**
- *	of_find_node_by_type - Find a node by its "device_type" property
- *	@from:	The node to start searching from or NULL, the node
- *		you pass will not be searched, only the next one
- *		will; typically, you pass what the previous call
- *		returned. of_node_put() will be called on it
- *	@name:	The type string to match against
- *
- *	Returns a node pointer with refcount incremented, use
- *	of_node_put() on it when done.
- */
-struct device_node *of_find_node_by_type(struct device_node *from,
-	const char *type)
-{
-	struct device_node *np;
-
-	read_lock(&devtree_lock);
-	np = from ? from->allnext : allnodes;
-	for (; np != 0; np = np->allnext)
-		if (np->type != 0 && strcasecmp(np->type, type) == 0
-		    && of_node_get(np))
-			break;
-	if (from)
-		of_node_put(from);
-	read_unlock(&devtree_lock);
-	return np;
-}
-EXPORT_SYMBOL(of_find_node_by_type);
-
-/**
- *	of_find_compatible_node - Find a node based on type and one of the
- *                                tokens in its "compatible" property
- *	@from:		The node to start searching from or NULL, the node
- *			you pass will not be searched, only the next one
- *			will; typically, you pass what the previous call
- *			returned. of_node_put() will be called on it
- *	@type:		The type string to match "device_type" or NULL to ignore
- *	@compatible:	The string to match to one of the tokens in the device
- *			"compatible" list.
- *
- *	Returns a node pointer with refcount incremented, use
- *	of_node_put() on it when done.
- */
-struct device_node *of_find_compatible_node(struct device_node *from,
-	const char *type, const char *compatible)
-{
-	struct device_node *np;
-
-	read_lock(&devtree_lock);
-	np = from ? from->allnext : allnodes;
-	for (; np != 0; np = np->allnext) {
-		if (type != NULL
-		    && !(np->type != 0 && strcasecmp(np->type, type) == 0))
-			continue;
-		if (device_is_compatible(np, compatible) && of_node_get(np))
-			break;
-	}
-	if (from)
-		of_node_put(from);
-	read_unlock(&devtree_lock);
-	return np;
-}
-EXPORT_SYMBOL(of_find_compatible_node);
-
-/**
- *	of_find_node_by_path - Find a node matching a full OF path
- *	@path:	The full path to match
- *
- *	Returns a node pointer with refcount incremented, use
- *	of_node_put() on it when done.
- */
-struct device_node *of_find_node_by_path(const char *path)
-{
-	struct device_node *np = allnodes;
-
-	read_lock(&devtree_lock);
-	for (; np != 0; np = np->allnext) {
-		if (np->full_name != 0 && strcasecmp(np->full_name, path) == 0
-		    && of_node_get(np))
-			break;
-	}
-	read_unlock(&devtree_lock);
-	return np;
-}
-EXPORT_SYMBOL(of_find_node_by_path);
-
-/**
- *	of_find_node_by_phandle - Find a node given a phandle
- *	@handle:	phandle of the node to find
- *
- *	Returns a node pointer with refcount incremented, use
- *	of_node_put() on it when done.
- */
-struct device_node *of_find_node_by_phandle(phandle handle)
-{
-	struct device_node *np;
-
-	read_lock(&devtree_lock);
-	for (np = allnodes; np != 0; np = np->allnext)
-		if (np->linux_phandle == handle)
-			break;
-	if (np)
-		of_node_get(np);
-	read_unlock(&devtree_lock);
-	return np;
-}
-EXPORT_SYMBOL(of_find_node_by_phandle);
-
-/**
- *	of_find_all_nodes - Get next node in global list
- *	@prev:	Previous node or NULL to start iteration
- *		of_node_put() will be called on it
- *
- *	Returns a node pointer with refcount incremented, use
- *	of_node_put() on it when done.
- */
-struct device_node *of_find_all_nodes(struct device_node *prev)
-{
-	struct device_node *np;
-
-	read_lock(&devtree_lock);
-	np = prev ? prev->allnext : allnodes;
-	for (; np != 0; np = np->allnext)
-		if (of_node_get(np))
-			break;
-	if (prev)
-		of_node_put(prev);
-	read_unlock(&devtree_lock);
-	return np;
-}
-EXPORT_SYMBOL(of_find_all_nodes);
-
-/**
- *	of_get_parent - Get a node's parent if any
- *	@node:	Node to get parent
- *
- *	Returns a node pointer with refcount incremented, use
- *	of_node_put() on it when done.
- */
-struct device_node *of_get_parent(const struct device_node *node)
-{
-	struct device_node *np;
-
-	if (!node)
-		return NULL;
-
-	read_lock(&devtree_lock);
-	np = of_node_get(node->parent);
-	read_unlock(&devtree_lock);
-	return np;
-}
-EXPORT_SYMBOL(of_get_parent);
-
-/**
- *	of_get_next_child - Iterate a node childs
- *	@node:	parent node
- *	@prev:	previous child of the parent node, or NULL to get first
- *
- *	Returns a node pointer with refcount incremented, use
- *	of_node_put() on it when done.
- */
-struct device_node *of_get_next_child(const struct device_node *node,
-	struct device_node *prev)
-{
-	struct device_node *next;
-
-	read_lock(&devtree_lock);
-	next = prev ? prev->sibling : node->child;
-	for (; next != 0; next = next->sibling)
-		if (of_node_get(next))
-			break;
-	if (prev)
-		of_node_put(prev);
-	read_unlock(&devtree_lock);
-	return next;
-}
-EXPORT_SYMBOL(of_get_next_child);
-
-/**
- *	of_node_get - Increment refcount of a node
- *	@node:	Node to inc refcount, NULL is supported to
- *		simplify writing of callers
- *
- *	Returns node.
- */
-struct device_node *of_node_get(struct device_node *node)
-{
-	if (node)
-		kref_get(&node->kref);
-	return node;
-}
-EXPORT_SYMBOL(of_node_get);
-
-static inline struct device_node * kref_to_device_node(struct kref *kref)
-{
-	return container_of(kref, struct device_node, kref);
-}
-
-/**
- *	of_node_release - release a dynamically allocated node
- *	@kref:  kref element of the node to be released
- *
- *	In of_node_put() this function is passed to kref_put()
- *	as the destructor.
- */
-static void of_node_release(struct kref *kref)
-{
-	struct device_node *node = kref_to_device_node(kref);
-	struct property *prop = node->properties;
-
-	if (!OF_IS_DYNAMIC(node))
-		return;
-	while (prop) {
-		struct property *next = prop->next;
-		kfree(prop->name);
-		kfree(prop->value);
-		kfree(prop);
-		prop = next;
-	}
-	kfree(node->intrs);
-	kfree(node->addrs);
-	kfree(node->full_name);
-	kfree(node->data);
-	kfree(node);
-}
-
-/**
- *	of_node_put - Decrement refcount of a node
- *	@node:	Node to dec refcount, NULL is supported to
- *		simplify writing of callers
- *
- */
-void of_node_put(struct device_node *node)
-{
-	if (node)
-		kref_put(&node->kref, of_node_release);
-}
-EXPORT_SYMBOL(of_node_put);
-
-/*
- * Fix up the uninitialized fields in a new device node:
- * name, type, n_addrs, addrs, n_intrs, intrs, and pci-specific fields
- *
- * A lot of boot-time code is duplicated here, because functions such
- * as finish_node_interrupts, interpret_pci_props, etc. cannot use the
- * slab allocator.
- *
- * This should probably be split up into smaller chunks.
- */
-
-static int of_finish_dynamic_node(struct device_node *node,
-				  unsigned long *unused1, int unused2,
-				  int unused3, int unused4)
-{
-	struct device_node *parent = of_get_parent(node);
-	int err = 0;
-	phandle *ibm_phandle;
-
-	node->name = get_property(node, "name", NULL);
-	node->type = get_property(node, "device_type", NULL);
-
-	if (!parent) {
-		err = -ENODEV;
-		goto out;
-	}
-
-	/* We don't support that function on PowerMac, at least
-	 * not yet
-	 */
-	if (_machine == PLATFORM_POWERMAC)
-		return -ENODEV;
-
-	/* fix up new node's linux_phandle field */
-	if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL)))
-		node->linux_phandle = *ibm_phandle;
-
-out:
-	of_node_put(parent);
-	return err;
-}
-
-/*
- * Plug a device node into the tree and global list.
- */
-void of_attach_node(struct device_node *np)
-{
-	write_lock(&devtree_lock);
-	np->sibling = np->parent->child;
-	np->allnext = allnodes;
-	np->parent->child = np;
-	allnodes = np;
-	write_unlock(&devtree_lock);
-}
-
-/*
- * "Unplug" a node from the device tree.  The caller must hold
- * a reference to the node.  The memory associated with the node
- * is not freed until its refcount goes to zero.
- */
-void of_detach_node(const struct device_node *np)
-{
-	struct device_node *parent;
-
-	write_lock(&devtree_lock);
-
-	parent = np->parent;
-
-	if (allnodes == np)
-		allnodes = np->allnext;
-	else {
-		struct device_node *prev;
-		for (prev = allnodes;
-		     prev->allnext != np;
-		     prev = prev->allnext)
-			;
-		prev->allnext = np->allnext;
-	}
-
-	if (parent->child == np)
-		parent->child = np->sibling;
-	else {
-		struct device_node *prevsib;
-		for (prevsib = np->parent->child;
-		     prevsib->sibling != np;
-		     prevsib = prevsib->sibling)
-			;
-		prevsib->sibling = np->sibling;
-	}
-
-	write_unlock(&devtree_lock);
-}
-
-static int prom_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
-{
-	int err;
-
-	switch (action) {
-	case PSERIES_RECONFIG_ADD:
-		err = finish_node(node, NULL, of_finish_dynamic_node, 0, 0, 0);
-		if (err < 0) {
-			printk(KERN_ERR "finish_node returned %d\n", err);
-			err = NOTIFY_BAD;
-		}
-		break;
-	default:
-		err = NOTIFY_DONE;
-		break;
-	}
-	return err;
-}
-
-static struct notifier_block prom_reconfig_nb = {
-	.notifier_call = prom_reconfig_notifier,
-	.priority = 10, /* This one needs to run first */
-};
-
-static int __init prom_reconfig_setup(void)
-{
-	return pSeries_reconfig_notifier_register(&prom_reconfig_nb);
-}
-__initcall(prom_reconfig_setup);
-
-/*
- * Find a property with a given name for a given node
- * and return the value.
- */
-unsigned char *
-get_property(struct device_node *np, const char *name, int *lenp)
-{
-	struct property *pp;
-
-	for (pp = np->properties; pp != 0; pp = pp->next)
-		if (strcmp(pp->name, name) == 0) {
-			if (lenp != 0)
-				*lenp = pp->length;
-			return pp->value;
-		}
-	return NULL;
-}
-EXPORT_SYMBOL(get_property);
-
-/*
- * Add a property to a node.
- */
-int
-prom_add_property(struct device_node* np, struct property* prop)
-{
-	struct property **next;
-
-	prop->next = NULL;	
-	write_lock(&devtree_lock);
-	next = &np->properties;
-	while (*next) {
-		if (strcmp(prop->name, (*next)->name) == 0) {
-			/* duplicate ! don't insert it */
-			write_unlock(&devtree_lock);
-			return -1;
-		}
-		next = &(*next)->next;
-	}
-	*next = prop;
-	write_unlock(&devtree_lock);
-
-	/* try to add to proc as well if it was initialized */
-	if (np->pde)
-		proc_device_tree_add_prop(np->pde, prop);
-
-	return 0;
-}
-
-#if 0
-void
-print_properties(struct device_node *np)
-{
-	struct property *pp;
-	char *cp;
-	int i, n;
-
-	for (pp = np->properties; pp != 0; pp = pp->next) {
-		printk(KERN_INFO "%s", pp->name);
-		for (i = strlen(pp->name); i < 16; ++i)
-			printk(" ");
-		cp = (char *) pp->value;
-		for (i = pp->length; i > 0; --i, ++cp)
-			if ((i > 1 && (*cp < 0x20 || *cp > 0x7e))
-			    || (i == 1 && *cp != 0))
-				break;
-		if (i == 0 && pp->length > 1) {
-			/* looks like a string */
-			printk(" %s\n", (char *) pp->value);
-		} else {
-			/* dump it in hex */
-			n = pp->length;
-			if (n > 64)
-				n = 64;
-			if (pp->length % 4 == 0) {
-				unsigned int *p = (unsigned int *) pp->value;
-
-				n /= 4;
-				for (i = 0; i < n; ++i) {
-					if (i != 0 && (i % 4) == 0)
-						printk("\n                ");
-					printk(" %08x", *p++);
-				}
-			} else {
-				unsigned char *bp = pp->value;
-
-				for (i = 0; i < n; ++i) {
-					if (i != 0 && (i % 16) == 0)
-						printk("\n                ");
-					printk(" %02x", *bp++);
-				}
-			}
-			printk("\n");
-			if (pp->length > 64)
-				printk("                 ... (length = %d)\n",
-				       pp->length);
-		}
-	}
-}
-#endif
-
-
-
-
-
-
-
-
-
-
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c
deleted file mode 100644
index 6375f40..0000000
--- a/arch/ppc64/kernel/prom_init.c
+++ /dev/null
@@ -1,2051 +0,0 @@
-/*
- * 
- *
- * Procedures for interfacing to Open Firmware.
- *
- * Paul Mackerras	August 1996.
- * Copyright (C) 1996 Paul Mackerras.
- * 
- *  Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
- *    {engebret|bergner}@us.ibm.com 
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
- */
-
-#undef DEBUG_PROM
-
-#include <stdarg.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/threads.h>
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/stringify.h>
-#include <linux/delay.h>
-#include <linux/initrd.h>
-#include <linux/bitops.h>
-#include <asm/prom.h>
-#include <asm/rtas.h>
-#include <asm/abs_addr.h>
-#include <asm/page.h>
-#include <asm/processor.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/system.h>
-#include <asm/mmu.h>
-#include <asm/pgtable.h>
-#include <asm/pci.h>
-#include <asm/iommu.h>
-#include <asm/btext.h>
-#include <asm/sections.h>
-#include <asm/machdep.h>
-
-#ifdef CONFIG_LOGO_LINUX_CLUT224
-#include <linux/linux_logo.h>
-extern const struct linux_logo logo_linux_clut224;
-#endif
-
-/*
- * Properties whose value is longer than this get excluded from our
- * copy of the device tree. This value does need to be big enough to
- * ensure that we don't lose things like the interrupt-map property
- * on a PCI-PCI bridge.
- */
-#define MAX_PROPERTY_LENGTH	(1UL * 1024 * 1024)
-
-/*
- * Eventually bump that one up
- */
-#define DEVTREE_CHUNK_SIZE	0x100000
-
-/*
- * This is the size of the local memory reserve map that gets copied
- * into the boot params passed to the kernel. That size is totally
- * flexible as the kernel just reads the list until it encounters an
- * entry with size 0, so it can be changed without breaking binary
- * compatibility
- */
-#define MEM_RESERVE_MAP_SIZE	8
-
-/*
- * prom_init() is called very early on, before the kernel text
- * and data have been mapped to KERNELBASE.  At this point the code
- * is running at whatever address it has been loaded at, so
- * references to extern and static variables must be relocated
- * explicitly.  The procedure reloc_offset() returns the address
- * we're currently running at minus the address we were linked at.
- * (Note that strings count as static variables.)
- *
- * Because OF may have mapped I/O devices into the area starting at
- * KERNELBASE, particularly on CHRP machines, we can't safely call
- * OF once the kernel has been mapped to KERNELBASE.  Therefore all
- * OF calls should be done within prom_init(), and prom_init()
- * and all routines called within it must be careful to relocate
- * references as necessary.
- *
- * Note that the bss is cleared *after* prom_init runs, so we have
- * to make sure that any static or extern variables it accesses
- * are put in the data segment.
- */
-
-
-#define PROM_BUG() do {						\
-        prom_printf("kernel BUG at %s line 0x%x!\n",		\
-		    RELOC(__FILE__), __LINE__);			\
-        __asm__ __volatile__(".long " BUG_ILLEGAL_INSTR);	\
-} while (0)
-
-#ifdef DEBUG_PROM
-#define prom_debug(x...)	prom_printf(x)
-#else
-#define prom_debug(x...)
-#endif
-
-
-typedef u32 prom_arg_t;
-
-struct prom_args {
-        u32 service;
-        u32 nargs;
-        u32 nret;
-        prom_arg_t args[10];
-        prom_arg_t *rets;     /* Pointer to return values in args[16]. */
-};
-
-struct prom_t {
-	unsigned long entry;
-	ihandle root;
-	ihandle chosen;
-	int cpu;
-	ihandle stdout;
-	ihandle disp_node;
-	struct prom_args args;
-	unsigned long version;
-	unsigned long root_size_cells;
-	unsigned long root_addr_cells;
-};
-
-struct pci_reg_property {
-	struct pci_address addr;
-	u32 size_hi;
-	u32 size_lo;
-};
-
-struct mem_map_entry {
-	u64	base;
-	u64	size;
-};
-
-typedef u32 cell_t;
-
-extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
-
-extern void enter_prom(struct prom_args *args, unsigned long entry);
-extern void copy_and_flush(unsigned long dest, unsigned long src,
-			   unsigned long size, unsigned long offset);
-
-extern unsigned long klimit;
-
-/* prom structure */
-static struct prom_t __initdata prom;
-
-#define PROM_SCRATCH_SIZE 256
-
-static char __initdata of_stdout_device[256];
-static char __initdata prom_scratch[PROM_SCRATCH_SIZE];
-
-static unsigned long __initdata dt_header_start;
-static unsigned long __initdata dt_struct_start, dt_struct_end;
-static unsigned long __initdata dt_string_start, dt_string_end;
-
-static unsigned long __initdata prom_initrd_start, prom_initrd_end;
-
-static int __initdata iommu_force_on;
-static int __initdata ppc64_iommu_off;
-static int __initdata of_platform;
-
-static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
-
-static unsigned long __initdata prom_memory_limit;
-static unsigned long __initdata prom_tce_alloc_start;
-static unsigned long __initdata prom_tce_alloc_end;
-
-static unsigned long __initdata alloc_top;
-static unsigned long __initdata alloc_top_high;
-static unsigned long __initdata alloc_bottom;
-static unsigned long __initdata rmo_top;
-static unsigned long __initdata ram_top;
-
-static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
-static int __initdata mem_reserve_cnt;
-
-static cell_t __initdata regbuf[1024];
-
-
-#define MAX_CPU_THREADS 2
-
-/* TO GO */
-#ifdef CONFIG_HMT
-struct {
-	unsigned int pir;
-	unsigned int threadid;
-} hmt_thread_data[NR_CPUS];
-#endif /* CONFIG_HMT */
-
-/*
- * This are used in calls to call_prom.  The 4th and following
- * arguments to call_prom should be 32-bit values.  64 bit values
- * are truncated to 32 bits (and fortunately don't get interpreted
- * as two arguments).
- */
-#define ADDR(x)		(u32) ((unsigned long)(x) - offset)
-
-/*
- * Error results ... some OF calls will return "-1" on error, some
- * will return 0, some will return either. To simplify, here are
- * macros to use with any ihandle or phandle return value to check if
- * it is valid
- */
-
-#define PROM_ERROR		(-1u)
-#define PHANDLE_VALID(p)	((p) != 0 && (p) != PROM_ERROR)
-#define IHANDLE_VALID(i)	((i) != 0 && (i) != PROM_ERROR)
-
-
-/* This is the one and *ONLY* place where we actually call open
- * firmware from, since we need to make sure we're running in 32b
- * mode when we do.  We switch back to 64b mode upon return.
- */
-
-static int __init call_prom(const char *service, int nargs, int nret, ...)
-{
-	int i;
-	unsigned long offset = reloc_offset();
-	struct prom_t *_prom = PTRRELOC(&prom);
-	va_list list;
-
-	_prom->args.service = ADDR(service);
-	_prom->args.nargs = nargs;
-	_prom->args.nret = nret;
-	_prom->args.rets = (prom_arg_t *)&(_prom->args.args[nargs]);
-
-	va_start(list, nret);
-	for (i=0; i < nargs; i++)
-		_prom->args.args[i] = va_arg(list, prom_arg_t);
-	va_end(list);
-
-	for (i=0; i < nret ;i++)
-		_prom->args.rets[i] = 0;
-
-	enter_prom(&_prom->args, _prom->entry);
-
-	return (nret > 0) ? _prom->args.rets[0] : 0;
-}
-
-
-static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
-				unsigned long align)
-{
-	return (unsigned int)call_prom("claim", 3, 1,
-				       (prom_arg_t)virt, (prom_arg_t)size,
-				       (prom_arg_t)align);
-}
-
-static void __init prom_print(const char *msg)
-{
-	const char *p, *q;
-	unsigned long offset = reloc_offset();
-	struct prom_t *_prom = PTRRELOC(&prom);
-
-	if (_prom->stdout == 0)
-		return;
-
-	for (p = msg; *p != 0; p = q) {
-		for (q = p; *q != 0 && *q != '\n'; ++q)
-			;
-		if (q > p)
-			call_prom("write", 3, 1, _prom->stdout, p, q - p);
-		if (*q == 0)
-			break;
-		++q;
-		call_prom("write", 3, 1, _prom->stdout, ADDR("\r\n"), 2);
-	}
-}
-
-
-static void __init prom_print_hex(unsigned long val)
-{
-	unsigned long offset = reloc_offset();
-	int i, nibbles = sizeof(val)*2;
-	char buf[sizeof(val)*2+1];
-	struct prom_t *_prom = PTRRELOC(&prom);
-
-	for (i = nibbles-1;  i >= 0;  i--) {
-		buf[i] = (val & 0xf) + '0';
-		if (buf[i] > '9')
-			buf[i] += ('a'-'0'-10);
-		val >>= 4;
-	}
-	buf[nibbles] = '\0';
-	call_prom("write", 3, 1, _prom->stdout, buf, nibbles);
-}
-
-
-static void __init prom_printf(const char *format, ...)
-{
-	unsigned long offset = reloc_offset();
-	const char *p, *q, *s;
-	va_list args;
-	unsigned long v;
-	struct prom_t *_prom = PTRRELOC(&prom);
-
-	va_start(args, format);
-	for (p = PTRRELOC(format); *p != 0; p = q) {
-		for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
-			;
-		if (q > p)
-			call_prom("write", 3, 1, _prom->stdout, p, q - p);
-		if (*q == 0)
-			break;
-		if (*q == '\n') {
-			++q;
-			call_prom("write", 3, 1, _prom->stdout,
-				  ADDR("\r\n"), 2);
-			continue;
-		}
-		++q;
-		if (*q == 0)
-			break;
-		switch (*q) {
-		case 's':
-			++q;
-			s = va_arg(args, const char *);
-			prom_print(s);
-			break;
-		case 'x':
-			++q;
-			v = va_arg(args, unsigned long);
-			prom_print_hex(v);
-			break;
-		}
-	}
-}
-
-
-static void __init __attribute__((noreturn)) prom_panic(const char *reason)
-{
-	unsigned long offset = reloc_offset();
-
-	prom_print(PTRRELOC(reason));
-	/* ToDo: should put up an SRC here */
-	call_prom("exit", 0, 0);
-
-	for (;;)			/* should never get here */
-		;
-}
-
-
-static int __init prom_next_node(phandle *nodep)
-{
-	phandle node;
-
-	if ((node = *nodep) != 0
-	    && (*nodep = call_prom("child", 1, 1, node)) != 0)
-		return 1;
-	if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
-		return 1;
-	for (;;) {
-		if ((node = call_prom("parent", 1, 1, node)) == 0)
-			return 0;
-		if ((*nodep = call_prom("peer", 1, 1, node)) != 0)
-			return 1;
-	}
-}
-
-static int __init prom_getprop(phandle node, const char *pname,
-			       void *value, size_t valuelen)
-{
-	unsigned long offset = reloc_offset();
-
-	return call_prom("getprop", 4, 1, node, ADDR(pname),
-			 (u32)(unsigned long) value, (u32) valuelen);
-}
-
-static int __init prom_getproplen(phandle node, const char *pname)
-{
-	unsigned long offset = reloc_offset();
-
-	return call_prom("getproplen", 2, 1, node, ADDR(pname));
-}
-
-static int __init prom_setprop(phandle node, const char *pname,
-			       void *value, size_t valuelen)
-{
-	unsigned long offset = reloc_offset();
-
-	return call_prom("setprop", 4, 1, node, ADDR(pname),
-			 (u32)(unsigned long) value, (u32) valuelen);
-}
-
-/* We can't use the standard versions because of RELOC headaches. */
-#define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
-			 || ('a' <= (c) && (c) <= 'f') \
-			 || ('A' <= (c) && (c) <= 'F'))
-
-#define isdigit(c)	('0' <= (c) && (c) <= '9')
-#define islower(c)	('a' <= (c) && (c) <= 'z')
-#define toupper(c)	(islower(c) ? ((c) - 'a' + 'A') : (c))
-
-unsigned long prom_strtoul(const char *cp, const char **endp)
-{
-	unsigned long result = 0, base = 10, value;
-
-	if (*cp == '0') {
-		base = 8;
-		cp++;
-		if (toupper(*cp) == 'X') {
-			cp++;
-			base = 16;
-		}
-	}
-
-	while (isxdigit(*cp) &&
-	       (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) {
-		result = result * base + value;
-		cp++;
-	}
-
-	if (endp)
-		*endp = cp;
-
-	return result;
-}
-
-unsigned long prom_memparse(const char *ptr, const char **retptr)
-{
-	unsigned long ret = prom_strtoul(ptr, retptr);
-	int shift = 0;
-
-	/*
-	 * We can't use a switch here because GCC *may* generate a
-	 * jump table which won't work, because we're not running at
-	 * the address we're linked at.
-	 */
-	if ('G' == **retptr || 'g' == **retptr)
-		shift = 30;
-
-	if ('M' == **retptr || 'm' == **retptr)
-		shift = 20;
-
-	if ('K' == **retptr || 'k' == **retptr)
-		shift = 10;
-
-	if (shift) {
-		ret <<= shift;
-		(*retptr)++;
-	}
-
-	return ret;
-}
-
-/*
- * Early parsing of the command line passed to the kernel, used for
- * "mem=x" and the options that affect the iommu
- */
-static void __init early_cmdline_parse(void)
-{
-	unsigned long offset = reloc_offset();
-	struct prom_t *_prom = PTRRELOC(&prom);
-	char *opt, *p;
-	int l = 0;
-
-	RELOC(prom_cmd_line[0]) = 0;
-	p = RELOC(prom_cmd_line);
-	if ((long)_prom->chosen > 0)
-		l = prom_getprop(_prom->chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
-#ifdef CONFIG_CMDLINE
-	if (l == 0) /* dbl check */
-		strlcpy(RELOC(prom_cmd_line),
-			RELOC(CONFIG_CMDLINE), sizeof(prom_cmd_line));
-#endif /* CONFIG_CMDLINE */
-	prom_printf("command line: %s\n", RELOC(prom_cmd_line));
-
-	opt = strstr(RELOC(prom_cmd_line), RELOC("iommu="));
-	if (opt) {
-		prom_printf("iommu opt is: %s\n", opt);
-		opt += 6;
-		while (*opt && *opt == ' ')
-			opt++;
-		if (!strncmp(opt, RELOC("off"), 3))
-			RELOC(ppc64_iommu_off) = 1;
-		else if (!strncmp(opt, RELOC("force"), 5))
-			RELOC(iommu_force_on) = 1;
-	}
-
-	opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
-	if (opt) {
-		opt += 4;
-		RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
-		/* Align to 16 MB == size of large page */
-		RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
-	}
-}
-
-/*
- * To tell the firmware what our capabilities are, we have to pass
- * it a fake 32-bit ELF header containing a couple of PT_NOTE sections
- * that contain structures that contain the actual values.
- */
-static struct fake_elf {
-	Elf32_Ehdr	elfhdr;
-	Elf32_Phdr	phdr[2];
-	struct chrpnote {
-		u32	namesz;
-		u32	descsz;
-		u32	type;
-		char	name[8];	/* "PowerPC" */
-		struct chrpdesc {
-			u32	real_mode;
-			u32	real_base;
-			u32	real_size;
-			u32	virt_base;
-			u32	virt_size;
-			u32	load_base;
-		} chrpdesc;
-	} chrpnote;
-	struct rpanote {
-		u32	namesz;
-		u32	descsz;
-		u32	type;
-		char	name[24];	/* "IBM,RPA-Client-Config" */
-		struct rpadesc {
-			u32	lpar_affinity;
-			u32	min_rmo_size;
-			u32	min_rmo_percent;
-			u32	max_pft_size;
-			u32	splpar;
-			u32	min_load;
-			u32	new_mem_def;
-			u32	ignore_me;
-		} rpadesc;
-	} rpanote;
-} fake_elf = {
-	.elfhdr = {
-		.e_ident = { 0x7f, 'E', 'L', 'F',
-			     ELFCLASS32, ELFDATA2MSB, EV_CURRENT },
-		.e_type = ET_EXEC,	/* yeah right */
-		.e_machine = EM_PPC,
-		.e_version = EV_CURRENT,
-		.e_phoff = offsetof(struct fake_elf, phdr),
-		.e_phentsize = sizeof(Elf32_Phdr),
-		.e_phnum = 2
-	},
-	.phdr = {
-		[0] = {
-			.p_type = PT_NOTE,
-			.p_offset = offsetof(struct fake_elf, chrpnote),
-			.p_filesz = sizeof(struct chrpnote)
-		}, [1] = {
-			.p_type = PT_NOTE,
-			.p_offset = offsetof(struct fake_elf, rpanote),
-			.p_filesz = sizeof(struct rpanote)
-		}
-	},
-	.chrpnote = {
-		.namesz = sizeof("PowerPC"),
-		.descsz = sizeof(struct chrpdesc),
-		.type = 0x1275,
-		.name = "PowerPC",
-		.chrpdesc = {
-			.real_mode = ~0U,	/* ~0 means "don't care" */
-			.real_base = ~0U,
-			.real_size = ~0U,
-			.virt_base = ~0U,
-			.virt_size = ~0U,
-			.load_base = ~0U
-		},
-	},
-	.rpanote = {
-		.namesz = sizeof("IBM,RPA-Client-Config"),
-		.descsz = sizeof(struct rpadesc),
-		.type = 0x12759999,
-		.name = "IBM,RPA-Client-Config",
-		.rpadesc = {
-			.lpar_affinity = 0,
-			.min_rmo_size = 64,	/* in megabytes */
-			.min_rmo_percent = 0,
-			.max_pft_size = 48,	/* 2^48 bytes max PFT size */
-			.splpar = 1,
-			.min_load = ~0U,
-			.new_mem_def = 0
-		}
-	}
-};
-
-static void __init prom_send_capabilities(void)
-{
-	unsigned long offset = reloc_offset();
-	ihandle elfloader;
-
-	elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
-	if (elfloader == 0) {
-		prom_printf("couldn't open /packages/elf-loader\n");
-		return;
-	}
-	call_prom("call-method", 3, 1, ADDR("process-elf-header"),
-			elfloader, ADDR(&fake_elf));
-	call_prom("close", 1, 0, elfloader);
-}
-
-/*
- * Memory allocation strategy... our layout is normally:
- *
- *  at 14Mb or more we vmlinux, then a gap and initrd. In some rare cases, initrd
- *  might end up beeing before the kernel though. We assume this won't override
- *  the final kernel at 0, we have no provision to handle that in this version,
- *  but it should hopefully never happen.
- *
- *  alloc_top is set to the top of RMO, eventually shrink down if the TCEs overlap
- *  alloc_bottom is set to the top of kernel/initrd
- *
- *  from there, allocations are done that way : rtas is allocated topmost, and
- *  the device-tree is allocated from the bottom. We try to grow the device-tree
- *  allocation as we progress. If we can't, then we fail, we don't currently have
- *  a facility to restart elsewhere, but that shouldn't be necessary neither
- *
- *  Note that calls to reserve_mem have to be done explicitely, memory allocated
- *  with either alloc_up or alloc_down isn't automatically reserved.
- */
-
-
-/*
- * Allocates memory in the RMO upward from the kernel/initrd
- *
- * When align is 0, this is a special case, it means to allocate in place
- * at the current location of alloc_bottom or fail (that is basically
- * extending the previous allocation). Used for the device-tree flattening
- */
-static unsigned long __init alloc_up(unsigned long size, unsigned long align)
-{
-	unsigned long offset = reloc_offset();
-	unsigned long base = _ALIGN_UP(RELOC(alloc_bottom), align);
-	unsigned long addr = 0;
-
-	prom_debug("alloc_up(%x, %x)\n", size, align);
-	if (RELOC(ram_top) == 0)
-		prom_panic("alloc_up() called with mem not initialized\n");
-
-	if (align)
-		base = _ALIGN_UP(RELOC(alloc_bottom), align);
-	else
-		base = RELOC(alloc_bottom);
-
-	for(; (base + size) <= RELOC(alloc_top); 
-	    base = _ALIGN_UP(base + 0x100000, align)) {
-		prom_debug("    trying: 0x%x\n\r", base);
-		addr = (unsigned long)prom_claim(base, size, 0);
-		if (addr != PROM_ERROR)
-			break;
-		addr = 0;
-		if (align == 0)
-			break;
-	}
-	if (addr == 0)
-		return 0;
-	RELOC(alloc_bottom) = addr;
-
-	prom_debug(" -> %x\n", addr);
-	prom_debug("  alloc_bottom : %x\n", RELOC(alloc_bottom));
-	prom_debug("  alloc_top    : %x\n", RELOC(alloc_top));
-	prom_debug("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
-	prom_debug("  rmo_top      : %x\n", RELOC(rmo_top));
-	prom_debug("  ram_top      : %x\n", RELOC(ram_top));
-
-	return addr;
-}
-
-/*
- * Allocates memory downard, either from top of RMO, or if highmem
- * is set, from the top of RAM. Note that this one doesn't handle
- * failures. In does claim memory if highmem is not set.
- */
-static unsigned long __init alloc_down(unsigned long size, unsigned long align,
-				       int highmem)
-{
-	unsigned long offset = reloc_offset();
-	unsigned long base, addr = 0;
-
-	prom_debug("alloc_down(%x, %x, %s)\n", size, align,
-		   highmem ? RELOC("(high)") : RELOC("(low)"));
-	if (RELOC(ram_top) == 0)
-		prom_panic("alloc_down() called with mem not initialized\n");
-
-	if (highmem) {
-		/* Carve out storage for the TCE table. */
-		addr = _ALIGN_DOWN(RELOC(alloc_top_high) - size, align);
-		if (addr <= RELOC(alloc_bottom))
-			return 0;
-		else {
-			/* Will we bump into the RMO ? If yes, check out that we
-			 * didn't overlap existing allocations there, if we did,
-			 * we are dead, we must be the first in town !
-			 */
-			if (addr < RELOC(rmo_top)) {
-				/* Good, we are first */
-				if (RELOC(alloc_top) == RELOC(rmo_top))
-					RELOC(alloc_top) = RELOC(rmo_top) = addr;
-				else
-					return 0;
-			}
-			RELOC(alloc_top_high) = addr;
-		}
-		goto bail;
-	}
-
-	base = _ALIGN_DOWN(RELOC(alloc_top) - size, align);
-	for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align))  {
-		prom_debug("    trying: 0x%x\n\r", base);
-		addr = (unsigned long)prom_claim(base, size, 0);
-		if (addr != PROM_ERROR)
-			break;
-		addr = 0;
-	}
-	if (addr == 0)
-		return 0;
-	RELOC(alloc_top) = addr;
-
- bail:
-	prom_debug(" -> %x\n", addr);
-	prom_debug("  alloc_bottom : %x\n", RELOC(alloc_bottom));
-	prom_debug("  alloc_top    : %x\n", RELOC(alloc_top));
-	prom_debug("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
-	prom_debug("  rmo_top      : %x\n", RELOC(rmo_top));
-	prom_debug("  ram_top      : %x\n", RELOC(ram_top));
-
-	return addr;
-}
-
-/*
- * Parse a "reg" cell
- */
-static unsigned long __init prom_next_cell(int s, cell_t **cellp)
-{
-	cell_t *p = *cellp;
-	unsigned long r = 0;
-
-	/* Ignore more than 2 cells */
-	while (s > 2) {
-		p++;
-		s--;
-	}
-	while (s) {
-		r <<= 32;
-		r |= *(p++);
-		s--;
-	}
-
-	*cellp = p;
-	return r;
-}
-
-/*
- * Very dumb function for adding to the memory reserve list, but
- * we don't need anything smarter at this point
- *
- * XXX Eventually check for collisions. They should NEVER happen
- * if problems seem to show up, it would be a good start to track
- * them down.
- */
-static void reserve_mem(unsigned long base, unsigned long size)
-{
-	unsigned long offset = reloc_offset();
-	unsigned long top = base + size;
-	unsigned long cnt = RELOC(mem_reserve_cnt);
-
-	if (size == 0)
-		return;
-
-	/* We need to always keep one empty entry so that we
-	 * have our terminator with "size" set to 0 since we are
-	 * dumb and just copy this entire array to the boot params
-	 */
-	base = _ALIGN_DOWN(base, PAGE_SIZE);
-	top = _ALIGN_UP(top, PAGE_SIZE);
-	size = top - base;
-
-	if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
-		prom_panic("Memory reserve map exhausted !\n");
-	RELOC(mem_reserve_map)[cnt].base = base;
-	RELOC(mem_reserve_map)[cnt].size = size;
-	RELOC(mem_reserve_cnt) = cnt + 1;
-}
-
-/*
- * Initialize memory allocation mecanism, parse "memory" nodes and
- * obtain that way the top of memory and RMO to setup out local allocator
- */
-static void __init prom_init_mem(void)
-{
-	phandle node;
-	char *path, type[64];
-	unsigned int plen;
-	cell_t *p, *endp;
-	unsigned long offset = reloc_offset();
-	struct prom_t *_prom = PTRRELOC(&prom);
-
-	/*
-	 * We iterate the memory nodes to find
-	 * 1) top of RMO (first node)
-	 * 2) top of memory
-	 */
-	prom_debug("root_addr_cells: %x\n", (long)_prom->root_addr_cells);
-	prom_debug("root_size_cells: %x\n", (long)_prom->root_size_cells);
-
-	prom_debug("scanning memory:\n");
-	path = RELOC(prom_scratch);
-
-	for (node = 0; prom_next_node(&node); ) {
-		type[0] = 0;
-		prom_getprop(node, "device_type", type, sizeof(type));
-
-		if (strcmp(type, RELOC("memory")))
-			continue;
-	
-		plen = prom_getprop(node, "reg", RELOC(regbuf), sizeof(regbuf));
-		if (plen > sizeof(regbuf)) {
-			prom_printf("memory node too large for buffer !\n");
-			plen = sizeof(regbuf);
-		}
-		p = RELOC(regbuf);
-		endp = p + (plen / sizeof(cell_t));
-
-#ifdef DEBUG_PROM
-		memset(path, 0, PROM_SCRATCH_SIZE);
-		call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
-		prom_debug("  node %s :\n", path);
-#endif /* DEBUG_PROM */
-
-		while ((endp - p) >= (_prom->root_addr_cells + _prom->root_size_cells)) {
-			unsigned long base, size;
-
-			base = prom_next_cell(_prom->root_addr_cells, &p);
-			size = prom_next_cell(_prom->root_size_cells, &p);
-
-			if (size == 0)
-				continue;
-			prom_debug("    %x %x\n", base, size);
-			if (base == 0)
-				RELOC(rmo_top) = size;
-			if ((base + size) > RELOC(ram_top))
-				RELOC(ram_top) = base + size;
-		}
-	}
-
-	RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(klimit) - offset + 0x4000);
-
-	/* Check if we have an initrd after the kernel, if we do move our bottom
-	 * point to after it
-	 */
-	if (RELOC(prom_initrd_start)) {
-		if (RELOC(prom_initrd_end) > RELOC(alloc_bottom))
-			RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
-	}
-
-	/*
-	 * If prom_memory_limit is set we reduce the upper limits *except* for
-	 * alloc_top_high. This must be the real top of RAM so we can put
-	 * TCE's up there.
-	 */
-
-	RELOC(alloc_top_high) = RELOC(ram_top);
-
-	if (RELOC(prom_memory_limit)) {
-		if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
-			prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
-				RELOC(prom_memory_limit));
-			RELOC(prom_memory_limit) = 0;
-		} else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
-			prom_printf("Ignoring mem=%x >= ram_top.\n",
-				RELOC(prom_memory_limit));
-			RELOC(prom_memory_limit) = 0;
-		} else {
-			RELOC(ram_top) = RELOC(prom_memory_limit);
-			RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
-		}
-	}
-
-	/*
-	 * Setup our top alloc point, that is top of RMO or top of
-	 * segment 0 when running non-LPAR.
-	 */
-	if ( RELOC(of_platform) == PLATFORM_PSERIES_LPAR )
-		RELOC(alloc_top) = RELOC(rmo_top);
-	else
-		/* Some RS64 machines have buggy firmware where claims up at 1GB
-		 * fails. Cap at 768MB as a workaround. Still plenty of room.
-		 */
-		RELOC(alloc_top) = RELOC(rmo_top) = min(0x30000000ul, RELOC(ram_top));
-
-	prom_printf("memory layout at init:\n");
-	prom_printf("  memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
-	prom_printf("  alloc_bottom : %x\n", RELOC(alloc_bottom));
-	prom_printf("  alloc_top    : %x\n", RELOC(alloc_top));
-	prom_printf("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
-	prom_printf("  rmo_top      : %x\n", RELOC(rmo_top));
-	prom_printf("  ram_top      : %x\n", RELOC(ram_top));
-}
-
-
-/*
- * Allocate room for and instanciate RTAS
- */
-static void __init prom_instantiate_rtas(void)
-{
-	unsigned long offset = reloc_offset();
-	struct prom_t *_prom = PTRRELOC(&prom);
-	phandle rtas_node;
-	ihandle rtas_inst;
-	u32 base, entry = 0;
-	u32 size = 0;
-
-	prom_debug("prom_instantiate_rtas: start...\n");
-
-	rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
-	prom_debug("rtas_node: %x\n", rtas_node);
-	if (!PHANDLE_VALID(rtas_node))
-		return;
-
-	prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
-	if (size == 0)
-		return;
-
-	base = alloc_down(size, PAGE_SIZE, 0);
-	if (base == 0) {
-		prom_printf("RTAS allocation failed !\n");
-		return;
-	}
-
-	rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
-	if (!IHANDLE_VALID(rtas_inst)) {
-		prom_printf("opening rtas package failed");
-		return;
-	}
-
-	prom_printf("instantiating rtas at 0x%x ...", base);
-
-	if (call_prom("call-method", 3, 2,
-		      ADDR("instantiate-rtas"),
-		      rtas_inst, base) != PROM_ERROR) {
-		entry = (long)_prom->args.rets[1];
-	}
-	if (entry == 0) {
-		prom_printf(" failed\n");
-		return;
-	}
-	prom_printf(" done\n");
-
-	reserve_mem(base, size);
-
-	prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base));
-	prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry));
-
-	prom_debug("rtas base     = 0x%x\n", base);
-	prom_debug("rtas entry    = 0x%x\n", entry);
-	prom_debug("rtas size     = 0x%x\n", (long)size);
-
-	prom_debug("prom_instantiate_rtas: end...\n");
-}
-
-
-/*
- * Allocate room for and initialize TCE tables
- */
-static void __init prom_initialize_tce_table(void)
-{
-	phandle node;
-	ihandle phb_node;
-	unsigned long offset = reloc_offset();
-	char compatible[64], type[64], model[64];
-	char *path = RELOC(prom_scratch);
-	u64 base, align;
-	u32 minalign, minsize;
-	u64 tce_entry, *tce_entryp;
-	u64 local_alloc_top, local_alloc_bottom;
-	u64 i;
-
-	if (RELOC(ppc64_iommu_off))
-		return;
-
-	prom_debug("starting prom_initialize_tce_table\n");
-
-	/* Cache current top of allocs so we reserve a single block */
-	local_alloc_top = RELOC(alloc_top_high);
-	local_alloc_bottom = local_alloc_top;
-
-	/* Search all nodes looking for PHBs. */
-	for (node = 0; prom_next_node(&node); ) {
-		compatible[0] = 0;
-		type[0] = 0;
-		model[0] = 0;
-		prom_getprop(node, "compatible",
-			     compatible, sizeof(compatible));
-		prom_getprop(node, "device_type", type, sizeof(type));
-		prom_getprop(node, "model", model, sizeof(model));
-
-		if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL))
-			continue;
-
-		/* Keep the old logic in tack to avoid regression. */
-		if (compatible[0] != 0) {
-			if ((strstr(compatible, RELOC("python")) == NULL) &&
-			    (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
-			    (strstr(compatible, RELOC("Winnipeg")) == NULL))
-				continue;
-		} else if (model[0] != 0) {
-			if ((strstr(model, RELOC("ython")) == NULL) &&
-			    (strstr(model, RELOC("peedwagon")) == NULL) &&
-			    (strstr(model, RELOC("innipeg")) == NULL))
-				continue;
-		}
-
-		if (prom_getprop(node, "tce-table-minalign", &minalign,
-				 sizeof(minalign)) == PROM_ERROR)
-			minalign = 0;
-		if (prom_getprop(node, "tce-table-minsize", &minsize,
-				 sizeof(minsize)) == PROM_ERROR)
-			minsize = 4UL << 20;
-
-		/*
-		 * Even though we read what OF wants, we just set the table
-		 * size to 4 MB.  This is enough to map 2GB of PCI DMA space.
-		 * By doing this, we avoid the pitfalls of trying to DMA to
-		 * MMIO space and the DMA alias hole.
-		 *
-		 * On POWER4, firmware sets the TCE region by assuming
-		 * each TCE table is 8MB. Using this memory for anything
-		 * else will impact performance, so we always allocate 8MB.
-		 * Anton
-		 */
-		if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
-			minsize = 8UL << 20;
-		else
-			minsize = 4UL << 20;
-
-		/* Align to the greater of the align or size */
-		align = max(minalign, minsize);
-		base = alloc_down(minsize, align, 1);
-		if (base == 0)
-			prom_panic("ERROR, cannot find space for TCE table.\n");
-		if (base < local_alloc_bottom)
-			local_alloc_bottom = base;
-
-		/* Save away the TCE table attributes for later use. */
-		prom_setprop(node, "linux,tce-base", &base, sizeof(base));
-		prom_setprop(node, "linux,tce-size", &minsize, sizeof(minsize));
-
-		/* It seems OF doesn't null-terminate the path :-( */
-		memset(path, 0, sizeof(path));
-		/* Call OF to setup the TCE hardware */
-		if (call_prom("package-to-path", 3, 1, node,
-			      path, PROM_SCRATCH_SIZE-1) == PROM_ERROR) {
-			prom_printf("package-to-path failed\n");
-		}
-
-		prom_debug("TCE table: %s\n", path);
-		prom_debug("\tnode = 0x%x\n", node);
-		prom_debug("\tbase = 0x%x\n", base);
-		prom_debug("\tsize = 0x%x\n", minsize);
-
-		/* Initialize the table to have a one-to-one mapping
-		 * over the allocated size.
-		 */
-		tce_entryp = (unsigned long *)base;
-		for (i = 0; i < (minsize >> 3) ;tce_entryp++, i++) {
-			tce_entry = (i << PAGE_SHIFT);
-			tce_entry |= 0x3;
-			*tce_entryp = tce_entry;
-		}
-
-		prom_printf("opening PHB %s", path);
-		phb_node = call_prom("open", 1, 1, path);
-		if (phb_node == 0)
-			prom_printf("... failed\n");
-		else
-			prom_printf("... done\n");
-
-		call_prom("call-method", 6, 0, ADDR("set-64-bit-addressing"),
-			  phb_node, -1, minsize,
-			  (u32) base, (u32) (base >> 32));
-		call_prom("close", 1, 0, phb_node);
-	}
-
-	reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
-
-	if (RELOC(prom_memory_limit)) {
-		/*
-		 * We align the start to a 16MB boundary so we can map the TCE area
-		 * using large pages if possible. The end should be the top of RAM
-		 * so no need to align it.
-		 */
-		RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom, 0x1000000);
-		RELOC(prom_tce_alloc_end) = local_alloc_top;
-	}
-
-	/* Flag the first invalid entry */
-	prom_debug("ending prom_initialize_tce_table\n");
-}
-
-/*
- * With CHRP SMP we need to use the OF to start the other
- * processors so we can't wait until smp_boot_cpus (the OF is
- * trashed by then) so we have to put the processors into
- * a holding pattern controlled by the kernel (not OF) before
- * we destroy the OF.
- *
- * This uses a chunk of low memory, puts some holding pattern
- * code there and sends the other processors off to there until
- * smp_boot_cpus tells them to do something.  The holding pattern
- * checks that address until its cpu # is there, when it is that
- * cpu jumps to __secondary_start().  smp_boot_cpus() takes care
- * of setting those values.
- *
- * We also use physical address 0x4 here to tell when a cpu
- * is in its holding pattern code.
- *
- * Fixup comment... DRENG / PPPBBB - Peter
- *
- * -- Cort
- */
-static void __init prom_hold_cpus(void)
-{
-	unsigned long i;
-	unsigned int reg;
-	phandle node;
-	unsigned long offset = reloc_offset();
-	char type[64];
-	int cpuid = 0;
-	unsigned int interrupt_server[MAX_CPU_THREADS];
-	unsigned int cpu_threads, hw_cpu_num;
-	int propsize;
-	extern void __secondary_hold(void);
-	extern unsigned long __secondary_hold_spinloop;
-	extern unsigned long __secondary_hold_acknowledge;
-	unsigned long *spinloop
-		= (void *)virt_to_abs(&__secondary_hold_spinloop);
-	unsigned long *acknowledge
-		= (void *)virt_to_abs(&__secondary_hold_acknowledge);
-	unsigned long secondary_hold
-		= virt_to_abs(*PTRRELOC((unsigned long *)__secondary_hold));
-	struct prom_t *_prom = PTRRELOC(&prom);
-
-	prom_debug("prom_hold_cpus: start...\n");
-	prom_debug("    1) spinloop       = 0x%x\n", (unsigned long)spinloop);
-	prom_debug("    1) *spinloop      = 0x%x\n", *spinloop);
-	prom_debug("    1) acknowledge    = 0x%x\n",
-		   (unsigned long)acknowledge);
-	prom_debug("    1) *acknowledge   = 0x%x\n", *acknowledge);
-	prom_debug("    1) secondary_hold = 0x%x\n", secondary_hold);
-
-	/* Set the common spinloop variable, so all of the secondary cpus
-	 * will block when they are awakened from their OF spinloop.
-	 * This must occur for both SMP and non SMP kernels, since OF will
-	 * be trashed when we move the kernel.
-	 */
-	*spinloop = 0;
-
-#ifdef CONFIG_HMT
-	for (i=0; i < NR_CPUS; i++) {
-		RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;
-	}
-#endif
-	/* look for cpus */
-	for (node = 0; prom_next_node(&node); ) {
-		type[0] = 0;
-		prom_getprop(node, "device_type", type, sizeof(type));
-		if (strcmp(type, RELOC("cpu")) != 0)
-			continue;
-
-		/* Skip non-configured cpus. */
-		if (prom_getprop(node, "status", type, sizeof(type)) > 0)
-			if (strcmp(type, RELOC("okay")) != 0)
-				continue;
-
-		reg = -1;
-		prom_getprop(node, "reg", &reg, sizeof(reg));
-
-		prom_debug("\ncpuid        = 0x%x\n", cpuid);
-		prom_debug("cpu hw idx   = 0x%x\n", reg);
-
-		/* Init the acknowledge var which will be reset by
-		 * the secondary cpu when it awakens from its OF
-		 * spinloop.
-		 */
-		*acknowledge = (unsigned long)-1;
-
-		propsize = prom_getprop(node, "ibm,ppc-interrupt-server#s",
-					&interrupt_server,
-					sizeof(interrupt_server));
-		if (propsize < 0) {
-			/* no property.  old hardware has no SMT */
-			cpu_threads = 1;
-			interrupt_server[0] = reg; /* fake it with phys id */
-		} else {
-			/* We have a threaded processor */
-			cpu_threads = propsize / sizeof(u32);
-			if (cpu_threads > MAX_CPU_THREADS) {
-				prom_printf("SMT: too many threads!\n"
-					    "SMT: found %x, max is %x\n",
-					    cpu_threads, MAX_CPU_THREADS);
-				cpu_threads = 1; /* ToDo: panic? */
-			}
-		}
-
-		hw_cpu_num = interrupt_server[0];
-		if (hw_cpu_num != _prom->cpu) {
-			/* Primary Thread of non-boot cpu */
-			prom_printf("%x : starting cpu hw idx %x... ", cpuid, reg);
-			call_prom("start-cpu", 3, 0, node,
-				  secondary_hold, reg);
-
-			for ( i = 0 ; (i < 100000000) && 
-			      (*acknowledge == ((unsigned long)-1)); i++ )
-				mb();
-
-			if (*acknowledge == reg) {
-				prom_printf("done\n");
-				/* We have to get every CPU out of OF,
-				 * even if we never start it. */
-				if (cpuid >= NR_CPUS)
-					goto next;
-			} else {
-				prom_printf("failed: %x\n", *acknowledge);
-			}
-		}
-#ifdef CONFIG_SMP
-		else
-			prom_printf("%x : boot cpu     %x\n", cpuid, reg);
-#endif
-next:
-#ifdef CONFIG_SMP
-		/* Init paca for secondary threads.   They start later. */
-		for (i=1; i < cpu_threads; i++) {
-			cpuid++;
-			if (cpuid >= NR_CPUS)
-				continue;
-		}
-#endif /* CONFIG_SMP */
-		cpuid++;
-	}
-#ifdef CONFIG_HMT
-	/* Only enable HMT on processors that provide support. */
-	if (__is_processor(PV_PULSAR) || 
-	    __is_processor(PV_ICESTAR) ||
-	    __is_processor(PV_SSTAR)) {
-		prom_printf("    starting secondary threads\n");
-
-		for (i = 0; i < NR_CPUS; i += 2) {
-			if (!cpu_online(i))
-				continue;
-
-			if (i == 0) {
-				unsigned long pir = mfspr(SPRN_PIR);
-				if (__is_processor(PV_PULSAR)) {
-					RELOC(hmt_thread_data)[i].pir = 
-						pir & 0x1f;
-				} else {
-					RELOC(hmt_thread_data)[i].pir = 
-						pir & 0x3ff;
-				}
-			}
-		}
-	} else {
-		prom_printf("Processor is not HMT capable\n");
-	}
-#endif
-
-	if (cpuid > NR_CPUS)
-		prom_printf("WARNING: maximum CPUs (" __stringify(NR_CPUS)
-			    ") exceeded: ignoring extras\n");
-
-	prom_debug("prom_hold_cpus: end...\n");
-}
-
-
-static void __init prom_init_client_services(unsigned long pp)
-{
-	unsigned long offset = reloc_offset();
-	struct prom_t *_prom = PTRRELOC(&prom);
-
-	/* Get a handle to the prom entry point before anything else */
-	_prom->entry = pp;
-
-	/* Init default value for phys size */
-	_prom->root_size_cells = 1;
-	_prom->root_addr_cells = 2;
-
-	/* get a handle for the stdout device */
-	_prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
-	if (!PHANDLE_VALID(_prom->chosen))
-		prom_panic("cannot find chosen"); /* msg won't be printed :( */
-
-	/* get device tree root */
-	_prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
-	if (!PHANDLE_VALID(_prom->root))
-		prom_panic("cannot find device tree root"); /* msg won't be printed :( */
-}
-
-static void __init prom_init_stdout(void)
-{
-	unsigned long offset = reloc_offset();
-	struct prom_t *_prom = PTRRELOC(&prom);
-	char *path = RELOC(of_stdout_device);
-	char type[16];
-	u32 val;
-
-	if (prom_getprop(_prom->chosen, "stdout", &val, sizeof(val)) <= 0)
-		prom_panic("cannot find stdout");
-
-	_prom->stdout = val;
-
-	/* Get the full OF pathname of the stdout device */
-	memset(path, 0, 256);
-	call_prom("instance-to-path", 3, 1, _prom->stdout, path, 255);
-	val = call_prom("instance-to-package", 1, 1, _prom->stdout);
-	prom_setprop(_prom->chosen, "linux,stdout-package", &val, sizeof(val));
-	prom_printf("OF stdout device is: %s\n", RELOC(of_stdout_device));
-	prom_setprop(_prom->chosen, "linux,stdout-path",
-		     RELOC(of_stdout_device), strlen(RELOC(of_stdout_device))+1);
-
-	/* If it's a display, note it */
-	memset(type, 0, sizeof(type));
-	prom_getprop(val, "device_type", type, sizeof(type));
-	if (strcmp(type, RELOC("display")) == 0) {
-		_prom->disp_node = val;
-		prom_setprop(val, "linux,boot-display", NULL, 0);
-	}
-}
-
-static void __init prom_close_stdin(void)
-{
-	unsigned long offset = reloc_offset();
-	struct prom_t *_prom = PTRRELOC(&prom);
-	ihandle val;
-
-	if (prom_getprop(_prom->chosen, "stdin", &val, sizeof(val)) > 0)
-		call_prom("close", 1, 0, val);
-}
-
-static int __init prom_find_machine_type(void)
-{
-	unsigned long offset = reloc_offset();
-	struct prom_t *_prom = PTRRELOC(&prom);
-	char compat[256];
-	int len, i = 0;
-	phandle rtas;
-
-	len = prom_getprop(_prom->root, "compatible",
-			   compat, sizeof(compat)-1);
-	if (len > 0) {
-		compat[len] = 0;
-		while (i < len) {
-			char *p = &compat[i];
-			int sl = strlen(p);
-			if (sl == 0)
-				break;
-			if (strstr(p, RELOC("Power Macintosh")) ||
-			    strstr(p, RELOC("MacRISC4")))
-				return PLATFORM_POWERMAC;
-			if (strstr(p, RELOC("Momentum,Maple")))
-				return PLATFORM_MAPLE;
-			i += sl + 1;
-		}
-	}
-	/* Default to pSeries. We need to know if we are running LPAR */
-	rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
-	if (PHANDLE_VALID(rtas)) {
-		int x = prom_getproplen(rtas, "ibm,hypertas-functions");
-		if (x != PROM_ERROR) {
-			prom_printf("Hypertas detected, assuming LPAR !\n");
-			return PLATFORM_PSERIES_LPAR;
-		}
-	}
-	return PLATFORM_PSERIES;
-}
-
-static int __init prom_set_color(ihandle ih, int i, int r, int g, int b)
-{
-	unsigned long offset = reloc_offset();
-
-	return call_prom("call-method", 6, 1, ADDR("color!"), ih, i, b, g, r);
-}
-
-/*
- * If we have a display that we don't know how to drive,
- * we will want to try to execute OF's open method for it
- * later.  However, OF will probably fall over if we do that
- * we've taken over the MMU.
- * So we check whether we will need to open the display,
- * and if so, open it now.
- */
-static void __init prom_check_displays(void)
-{
-	unsigned long offset = reloc_offset();
-	struct prom_t *_prom = PTRRELOC(&prom);
-	char type[16], *path;
-	phandle node;
-	ihandle ih;
-	int i;
-
-	static unsigned char default_colors[] = {
-		0x00, 0x00, 0x00,
-		0x00, 0x00, 0xaa,
-		0x00, 0xaa, 0x00,
-		0x00, 0xaa, 0xaa,
-		0xaa, 0x00, 0x00,
-		0xaa, 0x00, 0xaa,
-		0xaa, 0xaa, 0x00,
-		0xaa, 0xaa, 0xaa,
-		0x55, 0x55, 0x55,
-		0x55, 0x55, 0xff,
-		0x55, 0xff, 0x55,
-		0x55, 0xff, 0xff,
-		0xff, 0x55, 0x55,
-		0xff, 0x55, 0xff,
-		0xff, 0xff, 0x55,
-		0xff, 0xff, 0xff
-	};
-	const unsigned char *clut;
-
-	prom_printf("Looking for displays\n");
-	for (node = 0; prom_next_node(&node); ) {
-		memset(type, 0, sizeof(type));
-		prom_getprop(node, "device_type", type, sizeof(type));
-		if (strcmp(type, RELOC("display")) != 0)
-			continue;
-
-		/* It seems OF doesn't null-terminate the path :-( */
-		path = RELOC(prom_scratch);
-		memset(path, 0, PROM_SCRATCH_SIZE);
-
-		/*
-		 * leave some room at the end of the path for appending extra
-		 * arguments
-		 */
-		if (call_prom("package-to-path", 3, 1, node, path,
-			      PROM_SCRATCH_SIZE-10) == PROM_ERROR)
-			continue;
-		prom_printf("found display   : %s, opening ... ", path);
-		
-		ih = call_prom("open", 1, 1, path);
-		if (ih == 0) {
-			prom_printf("failed\n");
-			continue;
-		}
-
-		/* Success */
-		prom_printf("done\n");
-		prom_setprop(node, "linux,opened", NULL, 0);
-
-		/*
-		 * stdout wasn't a display node, pick the first we can find
-		 * for btext
-		 */
-		if (_prom->disp_node == 0)
-			_prom->disp_node = node;
-
-		/* Setup a useable color table when the appropriate
-		 * method is available. Should update this to set-colors */
-		clut = RELOC(default_colors);
-		for (i = 0; i < 32; i++, clut += 3)
-			if (prom_set_color(ih, i, clut[0], clut[1],
-					   clut[2]) != 0)
-				break;
-
-#ifdef CONFIG_LOGO_LINUX_CLUT224
-		clut = PTRRELOC(RELOC(logo_linux_clut224.clut));
-		for (i = 0; i < RELOC(logo_linux_clut224.clutsize); i++, clut += 3)
-			if (prom_set_color(ih, i + 32, clut[0], clut[1],
-					   clut[2]) != 0)
-				break;
-#endif /* CONFIG_LOGO_LINUX_CLUT224 */
-	}
-}
-
-
-/* Return (relocated) pointer to this much memory: moves initrd if reqd. */
-static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
-			      unsigned long needed, unsigned long align)
-{
-	unsigned long offset = reloc_offset();
-	void *ret;
-
-	*mem_start = _ALIGN(*mem_start, align);
-	while ((*mem_start + needed) > *mem_end) {
-		unsigned long room, chunk;
-
-		prom_debug("Chunk exhausted, claiming more at %x...\n",
-			   RELOC(alloc_bottom));
-		room = RELOC(alloc_top) - RELOC(alloc_bottom);
-		if (room > DEVTREE_CHUNK_SIZE)
-			room = DEVTREE_CHUNK_SIZE;
-		if (room < PAGE_SIZE)
-			prom_panic("No memory for flatten_device_tree (no room)");
-		chunk = alloc_up(room, 0);
-		if (chunk == 0)
-			prom_panic("No memory for flatten_device_tree (claim failed)");
-		*mem_end = RELOC(alloc_top);
-	}
-
-	ret = (void *)*mem_start;
-	*mem_start += needed;
-
-	return ret;
-}
-
-#define dt_push_token(token, mem_start, mem_end) \
-	do { *((u32 *)make_room(mem_start, mem_end, 4, 4)) = token; } while(0)
-
-static unsigned long __init dt_find_string(char *str)
-{
-	unsigned long offset = reloc_offset();
-	char *s, *os;
-
-	s = os = (char *)RELOC(dt_string_start);
-	s += 4;
-	while (s <  (char *)RELOC(dt_string_end)) {
-		if (strcmp(s, str) == 0)
-			return s - os;
-		s += strlen(s) + 1;
-	}
-	return 0;
-}
-
-/*
- * The Open Firmware 1275 specification states properties must be 31 bytes or
- * less, however not all firmwares obey this. Make it 64 bytes to be safe.
- */
-#define MAX_PROPERTY_NAME 64
-
-static void __init scan_dt_build_strings(phandle node,
-					 unsigned long *mem_start,
-					 unsigned long *mem_end)
-{
-	unsigned long offset = reloc_offset();
-	char *prev_name, *namep, *sstart;
-	unsigned long soff;
-	phandle child;
-
-	sstart =  (char *)RELOC(dt_string_start);
-
-	/* get and store all property names */
-	prev_name = RELOC("");
-	for (;;) {
-		/* 64 is max len of name including nul. */
-		namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
-		if (call_prom("nextprop", 3, 1, node, prev_name, namep) != 1) {
-			/* No more nodes: unwind alloc */
-			*mem_start = (unsigned long)namep;
-			break;
-		}
-
- 		/* skip "name" */
- 		if (strcmp(namep, RELOC("name")) == 0) {
- 			*mem_start = (unsigned long)namep;
- 			prev_name = RELOC("name");
- 			continue;
- 		}
-		/* get/create string entry */
-		soff = dt_find_string(namep);
-		if (soff != 0) {
-			*mem_start = (unsigned long)namep;
-			namep = sstart + soff;
-		} else {
-			/* Trim off some if we can */
-			*mem_start = (unsigned long)namep + strlen(namep) + 1;
-			RELOC(dt_string_end) = *mem_start;
-		}
-		prev_name = namep;
-	}
-
-	/* do all our children */
-	child = call_prom("child", 1, 1, node);
-	while (child != 0) {
-		scan_dt_build_strings(child, mem_start, mem_end);
-		child = call_prom("peer", 1, 1, child);
-	}
-}
-
-static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
-					unsigned long *mem_end)
-{
-	phandle child;
-	char *namep, *prev_name, *sstart, *p, *ep, *lp, *path;
-	unsigned long soff;
-	unsigned char *valp;
-	unsigned long offset = reloc_offset();
-	static char pname[MAX_PROPERTY_NAME];
-	int l;
-
-	dt_push_token(OF_DT_BEGIN_NODE, mem_start, mem_end);
-
-	/* get the node's full name */
-	namep = (char *)*mem_start;
-	l = call_prom("package-to-path", 3, 1, node,
-		      namep, *mem_end - *mem_start);
-	if (l >= 0) {
-		/* Didn't fit?  Get more room. */
-		if ((l+1) > (*mem_end - *mem_start)) {
-			namep = make_room(mem_start, mem_end, l+1, 1);
-			call_prom("package-to-path", 3, 1, node, namep, l);
-		}
-		namep[l] = '\0';
-
-		/* Fixup an Apple bug where they have bogus \0 chars in the
-		 * middle of the path in some properties
-		 */
-		for (p = namep, ep = namep + l; p < ep; p++)
-			if (*p == '\0') {
-				memmove(p, p+1, ep - p);
-				ep--; l--; p--;
-			}
-
-		/* now try to extract the unit name in that mess */
-		for (p = namep, lp = NULL; *p; p++)
-			if (*p == '/')
-				lp = p + 1;
-		if (lp != NULL)
-			memmove(namep, lp, strlen(lp) + 1);
-		*mem_start = _ALIGN(((unsigned long) namep) +
-				    strlen(namep) + 1, 4);
-	}
-
-	/* get it again for debugging */
-	path = RELOC(prom_scratch);
-	memset(path, 0, PROM_SCRATCH_SIZE);
-	call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-1);
-
-	/* get and store all properties */
-	prev_name = RELOC("");
-	sstart = (char *)RELOC(dt_string_start);
-	for (;;) {
-		if (call_prom("nextprop", 3, 1, node, prev_name,
-			      RELOC(pname)) != 1)
-			break;
-
- 		/* skip "name" */
- 		if (strcmp(RELOC(pname), RELOC("name")) == 0) {
- 			prev_name = RELOC("name");
- 			continue;
- 		}
-
-		/* find string offset */
-		soff = dt_find_string(RELOC(pname));
-		if (soff == 0) {
-			prom_printf("WARNING: Can't find string index for"
-				    " <%s>, node %s\n", RELOC(pname), path);
-			break;
-		}
-		prev_name = sstart + soff;
-
-		/* get length */
-		l = call_prom("getproplen", 2, 1, node, RELOC(pname));
-
-		/* sanity checks */
-		if (l == PROM_ERROR)
-			continue;
-		if (l > MAX_PROPERTY_LENGTH) {
-			prom_printf("WARNING: ignoring large property ");
-			/* It seems OF doesn't null-terminate the path :-( */
-			prom_printf("[%s] ", path);
-			prom_printf("%s length 0x%x\n", RELOC(pname), l);
-			continue;
-		}
-
-		/* push property head */
-		dt_push_token(OF_DT_PROP, mem_start, mem_end);
-		dt_push_token(l, mem_start, mem_end);
-		dt_push_token(soff, mem_start, mem_end);
-
-		/* push property content */
-		valp = make_room(mem_start, mem_end, l, 4);
-		call_prom("getprop", 4, 1, node, RELOC(pname), valp, l);
-		*mem_start = _ALIGN(*mem_start, 4);
-	}
-
-	/* Add a "linux,phandle" property. */
-	soff = dt_find_string(RELOC("linux,phandle"));
-	if (soff == 0)
-		prom_printf("WARNING: Can't find string index for"
-			    " <linux-phandle> node %s\n", path);
-	else {
-		dt_push_token(OF_DT_PROP, mem_start, mem_end);
-		dt_push_token(4, mem_start, mem_end);
-		dt_push_token(soff, mem_start, mem_end);
-		valp = make_room(mem_start, mem_end, 4, 4);
-		*(u32 *)valp = node;
-	}
-
-	/* do all our children */
-	child = call_prom("child", 1, 1, node);
-	while (child != 0) {
-		scan_dt_build_struct(child, mem_start, mem_end);
-		child = call_prom("peer", 1, 1, child);
-	}
-
-	dt_push_token(OF_DT_END_NODE, mem_start, mem_end);
-}
-
-static void __init flatten_device_tree(void)
-{
-	phandle root;
-	unsigned long offset = reloc_offset();
-	unsigned long mem_start, mem_end, room;
-	struct boot_param_header *hdr;
-	struct prom_t *_prom = PTRRELOC(&prom);
-	char *namep;
-	u64 *rsvmap;
-
-	/*
-	 * Check how much room we have between alloc top & bottom (+/- a
-	 * few pages), crop to 4Mb, as this is our "chuck" size
-	 */
-	room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000;
-	if (room > DEVTREE_CHUNK_SIZE)
-		room = DEVTREE_CHUNK_SIZE;
-	prom_debug("starting device tree allocs at %x\n", RELOC(alloc_bottom));
-
-	/* Now try to claim that */
-	mem_start = (unsigned long)alloc_up(room, PAGE_SIZE);
-	if (mem_start == 0)
-		prom_panic("Can't allocate initial device-tree chunk\n");
-	mem_end = RELOC(alloc_top);
-
-	/* Get root of tree */
-	root = call_prom("peer", 1, 1, (phandle)0);
-	if (root == (phandle)0)
-		prom_panic ("couldn't get device tree root\n");
-
-	/* Build header and make room for mem rsv map */ 
-	mem_start = _ALIGN(mem_start, 4);
-	hdr = make_room(&mem_start, &mem_end,
-			sizeof(struct boot_param_header), 4);
-	RELOC(dt_header_start) = (unsigned long)hdr;
-	rsvmap = make_room(&mem_start, &mem_end, sizeof(mem_reserve_map), 8);
-
-	/* Start of strings */
-	mem_start = PAGE_ALIGN(mem_start);
-	RELOC(dt_string_start) = mem_start;
-	mem_start += 4; /* hole */
-
-	/* Add "linux,phandle" in there, we'll need it */
-	namep = make_room(&mem_start, &mem_end, 16, 1);
-	strcpy(namep, RELOC("linux,phandle"));
-	mem_start = (unsigned long)namep + strlen(namep) + 1;
-
-	/* Build string array */
-	prom_printf("Building dt strings...\n"); 
-	scan_dt_build_strings(root, &mem_start, &mem_end);
-	RELOC(dt_string_end) = mem_start;
-
-	/* Build structure */
-	mem_start = PAGE_ALIGN(mem_start);
-	RELOC(dt_struct_start) = mem_start;
-	prom_printf("Building dt structure...\n"); 
-	scan_dt_build_struct(root, &mem_start, &mem_end);
-	dt_push_token(OF_DT_END, &mem_start, &mem_end);
-	RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
-
-	/* Finish header */
-	hdr->boot_cpuid_phys = _prom->cpu;
-	hdr->magic = OF_DT_HEADER;
-	hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
-	hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
-	hdr->off_dt_strings = RELOC(dt_string_start) - RELOC(dt_header_start);
-	hdr->dt_strings_size = RELOC(dt_string_end) - RELOC(dt_string_start);
-	hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - RELOC(dt_header_start);
-	hdr->version = OF_DT_VERSION;
-	/* Version 16 is not backward compatible */
-	hdr->last_comp_version = 0x10;
-
-	/* Reserve the whole thing and copy the reserve map in, we
-	 * also bump mem_reserve_cnt to cause further reservations to
-	 * fail since it's too late.
-	 */
-	reserve_mem(RELOC(dt_header_start), hdr->totalsize);
-	memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
-
-#ifdef DEBUG_PROM
-	{
-		int i;
-		prom_printf("reserved memory map:\n");
-		for (i = 0; i < RELOC(mem_reserve_cnt); i++)
-			prom_printf("  %x - %x\n", RELOC(mem_reserve_map)[i].base,
-				    RELOC(mem_reserve_map)[i].size);
-	}
-#endif
-	RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
-
-	prom_printf("Device tree strings 0x%x -> 0x%x\n",
-		    RELOC(dt_string_start), RELOC(dt_string_end)); 
-	prom_printf("Device tree struct  0x%x -> 0x%x\n",
-		    RELOC(dt_struct_start), RELOC(dt_struct_end));
-
-}
-
-
-static void __init fixup_device_tree(void)
-{
-	unsigned long offset = reloc_offset();
-	phandle u3, i2c, mpic;
-	u32 u3_rev;
-	u32 interrupts[2];
-	u32 parent;
-
-	/* Some G5s have a missing interrupt definition, fix it up here */
-	u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
-	if (!PHANDLE_VALID(u3))
-		return;
-	i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
-	if (!PHANDLE_VALID(i2c))
-		return;
-	mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
-	if (!PHANDLE_VALID(mpic))
-		return;
-
-	/* check if proper rev of u3 */
-	if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
-	    == PROM_ERROR)
-		return;
-	if (u3_rev < 0x35 || u3_rev > 0x39)
-		return;
-	/* does it need fixup ? */
-	if (prom_getproplen(i2c, "interrupts") > 0)
-		return;
-
-	prom_printf("fixing up bogus interrupts for u3 i2c...\n");
-
-	/* interrupt on this revision of u3 is number 0 and level */
-	interrupts[0] = 0;
-	interrupts[1] = 1;
-	prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
-	parent = (u32)mpic;
-	prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
-}
-
-
-static void __init prom_find_boot_cpu(void)
-{
-	unsigned long offset = reloc_offset();
-       	struct prom_t *_prom = PTRRELOC(&prom);
-	u32 getprop_rval;
-	ihandle prom_cpu;
-	phandle cpu_pkg;
-
-	if (prom_getprop(_prom->chosen, "cpu", &prom_cpu, sizeof(prom_cpu)) <= 0)
-		prom_panic("cannot find boot cpu");
-
-	cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
-
-	prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
-	_prom->cpu = getprop_rval;
-
-	prom_debug("Booting CPU hw index = 0x%x\n", _prom->cpu);
-}
-
-static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
-	unsigned long offset = reloc_offset();
-       	struct prom_t *_prom = PTRRELOC(&prom);
-
-	if ( r3 && r4 && r4 != 0xdeadbeef) {
-		u64 val;
-
-		RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3;
-		RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4;
-
-		val = (u64)RELOC(prom_initrd_start);
-		prom_setprop(_prom->chosen, "linux,initrd-start", &val, sizeof(val));
-		val = (u64)RELOC(prom_initrd_end);
-		prom_setprop(_prom->chosen, "linux,initrd-end", &val, sizeof(val));
-
-		reserve_mem(RELOC(prom_initrd_start),
-			    RELOC(prom_initrd_end) - RELOC(prom_initrd_start));
-
-		prom_debug("initrd_start=0x%x\n", RELOC(prom_initrd_start));
-		prom_debug("initrd_end=0x%x\n", RELOC(prom_initrd_end));
-	}
-#endif /* CONFIG_BLK_DEV_INITRD */
-}
-
-/*
- * We enter here early on, when the Open Firmware prom is still
- * handling exceptions and the MMU hash table for us.
- */
-
-unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
-			       unsigned long r6, unsigned long r7)
-{	
-	unsigned long offset = reloc_offset();
-       	struct prom_t *_prom = PTRRELOC(&prom);
-	unsigned long phys = KERNELBASE - offset;
-	u32 getprop_rval;
-	
-	/*
-	 * First zero the BSS
-	 */
-	memset(PTRRELOC(&__bss_start), 0, __bss_stop - __bss_start);
-
-	/*
-	 * Init interface to Open Firmware, get some node references,
-	 * like /chosen
-	 */
-	prom_init_client_services(pp);
-
-	/*
-	 * Init prom stdout device
-	 */
-	prom_init_stdout();
-	prom_debug("klimit=0x%x\n", RELOC(klimit));
-	prom_debug("offset=0x%x\n", offset);
-
-	/*
-	 * Check for an initrd
-	 */
-	prom_check_initrd(r3, r4);
-
-	/*
-	 * Get default machine type. At this point, we do not differenciate
-	 * between pSeries SMP and pSeries LPAR
-	 */
-	RELOC(of_platform) = prom_find_machine_type();
-	getprop_rval = RELOC(of_platform);
-	prom_setprop(_prom->chosen, "linux,platform",
-		     &getprop_rval, sizeof(getprop_rval));
-
-	/*
-	 * On pSeries, inform the firmware about our capabilities
-	 */
-	if (RELOC(of_platform) == PLATFORM_PSERIES ||
-	    RELOC(of_platform) == PLATFORM_PSERIES_LPAR)
-		prom_send_capabilities();
-
-	/*
-	 * On pSeries and Cell, copy the CPU hold code
-	 */
-       	if (RELOC(of_platform) & (PLATFORM_PSERIES | PLATFORM_CELL))
-       		copy_and_flush(0, KERNELBASE - offset, 0x100, 0);
-
-	/*
-	 * Get memory cells format
-	 */
-	getprop_rval = 1;
-	prom_getprop(_prom->root, "#size-cells",
-		     &getprop_rval, sizeof(getprop_rval));
-	_prom->root_size_cells = getprop_rval;
-	getprop_rval = 2;
-	prom_getprop(_prom->root, "#address-cells",
-		     &getprop_rval, sizeof(getprop_rval));
-	_prom->root_addr_cells = getprop_rval;
-
-	/*
-	 * Do early parsing of command line
-	 */
-	early_cmdline_parse();
-
-	/*
-	 * Initialize memory management within prom_init
-	 */
-	prom_init_mem();
-
-	/*
-	 * Determine which cpu is actually running right _now_
-	 */
-	prom_find_boot_cpu();
-
-	/* 
-	 * Initialize display devices
-	 */
-	prom_check_displays();
-
-	/*
-	 * Initialize IOMMU (TCE tables) on pSeries. Do that before anything else
-	 * that uses the allocator, we need to make sure we get the top of memory
-	 * available for us here...
-	 */
-	if (RELOC(of_platform) == PLATFORM_PSERIES)
-		prom_initialize_tce_table();
-
-	/*
-	 * On non-powermacs, try to instantiate RTAS and puts all CPUs
-	 * in spin-loops. PowerMacs don't have a working RTAS and use
-	 * a different way to spin CPUs
-	 */
-	if (RELOC(of_platform) != PLATFORM_POWERMAC) {
-		prom_instantiate_rtas();
-		prom_hold_cpus();
-	}
-
-	/*
-	 * Fill in some infos for use by the kernel later on
-	 */
-	if (RELOC(ppc64_iommu_off))
-		prom_setprop(_prom->chosen, "linux,iommu-off", NULL, 0);
-
-	if (RELOC(iommu_force_on))
-		prom_setprop(_prom->chosen, "linux,iommu-force-on", NULL, 0);
-
-	if (RELOC(prom_memory_limit))
-		prom_setprop(_prom->chosen, "linux,memory-limit",
-			PTRRELOC(&prom_memory_limit), sizeof(RELOC(prom_memory_limit)));
-
-	if (RELOC(prom_tce_alloc_start)) {
-		prom_setprop(_prom->chosen, "linux,tce-alloc-start",
-			PTRRELOC(&prom_tce_alloc_start), sizeof(RELOC(prom_tce_alloc_start)));
-		prom_setprop(_prom->chosen, "linux,tce-alloc-end",
-			PTRRELOC(&prom_tce_alloc_end), sizeof(RELOC(prom_tce_alloc_end)));
-	}
-
-	/*
-	 * Fixup any known bugs in the device-tree
-	 */
-	fixup_device_tree();
-
-	/*
-	 * Now finally create the flattened device-tree
-	 */
-       	prom_printf("copying OF device tree ...\n");
-       	flatten_device_tree();
-
-	/* in case stdin is USB and still active on IBM machines... */
-	prom_close_stdin();
-
-	/*
-	 * Call OF "quiesce" method to shut down pending DMA's from
-	 * devices etc...
-	 */
-	prom_printf("Calling quiesce ...\n");
-	call_prom("quiesce", 0, 0);
-
-	/*
-	 * And finally, call the kernel passing it the flattened device
-	 * tree and NULL as r5, thus triggering the new entry point which
-	 * is common to us and kexec
-	 */
-	prom_printf("returning from prom_init\n");
-	prom_debug("->dt_header_start=0x%x\n", RELOC(dt_header_start));
-	prom_debug("->phys=0x%x\n", phys);
-
-	__start(RELOC(dt_header_start), phys, 0);
-
-	return 0;
-}
-
diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c
deleted file mode 100644
index 79e7ed2..0000000
--- a/arch/ppc64/kernel/rtc.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- *	Real Time Clock interface for PPC64.
- *
- *	Based on rtc.c by Paul Gortmaker
- *
- *	This driver allows use of the real time clock
- *	from user space. It exports the /dev/rtc
- *	interface supporting various ioctl() and also the
- *	/proc/driver/rtc pseudo-file for status information.
- *
- * 	Interface does not support RTC interrupts nor an alarm.
- *
- *	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.
- *
- *      1.0	Mike Corrigan:    IBM iSeries rtc support
- *      1.1	Dave Engebretsen: IBM pSeries rtc support
- */
-
-#define RTC_VERSION		"1.1"
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/miscdevice.h>
-#include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/mc146818rtc.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-#include <linux/bcd.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/time.h>
-#include <asm/rtas.h>
-
-#include <asm/machdep.h>
-
-/*
- *	We sponge a minor off of the misc major. No need slurping
- *	up another valuable major dev number for this. If you add
- *	an ioctl, make sure you don't conflict with SPARC's RTC
- *	ioctls.
- */
-
-static ssize_t rtc_read(struct file *file, char __user *buf,
-			size_t count, loff_t *ppos);
-
-static int rtc_ioctl(struct inode *inode, struct file *file,
-		     unsigned int cmd, unsigned long arg);
-
-static int rtc_read_proc(char *page, char **start, off_t off,
-                         int count, int *eof, void *data);
-
-/*
- *	If this driver ever becomes modularised, it will be really nice
- *	to make the epoch retain its value across module reload...
- */
-
-static unsigned long epoch = 1900;	/* year corresponding to 0x00	*/
-
-static const unsigned char days_in_mo[] = 
-{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
-/*
- *	Now all the various file operations that we export.
- */
-
-static ssize_t rtc_read(struct file *file, char __user *buf,
-			size_t count, loff_t *ppos)
-{
-	return -EIO;
-}
-
-static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-		     unsigned long arg)
-{
-	struct rtc_time wtime; 
-
-	switch (cmd) {
-	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
-	{
-		memset(&wtime, 0, sizeof(struct rtc_time));
-		ppc_md.get_rtc_time(&wtime);
-		break;
-	}
-	case RTC_SET_TIME:	/* Set the RTC */
-	{
-		struct rtc_time rtc_tm;
-		unsigned char mon, day, hrs, min, sec, leap_yr;
-		unsigned int yrs;
-
-		if (!capable(CAP_SYS_TIME))
-			return -EACCES;
-
-		if (copy_from_user(&rtc_tm, (struct rtc_time __user *)arg,
-				   sizeof(struct rtc_time)))
-			return -EFAULT;
-
-		yrs = rtc_tm.tm_year;
-		mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
-		day = rtc_tm.tm_mday;
-		hrs = rtc_tm.tm_hour;
-		min = rtc_tm.tm_min;
-		sec = rtc_tm.tm_sec;
-
-		if (yrs < 70)
-			return -EINVAL;
-
-		leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
-
-		if ((mon > 12) || (day == 0))
-			return -EINVAL;
-
-		if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
-			return -EINVAL;
-			
-		if ((hrs >= 24) || (min >= 60) || (sec >= 60))
-			return -EINVAL;
-
-		if ( yrs > 169 )
-			return -EINVAL;
-
-		ppc_md.set_rtc_time(&rtc_tm);
-		
-		return 0;
-	}
-	case RTC_EPOCH_READ:	/* Read the epoch.	*/
-	{
-		return put_user (epoch, (unsigned long __user *)arg);
-	}
-	case RTC_EPOCH_SET:	/* Set the epoch.	*/
-	{
-		/* 
-		 * There were no RTC clocks before 1900.
-		 */
-		if (arg < 1900)
-			return -EINVAL;
-
-		if (!capable(CAP_SYS_TIME))
-			return -EACCES;
-
-		epoch = arg;
-		return 0;
-	}
-	default:
-		return -EINVAL;
-	}
-	return copy_to_user((void __user *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
-}
-
-static int rtc_open(struct inode *inode, struct file *file)
-{
-	nonseekable_open(inode, file);
-	return 0;
-}
-
-static int rtc_release(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-/*
- *	The various file operations we support.
- */
-static struct file_operations rtc_fops = {
-	.owner =	THIS_MODULE,
-	.llseek =	no_llseek,
-	.read =		rtc_read,
-	.ioctl =	rtc_ioctl,
-	.open =		rtc_open,
-	.release =	rtc_release,
-};
-
-static struct miscdevice rtc_dev = {
-	.minor =	RTC_MINOR,
-	.name =		"rtc",
-	.fops =		&rtc_fops
-};
-
-static int __init rtc_init(void)
-{
-	int retval;
-
-	retval = misc_register(&rtc_dev);
-	if(retval < 0)
-		return retval;
-
-#ifdef CONFIG_PROC_FS
-	if (create_proc_read_entry("driver/rtc", 0, NULL, rtc_read_proc, NULL)
-			== NULL) {
-		misc_deregister(&rtc_dev);
-		return -ENOMEM;
-	}
-#endif
-
-	printk(KERN_INFO "i/pSeries Real Time Clock Driver v" RTC_VERSION "\n");
-
-	return 0;
-}
-
-static void __exit rtc_exit (void)
-{
-	remove_proc_entry ("driver/rtc", NULL);
-	misc_deregister(&rtc_dev);
-}
-
-module_init(rtc_init);
-module_exit(rtc_exit);
-
-/*
- *	Info exported via "/proc/driver/rtc".
- */
-
-static int rtc_proc_output (char *buf)
-{
-	
-	char *p;
-	struct rtc_time tm;
-	
-	p = buf;
-
-	ppc_md.get_rtc_time(&tm);
-
-	/*
-	 * There is no way to tell if the luser has the RTC set for local
-	 * time or for Universal Standard Time (GMT). Probably local though.
-	 */
-	p += sprintf(p,
-		     "rtc_time\t: %02d:%02d:%02d\n"
-		     "rtc_date\t: %04d-%02d-%02d\n"
-	 	     "rtc_epoch\t: %04lu\n",
-		     tm.tm_hour, tm.tm_min, tm.tm_sec,
-		     tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
-
-	p += sprintf(p,
-		     "DST_enable\t: no\n"
-		     "BCD\t\t: yes\n"
-		     "24hr\t\t: yes\n" );
-
-	return  p - buf;
-}
-
-static int rtc_read_proc(char *page, char **start, off_t off,
-                         int count, int *eof, void *data)
-{
-        int len = rtc_proc_output (page);
-        if (len <= off+count) *eof = 1;
-        *start = page + off;
-        len -= off;
-        if (len>count) len = count;
-        if (len<0) len = 0;
-        return len;
-}
-
-#ifdef CONFIG_PPC_RTAS
-#define MAX_RTC_WAIT 5000	/* 5 sec */
-#define RTAS_CLOCK_BUSY (-2)
-unsigned long rtas_get_boot_time(void)
-{
-	int ret[8];
-	int error, wait_time;
-	unsigned long max_wait_tb;
-
-	max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
-	do {
-		error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
-		if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
-			wait_time = rtas_extended_busy_delay_time(error);
-			/* This is boot time so we spin. */
-			udelay(wait_time*1000);
-			error = RTAS_CLOCK_BUSY;
-		}
-	} while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
-
-	if (error != 0 && printk_ratelimit()) {
-		printk(KERN_WARNING "error: reading the clock failed (%d)\n",
-			error);
-		return 0;
-	}
-
-	return mktime(ret[0], ret[1], ret[2], ret[3], ret[4], ret[5]);
-}
-
-/* NOTE: get_rtc_time will get an error if executed in interrupt context
- * and if a delay is needed to read the clock.  In this case we just
- * silently return without updating rtc_tm.
- */
-void rtas_get_rtc_time(struct rtc_time *rtc_tm)
-{
-        int ret[8];
-	int error, wait_time;
-	unsigned long max_wait_tb;
-
-	max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
-	do {
-		error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
-		if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
-			if (in_interrupt() && printk_ratelimit()) {
-				printk(KERN_WARNING "error: reading clock would delay interrupt\n");
-				return;	/* delay not allowed */
-			}
-			wait_time = rtas_extended_busy_delay_time(error);
-			msleep_interruptible(wait_time);
-			error = RTAS_CLOCK_BUSY;
-		}
-	} while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
-
-        if (error != 0 && printk_ratelimit()) {
-                printk(KERN_WARNING "error: reading the clock failed (%d)\n",
-		       error);
-		return;
-        }
-
-	rtc_tm->tm_sec = ret[5];
-	rtc_tm->tm_min = ret[4];
-	rtc_tm->tm_hour = ret[3];
-	rtc_tm->tm_mday = ret[2];
-	rtc_tm->tm_mon = ret[1] - 1;
-	rtc_tm->tm_year = ret[0] - 1900;
-}
-
-int rtas_set_rtc_time(struct rtc_time *tm)
-{
-	int error, wait_time;
-	unsigned long max_wait_tb;
-
-	max_wait_tb = __get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
-	do {
-	        error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
-				  tm->tm_year + 1900, tm->tm_mon + 1, 
-				  tm->tm_mday, tm->tm_hour, tm->tm_min, 
-				  tm->tm_sec, 0);
-		if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
-			if (in_interrupt())
-				return 1;	/* probably decrementer */
-			wait_time = rtas_extended_busy_delay_time(error);
-			msleep_interruptible(wait_time);
-			error = RTAS_CLOCK_BUSY;
-		}
-	} while (error == RTAS_CLOCK_BUSY && (__get_tb() < max_wait_tb));
-
-        if (error != 0 && printk_ratelimit())
-                printk(KERN_WARNING "error: setting the clock failed (%d)\n",
-		       error); 
-
-        return 0;
-}
-#endif
diff --git a/arch/ppc64/kernel/semaphore.c b/arch/ppc64/kernel/semaphore.c
deleted file mode 100644
index a1c1db5..0000000
--- a/arch/ppc64/kernel/semaphore.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 
- *
- * PowerPC-specific semaphore code.
- *
- * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
- *
- * 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.
- *
- * April 2001 - Reworked by Paul Mackerras <paulus@samba.org>
- * to eliminate the SMP races in the old version between the updates
- * of `count' and `waking'.  Now we use negative `count' values to
- * indicate that some process(es) are waiting for the semaphore.
- */
-
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <asm/atomic.h>
-#include <asm/semaphore.h>
-#include <asm/errno.h>
-
-/*
- * Atomically update sem->count.
- * This does the equivalent of the following:
- *
- *	old_count = sem->count;
- *	tmp = MAX(old_count, 0) + incr;
- *	sem->count = tmp;
- *	return old_count;
- */
-static inline int __sem_update_count(struct semaphore *sem, int incr)
-{
-	int old_count, tmp;
-
-	__asm__ __volatile__("\n"
-"1:	lwarx	%0,0,%3\n"
-"	srawi	%1,%0,31\n"
-"	andc	%1,%0,%1\n"
-"	add	%1,%1,%4\n"
-"	stwcx.	%1,0,%3\n"
-"	bne	1b"
-	: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
-	: "r" (&sem->count), "r" (incr), "m" (sem->count)
-	: "cc");
-
-	return old_count;
-}
-
-void __up(struct semaphore *sem)
-{
-	/*
-	 * Note that we incremented count in up() before we came here,
-	 * but that was ineffective since the result was <= 0, and
-	 * any negative value of count is equivalent to 0.
-	 * This ends up setting count to 1, unless count is now > 0
-	 * (i.e. because some other cpu has called up() in the meantime),
-	 * in which case we just increment count.
-	 */
-	__sem_update_count(sem, 1);
-	wake_up(&sem->wait);
-}
-EXPORT_SYMBOL(__up);
-
-/*
- * Note that when we come in to __down or __down_interruptible,
- * we have already decremented count, but that decrement was
- * ineffective since the result was < 0, and any negative value
- * of count is equivalent to 0.
- * Thus it is only when we decrement count from some value > 0
- * that we have actually got the semaphore.
- */
-void __sched __down(struct semaphore *sem)
-{
-	struct task_struct *tsk = current;
-	DECLARE_WAITQUEUE(wait, tsk);
-
-	__set_task_state(tsk, TASK_UNINTERRUPTIBLE);
-	add_wait_queue_exclusive(&sem->wait, &wait);
-
-	/*
-	 * Try to get the semaphore.  If the count is > 0, then we've
-	 * got the semaphore; we decrement count and exit the loop.
-	 * If the count is 0 or negative, we set it to -1, indicating
-	 * that we are asleep, and then sleep.
-	 */
-	while (__sem_update_count(sem, -1) <= 0) {
-		schedule();
-		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
-	}
-	remove_wait_queue(&sem->wait, &wait);
-	__set_task_state(tsk, TASK_RUNNING);
-
-	/*
-	 * If there are any more sleepers, wake one of them up so
-	 * that it can either get the semaphore, or set count to -1
-	 * indicating that there are still processes sleeping.
-	 */
-	wake_up(&sem->wait);
-}
-EXPORT_SYMBOL(__down);
-
-int __sched __down_interruptible(struct semaphore * sem)
-{
-	int retval = 0;
-	struct task_struct *tsk = current;
-	DECLARE_WAITQUEUE(wait, tsk);
-
-	__set_task_state(tsk, TASK_INTERRUPTIBLE);
-	add_wait_queue_exclusive(&sem->wait, &wait);
-
-	while (__sem_update_count(sem, -1) <= 0) {
-		if (signal_pending(current)) {
-			/*
-			 * A signal is pending - give up trying.
-			 * Set sem->count to 0 if it is negative,
-			 * since we are no longer sleeping.
-			 */
-			__sem_update_count(sem, 0);
-			retval = -EINTR;
-			break;
-		}
-		schedule();
-		set_task_state(tsk, TASK_INTERRUPTIBLE);
-	}
-	remove_wait_queue(&sem->wait, &wait);
-	__set_task_state(tsk, TASK_RUNNING);
-
-	wake_up(&sem->wait);
-	return retval;
-}
-EXPORT_SYMBOL(__down_interruptible);
diff --git a/arch/ppc64/kernel/vdso.c b/arch/ppc64/kernel/vdso.c
deleted file mode 100644
index 1bbacac..0000000
--- a/arch/ppc64/kernel/vdso.c
+++ /dev/null
@@ -1,625 +0,0 @@
-/*
- *  linux/arch/ppc64/kernel/vdso.c
- *
- *    Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
- *			 <benh@kernel.crashing.org>
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/elf.h>
-#include <linux/security.h>
-#include <linux/bootmem.h>
-
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/processor.h>
-#include <asm/mmu.h>
-#include <asm/mmu_context.h>
-#include <asm/machdep.h>
-#include <asm/cputable.h>
-#include <asm/sections.h>
-#include <asm/systemcfg.h>
-#include <asm/vdso.h>
-
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(fmt...) printk(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-
-/*
- * The vDSOs themselves are here
- */
-extern char vdso64_start, vdso64_end;
-extern char vdso32_start, vdso32_end;
-
-static void *vdso64_kbase = &vdso64_start;
-static void *vdso32_kbase = &vdso32_start;
-
-unsigned int vdso64_pages;
-unsigned int vdso32_pages;
-
-/* Signal trampolines user addresses */
-
-unsigned long vdso64_rt_sigtramp;
-unsigned long vdso32_sigtramp;
-unsigned long vdso32_rt_sigtramp;
-
-/* Format of the patch table */
-struct vdso_patch_def
-{
-	u32		pvr_mask, pvr_value;
-	const char	*gen_name;
-	const char	*fix_name;
-};
-
-/* Table of functions to patch based on the CPU type/revision
- *
- * TODO: Improve by adding whole lists for each entry
- */
-static struct vdso_patch_def vdso_patches[] = {
-	{
-		0xffff0000, 0x003a0000,		/* POWER5 */
-		"__kernel_sync_dicache", "__kernel_sync_dicache_p5"
-	},
-	{
-		0xffff0000, 0x003b0000,		/* POWER5 */
-		"__kernel_sync_dicache", "__kernel_sync_dicache_p5"
-	},
-};
-
-/*
- * Some infos carried around for each of them during parsing at
- * boot time.
- */
-struct lib32_elfinfo
-{
-	Elf32_Ehdr	*hdr;		/* ptr to ELF */
-	Elf32_Sym	*dynsym;	/* ptr to .dynsym section */
-	unsigned long	dynsymsize;	/* size of .dynsym section */
-	char		*dynstr;	/* ptr to .dynstr section */
-	unsigned long	text;		/* offset of .text section in .so */
-};
-
-struct lib64_elfinfo
-{
-	Elf64_Ehdr	*hdr;
-	Elf64_Sym	*dynsym;
-	unsigned long	dynsymsize;
-	char		*dynstr;
-	unsigned long	text;
-};
-
-
-#ifdef __DEBUG
-static void dump_one_vdso_page(struct page *pg, struct page *upg)
-{
-	printk("kpg: %p (c:%d,f:%08lx)", __va(page_to_pfn(pg) << PAGE_SHIFT),
-	       page_count(pg),
-	       pg->flags);
-	if (upg/* && pg != upg*/) {
-		printk(" upg: %p (c:%d,f:%08lx)", __va(page_to_pfn(upg) << PAGE_SHIFT),
-		       page_count(upg),
-		       upg->flags);
-	}
-	printk("\n");
-}
-
-static void dump_vdso_pages(struct vm_area_struct * vma)
-{
-	int i;
-
-	if (!vma || test_thread_flag(TIF_32BIT)) {
-		printk("vDSO32 @ %016lx:\n", (unsigned long)vdso32_kbase);
-		for (i=0; i<vdso32_pages; i++) {
-			struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);
-			struct page *upg = (vma && vma->vm_mm) ?
-				follow_page(vma->vm_mm, vma->vm_start + i*PAGE_SIZE, 0)
-				: NULL;
-			dump_one_vdso_page(pg, upg);
-		}
-	}
-	if (!vma || !test_thread_flag(TIF_32BIT)) {
-		printk("vDSO64 @ %016lx:\n", (unsigned long)vdso64_kbase);
-		for (i=0; i<vdso64_pages; i++) {
-			struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);
-			struct page *upg = (vma && vma->vm_mm) ?
-				follow_page(vma->vm_mm, vma->vm_start + i*PAGE_SIZE, 0)
-				: NULL;
-			dump_one_vdso_page(pg, upg);
-		}
-	}
-}
-#endif /* DEBUG */
-
-/*
- * Keep a dummy vma_close for now, it will prevent VMA merging.
- */
-static void vdso_vma_close(struct vm_area_struct * vma)
-{
-}
-
-/*
- * Our nopage() function, maps in the actual vDSO kernel pages, they will
- * be mapped read-only by do_no_page(), and eventually COW'ed, either
- * right away for an initial write access, or by do_wp_page().
- */
-static struct page * vdso_vma_nopage(struct vm_area_struct * vma,
-				     unsigned long address, int *type)
-{
-	unsigned long offset = address - vma->vm_start;
-	struct page *pg;
-	void *vbase = test_thread_flag(TIF_32BIT) ? vdso32_kbase : vdso64_kbase;
-
-	DBG("vdso_vma_nopage(current: %s, address: %016lx, off: %lx)\n",
-	    current->comm, address, offset);
-
-	if (address < vma->vm_start || address > vma->vm_end)
-		return NOPAGE_SIGBUS;
-
-	/*
-	 * Last page is systemcfg.
-	 */
-	if ((vma->vm_end - address) <= PAGE_SIZE)
-		pg = virt_to_page(_systemcfg);
-	else
-		pg = virt_to_page(vbase + offset);
-
-	get_page(pg);
-	DBG(" ->page count: %d\n", page_count(pg));
-
-	return pg;
-}
-
-static struct vm_operations_struct vdso_vmops = {
-	.close	= vdso_vma_close,
-	.nopage	= vdso_vma_nopage,
-};
-
-/*
- * This is called from binfmt_elf, we create the special vma for the
- * vDSO and insert it into the mm struct tree
- */
-int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack)
-{
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
-	unsigned long vdso_pages;
-	unsigned long vdso_base;
-
-	if (test_thread_flag(TIF_32BIT)) {
-		vdso_pages = vdso32_pages;
-		vdso_base = VDSO32_MBASE;
-	} else {
-		vdso_pages = vdso64_pages;
-		vdso_base = VDSO64_MBASE;
-	}
-
-	current->thread.vdso_base = 0;
-
-	/* vDSO has a problem and was disabled, just don't "enable" it for the
-	 * process
-	 */
-	if (vdso_pages == 0)
-		return 0;
-
-	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-	if (vma == NULL)
-		return -ENOMEM;
-
-	memset(vma, 0, sizeof(*vma));
-
-	/*
-	 * pick a base address for the vDSO in process space. We try to put it
-	 * at vdso_base which is the "natural" base for it, but we might fail
-	 * and end up putting it elsewhere.
-	 */
-	vdso_base = get_unmapped_area(NULL, vdso_base,
-				      vdso_pages << PAGE_SHIFT, 0, 0);
-	if (vdso_base & ~PAGE_MASK) {
-		kmem_cache_free(vm_area_cachep, vma);
-		return (int)vdso_base;
-	}
-
-	current->thread.vdso_base = vdso_base;
-
-	vma->vm_mm = mm;
-	vma->vm_start = current->thread.vdso_base;
-
-	/*
-	 * the VMA size is one page more than the vDSO since systemcfg
-	 * is mapped in the last one
-	 */
-	vma->vm_end = vma->vm_start + ((vdso_pages + 1) << PAGE_SHIFT);
-
-	/*
-	 * our vma flags don't have VM_WRITE so by default, the process isn't allowed
-	 * to write those pages.
-	 * gdb can break that with ptrace interface, and thus trigger COW on those
-	 * pages but it's then your responsibility to never do that on the "data" page
-	 * of the vDSO or you'll stop getting kernel updates and your nice userland
-	 * gettimeofday will be totally dead. It's fine to use that for setting
-	 * breakpoints in the vDSO code pages though
-	 */
-	vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC | VM_RESERVED;
-	vma->vm_flags |= mm->def_flags;
-	vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
-	vma->vm_ops = &vdso_vmops;
-
-	down_write(&mm->mmap_sem);
-	if (insert_vm_struct(mm, vma)) {
-		up_write(&mm->mmap_sem);
-		kmem_cache_free(vm_area_cachep, vma);
-		return -ENOMEM;
-	}
-	mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
-	up_write(&mm->mmap_sem);
-
-	return 0;
-}
-
-static void * __init find_section32(Elf32_Ehdr *ehdr, const char *secname,
-				  unsigned long *size)
-{
-	Elf32_Shdr *sechdrs;
-	unsigned int i;
-	char *secnames;
-
-	/* Grab section headers and strings so we can tell who is who */
-	sechdrs = (void *)ehdr + ehdr->e_shoff;
-	secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset;
-
-	/* Find the section they want */
-	for (i = 1; i < ehdr->e_shnum; i++) {
-		if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) {
-			if (size)
-				*size = sechdrs[i].sh_size;
-			return (void *)ehdr + sechdrs[i].sh_offset;
-		}
-	}
-	*size = 0;
-	return NULL;
-}
-
-static void * __init find_section64(Elf64_Ehdr *ehdr, const char *secname,
-				  unsigned long *size)
-{
-	Elf64_Shdr *sechdrs;
-	unsigned int i;
-	char *secnames;
-
-	/* Grab section headers and strings so we can tell who is who */
-	sechdrs = (void *)ehdr + ehdr->e_shoff;
-	secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset;
-
-	/* Find the section they want */
-	for (i = 1; i < ehdr->e_shnum; i++) {
-		if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) {
-			if (size)
-				*size = sechdrs[i].sh_size;
-			return (void *)ehdr + sechdrs[i].sh_offset;
-		}
-	}
-	if (size)
-		*size = 0;
-	return NULL;
-}
-
-static Elf32_Sym * __init find_symbol32(struct lib32_elfinfo *lib, const char *symname)
-{
-	unsigned int i;
-	char name[32], *c;
-
-	for (i = 0; i < (lib->dynsymsize / sizeof(Elf32_Sym)); i++) {
-		if (lib->dynsym[i].st_name == 0)
-			continue;
-		strlcpy(name, lib->dynstr + lib->dynsym[i].st_name, 32);
-		c = strchr(name, '@');
-		if (c)
-			*c = 0;
-		if (strcmp(symname, name) == 0)
-			return &lib->dynsym[i];
-	}
-	return NULL;
-}
-
-static Elf64_Sym * __init find_symbol64(struct lib64_elfinfo *lib, const char *symname)
-{
-	unsigned int i;
-	char name[32], *c;
-
-	for (i = 0; i < (lib->dynsymsize / sizeof(Elf64_Sym)); i++) {
-		if (lib->dynsym[i].st_name == 0)
-			continue;
-		strlcpy(name, lib->dynstr + lib->dynsym[i].st_name, 32);
-		c = strchr(name, '@');
-		if (c)
-			*c = 0;
-		if (strcmp(symname, name) == 0)
-			return &lib->dynsym[i];
-	}
-	return NULL;
-}
-
-/* Note that we assume the section is .text and the symbol is relative to
- * the library base
- */
-static unsigned long __init find_function32(struct lib32_elfinfo *lib, const char *symname)
-{
-	Elf32_Sym *sym = find_symbol32(lib, symname);
-
-	if (sym == NULL) {
-		printk(KERN_WARNING "vDSO32: function %s not found !\n", symname);
-		return 0;
-	}
-	return sym->st_value - VDSO32_LBASE;
-}
-
-/* Note that we assume the section is .text and the symbol is relative to
- * the library base
- */
-static unsigned long __init find_function64(struct lib64_elfinfo *lib, const char *symname)
-{
-	Elf64_Sym *sym = find_symbol64(lib, symname);
-
-	if (sym == NULL) {
-		printk(KERN_WARNING "vDSO64: function %s not found !\n", symname);
-		return 0;
-	}
-#ifdef VDS64_HAS_DESCRIPTORS
-	return *((u64 *)(vdso64_kbase + sym->st_value - VDSO64_LBASE)) - VDSO64_LBASE;
-#else
-	return sym->st_value - VDSO64_LBASE;
-#endif
-}
-
-
-static __init int vdso_do_find_sections(struct lib32_elfinfo *v32,
-					struct lib64_elfinfo *v64)
-{
-	void *sect;
-
-	/*
-	 * Locate symbol tables & text section
-	 */
-
-	v32->dynsym = find_section32(v32->hdr, ".dynsym", &v32->dynsymsize);
-	v32->dynstr = find_section32(v32->hdr, ".dynstr", NULL);
-	if (v32->dynsym == NULL || v32->dynstr == NULL) {
-		printk(KERN_ERR "vDSO32: a required symbol section was not found\n");
-		return -1;
-	}
-	sect = find_section32(v32->hdr, ".text", NULL);
-	if (sect == NULL) {
-		printk(KERN_ERR "vDSO32: the .text section was not found\n");
-		return -1;
-	}
-	v32->text = sect - vdso32_kbase;
-
-	v64->dynsym = find_section64(v64->hdr, ".dynsym", &v64->dynsymsize);
-	v64->dynstr = find_section64(v64->hdr, ".dynstr", NULL);
-	if (v64->dynsym == NULL || v64->dynstr == NULL) {
-		printk(KERN_ERR "vDSO64: a required symbol section was not found\n");
-		return -1;
-	}
-	sect = find_section64(v64->hdr, ".text", NULL);
-	if (sect == NULL) {
-		printk(KERN_ERR "vDSO64: the .text section was not found\n");
-		return -1;
-	}
-	v64->text = sect - vdso64_kbase;
-
-	return 0;
-}
-
-static __init void vdso_setup_trampolines(struct lib32_elfinfo *v32,
-					  struct lib64_elfinfo *v64)
-{
-	/*
-	 * Find signal trampolines
-	 */
-
-	vdso64_rt_sigtramp	= find_function64(v64, "__kernel_sigtramp_rt64");
-	vdso32_sigtramp		= find_function32(v32, "__kernel_sigtramp32");
-	vdso32_rt_sigtramp	= find_function32(v32, "__kernel_sigtramp_rt32");
-}
-
-static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32,
-				       struct lib64_elfinfo *v64)
-{
-	Elf32_Sym *sym32;
-	Elf64_Sym *sym64;
-
-	sym32 = find_symbol32(v32, "__kernel_datapage_offset");
-	if (sym32 == NULL) {
-		printk(KERN_ERR "vDSO32: Can't find symbol __kernel_datapage_offset !\n");
-		return -1;
-	}
-	*((int *)(vdso32_kbase + (sym32->st_value - VDSO32_LBASE))) =
-		(vdso32_pages << PAGE_SHIFT) - (sym32->st_value - VDSO32_LBASE);
-
-       	sym64 = find_symbol64(v64, "__kernel_datapage_offset");
-	if (sym64 == NULL) {
-		printk(KERN_ERR "vDSO64: Can't find symbol __kernel_datapage_offset !\n");
-		return -1;
-	}
-	*((int *)(vdso64_kbase + sym64->st_value - VDSO64_LBASE)) =
-		(vdso64_pages << PAGE_SHIFT) - (sym64->st_value - VDSO64_LBASE);
-
-	return 0;
-}
-
-static int vdso_do_func_patch32(struct lib32_elfinfo *v32,
-				struct lib64_elfinfo *v64,
-				const char *orig, const char *fix)
-{
-	Elf32_Sym *sym32_gen, *sym32_fix;
-
-	sym32_gen = find_symbol32(v32, orig);
-	if (sym32_gen == NULL) {
-		printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", orig);
-		return -1;
-	}
-	sym32_fix = find_symbol32(v32, fix);
-	if (sym32_fix == NULL) {
-		printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", fix);
-		return -1;
-	}
-	sym32_gen->st_value = sym32_fix->st_value;
-	sym32_gen->st_size = sym32_fix->st_size;
-	sym32_gen->st_info = sym32_fix->st_info;
-	sym32_gen->st_other = sym32_fix->st_other;
-	sym32_gen->st_shndx = sym32_fix->st_shndx;
-
-	return 0;
-}
-
-static int vdso_do_func_patch64(struct lib32_elfinfo *v32,
-				struct lib64_elfinfo *v64,
-				const char *orig, const char *fix)
-{
-	Elf64_Sym *sym64_gen, *sym64_fix;
-
-	sym64_gen = find_symbol64(v64, orig);
-	if (sym64_gen == NULL) {
-		printk(KERN_ERR "vDSO64: Can't find symbol %s !\n", orig);
-		return -1;
-	}
-	sym64_fix = find_symbol64(v64, fix);
-	if (sym64_fix == NULL) {
-		printk(KERN_ERR "vDSO64: Can't find symbol %s !\n", fix);
-		return -1;
-	}
-	sym64_gen->st_value = sym64_fix->st_value;
-	sym64_gen->st_size = sym64_fix->st_size;
-	sym64_gen->st_info = sym64_fix->st_info;
-	sym64_gen->st_other = sym64_fix->st_other;
-	sym64_gen->st_shndx = sym64_fix->st_shndx;
-
-	return 0;
-}
-
-static __init int vdso_fixup_alt_funcs(struct lib32_elfinfo *v32,
-				       struct lib64_elfinfo *v64)
-{
-	u32 pvr;
-	int i;
-
-	pvr = mfspr(SPRN_PVR);
-	for (i = 0; i < ARRAY_SIZE(vdso_patches); i++) {
-		struct vdso_patch_def *patch = &vdso_patches[i];
-		int match = (pvr & patch->pvr_mask) == patch->pvr_value;
-
-		DBG("patch %d (mask: %x, pvr: %x) : %s\n",
-		    i, patch->pvr_mask, patch->pvr_value, match ? "match" : "skip");
-
-		if (!match)
-			continue;
-
-		DBG("replacing %s with %s...\n", patch->gen_name, patch->fix_name);
-
-		/*
-		 * Patch the 32 bits and 64 bits symbols. Note that we do not patch
-		 * the "." symbol on 64 bits. It would be easy to do, but doesn't
-		 * seem to be necessary, patching the OPD symbol is enough.
-		 */
-		vdso_do_func_patch32(v32, v64, patch->gen_name, patch->fix_name);
-		vdso_do_func_patch64(v32, v64, patch->gen_name, patch->fix_name);
-	}
-
-	return 0;
-}
-
-
-static __init int vdso_setup(void)
-{
-	struct lib32_elfinfo	v32;
-	struct lib64_elfinfo	v64;
-
-	v32.hdr = vdso32_kbase;
-	v64.hdr = vdso64_kbase;
-
-	if (vdso_do_find_sections(&v32, &v64))
-		return -1;
-
-	if (vdso_fixup_datapage(&v32, &v64))
-		return -1;
-
-	if (vdso_fixup_alt_funcs(&v32, &v64))
-		return -1;
-
-	vdso_setup_trampolines(&v32, &v64);
-
-	return 0;
-}
-
-void __init vdso_init(void)
-{
-	int i;
-
-	vdso64_pages = (&vdso64_end - &vdso64_start) >> PAGE_SHIFT;
-	vdso32_pages = (&vdso32_end - &vdso32_start) >> PAGE_SHIFT;
-
-	DBG("vdso64_kbase: %p, 0x%x pages, vdso32_kbase: %p, 0x%x pages\n",
-	       vdso64_kbase, vdso64_pages, vdso32_kbase, vdso32_pages);
-
-	/*
-	 * Initialize the vDSO images in memory, that is do necessary
-	 * fixups of vDSO symbols, locate trampolines, etc...
-	 */
-	if (vdso_setup()) {
-		printk(KERN_ERR "vDSO setup failure, not enabled !\n");
-		/* XXX should free pages here ? */
-		vdso64_pages = vdso32_pages = 0;
-		return;
-	}
-
-	/* Make sure pages are in the correct state */
-	for (i = 0; i < vdso64_pages; i++) {
-		struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);
-		ClearPageReserved(pg);
-		get_page(pg);
-	}
-	for (i = 0; i < vdso32_pages; i++) {
-		struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);
-		ClearPageReserved(pg);
-		get_page(pg);
-	}
-
-	get_page(virt_to_page(_systemcfg));
-}
-
-int in_gate_area_no_task(unsigned long addr)
-{
-	return 0;
-}
-
-int in_gate_area(struct task_struct *task, unsigned long addr)
-{
-	return 0;
-}
-
-struct vm_area_struct *get_gate_vma(struct task_struct *tsk)
-{
-	return NULL;
-}
-
diff --git a/arch/ppc64/kernel/vmlinux.lds.S b/arch/ppc64/kernel/vmlinux.lds.S
deleted file mode 100644
index 022f220..0000000
--- a/arch/ppc64/kernel/vmlinux.lds.S
+++ /dev/null
@@ -1,151 +0,0 @@
-#include <asm/page.h>
-#include <asm-generic/vmlinux.lds.h>
-
-OUTPUT_ARCH(powerpc:common64)
-jiffies = jiffies_64;
-SECTIONS
-{
-  /* Sections to be discarded. */
-  /DISCARD/ : {
-	*(.exitcall.exit)
-	}
-
-
-  /* Read-only sections, merged into text segment: */
-  .text : {
-	*(.text .text.*)
-	SCHED_TEXT
-	LOCK_TEXT
-	KPROBES_TEXT
-	*(.fixup)
-	. = ALIGN(PAGE_SIZE);
-	_etext = .;
-	}
-
-  __ex_table : {
-	__start___ex_table = .;
-	*(__ex_table)
-	__stop___ex_table = .;
-	}
-
-  __bug_table : {
-	__start___bug_table = .;
-	*(__bug_table)
-	__stop___bug_table = .;
-	}
-
-  __ftr_fixup : {
-	__start___ftr_fixup = .;
-	*(__ftr_fixup)
-	__stop___ftr_fixup = .;
-	}
-
-  RODATA
-
-
-  /* will be freed after init */
-  . = ALIGN(PAGE_SIZE);
-  __init_begin = .;
-
-  .init.text : {
-	_sinittext = .;
-	*(.init.text)
-	_einittext = .;
-	}
-
-  .init.data : {
-	*(.init.data)
-	}
-
-  . = ALIGN(16);
-  .init.setup : {
-	__setup_start = .;
-	*(.init.setup)
-	__setup_end = .;
-	}
-
-  .initcall.init : {
-	__initcall_start = .;
-	*(.initcall1.init)
-	*(.initcall2.init)
-	*(.initcall3.init)
-	*(.initcall4.init)
-	*(.initcall5.init)
-	*(.initcall6.init)
-	*(.initcall7.init)
-	__initcall_end = .;
-	}
-
-  .con_initcall.init : {
-	__con_initcall_start = .;
-	*(.con_initcall.init)
-	__con_initcall_end = .;
-	}
-
-  SECURITY_INIT
-
-  . = ALIGN(PAGE_SIZE);
-  .init.ramfs : {
-	__initramfs_start = .;
-	*(.init.ramfs)
-	__initramfs_end = .;
-	}
-
-  .data.percpu : {
-	__per_cpu_start = .;
-	*(.data.percpu)
-	__per_cpu_end = .;
-	}
-
-  . = ALIGN(PAGE_SIZE);
-  . = ALIGN(16384);
-  __init_end = .;
-  /* freed after init ends here */
-
-
-  /* Read/write sections */
-  . = ALIGN(PAGE_SIZE);
-  . = ALIGN(16384);
-  _sdata = .;
-  /* The initial task and kernel stack */
-  .data.init_task : {
-	*(.data.init_task)
-	}
-
-  . = ALIGN(PAGE_SIZE);
-  .data.page_aligned : {
-	*(.data.page_aligned)
-	}
-
-  .data.cacheline_aligned : {
-	*(.data.cacheline_aligned)
-	}
-
-  .data : {
-	*(.data .data.rel* .toc1)
-	*(.branch_lt)
-	}
-
-  .opd : {
-	*(.opd)
-	}
-
-  .got : {
-	__toc_start = .;
-	*(.got)
-	*(.toc)
-	. = ALIGN(PAGE_SIZE);
-	_edata = .;
-	}
-
-
-  . = ALIGN(PAGE_SIZE);
-  .bss : {
-	__bss_start = .;
-	*(.bss)
-	__bss_stop = .;
-	}
-
-  . = ALIGN(PAGE_SIZE);
-  _end = . ;
-}
diff --git a/arch/ppc64/xmon/privinst.h b/arch/ppc64/xmon/privinst.h
deleted file mode 100644
index 02eb40d..0000000
--- a/arch/ppc64/xmon/privinst.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 1996 Paul Mackerras.
- *
- *      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.
- */
-
-#define GETREG(reg)		\
-    static inline unsigned long get_ ## reg (void)	\
-	{ unsigned long ret; asm volatile ("mf" #reg " %0" : "=r" (ret) :); return ret; }
-
-#define SETREG(reg)		\
-    static inline void set_ ## reg (unsigned long val)	\
-	{ asm volatile ("mt" #reg " %0" : : "r" (val)); }
-
-GETREG(msr)
-SETREG(msrd)
-GETREG(cr)
-
-#define GSETSPR(n, name)	\
-    static inline long get_ ## name (void) \
-	{ long ret; asm volatile ("mfspr %0," #n : "=r" (ret) : ); return ret; } \
-    static inline void set_ ## name (long val) \
-	{ asm volatile ("mtspr " #n ",%0" : : "r" (val)); }
-
-GSETSPR(0, mq)
-GSETSPR(1, xer)
-GSETSPR(4, rtcu)
-GSETSPR(5, rtcl)
-GSETSPR(8, lr)
-GSETSPR(9, ctr)
-GSETSPR(18, dsisr)
-GSETSPR(19, dar)
-GSETSPR(22, dec)
-GSETSPR(25, sdr1)
-GSETSPR(26, srr0)
-GSETSPR(27, srr1)
-GSETSPR(272, sprg0)
-GSETSPR(273, sprg1)
-GSETSPR(274, sprg2)
-GSETSPR(275, sprg3)
-GSETSPR(282, ear)
-GSETSPR(287, pvr)
-GSETSPR(1008, hid0)
-GSETSPR(1009, hid1)
-GSETSPR(1010, iabr)
-GSETSPR(1023, pir)
-
-static inline void store_inst(void *p)
-{
-	asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
-}
-
-static inline void cflush(void *p)
-{
-	asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
-}
-
-static inline void cinval(void *p)
-{
-	asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
-}
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
index 2e64e8c..cb3cf0f 100644
--- a/arch/sparc/lib/atomic32.c
+++ b/arch/sparc/lib/atomic32.c
@@ -37,17 +37,43 @@ int __atomic_add_return(int i, atomic_t 
 	spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
 	return ret;
 }
+EXPORT_SYMBOL(__atomic_add_return);
 
-void atomic_set(atomic_t *v, int i)
+int atomic_cmpxchg(atomic_t *v, int old, int new)
 {
+	int ret;
 	unsigned long flags;
+
 	spin_lock_irqsave(ATOMIC_HASH(v), flags);
+	ret = v->counter;
+	if (likely(ret == old))
+		v->counter = new;
 
-	v->counter = i;
+	spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
+	return ret;
+}
 
+int atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(ATOMIC_HASH(v), flags);
+	ret = v->counter;
+	if (ret != u)
+		v->counter += a;
 	spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
+	return ret != u;
 }
 
-EXPORT_SYMBOL(__atomic_add_return);
-EXPORT_SYMBOL(atomic_set);
+static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
+/* Atomic operations are already serializing */
+void atomic_set(atomic_t *v, int i)
+{
+	unsigned long flags;
 
+	spin_lock_irqsave(ATOMIC_HASH(v), flags);
+	v->counter = i;
+	spin_unlock_irqrestore(ATOMIC_HASH(v), flags);
+}
+EXPORT_SYMBOL(atomic_set);
diff --git a/arch/sparc/lib/bitext.c b/arch/sparc/lib/bitext.c
index 94b05e8..2e168d1 100644
--- a/arch/sparc/lib/bitext.c
+++ b/arch/sparc/lib/bitext.c
@@ -10,6 +10,7 @@
  */
 
 #include <linux/smp_lock.h>
+#include <linux/string.h>
 #include <linux/bitops.h>
 
 #include <asm/bitext.h>
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
index e622143..196b208 100644
--- a/arch/sparc64/kernel/ioctl32.c
+++ b/arch/sparc64/kernel/ioctl32.c
@@ -12,86 +12,10 @@
 #define INCLUDES
 #include "compat_ioctl.c"
 #include <linux/syscalls.h>
-#include <asm/fbio.h>
-
-/* Use this to get at 32-bit user passed pointers. 
- * See sys_sparc32.c for description about it.
- */
-#define A(__x) compat_ptr(__x)
 
 #define CODE
 #include "compat_ioctl.c"
 
-struct  fbcmap32 {
-	int             index;          /* first element (0 origin) */
-	int             count;
-	u32		red;
-	u32		green;
-	u32		blue;
-};
-
-#define FBIOPUTCMAP32	_IOW('F', 3, struct fbcmap32)
-#define FBIOGETCMAP32	_IOW('F', 4, struct fbcmap32)
-
-static int fbiogetputcmap(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-	struct fbcmap32 __user *argp = (void __user *)arg;
-	struct fbcmap __user *p = compat_alloc_user_space(sizeof(*p));
-	u32 addr;
-	int ret;
-	
-	ret = copy_in_user(p, argp, 2 * sizeof(int));
-	ret |= get_user(addr, &argp->red);
-	ret |= put_user(compat_ptr(addr), &p->red);
-	ret |= get_user(addr, &argp->green);
-	ret |= put_user(compat_ptr(addr), &p->green);
-	ret |= get_user(addr, &argp->blue);
-	ret |= put_user(compat_ptr(addr), &p->blue);
-	if (ret)
-		return -EFAULT;
-	return sys_ioctl(fd, (cmd == FBIOPUTCMAP32) ? FBIOPUTCMAP_SPARC : FBIOGETCMAP_SPARC, (unsigned long)p);
-}
-
-struct fbcursor32 {
-	short set;		/* what to set, choose from the list above */
-	short enable;		/* cursor on/off */
-	struct fbcurpos pos;	/* cursor position */
-	struct fbcurpos hot;	/* cursor hot spot */
-	struct fbcmap32 cmap;	/* color map info */
-	struct fbcurpos size;	/* cursor bit map size */
-	u32	image;		/* cursor image bits */
-	u32	mask;		/* cursor mask bits */
-};
-	
-#define FBIOSCURSOR32	_IOW('F', 24, struct fbcursor32)
-#define FBIOGCURSOR32	_IOW('F', 25, struct fbcursor32)
-
-static int fbiogscursor(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-	struct fbcursor __user *p = compat_alloc_user_space(sizeof(*p));
-	struct fbcursor32 __user *argp =  (void __user *)arg;
-	compat_uptr_t addr;
-	int ret;
-	
-	ret = copy_in_user(p, argp,
-			      2 * sizeof (short) + 2 * sizeof(struct fbcurpos));
-	ret |= copy_in_user(&p->size, &argp->size, sizeof(struct fbcurpos));
-	ret |= copy_in_user(&p->cmap, &argp->cmap, 2 * sizeof(int));
-	ret |= get_user(addr, &argp->cmap.red);
-	ret |= put_user(compat_ptr(addr), &p->cmap.red);
-	ret |= get_user(addr, &argp->cmap.green);
-	ret |= put_user(compat_ptr(addr), &p->cmap.green);
-	ret |= get_user(addr, &argp->cmap.blue);
-	ret |= put_user(compat_ptr(addr), &p->cmap.blue);
-	ret |= get_user(addr, &argp->mask);
-	ret |= put_user(compat_ptr(addr), &p->mask);
-	ret |= get_user(addr, &argp->image);
-	ret |= put_user(compat_ptr(addr), &p->image);
-	if (ret)
-		return -EFAULT;
-	return sys_ioctl (fd, FBIOSCURSOR, (unsigned long)p);
-}
-
 #define COMPATIBLE_IOCTL(cmd)		HANDLE_IOCTL((cmd),sys_ioctl)
 #define HANDLE_IOCTL(cmd,handler)	{ (cmd), (ioctl_trans_handler_t)(handler), NULL },
 #define IOCTL_TABLE_START \
@@ -103,22 +27,6 @@ IOCTL_TABLE_START
 #include <linux/compat_ioctl.h>
 #define DECLARES
 #include "compat_ioctl.c"
-COMPATIBLE_IOCTL(FBIOGTYPE)
-COMPATIBLE_IOCTL(FBIOSATTR)
-COMPATIBLE_IOCTL(FBIOGATTR)
-COMPATIBLE_IOCTL(FBIOSVIDEO)
-COMPATIBLE_IOCTL(FBIOGVIDEO)
-COMPATIBLE_IOCTL(FBIOGCURSOR32)  /* This is not implemented yet. Later it should be converted... */
-COMPATIBLE_IOCTL(FBIOSCURPOS)
-COMPATIBLE_IOCTL(FBIOGCURPOS)
-COMPATIBLE_IOCTL(FBIOGCURMAX)
-/* Little k */
-/* Little v, the video4linux ioctls */
-/* And these ioctls need translation */
-/* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */
-HANDLE_IOCTL(FBIOPUTCMAP32, fbiogetputcmap)
-HANDLE_IOCTL(FBIOGETCMAP32, fbiogetputcmap)
-HANDLE_IOCTL(FBIOSCURSOR32, fbiogscursor)
 #if 0
 HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl)
 HANDLE_IOCTL(RTC32_IRQP_SET, do_rtc_ioctl)
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 3b5f47c..563301f 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -7,7 +7,6 @@ config UML
 	bool
 	default y
 
-# XXX: does UM have a mmu/swap?
 config MMU
 	bool
 	default y
@@ -36,12 +35,6 @@ config IRQ_RELEASE_METHOD
 	bool
 	default y
 
-menu "Host processor type and features"
-
-source "arch/i386/Kconfig.cpu"
-
-endmenu
-
 menu "UML-specific options"
 
 config MODE_TT
@@ -209,7 +202,8 @@ config MAGIC_SYSRQ
 config SMP
 	bool "Symmetric multi-processing support (EXPERIMENTAL)"
 	default n
-	depends on (MODE_TT && EXPERIMENTAL && !SMP_BROKEN) || (BROKEN && SMP_BROKEN)
+	#SMP_BROKEN is for x86_64.
+	depends on MODE_TT && EXPERIMENTAL && (!SMP_BROKEN || (BROKEN && SMP_BROKEN))
 	help
 	This option enables UML SMP support.
 	It is NOT related to having a real SMP box. Not directly, at least.
diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386
index 5d92cac..c71b39a 100644
--- a/arch/um/Kconfig.i386
+++ b/arch/um/Kconfig.i386
@@ -1,3 +1,9 @@
+menu "Host processor type and features"
+
+source "arch/i386/Kconfig.cpu"
+
+endmenu
+
 config UML_X86
 	bool
 	default y
@@ -42,7 +48,3 @@ config ARCH_HAS_SC_SIGNALS
 config ARCH_REUSE_HOST_VSYSCALL_AREA
 	bool
 	default y
-
-config X86_CMPXCHG
-	bool
-	default y
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 1f7dcb0..7a0e04e 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -35,4 +35,3 @@ cflags-y += $(call cc-option,-mpreferred
 
 CFLAGS += $(cflags-y)
 USER_CFLAGS += $(cflags-y)
-
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 16e7dc8..5b58fad 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -89,8 +89,7 @@ static int not_configged_write(int fd, c
 	return(-EIO);
 }
 
-static int not_configged_console_write(int fd, const char *buf, int len,
-				       void *data)
+static int not_configged_console_write(int fd, const char *buf, int len)
 {
 	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
@@ -299,7 +298,7 @@ int console_write_chan(struct list_head 
 		chan = list_entry(ele, struct chan, list);
 		if(!chan->output || (chan->ops->console_write == NULL))
 			continue;
-		n = chan->ops->console_write(chan->fd, buf, len, chan->data);
+		n = chan->ops->console_write(chan->fd, buf, len);
 		if(chan->primary) ret = n;
 	}
 	return(ret);
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 1c55d58..5d50d4a 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -20,7 +20,7 @@
 #include "choose-mode.h"
 #include "mode.h"
 
-int generic_console_write(int fd, const char *buf, int n, void *unused)
+int generic_console_write(int fd, const char *buf, int n)
 {
 	struct termios save, new;
 	int err;
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index c1b03f7..1bb085b 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -98,7 +98,7 @@ static int connect_to_switch(struct daem
 		printk("daemon_open : control setup request failed, err = %d\n",
 		       -n);
 		err = -ENOTCONN;
-		goto out;		
+		goto out_free;
 	}
 
 	n = os_read_file(pri->control, sun, sizeof(*sun));
@@ -106,12 +106,14 @@ static int connect_to_switch(struct daem
 		printk("daemon_open : read of data socket failed, err = %d\n",
 		       -n);
 		err = -ENOTCONN;
-		goto out_close;		
+		goto out_free;
 	}
 
 	pri->data_addr = sun;
 	return(fd);
 
+ out_free:
+	kfree(sun);
  out_close:
 	os_close_file(fd);
  out:
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index f0b888f..3296e86 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -76,13 +76,6 @@ static void fd_close(int fd, void *d)
 	}
 }
 
-static int fd_console_write(int fd, const char *buf, int n, void *d)
-{
-	struct fd_chan *data = d;
-
-	return(generic_console_write(fd, buf, n, &data->tt));
-}
-
 struct chan_ops fd_ops = {
 	.type		= "fd",
 	.init		= fd_init,
@@ -90,7 +83,7 @@ struct chan_ops fd_ops = {
 	.close		= fd_close,
 	.read		= generic_read,
 	.write		= generic_write,
-	.console_write	= fd_console_write,
+	.console_write	= generic_console_write,
 	.window_size	= generic_window_size,
 	.free		= generic_free,
 	.winch		= 1,
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index 5db136e..afe85bf 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -54,7 +54,7 @@ static int mcast_open(void *data)
 	struct mcast_data *pri = data;
 	struct sockaddr_in *sin = pri->mcast_addr;
 	struct ip_mreq mreq;
-	int fd, yes = 1, err = 0;
+	int fd, yes = 1, err = -EINVAL;
 
 
 	if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0))
@@ -63,40 +63,40 @@ static int mcast_open(void *data)
 	fd = socket(AF_INET, SOCK_DGRAM, 0);
 
 	if (fd < 0){
+		err = -errno;
 		printk("mcast_open : data socket failed, errno = %d\n", 
 		       errno);
-		err = -errno;
 		goto out;
 	}
 
 	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
+		err = -errno;
 		printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
 			errno);
-		err = -errno;
 		goto out_close;
 	}
 
 	/* set ttl according to config */
 	if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
 		       sizeof(pri->ttl)) < 0) {
+		err = -errno;
 		printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
 			errno);
-		err = -errno;
 		goto out_close;
 	}
 
 	/* set LOOP, so data does get fed back to local sockets */
 	if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
+		err = -errno;
 		printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
 			errno);
-		err = -errno;
 		goto out_close;
 	}
 
 	/* bind socket to mcast address */
 	if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
-		printk("mcast_open : data bind failed, errno = %d\n", errno);
 		err = -errno;
+		printk("mcast_open : data bind failed, errno = %d\n", errno);
 		goto out_close;
 	}		
 	
@@ -105,22 +105,22 @@ static int mcast_open(void *data)
 	mreq.imr_interface.s_addr = 0;
 	if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, 
 		       &mreq, sizeof(mreq)) < 0) {
+		err = -errno;
 		printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n",
 			errno);
 		printk("There appears not to be a multicast-capable network "
 		       "interface on the host.\n");
 		printk("eth0 should be configured in order to use the "
 		       "multicast transport.\n");
-		err = -errno;
-                goto out_close;
+		goto out_close;
 	}
 
 	return fd;
 
  out_close:
-        os_close_file(fd);
+	os_close_file(fd);
  out:
-        return err;
+	return err;
 }
 
 static void mcast_close(int fd, void *data)
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index ed4a1a6..c43e8bb 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -100,13 +100,6 @@ static void port_close(int fd, void *d)
 	os_close_file(fd);
 }
 
-static int port_console_write(int fd, const char *buf, int n, void *d)
-{
-	struct port_chan *data = d;
-
-	return(generic_console_write(fd, buf, n, &data->tt));
-}
-
 struct chan_ops port_ops = {
 	.type		= "port",
 	.init		= port_init,
@@ -114,7 +107,7 @@ struct chan_ops port_ops = {
 	.close		= port_close,
 	.read	        = generic_read,
 	.write		= generic_write,
-	.console_write	= port_console_write,
+	.console_write	= generic_console_write,
 	.window_size	= generic_window_size,
 	.free		= port_free,
 	.winch		= 1,
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index 0306a1b..1c555c3 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -118,13 +118,6 @@ static int pty_open(int input, int outpu
 	return(fd);
 }
 
-static int pty_console_write(int fd, const char *buf, int n, void *d)
-{
-	struct pty_chan *data = d;
-
-	return(generic_console_write(fd, buf, n, &data->tt));
-}
-
 struct chan_ops pty_ops = {
 	.type		= "pty",
 	.init		= pty_chan_init,
@@ -132,7 +125,7 @@ struct chan_ops pty_ops = {
 	.close		= generic_close,
 	.read		= generic_read,
 	.write		= generic_write,
-	.console_write	= pty_console_write,
+	.console_write	= generic_console_write,
 	.window_size	= generic_window_size,
 	.free		= generic_free,
 	.winch		= 0,
@@ -145,7 +138,7 @@ struct chan_ops pts_ops = {
 	.close		= generic_close,
 	.read		= generic_read,
 	.write		= generic_write,
-	.console_write	= pty_console_write,
+	.console_write	= generic_console_write,
 	.window_size	= generic_window_size,
 	.free		= generic_free,
 	.winch		= 0,
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index 6fbb670..94c9265 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -60,13 +60,6 @@ static int tty_open(int input, int outpu
 	return(fd);
 }
 
-static int tty_console_write(int fd, const char *buf, int n, void *d)
-{
-	struct tty_chan *data = d;
-
-	return(generic_console_write(fd, buf, n, &data->tt));
-}
-
 struct chan_ops tty_ops = {
 	.type		= "tty",
 	.init		= tty_chan_init,
@@ -74,7 +67,7 @@ struct chan_ops tty_ops = {
 	.close		= generic_close,
 	.read		= generic_read,
 	.write		= generic_write,
-	.console_write	= tty_console_write,
+	.console_write	= generic_console_write,
 	.window_size	= generic_window_size,
 	.free		= generic_free,
 	.winch		= 0,
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index b530f1a..aaa6366 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -194,13 +194,6 @@ static void xterm_free(void *d)
 	free(d);
 }
 
-static int xterm_console_write(int fd, const char *buf, int n, void *d)
-{
-	struct xterm_chan *data = d;
-
-	return(generic_console_write(fd, buf, n, &data->tt));
-}
-
 struct chan_ops xterm_ops = {
 	.type		= "xterm",
 	.init		= xterm_init,
@@ -208,7 +201,7 @@ struct chan_ops xterm_ops = {
 	.close		= xterm_close,
 	.read		= generic_read,
 	.write		= generic_write,
-	.console_write	= xterm_console_write,
+	.console_write	= generic_console_write,
 	.window_size	= generic_window_size,
 	.free		= xterm_free,
 	.winch		= 1,
diff --git a/arch/um/include/chan_user.h b/arch/um/include/chan_user.h
index f77d9aa..659bb3c 100644
--- a/arch/um/include/chan_user.h
+++ b/arch/um/include/chan_user.h
@@ -25,7 +25,7 @@ struct chan_ops {
 	void (*close)(int, void *);
 	int (*read)(int, char *, void *);
 	int (*write)(int, const char *, int, void *);
-	int (*console_write)(int, const char *, int, void *);
+	int (*console_write)(int, const char *, int);
 	int (*window_size)(int, void *, unsigned short *, unsigned short *);
 	void (*free)(void *);
 	int winch;
@@ -37,7 +37,7 @@ extern struct chan_ops fd_ops, null_ops,
 extern void generic_close(int fd, void *unused);
 extern int generic_read(int fd, char *c_out, void *unused);
 extern int generic_write(int fd, const char *buf, int n, void *unused);
-extern int generic_console_write(int fd, const char *buf, int n, void *state);
+extern int generic_console_write(int fd, const char *buf, int n);
 extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
 			       unsigned short *cols_out);
 extern void generic_free(void *data);
diff --git a/arch/um/include/um_uaccess.h b/arch/um/include/um_uaccess.h
index 84c0868..f8760a3 100644
--- a/arch/um/include/um_uaccess.h
+++ b/arch/um/include/um_uaccess.h
@@ -17,8 +17,25 @@
 #include "uaccess-skas.h"
 #endif
 
+#define __under_task_size(addr, size) \
+	(((unsigned long) (addr) < TASK_SIZE) && \
+         (((unsigned long) (addr) + (size)) < TASK_SIZE))
+
+#define __access_ok_vsyscall(type, addr, size) \
+	 ((type == VERIFY_READ) && \
+	  ((unsigned long) (addr) >= FIXADDR_USER_START) && \
+	  ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
+	  ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))
+
+#define __addr_range_nowrap(addr, size) \
+	((unsigned long) (addr) <= ((unsigned long) (addr) + (size)))
+
 #define access_ok(type, addr, size) \
-	CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)
+	(__addr_range_nowrap(addr, size) && \
+	 (__under_task_size(addr, size) || \
+	  __access_ok_vsyscall(type, addr, size) || \
+	  segment_eq(get_fs(), KERNEL_DS) || \
+	  CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)))
 
 static inline int copy_from_user(void *to, const void __user *from, int n)
 {
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h
index 7da0c2d..f611f83 100644
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/arch/um/kernel/skas/include/uaccess-skas.h
@@ -9,14 +9,8 @@
 #include "asm/errno.h"
 #include "asm/fixmap.h"
 
-#define access_ok_skas(type, addr, size) \
-	((segment_eq(get_fs(), KERNEL_DS)) || \
-	 (((unsigned long) (addr) < TASK_SIZE) && \
-	  ((unsigned long) (addr) + (size) <= TASK_SIZE)) || \
-	 ((type == VERIFY_READ ) && \
-	  ((unsigned long) (addr) >= FIXADDR_USER_START) && \
-	  ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
-	  ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))
+/* No SKAS-specific checking. */
+#define access_ok_skas(type, addr, size) 0
 
 extern int copy_from_user_skas(void *to, const void __user *from, int n);
 extern int copy_to_user_skas(void __user *to, const void *from, int n);
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 7519528..a5a4752 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -143,7 +143,7 @@ int copy_from_user_skas(void *to, const 
 		return(0);
 	}
 
-	return(access_ok_skas(VERIFY_READ, from, n) ?
+	return(access_ok(VERIFY_READ, from, n) ?
 	       buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
 	       n);
 }
@@ -164,7 +164,7 @@ int copy_to_user_skas(void __user *to, c
 		return(0);
 	}
 
-	return(access_ok_skas(VERIFY_WRITE, to, n) ?
+	return(access_ok(VERIFY_WRITE, to, n) ?
 	       buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
 	       n);
 }
@@ -193,7 +193,7 @@ int strncpy_from_user_skas(char *dst, co
 		return(strnlen(dst, count));
 	}
 
-	if(!access_ok_skas(VERIFY_READ, src, 1))
+	if(!access_ok(VERIFY_READ, src, 1))
 		return(-EFAULT);
 
 	n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
@@ -221,7 +221,7 @@ int clear_user_skas(void __user *mem, in
 		return(0);
 	}
 
-	return(access_ok_skas(VERIFY_WRITE, mem, len) ?
+	return(access_ok(VERIFY_WRITE, mem, len) ?
 	       buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
 }
 
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index 95c8f87..0d4c10a 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -95,7 +95,16 @@ survive:
 		pte = pte_offset_kernel(pmd, address);
 	} while(!pte_present(*pte));
 	err = 0;
+	/* The below warning was added in place of
+	 *	pte_mkyoung(); if (is_write) pte_mkdirty();
+	 * If it's triggered, we'd see normally a hang here (a clean pte is
+	 * marked read-only to emulate the dirty bit).
+	 * However, the generic code can mark a PTE writable but clean on a
+	 * concurrent read fault, triggering this harmlessly. So comment it out.
+	 */
+#if 0
 	WARN_ON(!pte_young(*pte) || (is_write && !pte_dirty(*pte)));
+#endif
 	flush_tlb_page(vma, address);
 out:
 	up_read(&mm->mmap_sem);
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h
index dc2ebfa..b9bfe9c 100644
--- a/arch/um/kernel/tt/include/uaccess-tt.h
+++ b/arch/um/kernel/tt/include/uaccess-tt.h
@@ -19,19 +19,13 @@
 extern unsigned long end_vm;
 extern unsigned long uml_physmem;
 
-#define under_task_size(addr, size) \
-	(((unsigned long) (addr) < TASK_SIZE) && \
-         (((unsigned long) (addr) + (size)) < TASK_SIZE))
-
 #define is_stack(addr, size) \
 	(((unsigned long) (addr) < STACK_TOP) && \
 	 ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
 	 (((unsigned long) (addr) + (size)) <= STACK_TOP))
 
 #define access_ok_tt(type, addr, size) \
-	((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \
-         (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
-          (under_task_size(addr, size) || is_stack(addr, size))))
+	(is_stack(addr, size))
 
 extern unsigned long get_fault_addr(void);
 
diff --git a/arch/um/kernel/tt/uaccess.c b/arch/um/kernel/tt/uaccess.c
index a72aa63..1cb6072 100644
--- a/arch/um/kernel/tt/uaccess.c
+++ b/arch/um/kernel/tt/uaccess.c
@@ -8,7 +8,7 @@
 
 int copy_from_user_tt(void *to, const void __user *from, int n)
 {
-	if(!access_ok_tt(VERIFY_READ, from, n))
+	if(!access_ok(VERIFY_READ, from, n))
 		return(n);
 
 	return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
@@ -17,7 +17,7 @@ int copy_from_user_tt(void *to, const vo
 
 int copy_to_user_tt(void __user *to, const void *from, int n)
 {
-	if(!access_ok_tt(VERIFY_WRITE, to, n))
+	if(!access_ok(VERIFY_WRITE, to, n))
 		return(n);
 
 	return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
@@ -28,7 +28,7 @@ int strncpy_from_user_tt(char *dst, cons
 {
 	int n;
 
-	if(!access_ok_tt(VERIFY_READ, src, 1))
+	if(!access_ok(VERIFY_READ, src, 1))
 		return(-EFAULT);
 
 	n = __do_strncpy_from_user(dst, src, count,
@@ -47,7 +47,7 @@ int __clear_user_tt(void __user *mem, in
 
 int clear_user_tt(void __user *mem, int len)
 {
-	if(!access_ok_tt(VERIFY_WRITE, mem, len))
+	if(!access_ok(VERIFY_WRITE, mem, len))
 		return(len);
 
 	return(__do_clear_user(mem, len, &current->thread.fault_addr,
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
index 89c053b..3108659 100644
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -23,6 +23,14 @@ config GENERIC_CALIBRATE_DELAY
 	bool
 	default y
 
+config GENERIC_HARDIRQS
+	bool
+	default y
+
+config GENERIC_IRQ_PROBE
+	bool
+	default y
+
 # Turn off some random 386 crap that can affect device config
 config ISA
 	bool
diff --git a/arch/v850/kernel/irq.c b/arch/v850/kernel/irq.c
index 9e85969..7a151c2 100644
--- a/arch/v850/kernel/irq.c
+++ b/arch/v850/kernel/irq.c
@@ -1,8 +1,8 @@
 /*
  * arch/v850/kernel/irq.c -- High-level interrupt handling
  *
- *  Copyright (C) 2001,02,03,04  NEC Electronics Corporation
- *  Copyright (C) 2001,02,03,04  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,03,04,05  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03,04,05  Miles Bader <miles@gnu.org>
  *  Copyright (C) 1994-2000  Ralf Baechle
  *  Copyright (C) 1992  Linus Torvalds
  *
@@ -27,55 +27,15 @@
 #include <asm/system.h>
 
 /*
- * Controller mappings for all interrupt sources:
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves, it doesn't deserve
+ * a generic callback i think.
  */
-irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
-	[0 ... NR_IRQS-1] = {
-		.handler = &no_irq_type,
-		.lock = SPIN_LOCK_UNLOCKED
-	}
-};
-
-/*
- * Special irq handlers.
- */
-
-irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
+void ack_bad_irq(unsigned int irq)
 {
-	return IRQ_NONE;
-}
-
-/*
- * Generic no controller code
- */
-
-static void enable_none(unsigned int irq) { }
-static unsigned int startup_none(unsigned int irq) { return 0; }
-static void disable_none(unsigned int irq) { }
-static void ack_none(unsigned int irq)
-{
-	/*
-	 * 'what should we do if we get a hw irq event on an illegal vector'.
-	 * each architecture has to answer this themselves, it doesn't deserve
-	 * a generic callback i think.
-	 */
 	printk("received IRQ %d with unknown interrupt type\n", irq);
 }
 
-/* startup is the same as "enable", shutdown is same as "disable" */
-#define shutdown_none	disable_none
-#define end_none	enable_none
-
-struct hw_interrupt_type no_irq_type = {
-	.typename = "none",
-	.startup = startup_none,
-	.shutdown = shutdown_none,
-	.enable = enable_none,
-	.disable = disable_none,
-	.ack = ack_none,
-	.end = end_none
-};
-
 volatile unsigned long irq_err_count, spurious_count;
 
 /*
@@ -84,643 +44,68 @@ volatile unsigned long irq_err_count, sp
 
 int show_interrupts(struct seq_file *p, void *v)
 {
-	int i = *(loff_t *) v;
-	struct irqaction * action;
-	unsigned long flags;
+	int irq = *(loff_t *) v;
 
-	if (i == 0) {
+	if (irq == 0) {
+		int cpu;
 		seq_puts(p, "           ");
-		for (i=0; i < 1 /*smp_num_cpus*/; i++)
-			seq_printf(p, "CPU%d       ", i);
+		for (cpu=0; cpu < 1 /*smp_num_cpus*/; cpu++)
+			seq_printf(p, "CPU%d       ", cpu);
 		seq_putc(p, '\n');
 	}
 
-	if (i < NR_IRQS) {
-		int j, count, num;
-		const char *type_name = irq_desc[i].handler->typename;
-		spin_lock_irqsave(&irq_desc[j].lock, flags);
-		action = irq_desc[i].action;
-		if (!action) 
-			goto skip;
-
-		count = 0;
-		num = -1;
-		for (j = 0; j < NR_IRQS; j++)
-			if (irq_desc[j].handler->typename == type_name) {
-				if (i == j)
-					num = count;
-				count++;
-			}
-
-		seq_printf(p, "%3d: ",i);
-		seq_printf(p, "%10u ", kstat_irqs(i));
-		if (count > 1) {
-			int prec = (num >= 100 ? 3 : num >= 10 ? 2 : 1);
-			seq_printf(p, " %*s%d", 14 - prec, type_name, num);
-		} else
-			seq_printf(p, " %14s", type_name);
-		
-		seq_printf(p, "  %s", action->name);
-		for (action=action->next; action; action = action->next)
-			seq_printf(p, ", %s", action->name);
-		seq_putc(p, '\n');
-skip:
-		spin_unlock_irqrestore(&irq_desc[j].lock, flags);
-	} else if (i == NR_IRQS)
-		seq_printf(p, "ERR: %10lu\n", irq_err_count);
-	return 0;
-}
-
-/*
- * This should really return information about whether
- * we should do bottom half handling etc. Right now we
- * end up _always_ checking the bottom half, which is a
- * waste of time and is not what some drivers would
- * prefer.
- */
-int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action)
-{
-	int status = 1; /* Force the "do bottom halves" bit */
-	int ret;
-
-	if (!(action->flags & SA_INTERRUPT))
-		local_irq_enable();
+	if (irq < NR_IRQS) {
+		unsigned long flags;
+		struct irqaction *action;
 
-	do {
-		ret = action->handler(irq, action->dev_id, regs);
-		if (ret == IRQ_HANDLED)
-			status |= action->flags;
-		action = action->next;
-	} while (action);
-	if (status & SA_SAMPLE_RANDOM)
-		add_interrupt_randomness(irq);
-	local_irq_disable();
-
-	return status;
-}
+		spin_lock_irqsave(&irq_desc[irq].lock, flags);
 
-/*
- * Generic enable/disable code: this just calls
- * down into the PIC-specific version for the actual
- * hardware disable after having gotten the irq
- * controller lock. 
- */
- 
-/**
- *	disable_irq_nosync - disable an irq without waiting
- *	@irq: Interrupt to disable
- *
- *	Disable the selected interrupt line. Disables of an interrupt
- *	stack. Unlike disable_irq(), this function does not ensure existing
- *	instances of the IRQ handler have completed before returning.
- *
- *	This function may be called from IRQ context.
- */
- 
-void inline disable_irq_nosync(unsigned int irq)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	unsigned long flags;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	if (!desc->depth++) {
-		desc->status |= IRQ_DISABLED;
-		desc->handler->disable(irq);
-	}
-	spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-/**
- *	disable_irq - disable an irq and wait for completion
- *	@irq: Interrupt to disable
- *
- *	Disable the selected interrupt line. Disables of an interrupt
- *	stack. That is for two disables you need two enables. This
- *	function waits for any pending IRQ handlers for this interrupt
- *	to complete before returning. If you use this function while
- *	holding a resource the IRQ handler may need you will deadlock.
- *
- *	This function may be called - with care - from IRQ context.
- */
- 
-void disable_irq(unsigned int irq)
-{
-	disable_irq_nosync(irq);
-	synchronize_irq(irq);
-}
+		action = irq_desc[irq].action;
+		if (action) {
+			int j;
+			int count = 0;
+			int num = -1;
+			const char *type_name = irq_desc[irq].handler->typename;
+
+			for (j = 0; j < NR_IRQS; j++)
+				if (irq_desc[j].handler->typename == type_name){
+					if (irq == j)
+						num = count;
+					count++;
+				}
+
+			seq_printf(p, "%3d: ",irq);
+			seq_printf(p, "%10u ", kstat_irqs(irq));
+			if (count > 1) {
+				int prec = (num >= 100 ? 3 : num >= 10 ? 2 : 1);
+				seq_printf(p, " %*s%d", 14 - prec,
+					   type_name, num);
+			} else
+				seq_printf(p, " %14s", type_name);
+		
+			seq_printf(p, "  %s", action->name);
+			for (action=action->next; action; action = action->next)
+				seq_printf(p, ", %s", action->name);
+			seq_putc(p, '\n');
+		}
 
-/**
- *	enable_irq - enable interrupt handling on an irq
- *	@irq: Interrupt to enable
- *
- *	Re-enables the processing of interrupts on this IRQ line
- *	providing no disable_irq calls are now in effect.
- *
- *	This function may be called from IRQ context.
- */
- 
-void enable_irq(unsigned int irq)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	unsigned long flags;
+		spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+	} else if (irq == NR_IRQS)
+		seq_printf(p, "ERR: %10lu\n", irq_err_count);
 
-	spin_lock_irqsave(&desc->lock, flags);
-	switch (desc->depth) {
-	case 1: {
-		unsigned int status = desc->status & ~IRQ_DISABLED;
-		desc->status = status;
-		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
-			desc->status = status | IRQ_REPLAY;
-			hw_resend_irq(desc->handler,irq);
-		}
-		desc->handler->enable(irq);
-		/* fall-through */
-	}
-	default:
-		desc->depth--;
-		break;
-	case 0:
-		printk("enable_irq(%u) unbalanced from %p\n", irq,
-		       __builtin_return_address(0));
-	}
-	spin_unlock_irqrestore(&desc->lock, flags);
+	return 0;
 }
 
 /* Handle interrupt IRQ.  REGS are the registers at the time of ther
    interrupt.  */
 unsigned int handle_irq (int irq, struct pt_regs *regs)
 {
-	/* 
-	 * We ack quickly, we don't want the irq controller
-	 * thinking we're snobs just because some other CPU has
-	 * disabled global interrupts (we have already done the
-	 * INT_ACK cycles, it's too late to try to pretend to the
-	 * controller that we aren't taking the interrupt).
-	 *
-	 * 0 return value means that this irq is already being
-	 * handled by some other CPU. (or is disabled)
-	 */
-	int cpu = smp_processor_id();
-	irq_desc_t *desc = irq_desc + irq;
-	struct irqaction * action;
-	unsigned int status;
-
 	irq_enter();
-	kstat_cpu(cpu).irqs[irq]++;
-	spin_lock(&desc->lock);
-	desc->handler->ack(irq);
-	/*
-	   REPLAY is when Linux resends an IRQ that was dropped earlier
-	   WAITING is used by probe to mark irqs that are being tested
-	   */
-	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
-	status |= IRQ_PENDING; /* we _want_ to handle it */
-
-	/*
-	 * If the IRQ is disabled for whatever reason, we cannot
-	 * use the action we have.
-	 */
-	action = NULL;
-	if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
-		action = desc->action;
-		status &= ~IRQ_PENDING; /* we commit to handling */
-		status |= IRQ_INPROGRESS; /* we are handling it */
-	}
-	desc->status = status;
-
-	/*
-	 * If there is no IRQ handler or it was disabled, exit early.
-	   Since we set PENDING, if another processor is handling
-	   a different instance of this same irq, the other processor
-	   will take care of it.
-	 */
-	if (unlikely(!action))
-		goto out;
-
-	/*
-	 * Edge triggered interrupts need to remember
-	 * pending events.
-	 * This applies to any hw interrupts that allow a second
-	 * instance of the same irq to arrive while we are in handle_irq
-	 * or in the handler. But the code here only handles the _second_
-	 * instance of the irq, not the third or fourth. So it is mostly
-	 * useful for irq hardware that does not mask cleanly in an
-	 * SMP environment.
-	 */
-	for (;;) {
-		spin_unlock(&desc->lock);
-		handle_IRQ_event(irq, regs, action);
-		spin_lock(&desc->lock);
-		
-		if (likely(!(desc->status & IRQ_PENDING)))
-			break;
-		desc->status &= ~IRQ_PENDING;
-	}
-	desc->status &= ~IRQ_INPROGRESS;
-
-out:
-	/*
-	 * The ->end() handler has to deal with interrupts which got
-	 * disabled while the handler was running.
-	 */
-	desc->handler->end(irq);
-	spin_unlock(&desc->lock);
-
+	__do_IRQ(irq, regs);
 	irq_exit();
-
 	return 1;
 }
 
-/**
- *	request_irq - allocate an interrupt line
- *	@irq: Interrupt line to allocate
- *	@handler: Function to be called when the IRQ occurs
- *	@irqflags: Interrupt type flags
- *	@devname: An ascii name for the claiming device
- *	@dev_id: A cookie passed back to the handler function
- *
- *	This call allocates interrupt resources and enables the
- *	interrupt line and IRQ handling. From the point this
- *	call is made your handler function may be invoked. Since
- *	your handler function must clear any interrupt the board 
- *	raises, you must take care both to initialise your hardware
- *	and to set up the interrupt handler in the right order.
- *
- *	Dev_id must be globally unique. Normally the address of the
- *	device data structure is used as the cookie. Since the handler
- *	receives this value it makes sense to use it.
- *
- *	If your interrupt is shared you must pass a non NULL dev_id
- *	as this is required when freeing the interrupt.
- *
- *	Flags:
- *
- *	SA_SHIRQ		Interrupt is shared
- *
- *	SA_INTERRUPT		Disable local interrupts while processing
- *
- *	SA_SAMPLE_RANDOM	The interrupt can be used for entropy
- *
- */
- 
-int request_irq(unsigned int irq, 
-		irqreturn_t (*handler)(int, void *, struct pt_regs *),
-		unsigned long irqflags, 
-		const char * devname,
-		void *dev_id)
-{
-	int retval;
-	struct irqaction * action;
-
-#if 1
-	/*
-	 * Sanity-check: shared interrupts should REALLY pass in
-	 * a real dev-ID, otherwise we'll have trouble later trying
-	 * to figure out which interrupt is which (messes up the
-	 * interrupt freeing logic etc).
-	 */
-	if (irqflags & SA_SHIRQ) {
-		if (!dev_id)
-			printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]);
-	}
-#endif
-
-	if (irq >= NR_IRQS)
-		return -EINVAL;
-	if (!handler)
-		return -EINVAL;
-
-	action = (struct irqaction *)
-			kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-	if (!action)
-		return -ENOMEM;
-
-	action->handler = handler;
-	action->flags = irqflags;
-	cpus_clear(action->mask);
-	action->name = devname;
-	action->next = NULL;
-	action->dev_id = dev_id;
-
-	retval = setup_irq(irq, action);
-	if (retval)
-		kfree(action);
-	return retval;
-}
-
-EXPORT_SYMBOL(request_irq);
-
-/**
- *	free_irq - free an interrupt
- *	@irq: Interrupt line to free
- *	@dev_id: Device identity to free
- *
- *	Remove an interrupt handler. The handler is removed and if the
- *	interrupt line is no longer in use by any driver it is disabled.
- *	On a shared IRQ the caller must ensure the interrupt is disabled
- *	on the card it drives before calling this function. The function
- *	does not return until any executing interrupts for this IRQ
- *	have completed.
- *
- *	This function may be called from interrupt context. 
- *
- *	Bugs: Attempting to free an irq in a handler for the same irq hangs
- *	      the machine.
- */
- 
-void free_irq(unsigned int irq, void *dev_id)
-{
-	irq_desc_t *desc;
-	struct irqaction **p;
-	unsigned long flags;
-
-	if (irq >= NR_IRQS)
-		return;
-
-	desc = irq_desc + irq;
-	spin_lock_irqsave(&desc->lock,flags);
-	p = &desc->action;
-	for (;;) {
-		struct irqaction * action = *p;
-		if (action) {
-			struct irqaction **pp = p;
-			p = &action->next;
-			if (action->dev_id != dev_id)
-				continue;
-
-			/* Found it - now remove it from the list of entries */
-			*pp = action->next;
-			if (!desc->action) {
-				desc->status |= IRQ_DISABLED;
-				desc->handler->shutdown(irq);
-			}
-			spin_unlock_irqrestore(&desc->lock,flags);
-
-			synchronize_irq(irq);
-			kfree(action);
-			return;
-		}
-		printk("Trying to free free IRQ%d\n",irq);
-		spin_unlock_irqrestore(&desc->lock,flags);
-		return;
-	}
-}
-
-EXPORT_SYMBOL(free_irq);
-
-/*
- * IRQ autodetection code..
- *
- * This depends on the fact that any interrupt that
- * comes in on to an unassigned handler will get stuck
- * with "IRQ_WAITING" cleared and the interrupt
- * disabled.
- */
-
-static DECLARE_MUTEX(probe_sem);
-
-/**
- *	probe_irq_on	- begin an interrupt autodetect
- *
- *	Commence probing for an interrupt. The interrupts are scanned
- *	and a mask of potential interrupt lines is returned.
- *
- */
- 
-unsigned long probe_irq_on(void)
-{
-	unsigned int i;
-	irq_desc_t *desc;
-	unsigned long val;
-	unsigned long delay;
-
-	down(&probe_sem);
-	/* 
-	 * something may have generated an irq long ago and we want to
-	 * flush such a longstanding irq before considering it as spurious. 
-	 */
-	for (i = NR_IRQS-1; i > 0; i--)  {
-		desc = irq_desc + i;
-
-		spin_lock_irq(&desc->lock);
-		if (!irq_desc[i].action) 
-			irq_desc[i].handler->startup(i);
-		spin_unlock_irq(&desc->lock);
-	}
-
-	/* Wait for longstanding interrupts to trigger. */
-	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
-		/* about 20ms delay */ barrier();
-
-	/*
-	 * enable any unassigned irqs
-	 * (we must startup again here because if a longstanding irq
-	 * happened in the previous stage, it may have masked itself)
-	 */
-	for (i = NR_IRQS-1; i > 0; i--) {
-		desc = irq_desc + i;
-
-		spin_lock_irq(&desc->lock);
-		if (!desc->action) {
-			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
-			if (desc->handler->startup(i))
-				desc->status |= IRQ_PENDING;
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-
-	/*
-	 * Wait for spurious interrupts to trigger
-	 */
-	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
-		/* about 100ms delay */ barrier();
-
-	/*
-	 * Now filter out any obviously spurious interrupts
-	 */
-	val = 0;
-	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc + i;
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			/* It triggered already - consider it spurious. */
-			if (!(status & IRQ_WAITING)) {
-				desc->status = status & ~IRQ_AUTODETECT;
-				desc->handler->shutdown(i);
-			} else
-				if (i < 32)
-					val |= 1 << i;
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-
-	return val;
-}
-
-EXPORT_SYMBOL(probe_irq_on);
-
-/*
- * Return a mask of triggered interrupts (this
- * can handle only legacy ISA interrupts).
- */
- 
-/**
- *	probe_irq_mask - scan a bitmap of interrupt lines
- *	@val:	mask of interrupts to consider
- *
- *	Scan the ISA bus interrupt lines and return a bitmap of
- *	active interrupts. The interrupt probe logic state is then
- *	returned to its previous value.
- *
- *	Note: we need to scan all the irq's even though we will
- *	only return ISA irq numbers - just so that we reset them
- *	all to a known state.
- */
-unsigned int probe_irq_mask(unsigned long val)
-{
-	int i;
-	unsigned int mask;
-
-	mask = 0;
-	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc + i;
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			if (i < 16 && !(status & IRQ_WAITING))
-				mask |= 1 << i;
-
-			desc->status = status & ~IRQ_AUTODETECT;
-			desc->handler->shutdown(i);
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-	up(&probe_sem);
-
-	return mask & val;
-}
-
-/*
- * Return the one interrupt that triggered (this can
- * handle any interrupt source).
- */
-
-/**
- *	probe_irq_off	- end an interrupt autodetect
- *	@val: mask of potential interrupts (unused)
- *
- *	Scans the unused interrupt lines and returns the line which
- *	appears to have triggered the interrupt. If no interrupt was
- *	found then zero is returned. If more than one interrupt is
- *	found then minus the first candidate is returned to indicate
- *	their is doubt.
- *
- *	The interrupt probe logic state is returned to its previous
- *	value.
- *
- *	BUGS: When used in a module (which arguably shouldnt happen)
- *	nothing prevents two IRQ probe callers from overlapping. The
- *	results of this are non-optimal.
- */
- 
-int probe_irq_off(unsigned long val)
-{
-	int i, irq_found, nr_irqs;
-
-	nr_irqs = 0;
-	irq_found = 0;
-	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc + i;
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			if (!(status & IRQ_WAITING)) {
-				if (!nr_irqs)
-					irq_found = i;
-				nr_irqs++;
-			}
-			desc->status = status & ~IRQ_AUTODETECT;
-			desc->handler->shutdown(i);
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-	up(&probe_sem);
-
-	if (nr_irqs > 1)
-		irq_found = -irq_found;
-	return irq_found;
-}
-
-EXPORT_SYMBOL(probe_irq_off);
-
-/* this was setup_x86_irq but it seems pretty generic */
-int setup_irq(unsigned int irq, struct irqaction * new)
-{
-	int shared = 0;
-	unsigned long flags;
-	struct irqaction *old, **p;
-	irq_desc_t *desc = irq_desc + irq;
-
-	/*
-	 * Some drivers like serial.c use request_irq() heavily,
-	 * so we have to be careful not to interfere with a
-	 * running system.
-	 */
-	if (new->flags & SA_SAMPLE_RANDOM) {
-		/*
-		 * This function might sleep, we want to call it first,
-		 * outside of the atomic block.
-		 * Yes, this might clear the entropy pool if the wrong
-		 * driver is attempted to be loaded, without actually
-		 * installing a new handler, but is this really a problem,
-		 * only the sysadmin is able to do this.
-		 */
-		rand_initialize_irq(irq);
-	}
-
-	/*
-	 * The following block of code has to be executed atomically
-	 */
-	spin_lock_irqsave(&desc->lock,flags);
-	p = &desc->action;
-	if ((old = *p) != NULL) {
-		/* Can't share interrupts unless both agree to */
-		if (!(old->flags & new->flags & SA_SHIRQ)) {
-			spin_unlock_irqrestore(&desc->lock,flags);
-			return -EBUSY;
-		}
-
-		/* add new interrupt at end of irq queue */
-		do {
-			p = &old->next;
-			old = *p;
-		} while (old);
-		shared = 1;
-	}
-
-	*p = new;
-
-	if (!shared) {
-		desc->depth = 0;
-		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
-		desc->handler->startup(irq);
-	}
-	spin_unlock_irqrestore(&desc->lock,flags);
-
-	/* register_irq_proc(irq); */
-	return 0;
-}
-
 /* Initialize irq handling for IRQs.
    BASE_IRQ, BASE_IRQ+INTERVAL, ..., BASE_IRQ+NUM*INTERVAL
    to IRQ_TYPE.  An IRQ_TYPE of 0 means to use a generic interrupt type.  */
@@ -736,9 +121,3 @@ init_irq_handlers (int base_irq, int num
 		base_irq += interval;
 	}
 }
-
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
-void init_irq_proc(void)
-{
-}
-#endif /* CONFIG_PROC_FS && CONFIG_SYSCTL */
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 4cce2f6..6ece645 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -226,22 +226,42 @@ config SCHED_SMT
 
 source "kernel/Kconfig.preempt"
 
-config K8_NUMA
-       bool "K8 NUMA support"
-       select NUMA
+config NUMA
+       bool "Non Uniform Memory Access (NUMA) Support"
        depends on SMP
        help
-	  Enable NUMA (Non Unified Memory Architecture) support for
-	  AMD Opteron Multiprocessor systems. The kernel will try to allocate
-	  memory used by a CPU on the local memory controller of the CPU
-	  and add some more NUMA awareness to the kernel.
-	  This code is recommended on all multiprocessor Opteron systems
-	  and normally doesn't hurt on others.
+	 Enable NUMA (Non Uniform Memory Access) support. The kernel 
+	 will try to allocate memory used by a CPU on the local memory 
+	 controller of the CPU and add some more NUMA awareness to the kernel.
+	 This code is recommended on all multiprocessor Opteron systems.
+	 If the system is EM64T, you should say N unless your system is EM64T 
+	 NUMA. 
+
+config K8_NUMA
+       bool "Old style AMD Opteron NUMA detection"
+       depends on NUMA
+       default y
+       help
+	 Enable K8 NUMA node topology detection.  You should say Y here if
+	 you have a multi processor AMD K8 system. This uses an old
+	 method to read the NUMA configurtion directly from the builtin
+	 Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA
+	 instead, which also takes priority if both are compiled in.   
+
+# Dummy CONFIG option to select ACPI_NUMA from drivers/acpi/Kconfig.
+
+config X86_64_ACPI_NUMA
+       bool "ACPI NUMA detection"
+       depends on NUMA
+       select ACPI 
+       select ACPI_NUMA
+       default y
+       help
+	 Enable ACPI SRAT based node topology detection.
 
 config NUMA_EMU
-	bool "NUMA emulation support"
-	select NUMA
-	depends on SMP
+	bool "NUMA emulation"
+	depends on NUMA
 	help
 	  Enable NUMA emulation. A flat machine will be split
 	  into virtual nodes when booted with "numa=fake=N", where N is the
@@ -252,9 +272,6 @@ config ARCH_DISCONTIGMEM_ENABLE
        depends on NUMA
        default y
 
-config NUMA
-       bool
-       default n
 
 config ARCH_DISCONTIGMEM_ENABLE
 	def_bool y
@@ -374,6 +391,14 @@ config X86_MCE_INTEL
 	   Additional support for intel specific MCE features such as
 	   the thermal monitor.
 
+config X86_MCE_AMD
+	bool "AMD MCE features"
+	depends on X86_MCE && X86_LOCAL_APIC
+	default y
+	help
+	   Additional support for AMD specific MCE features such as
+	   the DRAM Error Threshold.
+
 config PHYSICAL_START
 	hex "Physical address where the kernel is loaded" if EMBEDDED
 	default "0x100000"
@@ -502,7 +527,7 @@ config IA32_EMULATION
 	  left.
 
 config IA32_AOUT
-       bool "IA32 a.out support"
+       tristate "IA32 a.out support"
        depends on IA32_EMULATION
        help
          Support old a.out binaries in the 32bit emulation.
diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug
index d584ecc..e2c6e64 100644
--- a/arch/x86_64/Kconfig.debug
+++ b/arch/x86_64/Kconfig.debug
@@ -2,15 +2,6 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
-# !SMP for now because the context switch early causes GPF in segment reloading
-# and the GS base checking does the wrong thing then, causing a hang.
-config CHECKING
-	bool "Additional run-time checks"
-	depends on DEBUG_KERNEL && !SMP
-	help
-	  Enables some internal consistency checks for kernel debugging.
-	  You should normally say N.
-
 config INIT_DEBUG
 	bool "Debug __init statements"
 	depends on DEBUG_KERNEL
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index f8db7e5..5d56542 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-git11
-# Mon Sep 12 16:16:16 2005
+# Linux kernel version: 2.6.14-git7
+# Sat Nov  5 15:55:50 2005
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -35,7 +35,7 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
@@ -93,10 +93,11 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_PREEMPT_BKL=y
+CONFIG_NUMA=y
 CONFIG_K8_NUMA=y
+CONFIG_X86_64_ACPI_NUMA=y
 # CONFIG_NUMA_EMU is not set
 CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
-CONFIG_NUMA=y
 CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -107,9 +108,10 @@ CONFIG_DISCONTIGMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=y
 # CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
-CONFIG_HAVE_DEC_LOCK=y
 CONFIG_NR_CPUS=32
+CONFIG_HOTPLUG_CPU=y
 CONFIG_HPET_TIMER=y
 CONFIG_X86_PM_TIMER=y
 CONFIG_HPET_EMULATE_RTC=y
@@ -117,6 +119,7 @@ CONFIG_GART_IOMMU=y
 CONFIG_SWIOTLB=y
 CONFIG_X86_MCE=y
 CONFIG_X86_MCE_INTEL=y
+CONFIG_X86_MCE_AMD=y
 CONFIG_PHYSICAL_START=0x100000
 # CONFIG_KEXEC is not set
 CONFIG_SECCOMP=y
@@ -136,11 +139,15 @@ CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
 CONFIG_SOFTWARE_SUSPEND=y
 CONFIG_PM_STD_PARTITION=""
+CONFIG_SUSPEND_SMP=y
 
 #
 # ACPI (Advanced Configuration and Power Interface) Support
 #
 CONFIG_ACPI=y
+CONFIG_ACPI_SLEEP=y
+CONFIG_ACPI_SLEEP_PROC_FS=y
+CONFIG_ACPI_SLEEP_PROC_SLEEP=y
 CONFIG_ACPI_AC=y
 CONFIG_ACPI_BATTERY=y
 CONFIG_ACPI_BUTTON=y
@@ -148,6 +155,7 @@ CONFIG_ACPI_BUTTON=y
 CONFIG_ACPI_HOTKEY=m
 CONFIG_ACPI_FAN=y
 CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_HOTPLUG_CPU=y
 CONFIG_ACPI_THERMAL=y
 CONFIG_ACPI_NUMA=y
 # CONFIG_ACPI_ASUS is not set
@@ -158,7 +166,7 @@ CONFIG_ACPI_BLACKLIST_YEAR=2001
 CONFIG_ACPI_EC=y
 CONFIG_ACPI_POWER=y
 CONFIG_ACPI_SYSTEM=y
-# CONFIG_ACPI_CONTAINER is not set
+CONFIG_ACPI_CONTAINER=y
 
 #
 # CPU Frequency scaling
@@ -293,7 +301,6 @@ CONFIG_IPV6=y
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NETFILTER_NETLINK is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
@@ -312,6 +319,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_DEBUG_DRIVER is not set
 
 #
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
 # Memory Technology Devices (MTD)
 #
 # CONFIG_MTD is not set
@@ -354,6 +366,11 @@ CONFIG_IOSCHED_NOOP=y
 # CONFIG_IOSCHED_AS is not set
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -450,6 +467,7 @@ CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_FC_ATTRS is not set
 # CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
 
 #
 # SCSI low-level drivers
@@ -469,20 +487,24 @@ CONFIG_AIC79XX_DEBUG_MASK=0
 # CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
 CONFIG_SCSI_SATA=y
 # CONFIG_SCSI_SATA_AHCI is not set
 # CONFIG_SCSI_SATA_SVW is not set
 CONFIG_SCSI_ATA_PIIX=y
 # CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
+CONFIG_SCSI_SATA_NV=y
+# CONFIG_SCSI_PDC_ADMA is not set
 # CONFIG_SCSI_SATA_QSTOR is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
 # CONFIG_SCSI_SATA_SX4 is not set
 # CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIL24 is not set
 # CONFIG_SCSI_SATA_SIS is not set
 # CONFIG_SCSI_SATA_ULI is not set
 CONFIG_SCSI_SATA_VIA=y
 # CONFIG_SCSI_SATA_VITESSE is not set
+CONFIG_SCSI_SATA_INTEL_COMBINED=y
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
@@ -525,6 +547,7 @@ CONFIG_BLK_DEV_DM=y
 CONFIG_FUSION=y
 CONFIG_FUSION_SPI=y
 # CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
 CONFIG_FUSION_MAX_SGE=128
 # CONFIG_FUSION_CTL is not set
 
@@ -564,6 +587,7 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 CONFIG_NET_VENDOR_3COM=y
 CONFIG_VORTEX=y
 # CONFIG_TYPHOON is not set
@@ -740,7 +764,43 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Watchdog Cards
 #
-# CONFIG_WATCHDOG is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=y
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_ALIM1535_WDT is not set
+# CONFIG_ALIM7101_WDT is not set
+# CONFIG_SC520_WDT is not set
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_IBMASR is not set
+# CONFIG_WAFER_WDT is not set
+# CONFIG_I6300ESB_WDT is not set
+# CONFIG_I8XX_TCO is not set
+# CONFIG_SC1200_WDT is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_SBC8360_WDT is not set
+# CONFIG_CPU5_WDT is not set
+# CONFIG_W83627HF_WDT is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_W83977F_WDT is not set
+# CONFIG_MACHZ_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
 CONFIG_HW_RANDOM=y
 # CONFIG_NVRAM is not set
 CONFIG_RTC=y
@@ -767,6 +827,7 @@ CONFIG_MAX_RAW_DEVS=256
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -783,6 +844,7 @@ CONFIG_MAX_RAW_DEVS=256
 #
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_HDAPS is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
@@ -886,12 +948,15 @@ CONFIG_USB_UHCI_HCD=y
 # USB Device Class drivers
 #
 # CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
-# CONFIG_USB_BLUETOOTH_TTY is not set
 # CONFIG_USB_ACM is not set
 CONFIG_USB_PRINTER=y
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# 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
@@ -924,6 +989,7 @@ CONFIG_USB_HIDINPUT=y
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
 
 #
 # USB Imaging devices
@@ -1005,7 +1071,7 @@ CONFIG_USB_MON=y
 #
 # CONFIG_EDD is not set
 # CONFIG_DELL_RBU is not set
-CONFIG_DCDBAS=m
+# CONFIG_DCDBAS is not set
 
 #
 # File systems
@@ -1037,7 +1103,7 @@ CONFIG_INOTIFY=y
 # CONFIG_QUOTA is not set
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
 
 #
@@ -1068,7 +1134,7 @@ CONFIG_TMPFS=y
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+CONFIG_RELAYFS_FS=y
 
 #
 # Miscellaneous filesystems
@@ -1186,7 +1252,9 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
 # CONFIG_FRAME_POINTER is not set
+# CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_INIT_DEBUG=y
 # CONFIG_IOMMU_DEBUG is not set
 CONFIG_KPROBES=y
diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c
index 93c60f4..3bf58af 100644
--- a/arch/x86_64/ia32/ia32_aout.c
+++ b/arch/x86_64/ia32/ia32_aout.c
@@ -36,9 +36,6 @@
 #undef WARN_OLD
 #undef CORE_DUMP /* probably broken */
 
-extern int ia32_setup_arg_pages(struct linux_binprm *bprm,
-				unsigned long stack_top, int exec_stack);
-
 static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
 static int load_aout_library(struct file*);
 
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c
index d9161e3..830feb2 100644
--- a/arch/x86_64/ia32/ia32_binfmt.c
+++ b/arch/x86_64/ia32/ia32_binfmt.c
@@ -335,7 +335,8 @@ static void elf32_init(struct pt_regs *r
 	me->thread.es = __USER_DS;
 }
 
-int setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top, int executable_stack)
+int ia32_setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top,
+			 int executable_stack)
 {
 	unsigned long stack_base;
 	struct vm_area_struct *mpnt;
@@ -389,6 +390,7 @@ int setup_arg_pages(struct linux_binprm 
 	
 	return 0;
 }
+EXPORT_SYMBOL(ia32_setup_arg_pages);
 
 static unsigned long
 elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index 14328ca..fe4cbd1 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -11,6 +11,7 @@ obj-y	:= process.o signal.o entry.o trap
 
 obj-$(CONFIG_X86_MCE)         += mce.o
 obj-$(CONFIG_X86_MCE_INTEL)	+= mce_intel.o
+obj-$(CONFIG_X86_MCE_AMD)	+= mce_amd.o
 obj-$(CONFIG_MTRR)		+= ../../i386/kernel/cpu/mtrr/
 obj-$(CONFIG_ACPI)		+= acpi/
 obj-$(CONFIG_X86_MSR)		+= msr.o
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
index 962ad48..c7f4fdd 100644
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -196,7 +196,7 @@ static __u32 __init search_agp_bridge(u3
 void __init iommu_hole_init(void) 
 { 
 	int fix, num; 
-	u32 aper_size, aper_alloc = 0, aper_order, last_aper_order = 0;
+	u32 aper_size, aper_alloc = 0, aper_order = 0, last_aper_order = 0;
 	u64 aper_base, last_aper_base = 0;
 	int valid_agp = 0;
 
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index b6e7715..18691ce 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -833,6 +833,16 @@ int setup_profiling_timer(unsigned int m
 	return 0;
 }
 
+#ifdef CONFIG_X86_MCE_AMD
+void setup_threshold_lvt(unsigned long lvt_off)
+{
+	unsigned int v = 0;
+	unsigned long reg = (lvt_off << 4) + 0x500;
+	v |= THRESHOLD_APIC_VECTOR;
+	apic_write(reg, v);
+}
+#endif /* CONFIG_X86_MCE_AMD */
+
 #undef APIC_DIVISOR
 
 /*
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index ab3f87a..17579a1 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -23,8 +23,7 @@
 #include <asm/e820.h>
 #include <asm/proto.h>
 #include <asm/bootsetup.h>
-
-extern char _end[];
+#include <asm/sections.h>
 
 /* 
  * PFN of last memory page.
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 7937971..9ff4204 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -612,6 +612,9 @@ retint_kernel:	
 ENTRY(thermal_interrupt)
 	apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt
 
+ENTRY(threshold_interrupt)
+	apicinterrupt THRESHOLD_APIC_VECTOR,mce_threshold_interrupt
+
 #ifdef CONFIG_SMP	
 ENTRY(reschedule_interrupt)
 	apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S
index b92e5f4..1529096 100644
--- a/arch/x86_64/kernel/head.S
+++ b/arch/x86_64/kernel/head.S
@@ -12,6 +12,7 @@
 
 #include <linux/linkage.h>
 #include <linux/threads.h>
+#include <linux/init.h>
 #include <asm/desc.h>
 #include <asm/segment.h>
 #include <asm/page.h>
@@ -70,7 +71,7 @@ startup_32:
 	movl	%eax, %cr4
 
 	/* Setup early boot stage 4 level pagetables */
-	movl	$(init_level4_pgt - __START_KERNEL_map), %eax
+	movl	$(boot_level4_pgt - __START_KERNEL_map), %eax
 	movl	%eax, %cr3
 
 	/* Setup EFER (Extended Feature Enable Register) */
@@ -113,7 +114,7 @@ startup_64:
 	movq	%rax, %cr4
 
 	/* Setup early boot stage 4 level pagetables. */
-	movq	$(init_level4_pgt - __START_KERNEL_map), %rax
+	movq	$(boot_level4_pgt - __START_KERNEL_map), %rax
 	movq	%rax, %cr3
 
 	/* Check if nx is implemented */
@@ -240,20 +241,10 @@ ljumpvector:
 ENTRY(stext)
 ENTRY(_stext)
 
-	/*
-	 * This default setting generates an ident mapping at address 0x100000
-	 * and a mapping for the kernel that precisely maps virtual address
-	 * 0xffffffff80000000 to physical address 0x000000. (always using
-	 * 2Mbyte large pages provided by PAE mode)
-	 */
 .org 0x1000
 ENTRY(init_level4_pgt)
-	.quad	0x0000000000002007 + __PHYSICAL_START	/* -> level3_ident_pgt */
-	.fill	255,8,0
-	.quad	0x000000000000a007 + __PHYSICAL_START
-	.fill	254,8,0
-	/* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
-	.quad	0x0000000000003007 + __PHYSICAL_START	/* -> level3_kernel_pgt */
+	/* This gets initialized in x86_64_start_kernel */
+	.fill	512,8,0
 
 .org 0x2000
 ENTRY(level3_ident_pgt)
@@ -350,6 +341,24 @@ ENTRY(wakeup_level4_pgt)
 	.quad	0x0000000000003007 + __PHYSICAL_START	/* -> level3_kernel_pgt */
 #endif
 
+#ifndef CONFIG_HOTPLUG_CPU
+	__INITDATA
+#endif
+	/*
+	 * This default setting generates an ident mapping at address 0x100000
+	 * and a mapping for the kernel that precisely maps virtual address
+	 * 0xffffffff80000000 to physical address 0x000000. (always using
+	 * 2Mbyte large pages provided by PAE mode)
+	 */
+	.align PAGE_SIZE
+ENTRY(boot_level4_pgt)
+	.quad	0x0000000000002007 + __PHYSICAL_START	/* -> level3_ident_pgt */
+	.fill	255,8,0
+	.quad	0x000000000000a007 + __PHYSICAL_START
+	.fill	254,8,0
+	/* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
+	.quad	0x0000000000003007 + __PHYSICAL_START	/* -> level3_kernel_pgt */
+
 	.data
 
 	.align 16
diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
index cf6ab14..b675c5a 100644
--- a/arch/x86_64/kernel/head64.c
+++ b/arch/x86_64/kernel/head64.c
@@ -19,14 +19,15 @@
 #include <asm/bootsetup.h>
 #include <asm/setup.h>
 #include <asm/desc.h>
+#include <asm/pgtable.h>
+#include <asm/sections.h>
 
 /* Don't add a printk in there. printk relies on the PDA which is not initialized 
    yet. */
 static void __init clear_bss(void)
 {
-	extern char __bss_start[], __bss_end[];
 	memset(__bss_start, 0,
-	       (unsigned long) __bss_end - (unsigned long) __bss_start);
+	       (unsigned long) __bss_stop - (unsigned long) __bss_start);
 }
 
 #define NEW_CL_POINTER		0x228	/* Relative to real mode data */
@@ -75,8 +76,6 @@ static void __init setup_boot_cpu_data(v
 	boot_cpu_data.x86_mask = eax & 0xf;
 }
 
-extern char _end[];
-
 void __init x86_64_start_kernel(char * real_mode_data)
 {
 	char *s;
@@ -86,6 +85,13 @@ void __init x86_64_start_kernel(char * r
 		set_intr_gate(i, early_idt_handler);
 	asm volatile("lidt %0" :: "m" (idt_descr));
 	clear_bss();
+
+	/*
+	 * switch to init_level4_pgt from boot_level4_pgt
+	 */
+	memcpy(init_level4_pgt, boot_level4_pgt, PTRS_PER_PGD*sizeof(pgd_t));
+	asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt)));
+
 	pda_init(0);
 	copy_bootdata(real_mode_data);
 #ifdef CONFIG_SMP
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
index c6c9791..6e5101a 100644
--- a/arch/x86_64/kernel/i8259.c
+++ b/arch/x86_64/kernel/i8259.c
@@ -492,6 +492,7 @@ void invalidate_interrupt5(void);
 void invalidate_interrupt6(void);
 void invalidate_interrupt7(void);
 void thermal_interrupt(void);
+void threshold_interrupt(void);
 void i8254_timer_resume(void);
 
 static void setup_timer_hardware(void)
@@ -515,7 +516,7 @@ void i8254_timer_resume(void)
 }
 
 static struct sysdev_class timer_sysclass = {
-	set_kset_name("timer"),
+	set_kset_name("timer_pit"),
 	.resume		= timer_resume,
 };
 
@@ -580,6 +581,7 @@ void __init init_IRQ(void)
 	set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
 #endif	
 	set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
+	set_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
 
 #ifdef CONFIG_X86_LOCAL_APIC
 	/* self generated IPI for local APIC timer */
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index c8eee20..97154ab 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -57,7 +57,7 @@ int nr_ioapic_registers[MAX_IO_APICS];
  * Rough estimation of how many shared IRQs there are, can
  * be changed anytime.
  */
-#define MAX_PLUS_SHARED_IRQS NR_IRQS
+#define MAX_PLUS_SHARED_IRQS NR_IRQ_VECTORS
 #define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
 
 /*
@@ -85,6 +85,7 @@ int vector_irq[NR_VECTORS] __read_mostly
 	int pin;							\
 	struct irq_pin_list *entry = irq_2_pin + irq;			\
 									\
+	BUG_ON(irq >= NR_IRQS);						\
 	for (;;) {							\
 		unsigned int reg;					\
 		pin = entry->pin;					\
@@ -127,6 +128,8 @@ static void set_ioapic_affinity_irq(unsi
 }
 #endif
 
+static u8 gsi_2_irq[NR_IRQ_VECTORS] = { [0 ... NR_IRQ_VECTORS-1] = 0xFF };
+
 /*
  * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
  * shared ISA-space IRQs, so we have to support them. We are super
@@ -137,6 +140,7 @@ static void add_pin_to_irq(unsigned int 
 	static int first_free_entry = NR_IRQS;
 	struct irq_pin_list *entry = irq_2_pin + irq;
 
+	BUG_ON(irq >= NR_IRQS);
 	while (entry->next)
 		entry = irq_2_pin + entry->next;
 
@@ -144,7 +148,7 @@ static void add_pin_to_irq(unsigned int 
 		entry->next = first_free_entry;
 		entry = irq_2_pin + entry->next;
 		if (++first_free_entry >= PIN_MAP_SIZE)
-			panic("io_apic.c: whoops");
+			panic("io_apic.c: ran out of irq_2_pin entries!");
 	}
 	entry->apic = apic;
 	entry->pin = pin;
@@ -420,6 +424,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, 
 				best_guess = irq;
 		}
 	}
+	BUG_ON(best_guess >= NR_IRQS);
 	return best_guess;
 }
 
@@ -610,6 +615,64 @@ static inline int irq_trigger(int idx)
 	return MPBIOS_trigger(idx);
 }
 
+static int next_irq = 16;
+
+/*
+ * gsi_irq_sharing -- Name overload!  "irq" can be either a legacy IRQ
+ * in the range 0-15, a linux IRQ in the range 0-223, or a GSI number
+ * from ACPI, which can reach 800 in large boxen.
+ *
+ * Compact the sparse GSI space into a sequential IRQ series and reuse
+ * vectors if possible.
+ */
+int gsi_irq_sharing(int gsi)
+{
+	int i, tries, vector;
+
+	BUG_ON(gsi >= NR_IRQ_VECTORS);
+
+	if (platform_legacy_irq(gsi))
+		return gsi;
+
+	if (gsi_2_irq[gsi] != 0xFF)
+		return (int)gsi_2_irq[gsi];
+
+	tries = NR_IRQS;
+  try_again:
+	vector = assign_irq_vector(gsi);
+
+	/*
+	 * Sharing vectors means sharing IRQs, so scan irq_vectors for previous
+	 * use of vector and if found, return that IRQ.  However, we never want
+	 * to share legacy IRQs, which usually have a different trigger mode
+	 * than PCI.
+	 */
+	for (i = 0; i < NR_IRQS; i++)
+		if (IO_APIC_VECTOR(i) == vector)
+			break;
+	if (platform_legacy_irq(i)) {
+		if (--tries >= 0) {
+			IO_APIC_VECTOR(i) = 0;
+			goto try_again;
+		}
+		panic("gsi_irq_sharing: didn't find an IRQ using vector 0x%02X for GSI %d", vector, gsi);
+	}
+	if (i < NR_IRQS) {
+		gsi_2_irq[gsi] = i;
+		printk(KERN_INFO "GSI %d sharing vector 0x%02X and IRQ %d\n",
+				gsi, vector, i);
+		return i;
+	}
+
+	i = next_irq++;
+	BUG_ON(i >= NR_IRQS);
+	gsi_2_irq[gsi] = i;
+	IO_APIC_VECTOR(i) = vector;
+	printk(KERN_INFO "GSI %d assigned vector 0x%02X and IRQ %d\n",
+			gsi, vector, i);
+	return i;
+}
+
 static int pin_2_irq(int idx, int apic, int pin)
 {
 	int irq, i;
@@ -639,6 +702,7 @@ static int pin_2_irq(int idx, int apic, 
 			while (i < apic)
 				irq += nr_ioapic_registers[i++];
 			irq += pin;
+			irq = gsi_irq_sharing(irq);
 			break;
 		}
 		default:
@@ -648,6 +712,7 @@ static int pin_2_irq(int idx, int apic, 
 			break;
 		}
 	}
+	BUG_ON(irq >= NR_IRQS);
 
 	/*
 	 * PCI IRQ command line redirection. Yes, limits are hardcoded.
@@ -663,6 +728,7 @@ static int pin_2_irq(int idx, int apic, 
 			}
 		}
 	}
+	BUG_ON(irq >= NR_IRQS);
 	return irq;
 }
 
@@ -690,8 +756,8 @@ int assign_irq_vector(int irq)
 {
 	static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
 
-	BUG_ON(irq >= NR_IRQ_VECTORS);
-	if (IO_APIC_VECTOR(irq) > 0)
+	BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
+	if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
 		return IO_APIC_VECTOR(irq);
 next:
 	current_vector += 8;
@@ -699,9 +765,8 @@ next:
 		goto next;
 
 	if (current_vector >= FIRST_SYSTEM_VECTOR) {
-		offset++;
-		if (!(offset%8))
-			return -ENOSPC;
+		/* If we run out of vectors on large boxen, must share them. */
+		offset = (offset + 1) % 8;
 		current_vector = FIRST_DEVICE_VECTOR + offset;
 	}
 
@@ -1917,6 +1982,7 @@ int io_apic_set_pci_routing (int ioapic,
 	entry.polarity = active_high_low;
 	entry.mask = 1;					 /* Disabled (masked) */
 
+	irq = gsi_irq_sharing(irq);
 	/*
 	 * IRQs < 16 are already in the irq_2_pin[] map
 	 */
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index 69541db..183dc61 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -37,7 +37,7 @@ static unsigned long bank[NR_BANKS] = { 
 static unsigned long console_logged;
 static int notify_user;
 static int rip_msr;
-static int mce_bootlog;
+static int mce_bootlog = 1;
 
 /*
  * Lockless MCE logging infrastructure.
@@ -347,7 +347,11 @@ static void __cpuinit mce_cpu_quirks(str
 		/* disable GART TBL walk error reporting, which trips off 
 		   incorrectly with the IOMMU & 3ware & Cerberus. */
 		clear_bit(10, &bank[4]);
+		/* Lots of broken BIOS around that don't clear them
+		   by default and leave crap in there. Don't log. */
+		mce_bootlog = 0;
 	}
+
 }			
 
 static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c)
@@ -356,6 +360,9 @@ static void __cpuinit mce_cpu_features(s
 	case X86_VENDOR_INTEL:
 		mce_intel_feature_init(c);
 		break;
+	case X86_VENDOR_AMD:
+		mce_amd_feature_init(c);
+		break;
 	default:
 		break;
 	}
@@ -495,16 +502,16 @@ static int __init mcheck_disable(char *s
 /* mce=off disables machine check. Note you can reenable it later
    using sysfs.
    mce=TOLERANCELEVEL (number, see above)
-   mce=bootlog Log MCEs from before booting. Disabled by default to work
-   around buggy BIOS that leave bogus MCEs.  */
+   mce=bootlog Log MCEs from before booting. Disabled by default on AMD.
+   mce=nobootlog Don't log MCEs from before booting. */
 static int __init mcheck_enable(char *str)
 {
 	if (*str == '=')
 		str++;
 	if (!strcmp(str, "off"))
 		mce_dont_init = 1;
-	else if (!strcmp(str, "bootlog"))
-		mce_bootlog = 1;
+	else if (!strcmp(str, "bootlog") || !strcmp(str,"nobootlog"))
+		mce_bootlog = str[0] == 'b';
 	else if (isdigit(str[0]))
 		get_option(&str, &tolerant);
 	else
diff --git a/arch/x86_64/kernel/mce_amd.c b/arch/x86_64/kernel/mce_amd.c
new file mode 100644
index 0000000..1f76175
--- /dev/null
+++ b/arch/x86_64/kernel/mce_amd.c
@@ -0,0 +1,538 @@
+/*
+ *  (c) 2005 Advanced Micro Devices, Inc.
+ *  Your use of this code is subject to the terms and conditions of the
+ *  GNU general public license version 2. See "COPYING" or
+ *  http://www.gnu.org/licenses/gpl.html
+ *
+ *  Written by Jacob Shin - AMD, Inc.
+ *
+ *  Support : jacob.shin@amd.com
+ *
+ *  MC4_MISC0 DRAM ECC Error Threshold available under AMD K8 Rev F.
+ *  MC4_MISC0 exists per physical processor.
+ *
+ */
+
+#include <linux/cpu.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kobject.h>
+#include <linux/notifier.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/sysdev.h>
+#include <linux/sysfs.h>
+#include <asm/apic.h>
+#include <asm/mce.h>
+#include <asm/msr.h>
+#include <asm/percpu.h>
+
+#define PFX "mce_threshold: "
+#define VERSION "version 1.00.9"
+#define NR_BANKS 5
+#define THRESHOLD_MAX 0xFFF
+#define INT_TYPE_APIC 0x00020000
+#define MASK_VALID_HI 0x80000000
+#define MASK_LVTOFF_HI 0x00F00000
+#define MASK_COUNT_EN_HI 0x00080000
+#define MASK_INT_TYPE_HI 0x00060000
+#define MASK_OVERFLOW_HI 0x00010000
+#define MASK_ERR_COUNT_HI 0x00000FFF
+#define MASK_OVERFLOW 0x0001000000000000L
+
+struct threshold_bank {
+	unsigned int cpu;
+	u8 bank;
+	u8 interrupt_enable;
+	u16 threshold_limit;
+	struct kobject kobj;
+};
+
+static struct threshold_bank threshold_defaults = {
+	.interrupt_enable = 0,
+	.threshold_limit = THRESHOLD_MAX,
+};
+
+#ifdef CONFIG_SMP
+static unsigned char shared_bank[NR_BANKS] = {
+	0, 0, 0, 0, 1
+};
+#endif
+
+static DEFINE_PER_CPU(unsigned char, bank_map);	/* see which banks are on */
+
+/*
+ * CPU Initialization
+ */
+
+/* must be called with correct cpu affinity */
+static void threshold_restart_bank(struct threshold_bank *b,
+				   int reset, u16 old_limit)
+{
+	u32 mci_misc_hi, mci_misc_lo;
+
+	rdmsr(MSR_IA32_MC0_MISC + b->bank * 4, mci_misc_lo, mci_misc_hi);
+
+	if (b->threshold_limit < (mci_misc_hi & THRESHOLD_MAX))
+		reset = 1;	/* limit cannot be lower than err count */
+
+	if (reset) {		/* reset err count and overflow bit */
+		mci_misc_hi =
+		    (mci_misc_hi & ~(MASK_ERR_COUNT_HI | MASK_OVERFLOW_HI)) |
+		    (THRESHOLD_MAX - b->threshold_limit);
+	} else if (old_limit) {	/* change limit w/o reset */
+		int new_count = (mci_misc_hi & THRESHOLD_MAX) +
+		    (old_limit - b->threshold_limit);
+		mci_misc_hi = (mci_misc_hi & ~MASK_ERR_COUNT_HI) |
+		    (new_count & THRESHOLD_MAX);
+	}
+
+	b->interrupt_enable ?
+	    (mci_misc_hi = (mci_misc_hi & ~MASK_INT_TYPE_HI) | INT_TYPE_APIC) :
+	    (mci_misc_hi &= ~MASK_INT_TYPE_HI);
+
+	mci_misc_hi |= MASK_COUNT_EN_HI;
+	wrmsr(MSR_IA32_MC0_MISC + b->bank * 4, mci_misc_lo, mci_misc_hi);
+}
+
+void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c)
+{
+	int bank;
+	u32 mci_misc_lo, mci_misc_hi;
+	unsigned int cpu = smp_processor_id();
+
+	for (bank = 0; bank < NR_BANKS; ++bank) {
+		rdmsr(MSR_IA32_MC0_MISC + bank * 4, mci_misc_lo, mci_misc_hi);
+
+		/* !valid, !counter present, bios locked */
+		if (!(mci_misc_hi & MASK_VALID_HI) ||
+		    !(mci_misc_hi & MASK_VALID_HI >> 1) ||
+		    (mci_misc_hi & MASK_VALID_HI >> 2))
+			continue;
+
+		per_cpu(bank_map, cpu) |= (1 << bank);
+
+#ifdef CONFIG_SMP
+		if (shared_bank[bank] && cpu_core_id[cpu])
+			continue;
+#endif
+
+		setup_threshold_lvt((mci_misc_hi & MASK_LVTOFF_HI) >> 20);
+		threshold_defaults.cpu = cpu;
+		threshold_defaults.bank = bank;
+		threshold_restart_bank(&threshold_defaults, 0, 0);
+	}
+}
+
+/*
+ * APIC Interrupt Handler
+ */
+
+/*
+ * threshold interrupt handler will service THRESHOLD_APIC_VECTOR.
+ * the interrupt goes off when error_count reaches threshold_limit.
+ * the handler will simply log mcelog w/ software defined bank number.
+ */
+asmlinkage void mce_threshold_interrupt(void)
+{
+	int bank;
+	struct mce m;
+
+	ack_APIC_irq();
+	irq_enter();
+
+	memset(&m, 0, sizeof(m));
+	rdtscll(m.tsc);
+	m.cpu = smp_processor_id();
+
+	/* assume first bank caused it */
+	for (bank = 0; bank < NR_BANKS; ++bank) {
+		m.bank = MCE_THRESHOLD_BASE + bank;
+		rdmsrl(MSR_IA32_MC0_MISC + bank * 4, m.misc);
+
+		if (m.misc & MASK_OVERFLOW) {
+			mce_log(&m);
+			goto out;
+		}
+	}
+      out:
+	irq_exit();
+}
+
+/*
+ * Sysfs Interface
+ */
+
+static struct sysdev_class threshold_sysclass = {
+	set_kset_name("threshold"),
+};
+
+static DEFINE_PER_CPU(struct sys_device, device_threshold);
+
+struct threshold_attr {
+        struct attribute attr;
+        ssize_t(*show) (struct threshold_bank *, char *);
+        ssize_t(*store) (struct threshold_bank *, const char *, size_t count);
+};
+
+static DEFINE_PER_CPU(struct threshold_bank *, threshold_banks[NR_BANKS]);
+
+static cpumask_t affinity_set(unsigned int cpu)
+{
+	cpumask_t oldmask = current->cpus_allowed;
+	cpumask_t newmask = CPU_MASK_NONE;
+	cpu_set(cpu, newmask);
+	set_cpus_allowed(current, newmask);
+	return oldmask;
+}
+
+static void affinity_restore(cpumask_t oldmask)
+{
+	set_cpus_allowed(current, oldmask);
+}
+
+#define SHOW_FIELDS(name) \
+        static ssize_t show_ ## name(struct threshold_bank * b, char *buf) \
+        { \
+                return sprintf(buf, "%lx\n", (unsigned long) b->name); \
+        }
+SHOW_FIELDS(interrupt_enable)
+SHOW_FIELDS(threshold_limit)
+
+static ssize_t store_interrupt_enable(struct threshold_bank *b,
+				      const char *buf, size_t count)
+{
+	char *end;
+	cpumask_t oldmask;
+	unsigned long new = simple_strtoul(buf, &end, 0);
+	if (end == buf)
+		return -EINVAL;
+	b->interrupt_enable = !!new;
+
+	oldmask = affinity_set(b->cpu);
+	threshold_restart_bank(b, 0, 0);
+	affinity_restore(oldmask);
+
+	return end - buf;
+}
+
+static ssize_t store_threshold_limit(struct threshold_bank *b,
+				     const char *buf, size_t count)
+{
+	char *end;
+	cpumask_t oldmask;
+	u16 old;
+	unsigned long new = simple_strtoul(buf, &end, 0);
+	if (end == buf)
+		return -EINVAL;
+	if (new > THRESHOLD_MAX)
+		new = THRESHOLD_MAX;
+	if (new < 1)
+		new = 1;
+	old = b->threshold_limit;
+	b->threshold_limit = new;
+
+	oldmask = affinity_set(b->cpu);
+	threshold_restart_bank(b, 0, old);
+	affinity_restore(oldmask);
+
+	return end - buf;
+}
+
+static ssize_t show_error_count(struct threshold_bank *b, char *buf)
+{
+	u32 high, low;
+	cpumask_t oldmask;
+	oldmask = affinity_set(b->cpu);
+	rdmsr(MSR_IA32_MC0_MISC + b->bank * 4, low, high); /* ignore low 32 */
+	affinity_restore(oldmask);
+	return sprintf(buf, "%x\n",
+		       (high & 0xFFF) - (THRESHOLD_MAX - b->threshold_limit));
+}
+
+static ssize_t store_error_count(struct threshold_bank *b,
+				 const char *buf, size_t count)
+{
+	cpumask_t oldmask;
+	oldmask = affinity_set(b->cpu);
+	threshold_restart_bank(b, 1, 0);
+	affinity_restore(oldmask);
+	return 1;
+}
+
+#define THRESHOLD_ATTR(_name,_mode,_show,_store) {            \
+        .attr = {.name = __stringify(_name), .mode = _mode }, \
+        .show = _show,                                        \
+        .store = _store,                                      \
+};
+
+#define ATTR_FIELDS(name) \
+        static struct threshold_attr name = \
+        THRESHOLD_ATTR(name, 0644, show_## name, store_## name)
+
+ATTR_FIELDS(interrupt_enable);
+ATTR_FIELDS(threshold_limit);
+ATTR_FIELDS(error_count);
+
+static struct attribute *default_attrs[] = {
+	&interrupt_enable.attr,
+	&threshold_limit.attr,
+	&error_count.attr,
+	NULL
+};
+
+#define to_bank(k) container_of(k,struct threshold_bank,kobj)
+#define to_attr(a) container_of(a,struct threshold_attr,attr)
+
+static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
+{
+	struct threshold_bank *b = to_bank(kobj);
+	struct threshold_attr *a = to_attr(attr);
+	ssize_t ret;
+	ret = a->show ? a->show(b, buf) : -EIO;
+	return ret;
+}
+
+static ssize_t store(struct kobject *kobj, struct attribute *attr,
+		     const char *buf, size_t count)
+{
+	struct threshold_bank *b = to_bank(kobj);
+	struct threshold_attr *a = to_attr(attr);
+	ssize_t ret;
+	ret = a->store ? a->store(b, buf, count) : -EIO;
+	return ret;
+}
+
+static struct sysfs_ops threshold_ops = {
+	.show = show,
+	.store = store,
+};
+
+static struct kobj_type threshold_ktype = {
+	.sysfs_ops = &threshold_ops,
+	.default_attrs = default_attrs,
+};
+
+/* symlinks sibling shared banks to first core.  first core owns dir/files. */
+static __cpuinit int threshold_create_bank(unsigned int cpu, int bank)
+{
+	int err = 0;
+	struct threshold_bank *b = 0;
+
+#ifdef CONFIG_SMP
+	if (cpu_core_id[cpu] && shared_bank[bank]) {	/* symlink */
+		char name[16];
+		unsigned lcpu = first_cpu(cpu_core_map[cpu]);
+		if (cpu_core_id[lcpu])
+			goto out;	/* first core not up yet */
+
+		b = per_cpu(threshold_banks, lcpu)[bank];
+		if (!b)
+			goto out;
+		sprintf(name, "bank%i", bank);
+		err = sysfs_create_link(&per_cpu(device_threshold, cpu).kobj,
+					&b->kobj, name);
+		if (err)
+			goto out;
+		per_cpu(threshold_banks, cpu)[bank] = b;
+		goto out;
+	}
+#endif
+
+	b = kmalloc(sizeof(struct threshold_bank), GFP_KERNEL);
+	if (!b) {
+		err = -ENOMEM;
+		goto out;
+	}
+	memset(b, 0, sizeof(struct threshold_bank));
+
+	b->cpu = cpu;
+	b->bank = bank;
+	b->interrupt_enable = 0;
+	b->threshold_limit = THRESHOLD_MAX;
+	kobject_set_name(&b->kobj, "bank%i", bank);
+	b->kobj.parent = &per_cpu(device_threshold, cpu).kobj;
+	b->kobj.ktype = &threshold_ktype;
+
+	err = kobject_register(&b->kobj);
+	if (err) {
+		kfree(b);
+		goto out;
+	}
+	per_cpu(threshold_banks, cpu)[bank] = b;
+      out:
+	return err;
+}
+
+/* create dir/files for all valid threshold banks */
+static __cpuinit int threshold_create_device(unsigned int cpu)
+{
+	int bank;
+	int err = 0;
+
+	per_cpu(device_threshold, cpu).id = cpu;
+	per_cpu(device_threshold, cpu).cls = &threshold_sysclass;
+	err = sysdev_register(&per_cpu(device_threshold, cpu));
+	if (err)
+		goto out;
+
+	for (bank = 0; bank < NR_BANKS; ++bank) {
+		if (!(per_cpu(bank_map, cpu) & 1 << bank))
+			continue;
+		err = threshold_create_bank(cpu, bank);
+		if (err)
+			goto out;
+	}
+      out:
+	return err;
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * let's be hotplug friendly.
+ * in case of multiple core processors, the first core always takes ownership
+ *   of shared sysfs dir/files, and rest of the cores will be symlinked to it.
+ */
+
+/* cpu hotplug call removes all symlinks before first core dies */
+static __cpuinit void threshold_remove_bank(unsigned int cpu, int bank)
+{
+	struct threshold_bank *b;
+	char name[16];
+
+	b = per_cpu(threshold_banks, cpu)[bank];
+	if (!b)
+		return;
+	if (shared_bank[bank] && atomic_read(&b->kobj.kref.refcount) > 2) {
+		sprintf(name, "bank%i", bank);
+		sysfs_remove_link(&per_cpu(device_threshold, cpu).kobj, name);
+		per_cpu(threshold_banks, cpu)[bank] = 0;
+	} else {
+		kobject_unregister(&b->kobj);
+		kfree(per_cpu(threshold_banks, cpu)[bank]);
+	}
+}
+
+static __cpuinit void threshold_remove_device(unsigned int cpu)
+{
+	int bank;
+
+	for (bank = 0; bank < NR_BANKS; ++bank) {
+		if (!(per_cpu(bank_map, cpu) & 1 << bank))
+			continue;
+		threshold_remove_bank(cpu, bank);
+	}
+	sysdev_unregister(&per_cpu(device_threshold, cpu));
+}
+
+/* link all existing siblings when first core comes up */
+static __cpuinit int threshold_create_symlinks(unsigned int cpu)
+{
+	int bank, err = 0;
+	unsigned int lcpu = 0;
+
+	if (cpu_core_id[cpu])
+		return 0;
+	for_each_cpu_mask(lcpu, cpu_core_map[cpu]) {
+		if (lcpu == cpu)
+			continue;
+		for (bank = 0; bank < NR_BANKS; ++bank) {
+			if (!(per_cpu(bank_map, cpu) & 1 << bank))
+				continue;
+			if (!shared_bank[bank])
+				continue;
+			err = threshold_create_bank(lcpu, bank);
+		}
+	}
+	return err;
+}
+
+/* remove all symlinks before first core dies. */
+static __cpuinit void threshold_remove_symlinks(unsigned int cpu)
+{
+	int bank;
+	unsigned int lcpu = 0;
+	if (cpu_core_id[cpu])
+		return;
+	for_each_cpu_mask(lcpu, cpu_core_map[cpu]) {
+		if (lcpu == cpu)
+			continue;
+		for (bank = 0; bank < NR_BANKS; ++bank) {
+			if (!(per_cpu(bank_map, cpu) & 1 << bank))
+				continue;
+			if (!shared_bank[bank])
+				continue;
+			threshold_remove_bank(lcpu, bank);
+		}
+	}
+}
+#else /* !CONFIG_HOTPLUG_CPU */
+static __cpuinit void threshold_create_symlinks(unsigned int cpu)
+{
+}
+static __cpuinit void threshold_remove_symlinks(unsigned int cpu)
+{
+}
+static void threshold_remove_device(unsigned int cpu)
+{
+}
+#endif
+
+/* get notified when a cpu comes on/off */
+static __cpuinit int threshold_cpu_callback(struct notifier_block *nfb,
+					    unsigned long action, void *hcpu)
+{
+	/* cpu was unsigned int to begin with */
+	unsigned int cpu = (unsigned long)hcpu;
+
+	if (cpu >= NR_CPUS)
+		goto out;
+
+	switch (action) {
+	case CPU_ONLINE:
+		threshold_create_device(cpu);
+		threshold_create_symlinks(cpu);
+		break;
+	case CPU_DOWN_PREPARE:
+		threshold_remove_symlinks(cpu);
+		break;
+	case CPU_DOWN_FAILED:
+		threshold_create_symlinks(cpu);
+		break;
+	case CPU_DEAD:
+		threshold_remove_device(cpu);
+		break;
+	default:
+		break;
+	}
+      out:
+	return NOTIFY_OK;
+}
+
+static struct notifier_block threshold_cpu_notifier = {
+	.notifier_call = threshold_cpu_callback,
+};
+
+static __init int threshold_init_device(void)
+{
+	int err;
+	int lcpu = 0;
+
+	err = sysdev_class_register(&threshold_sysclass);
+	if (err)
+		goto out;
+
+	/* to hit CPUs online before the notifier is up */
+	for_each_online_cpu(lcpu) {
+		err = threshold_create_device(lcpu);
+		if (err)
+			goto out;
+	}
+	register_cpu_notifier(&threshold_cpu_notifier);
+
+      out:
+	return err;
+}
+
+device_initcall(threshold_init_device);
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index f16d38d..1105250 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -42,7 +42,7 @@ int acpi_found_madt;
  * Various Linux-internal data structures created from the
  * MP-table.
  */
-int apic_version [MAX_APICS];
+unsigned char apic_version [MAX_APICS];
 unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
 int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
 
@@ -65,7 +65,9 @@ unsigned long mp_lapic_addr = 0;
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_id = -1U;
 /* Internal processor count */
-static unsigned int num_processors = 0;
+unsigned int num_processors __initdata = 0;
+
+unsigned disabled_cpus __initdata;
 
 /* Bitmask of physically existing CPUs */
 physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE;
@@ -106,11 +108,14 @@ static int __init mpf_checksum(unsigned 
 
 static void __init MP_processor_info (struct mpc_config_processor *m)
 {
-	int ver, cpu;
+	int cpu;
+	unsigned char ver;
 	static int found_bsp=0;
 
-	if (!(m->mpc_cpuflag & CPU_ENABLED))
+	if (!(m->mpc_cpuflag & CPU_ENABLED)) {
+		disabled_cpus++;
 		return;
+	}
 
 	printk(KERN_INFO "Processor #%d %d:%d APIC version %d\n",
 		m->mpc_apicid,
@@ -129,12 +134,14 @@ static void __init MP_processor_info (st
 	}
 
 	cpu = num_processors++;
-
-	if (m->mpc_apicid > MAX_APICS) {
+	
+#if MAX_APICS < 255	
+	if ((int)m->mpc_apicid > MAX_APICS) {
 		printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
 			m->mpc_apicid, MAX_APICS);
 		return;
 	}
+#endif
 	ver = m->mpc_apicver;
 
 	physid_set(m->mpc_apicid, phys_cpu_present_map);
@@ -218,7 +225,7 @@ static void __init MP_intsrc_info (struc
 			m->mpc_irqtype, m->mpc_irqflag & 3,
 			(m->mpc_irqflag >> 2) & 3, m->mpc_srcbus,
 			m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq);
-	if (++mp_irq_entries == MAX_IRQ_SOURCES)
+	if (++mp_irq_entries >= MAX_IRQ_SOURCES)
 		panic("Max # of irq sources exceeded!!\n");
 }
 
@@ -549,7 +556,7 @@ void __init get_smp_config (void)
 		 * Read the physical hardware table.  Anything here will
 		 * override the defaults.
 		 */
-		if (!smp_read_mpc((void *)(unsigned long)mpf->mpf_physptr)) {
+		if (!smp_read_mpc(phys_to_virt(mpf->mpf_physptr))) {
 			smp_found_config = 0;
 			printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
 			printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 88be97c..2e28e85 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -220,6 +220,12 @@ dma_alloc_coherent(struct device *dev, s
 	   uses the normal dma_mask for alloc_coherent. */
 	dma_mask &= *dev->dma_mask;
 
+	/* Why <=? Even when the mask is smaller than 4GB it is often larger 
+	   than 16MB and in this case we have a chance of finding fitting memory 
+	   in the next higher zone first. If not retry with true GFP_DMA. -AK */
+	if (dma_mask <= 0xffffffff)
+		gfp |= GFP_DMA32;
+
  again:
 	memory = dma_alloc_pages(dev, gfp, get_order(size));
 	if (memory == NULL)
@@ -245,7 +251,7 @@ dma_alloc_coherent(struct device *dev, s
 				}
 
 				if (!(gfp & GFP_DMA)) { 
-					gfp |= GFP_DMA; 
+					gfp = (gfp & ~GFP_DMA32) | GFP_DMA;
 					goto again;
 				}
 				return NULL;
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 59be85d..5afd63e 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -144,7 +144,8 @@ void cpu_idle_wait(void)
 	do {
 		ssleep(1);
 		for_each_online_cpu(cpu) {
-			if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
+			if (cpu_isset(cpu, map) &&
+					!per_cpu(cpu_idle_state, cpu))
 				cpu_clear(cpu, map);
 		}
 		cpus_and(map, map, cpu_online_map);
@@ -275,7 +276,8 @@ void __show_regs(struct pt_regs * regs)
 		system_utsname.version);
 	printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
 	printk_address(regs->rip); 
-	printk("\nRSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->rsp, regs->eflags);
+	printk("\nRSP: %04lx:%016lx  EFLAGS: %08lx\n", regs->ss, regs->rsp,
+		regs->eflags);
 	printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
 	       regs->rax, regs->rbx, regs->rcx);
 	printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
@@ -427,15 +429,14 @@ int copy_thread(int nr, unsigned long cl
 	struct pt_regs * childregs;
 	struct task_struct *me = current;
 
-	childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
-
+	childregs = ((struct pt_regs *)
+			(THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
 	*childregs = *regs;
 
 	childregs->rax = 0;
 	childregs->rsp = rsp;
-	if (rsp == ~0UL) {
+	if (rsp == ~0UL)
 		childregs->rsp = (unsigned long)childregs;
-	}
 
 	p->thread.rsp = (unsigned long) childregs;
 	p->thread.rsp0 = (unsigned long) (childregs+1);
@@ -457,7 +458,8 @@ int copy_thread(int nr, unsigned long cl
 			p->thread.io_bitmap_max = 0;
 			return -ENOMEM;
 		}
-		memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr, IO_BITMAP_BYTES);
+		memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr,
+				IO_BITMAP_BYTES);
 	} 
 
 	/*
@@ -494,7 +496,8 @@ out:
  * - fold all the options into a flag word and test it with a single test.
  * - could test fs/gs bitsliced
  */
-struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct *next_p)
+struct task_struct *
+__switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 {
 	struct thread_struct *prev = &prev_p->thread,
 				 *next = &next_p->thread;
@@ -565,7 +568,8 @@ struct task_struct *__switch_to(struct t
 	prev->userrsp = read_pda(oldrsp); 
 	write_pda(oldrsp, next->userrsp); 
 	write_pda(pcurrent, next_p); 
-	write_pda(kernelstack, (unsigned long)next_p->thread_info + THREAD_SIZE - PDA_STACKOFFSET);
+	write_pda(kernelstack,
+	    (unsigned long)next_p->thread_info + THREAD_SIZE - PDA_STACKOFFSET);
 
 	/*
 	 * Now maybe reload the debug registers
@@ -646,7 +650,9 @@ asmlinkage long sys_fork(struct pt_regs 
 	return do_fork(SIGCHLD, regs->rsp, regs, 0, NULL, NULL);
 }
 
-asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
+asmlinkage long
+sys_clone(unsigned long clone_flags, unsigned long newsp,
+	  void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
 {
 	if (!newsp)
 		newsp = regs->rsp;
@@ -682,7 +688,8 @@ unsigned long get_wchan(struct task_stru
 		return 0;
 	fp = *(u64 *)(p->thread.rsp);
 	do { 
-		if (fp < (unsigned long)stack || fp > (unsigned long)stack+THREAD_SIZE)
+		if (fp < (unsigned long)stack ||
+		    fp > (unsigned long)stack+THREAD_SIZE)
 			return 0; 
 		rip = *(u64 *)(fp+8); 
 		if (!in_sched_functions(rip))
@@ -717,8 +724,8 @@ long do_arch_prctl(struct task_struct *t
 			task->thread.gsindex = 0;
 			task->thread.gs = addr;
 			if (doit) {
-		load_gs_index(0);
-		ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr); 
+				load_gs_index(0);
+				ret = checking_wrmsrl(MSR_KERNEL_GS_BASE, addr);
 			} 
 		}
 		put_cpu();
@@ -735,7 +742,7 @@ long do_arch_prctl(struct task_struct *t
 			set_32bit_tls(task, FS_TLS, addr);
 			if (doit) { 
 				load_TLS(&task->thread, cpu); 
-				asm volatile("movl %0,%%fs" :: "r" (FS_TLS_SEL));
+				asm volatile("movl %0,%%fs" :: "r"(FS_TLS_SEL));
 			}
 			task->thread.fsindex = FS_TLS_SEL;
 			task->thread.fs = 0;
@@ -745,8 +752,8 @@ long do_arch_prctl(struct task_struct *t
 			if (doit) {
 				/* set the selector to 0 to not confuse
 				   __switch_to */
-		asm volatile("movl %0,%%fs" :: "r" (0));
-		ret = checking_wrmsrl(MSR_FS_BASE, addr); 
+				asm volatile("movl %0,%%fs" :: "r" (0));
+				ret = checking_wrmsrl(MSR_FS_BASE, addr);
 			}
 		}
 		put_cpu();
@@ -755,9 +762,9 @@ long do_arch_prctl(struct task_struct *t
 		unsigned long base; 
 		if (task->thread.fsindex == FS_TLS_SEL)
 			base = read_32bit_tls(task, FS_TLS);
-		else if (doit) {
+		else if (doit)
 			rdmsrl(MSR_FS_BASE, base);
-		} else
+		else
 			base = task->thread.fs;
 		ret = put_user(base, (unsigned long __user *)addr); 
 		break; 
@@ -766,9 +773,9 @@ long do_arch_prctl(struct task_struct *t
 		unsigned long base;
 		if (task->thread.gsindex == GS_TLS_SEL)
 			base = read_32bit_tls(task, GS_TLS);
-		else if (doit) {
+		else if (doit)
 			rdmsrl(MSR_KERNEL_GS_BASE, base);
-		} else
+		else
 			base = task->thread.gs;
 		ret = put_user(base, (unsigned long __user *)addr); 
 		break;
diff --git a/arch/x86_64/kernel/reboot.c b/arch/x86_64/kernel/reboot.c
index 47f9568..75235ed 100644
--- a/arch/x86_64/kernel/reboot.c
+++ b/arch/x86_64/kernel/reboot.c
@@ -77,6 +77,7 @@ static inline void kb_wait(void)
 
 void machine_shutdown(void)
 {
+	unsigned long flags;
 	/* Stop the cpus and apics */
 #ifdef CONFIG_SMP
 	int reboot_cpu_id;
@@ -98,7 +99,7 @@ void machine_shutdown(void)
 	smp_send_stop();
 #endif
 
-	local_irq_disable();
+	local_irq_save(flags);
 
 #ifndef CONFIG_SMP
 	disable_local_APIC();
@@ -106,7 +107,7 @@ void machine_shutdown(void)
 
 	disable_IO_APIC();
 
-	local_irq_enable();
+	local_irq_restore(flags);
 }
 
 void machine_emergency_restart(void)
@@ -120,7 +121,7 @@ void machine_emergency_restart(void)
 		/* Could also try the reset bit in the Hammer NB */
 		switch (reboot_type) { 
 		case BOOT_KBD:
-		for (i=0; i<100; i++) {
+		for (i=0; i<10; i++) {
 			kb_wait();
 			udelay(50);
 			outb(0xfe,0x64);         /* pulse reset low */
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index da0bc3e..750e01d 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -60,6 +60,7 @@
 #include <asm/setup.h>
 #include <asm/mach_apic.h>
 #include <asm/numa.h>
+#include <asm/sections.h>
 
 /*
  * Machine setup..
@@ -103,7 +104,6 @@ struct edid_info edid_info;
 struct e820map e820;
 
 extern int root_mountflags;
-extern char _text, _etext, _edata, _end;
 
 char command_line[COMMAND_LINE_SIZE];
 
@@ -412,7 +412,6 @@ contig_initmem_init(unsigned long start_
 {
 	unsigned long bootmap_size, bootmap;
 
-	memory_present(0, start_pfn, end_pfn);
 	bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT;
 	bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size);
 	if (bootmap == -1L)
@@ -571,6 +570,8 @@ void __init setup_arch(char **cmdline_p)
 
 	init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
 
+	zap_low_mappings(0);
+
 #ifdef CONFIG_ACPI
 	/*
 	 * Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
@@ -657,8 +658,6 @@ void __init setup_arch(char **cmdline_p)
 	}
 #endif
 
-	sparse_init();
-
 	paging_init();
 
 	check_ioapic();
@@ -793,7 +792,7 @@ static void __init amd_detect_cmp(struct
 #endif
 
 	bits = 0;
-	while ((1 << bits) < c->x86_num_cores)
+	while ((1 << bits) < c->x86_max_cores)
 		bits++;
 
 	/* Low order bits define the core id (index of core in socket) */
@@ -823,10 +822,10 @@ static void __init amd_detect_cmp(struct
  		if (!node_online(node))
  			node = nearby_node(apicid);
  	}
-  	cpu_to_node[cpu] = node;
+	numa_set_node(cpu, node);
 
   	printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n",
-  			cpu, c->x86_num_cores, node, cpu_core_id[cpu]);
+  			cpu, c->x86_max_cores, node, cpu_core_id[cpu]);
 #endif
 #endif
 }
@@ -875,9 +874,9 @@ static int __init init_amd(struct cpuinf
 	display_cacheinfo(c);
 
 	if (c->extended_cpuid_level >= 0x80000008) {
-		c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
-		if (c->x86_num_cores & (c->x86_num_cores - 1))
-			c->x86_num_cores = 1;
+		c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
+		if (c->x86_max_cores & (c->x86_max_cores - 1))
+			c->x86_max_cores = 1;
 
 		amd_detect_cmp(c);
 	}
@@ -889,54 +888,44 @@ static void __cpuinit detect_ht(struct c
 {
 #ifdef CONFIG_SMP
 	u32 	eax, ebx, ecx, edx;
-	int 	index_msb, tmp;
+	int 	index_msb, core_bits;
 	int 	cpu = smp_processor_id();
-	
+
+	cpuid(1, &eax, &ebx, &ecx, &edx);
+
+	c->apicid = phys_pkg_id(0);
+
 	if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
 		return;
 
-	cpuid(1, &eax, &ebx, &ecx, &edx);
 	smp_num_siblings = (ebx & 0xff0000) >> 16;
-	
+
 	if (smp_num_siblings == 1) {
 		printk(KERN_INFO  "CPU: Hyper-Threading is disabled\n");
-	} else if (smp_num_siblings > 1) {
-		index_msb = 31;
-		/*
-		 * At this point we only support two siblings per
-		 * processor package.
-		 */
+	} else if (smp_num_siblings > 1 ) {
+
 		if (smp_num_siblings > NR_CPUS) {
 			printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
 			smp_num_siblings = 1;
 			return;
 		}
-		tmp = smp_num_siblings;
-		while ((tmp & 0x80000000 ) == 0) {
-			tmp <<=1 ;
-			index_msb--;
-		}
-		if (smp_num_siblings & (smp_num_siblings - 1))
-			index_msb++;
+
+		index_msb = get_count_order(smp_num_siblings);
 		phys_proc_id[cpu] = phys_pkg_id(index_msb);
-		
+
 		printk(KERN_INFO  "CPU: Physical Processor ID: %d\n",
 		       phys_proc_id[cpu]);
 
-		smp_num_siblings = smp_num_siblings / c->x86_num_cores;
+		smp_num_siblings = smp_num_siblings / c->x86_max_cores;
 
-		tmp = smp_num_siblings;
-		index_msb = 31;
-		while ((tmp & 0x80000000) == 0) {
-			tmp <<=1 ;
-			index_msb--;
-		}
-		if (smp_num_siblings & (smp_num_siblings - 1))
-			index_msb++;
+		index_msb = get_count_order(smp_num_siblings) ;
 
-		cpu_core_id[cpu] = phys_pkg_id(index_msb);
+		core_bits = get_count_order(c->x86_max_cores);
 
-		if (c->x86_num_cores > 1)
+		cpu_core_id[cpu] = phys_pkg_id(index_msb) &
+					       ((1 << core_bits) - 1);
+
+		if (c->x86_max_cores > 1)
 			printk(KERN_INFO  "CPU: Processor Core ID: %d\n",
 			       cpu_core_id[cpu]);
 	}
@@ -975,7 +964,7 @@ static void srat_detect_node(void)
 	node = apicid_to_node[hard_smp_processor_id()];
 	if (node == NUMA_NO_NODE)
 		node = 0;
-	cpu_to_node[cpu] = node;
+	numa_set_node(cpu, node);
 
 	if (acpi_numa > 0)
 		printk(KERN_INFO "CPU %d -> Node %d\n", cpu, node);
@@ -993,13 +982,18 @@ static void __cpuinit init_intel(struct 
 		unsigned eax = cpuid_eax(0x80000008);
 		c->x86_virt_bits = (eax >> 8) & 0xff;
 		c->x86_phys_bits = eax & 0xff;
+		/* CPUID workaround for Intel 0F34 CPU */
+		if (c->x86_vendor == X86_VENDOR_INTEL &&
+		    c->x86 == 0xF && c->x86_model == 0x3 &&
+		    c->x86_mask == 0x4)
+			c->x86_phys_bits = 36;
 	}
 
 	if (c->x86 == 15)
 		c->x86_cache_alignment = c->x86_clflush_size * 2;
 	if (c->x86 >= 15)
 		set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
- 	c->x86_num_cores = intel_num_cpu_cores(c);
+ 	c->x86_max_cores = intel_num_cpu_cores(c);
 
 	srat_detect_node();
 }
@@ -1037,7 +1031,7 @@ void __cpuinit early_identify_cpu(struct
 	c->x86_model_id[0] = '\0';  /* Unset */
 	c->x86_clflush_size = 64;
 	c->x86_cache_alignment = c->x86_clflush_size;
-	c->x86_num_cores = 1;
+	c->x86_max_cores = 1;
 	c->extended_cpuid_level = 0;
 	memset(&c->x86_capability, 0, sizeof c->x86_capability);
 
@@ -1060,10 +1054,10 @@ void __cpuinit early_identify_cpu(struct
 		c->x86 = (tfms >> 8) & 0xf;
 		c->x86_model = (tfms >> 4) & 0xf;
 		c->x86_mask = tfms & 0xf;
-		if (c->x86 == 0xf) {
+		if (c->x86 == 0xf)
 			c->x86 += (tfms >> 20) & 0xff;
+		if (c->x86 >= 0x6)
 			c->x86_model += ((tfms >> 16) & 0xF) << 4;
-		} 
 		if (c->x86_capability[0] & (1<<19)) 
 			c->x86_clflush_size = ((misc >> 8) & 0xff) * 8;
 	} else {
@@ -1271,13 +1265,12 @@ static int show_cpuinfo(struct seq_file 
 		seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
 	
 #ifdef CONFIG_SMP
-	if (smp_num_siblings * c->x86_num_cores > 1) {
+	if (smp_num_siblings * c->x86_max_cores > 1) {
 		int cpu = c - cpu_data;
 		seq_printf(m, "physical id\t: %d\n", phys_proc_id[cpu]);
-		seq_printf(m, "siblings\t: %d\n",
-				c->x86_num_cores * smp_num_siblings);
+		seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[cpu]));
 		seq_printf(m, "core id\t\t: %d\n", cpu_core_id[cpu]);
-		seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores);
+		seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
 	}
 #endif	
 
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index 7919089..06dc354 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -141,7 +141,6 @@ void pda_init(int cpu)
 			panic("cannot allocate irqstack for cpu %d", cpu); 
 	}
 
-	asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt)));
 
 	pda->irqstackptr += IRQSTACKSIZE-64;
 } 
@@ -197,6 +196,7 @@ void __cpuinit cpu_init (void)
 	/* CPU 0 is initialised in head64.c */
 	if (cpu != 0) {
 		pda_init(cpu);
+		zap_low_mappings(cpu);
 	} else 
 		estacks = boot_exception_stacks; 
 
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
index d642fbf..5876df1 100644
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -110,6 +110,15 @@ restore_sigcontext(struct pt_regs *regs,
 	COPY(r14);
 	COPY(r15);
 
+	/* Kernel saves and restores only the CS segment register on signals,
+	 * which is the bare minimum needed to allow mixed 32/64-bit code.
+	 * App's signal handler can save/restore other segments if needed. */
+	{
+		unsigned cs;
+		err |= __get_user(cs, &sc->cs);
+		regs->cs = cs | 3;	/* Force into user mode */
+	}
+
 	{
 		unsigned int tmpflags;
 		err |= __get_user(tmpflags, &sc->eflags);
@@ -187,6 +196,7 @@ setup_sigcontext(struct sigcontext __use
 {
 	int err = 0;
 
+	err |= __put_user(regs->cs, &sc->cs);
 	err |= __put_user(0, &sc->gs);
 	err |= __put_user(0, &sc->fs);
 
@@ -318,7 +328,14 @@ static int setup_rt_frame(int sig, struc
 
 	regs->rsp = (unsigned long)frame;
 
+	/* Set up the CS register to run signal handlers in 64-bit mode,
+	   even if the handler happens to be interrupting 32-bit code. */
+	regs->cs = __USER_CS;
+
+	/* This, by contrast, has nothing to do with segment registers -
+	   see include/asm-x86_64/uaccess.h for details. */
 	set_fs(USER_DS);
+
 	regs->eflags &= ~TF_MASK;
 	if (test_thread_flag(TIF_SINGLESTEP))
 		ptrace_notify(SIGTRAP);
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
index 9db9dda..cfc3d9d 100644
--- a/arch/x86_64/kernel/smp.c
+++ b/arch/x86_64/kernel/smp.c
@@ -28,8 +28,6 @@
 #include <asm/proto.h>
 #include <asm/apicdef.h>
 
-#define __cpuinit __init
-
 /*
  *	Smarter SMP flushing macros. 
  *		c/o Linus Torvalds.
@@ -452,13 +450,14 @@ int smp_call_function (void (*func) (voi
 
 void smp_stop_cpu(void)
 {
+	unsigned long flags;
 	/*
 	 * Remove this CPU:
 	 */
 	cpu_clear(smp_processor_id(), cpu_online_map);
-	local_irq_disable();
+	local_irq_save(flags);
 	disable_local_APIC();
-	local_irq_enable(); 
+	local_irq_restore(flags);
 }
 
 static void smp_really_stop_cpu(void *dummy)
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index c4e59bb..683c33f 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -64,6 +64,7 @@
 int smp_num_siblings = 1;
 /* Package ID of each logical CPU */
 u8 phys_proc_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
+/* core ID of each logical CPU */
 u8 cpu_core_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
 
 /* Bitmask of currently online CPUs */
@@ -87,7 +88,10 @@ struct cpuinfo_x86 cpu_data[NR_CPUS] __c
 /* Set when the idlers are all forked */
 int smp_threads_ready;
 
+/* representing HT siblings of each logical CPU */
 cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
+
+/* representing HT and core siblings of each logical CPU */
 cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
 EXPORT_SYMBOL(cpu_core_map);
 
@@ -434,30 +438,59 @@ void __cpuinit smp_callin(void)
 	cpu_set(cpuid, cpu_callin_map);
 }
 
+/* representing cpus for which sibling maps can be computed */
+static cpumask_t cpu_sibling_setup_map;
+
 static inline void set_cpu_sibling_map(int cpu)
 {
 	int i;
+	struct cpuinfo_x86 *c = cpu_data;
+
+	cpu_set(cpu, cpu_sibling_setup_map);
 
 	if (smp_num_siblings > 1) {
-		for_each_cpu(i) {
-			if (cpu_core_id[cpu] == cpu_core_id[i]) {
+		for_each_cpu_mask(i, cpu_sibling_setup_map) {
+			if (phys_proc_id[cpu] == phys_proc_id[i] &&
+			    cpu_core_id[cpu] == cpu_core_id[i]) {
 				cpu_set(i, cpu_sibling_map[cpu]);
 				cpu_set(cpu, cpu_sibling_map[i]);
+				cpu_set(i, cpu_core_map[cpu]);
+				cpu_set(cpu, cpu_core_map[i]);
 			}
 		}
 	} else {
 		cpu_set(cpu, cpu_sibling_map[cpu]);
 	}
 
-	if (current_cpu_data.x86_num_cores > 1) {
-		for_each_cpu(i) {
-			if (phys_proc_id[cpu] == phys_proc_id[i]) {
-				cpu_set(i, cpu_core_map[cpu]);
-				cpu_set(cpu, cpu_core_map[i]);
-			}
-		}
-	} else {
+	if (current_cpu_data.x86_max_cores == 1) {
 		cpu_core_map[cpu] = cpu_sibling_map[cpu];
+		c[cpu].booted_cores = 1;
+		return;
+	}
+
+	for_each_cpu_mask(i, cpu_sibling_setup_map) {
+		if (phys_proc_id[cpu] == phys_proc_id[i]) {
+			cpu_set(i, cpu_core_map[cpu]);
+			cpu_set(cpu, cpu_core_map[i]);
+			/*
+			 *  Does this new cpu bringup a new core?
+			 */
+			if (cpus_weight(cpu_sibling_map[cpu]) == 1) {
+				/*
+				 * for each core in package, increment
+				 * the booted_cores for this new cpu
+				 */
+				if (first_cpu(cpu_sibling_map[i]) == i)
+					c[cpu].booted_cores++;
+				/*
+				 * increment the core count for all
+				 * the other cpus in this package
+				 */
+				if (i != cpu)
+					c[i].booted_cores++;
+			} else if (i != cpu && !c[cpu].booted_cores)
+				c[cpu].booted_cores = c[i].booted_cores;
+		}
 	}
 }
 
@@ -879,6 +912,9 @@ static __init void disable_smp(void)
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
+
+int additional_cpus __initdata = -1;
+
 /*
  * cpu_possible_map should be static, it cannot change as cpu's
  * are onlined, or offlined. The reason is per-cpu data-structures
@@ -887,14 +923,38 @@ static __init void disable_smp(void)
  * cpu_present_map on the other hand can change dynamically.
  * In case when cpu_hotplug is not compiled, then we resort to current
  * behaviour, which is cpu_possible == cpu_present.
- * If cpu-hotplug is supported, then we need to preallocate for all
- * those NR_CPUS, hence cpu_possible_map represents entire NR_CPUS range.
  * - Ashok Raj
+ *
+ * Three ways to find out the number of additional hotplug CPUs:
+ * - If the BIOS specified disabled CPUs in ACPI/mptables use that.
+ * - otherwise use half of the available CPUs or 2, whatever is more.
+ * - The user can overwrite it with additional_cpus=NUM
+ * We do this because additional CPUs waste a lot of memory.
+ * -AK
  */
 __init void prefill_possible_map(void)
 {
 	int i;
-	for (i = 0; i < NR_CPUS; i++)
+	int possible;
+
+ 	if (additional_cpus == -1) {
+ 		if (disabled_cpus > 0) {
+ 			additional_cpus = disabled_cpus;
+ 		} else {
+ 			additional_cpus = num_processors / 2;
+ 			if (additional_cpus == 0)
+ 				additional_cpus = 2;
+ 		}
+ 	}
+	possible = num_processors + additional_cpus;
+	if (possible > NR_CPUS) 
+		possible = NR_CPUS;
+
+	printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n",
+		possible,
+	        max_t(int, possible - num_processors, 0));
+
+	for (i = 0; i < possible; i++)
 		cpu_set(i, cpu_possible_map);
 }
 #endif
@@ -965,6 +1025,7 @@ void __init smp_prepare_cpus(unsigned in
 	nmi_watchdog_default();
 	current_cpu_data = boot_cpu_data;
 	current_thread_info()->cpu = 0;  /* needed? */
+	set_cpu_sibling_map(0);
 
 	if (smp_sanity_check(max_cpus) < 0) {
 		printk(KERN_INFO "SMP disabled\n");
@@ -1008,8 +1069,6 @@ void __init smp_prepare_boot_cpu(void)
 	int me = smp_processor_id();
 	cpu_set(me, cpu_online_map);
 	cpu_set(me, cpu_callout_map);
-	cpu_set(0, cpu_sibling_map[0]);
-	cpu_set(0, cpu_core_map[0]);
 	per_cpu(cpu_state, me) = CPU_ONLINE;
 }
 
@@ -1062,9 +1121,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
  */
 void __init smp_cpus_done(unsigned int max_cpus)
 {
-#ifndef CONFIG_HOTPLUG_CPU
-	zap_low_mappings();
-#endif
 	smp_cleanup_boot();
 
 #ifdef CONFIG_X86_IO_APIC
@@ -1081,15 +1137,24 @@ void __init smp_cpus_done(unsigned int m
 static void remove_siblinginfo(int cpu)
 {
 	int sibling;
+	struct cpuinfo_x86 *c = cpu_data;
 
+	for_each_cpu_mask(sibling, cpu_core_map[cpu]) {
+		cpu_clear(cpu, cpu_core_map[sibling]);
+		/*
+		 * last thread sibling in this cpu core going down
+		 */
+		if (cpus_weight(cpu_sibling_map[cpu]) == 1)
+			c[sibling].booted_cores--;
+	}
+			
 	for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
 		cpu_clear(cpu, cpu_sibling_map[sibling]);
-	for_each_cpu_mask(sibling, cpu_core_map[cpu])
-		cpu_clear(cpu, cpu_core_map[sibling]);
 	cpus_clear(cpu_sibling_map[cpu]);
 	cpus_clear(cpu_core_map[cpu]);
 	phys_proc_id[cpu] = BAD_APICID;
 	cpu_core_id[cpu] = BAD_APICID;
+	cpu_clear(cpu, cpu_sibling_setup_map);
 }
 
 void remove_cpu_from_maps(void)
@@ -1153,6 +1218,12 @@ void __cpu_die(unsigned int cpu)
  	printk(KERN_ERR "CPU %u didn't die...\n", cpu);
 }
 
+static __init int setup_additional_cpus(char *s)
+{
+	return get_option(&s, &additional_cpus);
+}
+__setup("additional_cpus=", setup_additional_cpus);
+
 #else /* ... !CONFIG_HOTPLUG_CPU */
 
 int __cpu_disable(void)
diff --git a/arch/x86_64/kernel/sys_x86_64.c b/arch/x86_64/kernel/sys_x86_64.c
index cc7821c..6449ea8 100644
--- a/arch/x86_64/kernel/sys_x86_64.c
+++ b/arch/x86_64/kernel/sys_x86_64.c
@@ -154,17 +154,3 @@ asmlinkage long sys_uname(struct new_uts
 		err |= copy_to_user(&name->machine, "i686", 5); 		
 	return err ? -EFAULT : 0;
 }
-
-asmlinkage long sys_time64(long __user * tloc)
-{
-	struct timeval now; 
-	int i; 
-
-	do_gettimeofday(&now);
-	i = now.tv_sec;
-	if (tloc) {
-		if (put_user(i,tloc))
-			i = -EFAULT;
-	}
-	return i;
-}
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index b5e09e6..bf337f4 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -428,19 +428,6 @@ static void __kprobes do_trap(int trapnr
 {
 	conditional_sti(regs);
 
-#ifdef CONFIG_CHECKING
-       { 
-               unsigned long gs; 
-               struct x8664_pda *pda = cpu_pda + safe_smp_processor_id(); 
-               rdmsrl(MSR_GS_BASE, gs); 
-               if (gs != (unsigned long)pda) { 
-                       wrmsrl(MSR_GS_BASE, pda); 
-                       printk("%s: wrong gs %lx expected %p rip %lx\n", str, gs, pda,
-			      regs->rip);
-               }
-       }
-#endif
-
 	if (user_mode(regs)) {
 		struct task_struct *tsk = current;
 
@@ -513,20 +500,6 @@ asmlinkage void __kprobes do_general_pro
 {
 	conditional_sti(regs);
 
-#ifdef CONFIG_CHECKING
-       { 
-               unsigned long gs; 
-               struct x8664_pda *pda = cpu_pda + safe_smp_processor_id(); 
-               rdmsrl(MSR_GS_BASE, gs); 
-               if (gs != (unsigned long)pda) { 
-                       wrmsrl(MSR_GS_BASE, pda); 
-		       oops_in_progress++;
-                       printk("general protection handler: wrong gs %lx expected %p\n", gs, pda);
-		       oops_in_progress--;
-               }
-       }
-#endif
-
 	if (user_mode(regs)) {
 		struct task_struct *tsk = current;
 
@@ -665,19 +638,6 @@ asmlinkage void __kprobes do_debug(struc
 	struct task_struct *tsk = current;
 	siginfo_t info;
 
-#ifdef CONFIG_CHECKING
-       { 
-	       /* RED-PEN interaction with debugger - could destroy gs */
-               unsigned long gs; 
-               struct x8664_pda *pda = cpu_pda + safe_smp_processor_id(); 
-               rdmsrl(MSR_GS_BASE, gs); 
-               if (gs != (unsigned long)pda) { 
-                       wrmsrl(MSR_GS_BASE, pda); 
-                       printk("debug handler: wrong gs %lx expected %p\n", gs, pda);
-               }
-       }
-#endif
-
 	get_debugreg(condition, 6);
 
 	if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
@@ -888,6 +848,10 @@ asmlinkage void __attribute__((weak)) sm
 {
 }
 
+asmlinkage void __attribute__((weak)) mce_threshold_interrupt(void)
+{
+}
+
 /*
  *  'math_state_restore()' saves the current math information in the
  * old math state array, and gets the new ones from the current task
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index 6dd642c..58b1921 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -50,7 +50,7 @@ SECTIONS
 	*(.bss.page_aligned)	
 	*(.bss)
 	}
-  __bss_end = .;
+  __bss_stop = .;
 
   . = ALIGN(PAGE_SIZE);
   . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
index fd99ddd..4a54221 100644
--- a/arch/x86_64/kernel/x8664_ksyms.c
+++ b/arch/x86_64/kernel/x8664_ksyms.c
@@ -203,3 +203,6 @@ EXPORT_SYMBOL(flush_tlb_page);
 #endif
 
 EXPORT_SYMBOL(cpu_khz);
+
+EXPORT_SYMBOL(load_gs_index);
+
diff --git a/arch/x86_64/lib/clear_page.S b/arch/x86_64/lib/clear_page.S
index 30a9da4..43d9fa1 100644
--- a/arch/x86_64/lib/clear_page.S
+++ b/arch/x86_64/lib/clear_page.S
@@ -5,46 +5,8 @@
 	.globl clear_page
 	.p2align 4
 clear_page:
-	xorl   %eax,%eax
-	movl   $4096/64,%ecx
-	.p2align 4
-.Lloop:
-	decl	%ecx
-#define PUT(x) movq %rax,x*8(%rdi) 
-	movq %rax,(%rdi)
-	PUT(1)
-	PUT(2)
-	PUT(3)
-	PUT(4)
-	PUT(5)
-	PUT(6)
-	PUT(7)
-	leaq	64(%rdi),%rdi
-	jnz	.Lloop
-	nop
-	ret
-clear_page_end:	
-	
-	/* C stepping K8 run faster using the string instructions.
-	   It is also a lot simpler. Use this when possible */
-	
-#include <asm/cpufeature.h>
-	    	
-	.section .altinstructions,"a"
-	.align 8
-	.quad  clear_page
-	.quad  clear_page_c
-	.byte  X86_FEATURE_K8_C
-	.byte  clear_page_end-clear_page	
-	.byte  clear_page_c_end-clear_page_c
-	.previous
-
-	.section .altinstr_replacement,"ax"
-clear_page_c:
 	movl $4096/8,%ecx
 	xorl %eax,%eax
 	rep 
 	stosq
 	ret
-clear_page_c_end:
-	.previous
diff --git a/arch/x86_64/lib/copy_page.S b/arch/x86_64/lib/copy_page.S
index dd3aa47..621a197 100644
--- a/arch/x86_64/lib/copy_page.S
+++ b/arch/x86_64/lib/copy_page.S
@@ -8,94 +8,7 @@
 	.globl copy_page
 	.p2align 4
 copy_page:
-	subq	$3*8,%rsp
-	movq	%rbx,(%rsp)
-	movq	%r12,1*8(%rsp)
-	movq	%r13,2*8(%rsp)
-			
-	movl	$(4096/64)-5,%ecx
-	.p2align 4
-.Loop64:	
-  	dec     %rcx
-
-	movq        (%rsi), %rax
-	movq      8 (%rsi), %rbx
-	movq     16 (%rsi), %rdx
-	movq     24 (%rsi), %r8
-	movq     32 (%rsi), %r9
-	movq     40 (%rsi), %r10
-	movq     48 (%rsi), %r11
-	movq     56 (%rsi), %r12
-
-	prefetcht0 5*64(%rsi)
-
-	movq     %rax,    (%rdi)
-	movq     %rbx,  8 (%rdi)
-	movq     %rdx, 16 (%rdi)
-	movq     %r8,  24 (%rdi)
-	movq     %r9,  32 (%rdi)
-	movq     %r10, 40 (%rdi)
-	movq     %r11, 48 (%rdi)
-	movq     %r12, 56 (%rdi)
-
-	leaq    64 (%rsi), %rsi
-	leaq    64 (%rdi), %rdi
-
-	jnz     .Loop64
-
-	movl	$5,%ecx
-	.p2align 4
-.Loop2:	
-	decl   %ecx
-
-	movq        (%rsi), %rax
-	movq      8 (%rsi), %rbx
-	movq     16 (%rsi), %rdx
-	movq     24 (%rsi), %r8
-	movq     32 (%rsi), %r9
-	movq     40 (%rsi), %r10
-	movq     48 (%rsi), %r11
-	movq     56 (%rsi), %r12
-
-	movq     %rax,    (%rdi)
-	movq     %rbx,  8 (%rdi)
-	movq     %rdx, 16 (%rdi)
-	movq     %r8,  24 (%rdi)
-	movq     %r9,  32 (%rdi)
-	movq     %r10, 40 (%rdi)
-	movq     %r11, 48 (%rdi)
-	movq     %r12, 56 (%rdi)
-	
-	leaq	64(%rdi),%rdi			
-	leaq	64(%rsi),%rsi			
-	
-	jnz	.Loop2		
-	
-	movq	(%rsp),%rbx
-	movq	1*8(%rsp),%r12
-	movq	2*8(%rsp),%r13
-	addq	$3*8,%rsp
-	ret
-	
-	/* C stepping K8 run faster using the string copy instructions.
-	   It is also a lot simpler. Use this when possible */
-
-#include <asm/cpufeature.h>		
-		
-	.section .altinstructions,"a"
-	.align 8
-	.quad  copy_page
-	.quad  copy_page_c
-	.byte  X86_FEATURE_K8_C
-	.byte  copy_page_c_end-copy_page_c
-	.byte  copy_page_c_end-copy_page_c
-	.previous
-
-	.section .altinstr_replacement,"ax"
-copy_page_c:
 	movl $4096/8,%ecx
 	rep 
 	movsq 
 	ret
-copy_page_c_end:
-	.previous
diff --git a/arch/x86_64/lib/memcpy.S b/arch/x86_64/lib/memcpy.S
index c6c4649..92dd805 100644
--- a/arch/x86_64/lib/memcpy.S
+++ b/arch/x86_64/lib/memcpy.S
@@ -11,6 +11,8 @@
  * 
  * Output:
  * rax original destination
+ * 
+ * TODO: check best memcpy for PSC
  */	
 
  	.globl __memcpy
@@ -18,95 +20,6 @@
 	.p2align 4
 __memcpy:
 memcpy:		
-	pushq %rbx
-	movq %rdi,%rax
-
-	movl %edx,%ecx
-	shrl $6,%ecx
-	jz .Lhandle_tail
-	
-	.p2align 4
-.Lloop_64:
-	decl %ecx
-	
-	movq (%rsi),%r11
-	movq 8(%rsi),%r8
-
-	movq %r11,(%rdi)
-	movq %r8,1*8(%rdi)
-
-	movq 2*8(%rsi),%r9
-	movq 3*8(%rsi),%r10
-
-	movq %r9,2*8(%rdi)
-	movq %r10,3*8(%rdi)
-		
-	movq 4*8(%rsi),%r11
-	movq 5*8(%rsi),%r8
-
-	movq %r11,4*8(%rdi)
-	movq %r8,5*8(%rdi)
-
-	movq 6*8(%rsi),%r9
-	movq 7*8(%rsi),%r10
-
-	movq %r9,6*8(%rdi)
-	movq %r10,7*8(%rdi)
-
-	leaq 64(%rsi),%rsi
-	leaq 64(%rdi),%rdi
-	jnz  .Lloop_64
-
-.Lhandle_tail:
-	movl %edx,%ecx
-	andl $63,%ecx
-	shrl $3,%ecx
-	jz   .Lhandle_7
-	.p2align 4
-.Lloop_8: 
-	decl %ecx
-	movq (%rsi),%r8
-	movq %r8,(%rdi) 
-	leaq 8(%rdi),%rdi
-	leaq 8(%rsi),%rsi
-	jnz  .Lloop_8
-
-.Lhandle_7:
-	movl %edx,%ecx
-	andl $7,%ecx
-	jz .Lende
-	.p2align 4
-.Lloop_1:
-	movb (%rsi),%r8b
-	movb %r8b,(%rdi) 
-	incq %rdi
-	incq %rsi
-	decl %ecx
-	jnz .Lloop_1
-	
-.Lende: 	
-	popq %rbx
-	ret
-.Lfinal:
-	
-	/* C stepping K8 run faster using the string copy instructions.
-	   It is also a lot simpler. Use this when possible */
-	
-	.section .altinstructions,"a"
-	.align 8
-	.quad  memcpy
-	.quad  memcpy_c
-	.byte  X86_FEATURE_K8_C
-	.byte  .Lfinal-memcpy
-	.byte  memcpy_c_end-memcpy_c	
-	.previous
-
-	.section .altinstr_replacement,"ax"
- /* rdi	destination
-  * rsi source
-  * rdx count
-  */			
-memcpy_c:
 	movq %rdi,%rax
 	movl %edx,%ecx
 	shrl $3,%ecx
@@ -117,5 +30,3 @@ memcpy_c:
 	rep
 	movsb
 	ret
-memcpy_c_end:
-	.previous
diff --git a/arch/x86_64/lib/memset.S b/arch/x86_64/lib/memset.S
index 4b4c406..2aa48f2 100644
--- a/arch/x86_64/lib/memset.S
+++ b/arch/x86_64/lib/memset.S
@@ -13,98 +13,6 @@
 	.p2align 4
 memset:	
 __memset:
-	movq %rdi,%r10
-	movq %rdx,%r11
-
-	/* expand byte value  */
-	movzbl %sil,%ecx
-	movabs $0x0101010101010101,%rax
-	mul    %rcx		/* with rax, clobbers rdx */
-
-	/* align dst */
-	movl  %edi,%r9d		
-	andl  $7,%r9d	
-	jnz  .Lbad_alignment
-.Lafter_bad_alignment:
-	
-	movl %r11d,%ecx
-	shrl $6,%ecx
-	jz	 .Lhandle_tail
-
-	.p2align 4
-.Lloop_64:	
-	decl   %ecx
-	movq  %rax,(%rdi) 
-	movq  %rax,8(%rdi) 
-	movq  %rax,16(%rdi) 
-	movq  %rax,24(%rdi) 
-	movq  %rax,32(%rdi) 
-	movq  %rax,40(%rdi) 
-	movq  %rax,48(%rdi) 
-	movq  %rax,56(%rdi) 
-	leaq  64(%rdi),%rdi
-	jnz    .Lloop_64
-
-	/* Handle tail in loops. The loops should be faster than hard
-	   to predict jump tables. */ 
-	.p2align 4	   
-.Lhandle_tail:
-	movl	%r11d,%ecx
-	andl    $63&(~7),%ecx
-	jz 		.Lhandle_7
-	shrl	$3,%ecx
-	.p2align 4
-.Lloop_8:
-	decl   %ecx
-	movq  %rax,(%rdi)
-	leaq  8(%rdi),%rdi
-	jnz    .Lloop_8
-
-.Lhandle_7:
-	movl	%r11d,%ecx
-	andl	$7,%ecx
-	jz      .Lende
-	.p2align 4
-.Lloop_1:
-	decl    %ecx
-	movb 	%al,(%rdi)
-	leaq	1(%rdi),%rdi
-	jnz     .Lloop_1
-	
-.Lende:	
-	movq	%r10,%rax
-	ret
-
-.Lbad_alignment:
-	cmpq $7,%r11
-	jbe	.Lhandle_7
-	movq %rax,(%rdi)	/* unaligned store */
-	movq $8,%r8			
-	subq %r9,%r8 
-	addq %r8,%rdi
-	subq %r8,%r11
-	jmp .Lafter_bad_alignment
-
-	/* C stepping K8 run faster using the string instructions.
-	   It is also a lot simpler. Use this when possible */
-
-#include <asm/cpufeature.h>	
-		
-	.section .altinstructions,"a"
-	.align 8
-	.quad  memset
-	.quad  memset_c
-	.byte  X86_FEATURE_K8_C
-	.byte  memset_c_end-memset_c
-	.byte  memset_c_end-memset_c
-	.previous
-
-	.section .altinstr_replacement,"ax"
- /* rdi	destination
-  * rsi value
-  * rdx count
-  */			
-memset_c:	
 	movq %rdi,%r9
 	movl %edx,%r8d
 	andl $7,%r8d		
@@ -121,5 +29,3 @@ memset_c:	
 	stosb
 	movq %r9,%rax
 	ret
-memset_c_end:
-	.previous
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index b75b872..3a63707 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -308,18 +308,6 @@ asmlinkage void __kprobes do_page_fault(
 	unsigned long flags;
 	siginfo_t info;
 
-#ifdef CONFIG_CHECKING
-	{ 
-		unsigned long gs; 
-		struct x8664_pda *pda = cpu_pda + stack_smp_processor_id(); 
-		rdmsrl(MSR_GS_BASE, gs); 
-		if (gs != (unsigned long)pda) { 
-			wrmsrl(MSR_GS_BASE, pda); 
-			printk("page_fault: wrong gs %lx expected %p\n", gs, pda);
-		}
-	}
-#endif
-
 	/* get the address */
 	__asm__("movq %%cr2,%0":"=r" (address));
 	if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
@@ -571,3 +559,10 @@ do_sigbus:
 	force_sig_info(SIGBUS, &info, tsk);
 	return;
 }
+
+static int __init enable_pagefaulttrace(char *str)
+{
+	page_fault_trace = 1;
+	return 0;
+}
+__setup("pagefaulttrace", enable_pagefaulttrace);
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index e60a1a8..286f6a6 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -22,6 +22,7 @@
 #include <linux/pagemap.h>
 #include <linux/bootmem.h>
 #include <linux/proc_fs.h>
+#include <linux/pci.h>
 
 #include <asm/processor.h>
 #include <asm/system.h>
@@ -36,16 +37,13 @@
 #include <asm/mmu_context.h>
 #include <asm/proto.h>
 #include <asm/smp.h>
+#include <asm/sections.h>
 
 #ifndef Dprintk
 #define Dprintk(x...)
 #endif
 
-#ifdef CONFIG_GART_IOMMU
-extern int swiotlb;
-#endif
-
-extern char _stext[];
+static unsigned long dma_reserve __initdata;
 
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
@@ -86,9 +84,6 @@ void show_mem(void)
 
 /* References to section boundaries */
 
-extern char _text, _etext, _edata, __bss_start, _end[];
-extern char __init_begin, __init_end;
-
 int after_bootmem;
 
 static void *spp_getpage(void)
@@ -308,42 +303,81 @@ void __init init_memory_mapping(unsigned
 	       table_end<<PAGE_SHIFT);
 }
 
-extern struct x8664_pda cpu_pda[NR_CPUS];
-
-/* Assumes all CPUs still execute in init_mm */
-void zap_low_mappings(void)
+void __cpuinit zap_low_mappings(int cpu)
 {
-	pgd_t *pgd = pgd_offset_k(0UL);
-	pgd_clear(pgd);
-	flush_tlb_all();
+	if (cpu == 0) {
+		pgd_t *pgd = pgd_offset_k(0UL);
+		pgd_clear(pgd);
+	} else {
+		/*
+		 * For AP's, zap the low identity mappings by changing the cr3
+		 * to init_level4_pgt and doing local flush tlb all
+		 */
+		asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt)));
+	}
+	__flush_tlb_all();
+}
+
+/* Compute zone sizes for the DMA and DMA32 zones in a node. */
+__init void
+size_zones(unsigned long *z, unsigned long *h,
+	   unsigned long start_pfn, unsigned long end_pfn)
+{
+ 	int i;
+ 	unsigned long w;
+
+ 	for (i = 0; i < MAX_NR_ZONES; i++)
+ 		z[i] = 0;
+
+ 	if (start_pfn < MAX_DMA_PFN)
+ 		z[ZONE_DMA] = MAX_DMA_PFN - start_pfn;
+ 	if (start_pfn < MAX_DMA32_PFN) {
+ 		unsigned long dma32_pfn = MAX_DMA32_PFN;
+ 		if (dma32_pfn > end_pfn)
+ 			dma32_pfn = end_pfn;
+ 		z[ZONE_DMA32] = dma32_pfn - start_pfn;
+ 	}
+ 	z[ZONE_NORMAL] = end_pfn - start_pfn;
+
+ 	/* Remove lower zones from higher ones. */
+ 	w = 0;
+ 	for (i = 0; i < MAX_NR_ZONES; i++) {
+ 		if (z[i])
+ 			z[i] -= w;
+ 	        w += z[i];
+	}
+
+	/* Compute holes */
+	w = 0;
+	for (i = 0; i < MAX_NR_ZONES; i++) {
+		unsigned long s = w;
+		w += z[i];
+		h[i] = e820_hole_size(s, w);
+	}
+
+	/* Add the space pace needed for mem_map to the holes too. */
+	for (i = 0; i < MAX_NR_ZONES; i++)
+		h[i] += (z[i] * sizeof(struct page)) / PAGE_SIZE;
+
+	/* The 16MB DMA zone has the kernel and other misc mappings.
+ 	   Account them too */
+	if (h[ZONE_DMA]) {
+		h[ZONE_DMA] += dma_reserve;
+		if (h[ZONE_DMA] >= z[ZONE_DMA]) {
+			printk(KERN_WARNING
+				"Kernel too large and filling up ZONE_DMA?\n");
+			h[ZONE_DMA] = z[ZONE_DMA];
+		}
+	}
 }
 
 #ifndef CONFIG_NUMA
 void __init paging_init(void)
 {
-	{
-		unsigned long zones_size[MAX_NR_ZONES];
-		unsigned long holes[MAX_NR_ZONES];
-		unsigned int max_dma;
-
-		memset(zones_size, 0, sizeof(zones_size));
-		memset(holes, 0, sizeof(holes));
-
-		max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-
-		if (end_pfn < max_dma) {
-			zones_size[ZONE_DMA] = end_pfn;
-			holes[ZONE_DMA] = e820_hole_size(0, end_pfn);
-		} else {
-			zones_size[ZONE_DMA] = max_dma;
-			holes[ZONE_DMA] = e820_hole_size(0, max_dma);
-			zones_size[ZONE_NORMAL] = end_pfn - max_dma;
-			holes[ZONE_NORMAL] = e820_hole_size(max_dma, end_pfn);
-		}
-		free_area_init_node(0, NODE_DATA(0), zones_size,
-                        __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes);
-	}
-	return;
+	unsigned long zones[MAX_NR_ZONES], holes[MAX_NR_ZONES];
+	size_zones(zones, holes, 0, end_pfn);
+	free_area_init_node(0, NODE_DATA(0), zones,
+			    __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes);
 }
 #endif
 
@@ -438,19 +472,16 @@ void __init mem_init(void)
 		datasize >> 10,
 		initsize >> 10);
 
+#ifdef CONFIG_SMP
 	/*
-	 * Subtle. SMP is doing its boot stuff late (because it has to
-	 * fork idle threads) - but it also needs low mappings for the
-	 * protected-mode entry to work. We zap these entries only after
-	 * the WP-bit has been tested.
+	 * Sync boot_level4_pgt mappings with the init_level4_pgt
+	 * except for the low identity mappings which are already zapped
+	 * in init_level4_pgt. This sync-up is essential for AP's bringup
 	 */
-#ifndef CONFIG_SMP
-	zap_low_mappings();
+	memcpy(boot_level4_pgt+1, init_level4_pgt+1, (PTRS_PER_PGD-1)*sizeof(pgd_t));
 #endif
 }
 
-extern char __initdata_begin[], __initdata_end[];
-
 void free_initmem(void)
 {
 	unsigned long addr;
@@ -464,7 +495,7 @@ void free_initmem(void)
 		totalram_pages++;
 	}
 	memset(__initdata_begin, 0xba, __initdata_end - __initdata_begin);
-	printk ("Freeing unused kernel memory: %luk freed\n", (&__init_end - &__init_begin) >> 10);
+	printk ("Freeing unused kernel memory: %luk freed\n", (__init_end - __init_begin) >> 10);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -491,6 +522,8 @@ void __init reserve_bootmem_generic(unsi
 #else       		
 	reserve_bootmem(phys, len);    
 #endif
+	if (phys+len <= MAX_DMA_PFN*PAGE_SIZE)
+		dma_reserve += len / PAGE_SIZE;
 }
 
 int kern_addr_valid(unsigned long addr) 
@@ -532,10 +565,6 @@ extern int exception_trace, page_fault_t
 static ctl_table debug_table2[] = {
 	{ 99, "exception-trace", &exception_trace, sizeof(int), 0644, NULL,
 	  proc_dointvec },
-#ifdef CONFIG_CHECKING
-	{ 100, "page-fault-trace", &page_fault_trace, sizeof(int), 0644, NULL,
-	  proc_dointvec },
-#endif
 	{ 0, }
 }; 
 
diff --git a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c
index 65417b0..a5663e0 100644
--- a/arch/x86_64/mm/k8topology.c
+++ b/arch/x86_64/mm/k8topology.c
@@ -108,6 +108,7 @@ int __init k8_scan_nodes(unsigned long s
 		limit >>= 16; 
 		limit <<= 24; 
 		limit |= (1<<24)-1;
+		limit++;
 
 		if (limit > end_pfn << PAGE_SHIFT)
 			limit = end_pfn << PAGE_SHIFT;
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index 2148038..a828a01 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -38,38 +38,57 @@ cpumask_t node_to_cpumask[MAX_NUMNODES] 
 
 int numa_off __initdata;
 
-int __init compute_hash_shift(struct node *nodes, int numnodes)
+
+/*
+ * Given a shift value, try to populate memnodemap[]
+ * Returns :
+ * 1 if OK
+ * 0 if memnodmap[] too small (of shift too small)
+ * -1 if node overlap or lost ram (shift too big)
+ */
+static int __init populate_memnodemap(
+	const struct node *nodes, int numnodes, int shift)
 {
 	int i; 
-	int shift = 20;
-	unsigned long addr,maxend=0;
-	
-	for (i = 0; i < numnodes; i++)
-		if ((nodes[i].start != nodes[i].end) && (nodes[i].end > maxend))
-				maxend = nodes[i].end;
+	int res = -1;
+	unsigned long addr, end;
 
-	while ((1UL << shift) <  (maxend / NODEMAPSIZE))
-		shift++;
-
-	printk (KERN_DEBUG"Using %d for the hash shift. Max adder is %lx \n",
-			shift,maxend);
-	memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE);
+	memset(memnodemap, 0xff, sizeof(memnodemap));
 	for (i = 0; i < numnodes; i++) {
-		if (nodes[i].start == nodes[i].end)
+		addr = nodes[i].start;
+		end = nodes[i].end;
+		if (addr >= end)
 			continue;
-		for (addr = nodes[i].start;
-		     addr < nodes[i].end;
-		     addr += (1UL << shift)) {
-			if (memnodemap[addr >> shift] != 0xff) {
-				printk(KERN_INFO
-	"Your memory is not aligned you need to rebuild your kernel "
-	"with a bigger NODEMAPSIZE shift=%d adder=%lu\n",
-					shift,addr);
+		if ((end >> shift) >= NODEMAPSIZE)
+			return 0;
+		do {
+			if (memnodemap[addr >> shift] != 0xff)
 				return -1;
-			} 
 			memnodemap[addr >> shift] = i;
-		} 
+			addr += (1 << shift);
+		} while (addr < end);
+		res = 1;
 	} 
+	return res;
+}
+
+int __init compute_hash_shift(struct node *nodes, int numnodes)
+{
+	int shift = 20;
+
+	while (populate_memnodemap(nodes, numnodes, shift + 1) >= 0)
+		shift++;
+
+	printk(KERN_DEBUG "Using %d for the hash shift.\n",
+		shift);
+
+	if (populate_memnodemap(nodes, numnodes, shift) != 1) {
+		printk(KERN_INFO
+	"Your memory is not aligned you need to rebuild your kernel "
+	"with a bigger NODEMAPSIZE shift=%d\n",
+			shift);
+		return -1;
+	}
 	return shift;
 }
 
@@ -94,7 +113,6 @@ void __init setup_node_bootmem(int nodei
 	start_pfn = start >> PAGE_SHIFT;
 	end_pfn = end >> PAGE_SHIFT;
 
-	memory_present(nodeid, start_pfn, end_pfn);
 	nodedata_phys = find_e820_area(start, end, pgdat_size); 
 	if (nodedata_phys == -1L) 
 		panic("Cannot find memory pgdat in node %d\n", nodeid);
@@ -132,29 +150,14 @@ void __init setup_node_zones(int nodeid)
 	unsigned long start_pfn, end_pfn; 
 	unsigned long zones[MAX_NR_ZONES];
 	unsigned long holes[MAX_NR_ZONES];
-	unsigned long dma_end_pfn;
 
-	memset(zones, 0, sizeof(unsigned long) * MAX_NR_ZONES); 
-	memset(holes, 0, sizeof(unsigned long) * MAX_NR_ZONES);
+ 	start_pfn = node_start_pfn(nodeid);
+ 	end_pfn = node_end_pfn(nodeid);
 
-	start_pfn = node_start_pfn(nodeid);
-	end_pfn = node_end_pfn(nodeid);
+	Dprintk(KERN_INFO "setting up node %d %lx-%lx\n",
+		nodeid, start_pfn, end_pfn);
 
-	Dprintk(KERN_INFO "setting up node %d %lx-%lx\n", nodeid, start_pfn, end_pfn);
-	
-	/* All nodes > 0 have a zero length zone DMA */ 
-	dma_end_pfn = __pa(MAX_DMA_ADDRESS) >> PAGE_SHIFT; 
-	if (start_pfn < dma_end_pfn) { 
-		zones[ZONE_DMA] = dma_end_pfn - start_pfn;
-		holes[ZONE_DMA] = e820_hole_size(start_pfn, dma_end_pfn);
-		zones[ZONE_NORMAL] = end_pfn - dma_end_pfn; 
-		holes[ZONE_NORMAL] = e820_hole_size(dma_end_pfn, end_pfn);
-
-	} else { 
-		zones[ZONE_NORMAL] = end_pfn - start_pfn; 
-		holes[ZONE_NORMAL] = e820_hole_size(start_pfn, end_pfn);
-	} 
-    
+	size_zones(zones, holes, start_pfn, end_pfn);
 	free_area_init_node(nodeid, NODE_DATA(nodeid), zones,
 			    start_pfn, holes);
 } 
@@ -171,7 +174,7 @@ void __init numa_init_array(void)
 	for (i = 0; i < NR_CPUS; i++) {
 		if (cpu_to_node[i] != NUMA_NO_NODE)
 			continue;
-		cpu_to_node[i] = rr;
+ 		numa_set_node(i, rr);
 		rr = next_node(rr, node_online_map);
 		if (rr == MAX_NUMNODES)
 			rr = first_node(node_online_map);
@@ -205,8 +208,6 @@ static int numa_emulation(unsigned long 
  		if (i == numa_fake-1)
  			sz = (end_pfn<<PAGE_SHIFT) - nodes[i].start;
  		nodes[i].end = nodes[i].start + sz;
- 		if (i != numa_fake-1)
- 			nodes[i].end--;
  		printk(KERN_INFO "Faking node %d at %016Lx-%016Lx (%LuMB)\n",
  		       i,
  		       nodes[i].start, nodes[i].end,
@@ -257,7 +258,7 @@ void __init numa_initmem_init(unsigned l
 	nodes_clear(node_online_map);
 	node_set_online(0);
 	for (i = 0; i < NR_CPUS; i++)
-		cpu_to_node[i] = 0;
+		numa_set_node(i, 0);
 	node_to_cpumask[0] = cpumask_of_cpu(0);
 	setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT);
 }
@@ -267,6 +268,12 @@ __cpuinit void numa_add_cpu(int cpu)
 	set_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]);
 } 
 
+void __cpuinit numa_set_node(int cpu, int node)
+{
+	cpu_pda[cpu].nodenumber = node;
+	cpu_to_node[cpu] = node;
+}
+
 unsigned long __init numa_free_all_bootmem(void) 
 { 
 	int i;
@@ -277,9 +284,26 @@ unsigned long __init numa_free_all_bootm
 	return pages;
 } 
 
+#ifdef CONFIG_SPARSEMEM
+static void __init arch_sparse_init(void)
+{
+	int i;
+
+	for_each_online_node(i)
+		memory_present(i, node_start_pfn(i), node_end_pfn(i));
+
+	sparse_init();
+}
+#else
+#define arch_sparse_init() do {} while (0)
+#endif
+
 void __init paging_init(void)
 { 
 	int i;
+
+	arch_sparse_init();
+
 	for_each_online_node(i) {
 		setup_node_zones(i); 
 	}
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
index 4b2e844..33340bd 100644
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -71,8 +71,6 @@ static __init void cutoff_node(int i, un
 			nd->start = nd->end;
 	}
 	if (nd->end > end) {
-		if (!(end & 0xfff))
-			end--;
 		nd->end = end;
 		if (nd->start > nd->end)
 			nd->start = nd->end;
@@ -166,8 +164,6 @@ acpi_numa_memory_affinity_init(struct ac
 		if (nd->end < end)
 			nd->end = end;
 	}
-	if (!(nd->end & 0xfff))
-		nd->end--;
 	printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm,
 	       nd->start, nd->end);
 }
@@ -203,7 +199,7 @@ int __init acpi_scan_nodes(unsigned long
 		if (cpu_to_node[i] == NUMA_NO_NODE)
 			continue;
 		if (!node_isset(cpu_to_node[i], nodes_parsed))
-			cpu_to_node[i] = NUMA_NO_NODE; 
+			numa_set_node(i, NUMA_NO_NODE);
 	}
 	numa_init_array();
 	return 0;
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index ecacca9..2b64f58 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -861,8 +861,8 @@ __cfq_slice_expired(struct cfq_data *cfq
 	 * store what was left of this slice, if the queue idled out
 	 * or was preempted
 	 */
-	if (time_after(now, cfqq->slice_end))
-		cfqq->slice_left = now - cfqq->slice_end;
+	if (time_after(cfqq->slice_end, now))
+		cfqq->slice_left = cfqq->slice_end - now;
 	else
 		cfqq->slice_left = 0;
 
@@ -999,7 +999,7 @@ cfq_prio_to_maxrq(struct cfq_data *cfqd,
 /*
  * get next queue for service
  */
-static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd, int force)
+static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd)
 {
 	unsigned long now = jiffies;
 	struct cfq_queue *cfqq;
@@ -1023,7 +1023,7 @@ static struct cfq_queue *cfq_select_queu
 	 */
 	if (!RB_EMPTY(&cfqq->sort_list))
 		goto keep_queue;
-	else if (!force && cfq_cfqq_class_sync(cfqq) &&
+	else if (cfq_cfqq_class_sync(cfqq) &&
 		 time_before(now, cfqq->slice_end)) {
 		if (cfq_arm_slice_timer(cfqd, cfqq))
 			return NULL;
@@ -1092,6 +1092,42 @@ __cfq_dispatch_requests(struct cfq_data 
 }
 
 static int
+cfq_forced_dispatch_cfqqs(struct list_head *list)
+{
+	int dispatched = 0;
+	struct cfq_queue *cfqq, *next;
+	struct cfq_rq *crq;
+
+	list_for_each_entry_safe(cfqq, next, list, cfq_list) {
+		while ((crq = cfqq->next_crq)) {
+			cfq_dispatch_insert(cfqq->cfqd->queue, crq);
+			dispatched++;
+		}
+		BUG_ON(!list_empty(&cfqq->fifo));
+	}
+	return dispatched;
+}
+
+static int
+cfq_forced_dispatch(struct cfq_data *cfqd)
+{
+	int i, dispatched = 0;
+
+	for (i = 0; i < CFQ_PRIO_LISTS; i++)
+		dispatched += cfq_forced_dispatch_cfqqs(&cfqd->rr_list[i]);
+
+	dispatched += cfq_forced_dispatch_cfqqs(&cfqd->busy_rr);
+	dispatched += cfq_forced_dispatch_cfqqs(&cfqd->cur_rr);
+	dispatched += cfq_forced_dispatch_cfqqs(&cfqd->idle_rr);
+
+	cfq_slice_expired(cfqd, 0);
+
+	BUG_ON(cfqd->busy_queues);
+
+	return dispatched;
+}
+
+static int
 cfq_dispatch_requests(request_queue_t *q, int force)
 {
 	struct cfq_data *cfqd = q->elevator->elevator_data;
@@ -1100,7 +1136,10 @@ cfq_dispatch_requests(request_queue_t *q
 	if (!cfqd->busy_queues)
 		return 0;
 
-	cfqq = cfq_select_queue(cfqd, force);
+	if (unlikely(force))
+		return cfq_forced_dispatch(cfqd);
+
+	cfqq = cfq_select_queue(cfqd);
 	if (cfqq) {
 		int max_dispatch;
 
@@ -1115,12 +1154,9 @@ cfq_dispatch_requests(request_queue_t *q
 		cfq_clear_cfqq_wait_request(cfqq);
 		del_timer(&cfqd->idle_slice_timer);
 
-		if (!force) {
-			max_dispatch = cfqd->cfq_quantum;
-			if (cfq_class_idle(cfqq))
-				max_dispatch = 1;
-		} else
-			max_dispatch = INT_MAX;
+		max_dispatch = cfqd->cfq_quantum;
+		if (cfq_class_idle(cfqq))
+			max_dispatch = 1;
 
 		return __cfq_dispatch_requests(cfqd, cfqq, max_dispatch);
 	}
diff --git a/block/elevator.c b/block/elevator.c
index d4a49a3..e4c5882 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -155,9 +155,10 @@ static void elevator_setup_default(void)
  	/*
  	 * If the given scheduler is not available, fall back to no-op.
  	 */
- 	if (!(e = elevator_find(chosen_elevator)))
+ 	if ((e = elevator_find(chosen_elevator)))
+		elevator_put(e);
+	else
  		strcpy(chosen_elevator, "noop");
-	elevator_put(e);
 }
 
 static int __init elevator_setup(char *str)
@@ -190,14 +191,14 @@ int elevator_init(request_queue_t *q, ch
 
 	eq = kmalloc(sizeof(struct elevator_queue), GFP_KERNEL);
 	if (!eq) {
-		elevator_put(e->elevator_type);
+		elevator_put(e);
 		return -ENOMEM;
 	}
 
 	ret = elevator_attach(q, e, eq);
 	if (ret) {
 		kfree(eq);
-		elevator_put(e->elevator_type);
+		elevator_put(e);
 	}
 
 	return ret;
@@ -225,6 +226,7 @@ void elv_dispatch_sort(request_queue_t *
 
 	if (q->last_merge == rq)
 		q->last_merge = NULL;
+	q->nr_sorted--;
 
 	boundary = q->end_sector;
 
@@ -283,6 +285,7 @@ void elv_merge_requests(request_queue_t 
 
 	if (e->ops->elevator_merge_req_fn)
 		e->ops->elevator_merge_req_fn(q, rq, next);
+	q->nr_sorted--;
 
 	q->last_merge = rq;
 }
@@ -314,6 +317,20 @@ void elv_requeue_request(request_queue_t
 	__elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
 }
 
+static void elv_drain_elevator(request_queue_t *q)
+{
+	static int printed;
+	while (q->elevator->ops->elevator_dispatch_fn(q, 1))
+		;
+	if (q->nr_sorted == 0)
+		return;
+	if (printed++ < 10) {
+		printk(KERN_ERR "%s: forced dispatching is broken "
+		       "(nr_sorted=%u), please report this\n",
+		       q->elevator->elevator_type->elevator_name, q->nr_sorted);
+	}
+}
+
 void __elv_add_request(request_queue_t *q, struct request *rq, int where,
 		       int plug)
 {
@@ -348,9 +365,7 @@ void __elv_add_request(request_queue_t *
 
 	case ELEVATOR_INSERT_BACK:
 		rq->flags |= REQ_SOFTBARRIER;
-
-		while (q->elevator->ops->elevator_dispatch_fn(q, 1))
-			;
+		elv_drain_elevator(q);
 		list_add_tail(&rq->queuelist, &q->queue_head);
 		/*
 		 * We kick the queue here for the following reasons.
@@ -369,6 +384,7 @@ void __elv_add_request(request_queue_t *
 	case ELEVATOR_INSERT_SORT:
 		BUG_ON(!blk_fs_request(rq));
 		rq->flags |= REQ_SORTED;
+		q->nr_sorted++;
 		if (q->last_merge == NULL && rq_mergeable(rq))
 			q->last_merge = rq;
 		/*
@@ -525,33 +541,19 @@ int elv_queue_empty(request_queue_t *q)
 
 struct request *elv_latter_request(request_queue_t *q, struct request *rq)
 {
-	struct list_head *next;
-
 	elevator_t *e = q->elevator;
 
 	if (e->ops->elevator_latter_req_fn)
 		return e->ops->elevator_latter_req_fn(q, rq);
-
-	next = rq->queuelist.next;
-	if (next != &q->queue_head && next != &rq->queuelist)
-		return list_entry_rq(next);
-
 	return NULL;
 }
 
 struct request *elv_former_request(request_queue_t *q, struct request *rq)
 {
-	struct list_head *prev;
-
 	elevator_t *e = q->elevator;
 
 	if (e->ops->elevator_former_req_fn)
 		return e->ops->elevator_former_req_fn(q, rq);
-
-	prev = rq->queuelist.prev;
-	if (prev != &q->queue_head && prev != &rq->queuelist)
-		return list_entry_rq(prev);
-
 	return NULL;
 }
 
@@ -691,13 +693,15 @@ static void elevator_switch(request_queu
 
 	set_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
 
-	while (q->elevator->ops->elevator_dispatch_fn(q, 1))
-		;
+	elv_drain_elevator(q);
 
 	while (q->rq.elvpriv) {
+		blk_remove_plug(q);
+		q->request_fn(q);
 		spin_unlock_irq(q->queue_lock);
 		msleep(10);
 		spin_lock_irq(q->queue_lock);
+		elv_drain_elevator(q);
 	}
 
 	spin_unlock_irq(q->queue_lock);
@@ -744,13 +748,15 @@ error:
 ssize_t elv_iosched_store(request_queue_t *q, const char *name, size_t count)
 {
 	char elevator_name[ELV_NAME_MAX];
+	size_t len;
 	struct elevator_type *e;
 
-	memset(elevator_name, 0, sizeof(elevator_name));
-	strncpy(elevator_name, name, sizeof(elevator_name));
+	elevator_name[sizeof(elevator_name) - 1] = '\0';
+	strncpy(elevator_name, name, sizeof(elevator_name) - 1);
+	len = strlen(elevator_name);
 
-	if (elevator_name[strlen(elevator_name) - 1] == '\n')
-		elevator_name[strlen(elevator_name) - 1] = '\0';
+	if (len && elevator_name[len - 1] == '\n')
+		elevator_name[len - 1] = '\0';
 
 	e = elevator_get(elevator_name);
 	if (!e) {
diff --git a/block/genhd.c b/block/genhd.c
index 54aec4a..f04609d 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -391,12 +391,14 @@ static ssize_t disk_stats_read(struct ge
 		"%8u %8u %8llu %8u "
 		"%8u %8u %8u"
 		"\n",
-		disk_stat_read(disk, ios[0]), disk_stat_read(disk, merges[0]),
-		(unsigned long long)disk_stat_read(disk, sectors[0]),
-		jiffies_to_msecs(disk_stat_read(disk, ticks[0])),
-		disk_stat_read(disk, ios[1]), disk_stat_read(disk, merges[1]),
-		(unsigned long long)disk_stat_read(disk, sectors[1]),
-		jiffies_to_msecs(disk_stat_read(disk, ticks[1])),
+		disk_stat_read(disk, ios[READ]),
+		disk_stat_read(disk, merges[READ]),
+		(unsigned long long)disk_stat_read(disk, sectors[READ]),
+		jiffies_to_msecs(disk_stat_read(disk, ticks[READ])),
+		disk_stat_read(disk, ios[WRITE]),
+		disk_stat_read(disk, merges[WRITE]),
+		(unsigned long long)disk_stat_read(disk, sectors[WRITE]),
+		jiffies_to_msecs(disk_stat_read(disk, ticks[WRITE])),
 		disk->in_flight,
 		jiffies_to_msecs(disk_stat_read(disk, io_ticks)),
 		jiffies_to_msecs(disk_stat_read(disk, time_in_queue)));
diff --git a/block/noop-iosched.c b/block/noop-iosched.c
index e54f006..f370e4a 100644
--- a/block/noop-iosched.c
+++ b/block/noop-iosched.c
@@ -7,21 +7,94 @@
 #include <linux/module.h>
 #include <linux/init.h>
 
-static void elevator_noop_add_request(request_queue_t *q, struct request *rq)
+struct noop_data {
+	struct list_head queue;
+};
+
+static void noop_merged_requests(request_queue_t *q, struct request *rq,
+				 struct request *next)
+{
+	list_del_init(&next->queuelist);
+}
+
+static int noop_dispatch(request_queue_t *q, int force)
+{
+	struct noop_data *nd = q->elevator->elevator_data;
+
+	if (!list_empty(&nd->queue)) {
+		struct request *rq;
+		rq = list_entry(nd->queue.next, struct request, queuelist);
+		list_del_init(&rq->queuelist);
+		elv_dispatch_sort(q, rq);
+		return 1;
+	}
+	return 0;
+}
+
+static void noop_add_request(request_queue_t *q, struct request *rq)
+{
+	struct noop_data *nd = q->elevator->elevator_data;
+
+	list_add_tail(&rq->queuelist, &nd->queue);
+}
+
+static int noop_queue_empty(request_queue_t *q)
 {
-	rq->flags |= REQ_NOMERGE;
-	elv_dispatch_add_tail(q, rq);
+	struct noop_data *nd = q->elevator->elevator_data;
+
+	return list_empty(&nd->queue);
+}
+
+static struct request *
+noop_former_request(request_queue_t *q, struct request *rq)
+{
+	struct noop_data *nd = q->elevator->elevator_data;
+
+	if (rq->queuelist.prev == &nd->queue)
+		return NULL;
+	return list_entry(rq->queuelist.prev, struct request, queuelist);
+}
+
+static struct request *
+noop_latter_request(request_queue_t *q, struct request *rq)
+{
+	struct noop_data *nd = q->elevator->elevator_data;
+
+	if (rq->queuelist.next == &nd->queue)
+		return NULL;
+	return list_entry(rq->queuelist.next, struct request, queuelist);
 }
 
-static int elevator_noop_dispatch(request_queue_t *q, int force)
+static int noop_init_queue(request_queue_t *q, elevator_t *e)
 {
+	struct noop_data *nd;
+
+	nd = kmalloc(sizeof(*nd), GFP_KERNEL);
+	if (!nd)
+		return -ENOMEM;
+	INIT_LIST_HEAD(&nd->queue);
+	e->elevator_data = nd;
 	return 0;
 }
 
+static void noop_exit_queue(elevator_t *e)
+{
+	struct noop_data *nd = e->elevator_data;
+
+	BUG_ON(!list_empty(&nd->queue));
+	kfree(nd);
+}
+
 static struct elevator_type elevator_noop = {
 	.ops = {
-		.elevator_dispatch_fn		= elevator_noop_dispatch,
-		.elevator_add_req_fn		= elevator_noop_add_request,
+		.elevator_merge_req_fn		= noop_merged_requests,
+		.elevator_dispatch_fn		= noop_dispatch,
+		.elevator_add_req_fn		= noop_add_request,
+		.elevator_queue_empty_fn	= noop_queue_empty,
+		.elevator_former_req_fn		= noop_former_request,
+		.elevator_latter_req_fn		= noop_latter_request,
+		.elevator_init_fn		= noop_init_queue,
+		.elevator_exit_fn		= noop_exit_queue,
 	},
 	.elevator_name = "noop",
 	.elevator_owner = THIS_MODULE,
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 6a4da41..606f873 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -28,6 +28,7 @@
 #include <linux/list.h>
 #include <linux/sched.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/device.h>
 #include <linux/proc_fs.h>
 #ifdef CONFIG_X86
@@ -754,7 +755,7 @@ static int __init acpi_init(void)
 	result = acpi_bus_init();
 
 	if (!result) {
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
 		if (!PM_IS_ACTIVE())
 			pm_active = 1;
 		else {
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 98f6c02..59dacb6 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -526,18 +526,23 @@ request_firmware_work_func(void *arg)
 {
 	struct firmware_work *fw_work = arg;
 	const struct firmware *fw;
+	int ret;
 	if (!arg) {
 		WARN_ON(1);
 		return 0;
 	}
 	daemonize("%s/%s", "firmware", fw_work->name);
-	_request_firmware(&fw, fw_work->name, fw_work->device,
+	ret = _request_firmware(&fw, fw_work->name, fw_work->device,
 		fw_work->hotplug);
-	fw_work->cont(fw, fw_work->context);
-	release_firmware(fw);
+	if (ret < 0)
+		fw_work->cont(NULL, fw_work->context);
+	else {
+		fw_work->cont(fw, fw_work->context);
+		release_firmware(fw);
+	}
 	module_put(fw_work->module);
 	kfree(fw_work);
-	return 0;
+	return ret;
 }
 
 /**
@@ -586,6 +591,8 @@ request_firmware_nowait(
 
 	if (ret < 0) {
 		fw_work->cont(NULL, fw_work->context);
+		module_put(fw_work->module);
+		kfree(fw_work);
 		return ret;
 	}
 	return 0;
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index 3226aa1..2942d32 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -255,7 +255,7 @@ scsi_cmd_stack_free(int ctlr)
 #define DEVICETYPE(n) (n<0 || n>MAX_SCSI_DEVICE_CODE) ? \
 	"Unknown" : scsi_device_types[n]
 
-#if 1
+#if 0
 static int xmargin=8;
 static int amargin=60;
 
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 59e5982..c0233ef 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -1188,7 +1188,7 @@ static void pkt_count_states(struct pktc
 	struct packet_data *pkt;
 	int i;
 
-	for (i = 0; i <= PACKET_NUM_STATES; i++)
+	for (i = 0; i < PACKET_NUM_STATES; i++)
 		states[i] = 0;
 
 	spin_lock(&pd->cdrw.active_list_lock);
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index fdf4370..970f70d 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -735,7 +735,7 @@ config SGI_IP27_RTC
 
 config GEN_RTC
 	tristate "Generic /dev/rtc emulation"
-	depends on RTC!=y && !IA64 && !ARM && !PPC64 && !M32R && !SPARC32 && !SPARC64
+	depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC32 && !SPARC64
 	---help---
 	  If you say Y here and create a character special file /dev/rtc with
 	  major number 10 and minor number 135 using mknod ("man mknod"), you
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 78ce98a..7658978 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -57,9 +57,8 @@ static int nr_garts;
 static struct pci_dev * hammers[MAX_HAMMER_GARTS];
 
 static struct resource *aperture_resource;
-static int __initdata agp_try_unsupported;
+static int __initdata agp_try_unsupported = 1;
 
-static int gart_iterator;
 #define for_each_nb() for(gart_iterator=0;gart_iterator<nr_garts;gart_iterator++)
 
 static void flush_amd64_tlb(struct pci_dev *dev)
@@ -73,6 +72,7 @@ static void flush_amd64_tlb(struct pci_d
 
 static void amd64_tlbflush(struct agp_memory *temp)
 {
+	int gart_iterator;
 	for_each_nb()
 		flush_amd64_tlb(hammers[gart_iterator]);
 }
@@ -222,6 +222,7 @@ static struct aper_size_info_32 amd_8151
 static int amd_8151_configure(void)
 {
 	unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real);
+	int gart_iterator;
 
 	/* Configure AGP regs in each x86-64 host bridge. */
 	for_each_nb() {
@@ -235,7 +236,7 @@ static int amd_8151_configure(void)
 static void amd64_cleanup(void)
 {
 	u32 tmp;
-
+	int gart_iterator;
 	for_each_nb() {
 		/* disable gart translation */
 		pci_read_config_dword (hammers[gart_iterator], AMD64_GARTAPERTURECTL, &tmp);
@@ -697,6 +698,16 @@ static struct pci_device_id agp_amd64_pc
 	.subvendor	= PCI_ANY_ID,
 	.subdevice	= PCI_ANY_ID,
 	},
+	/* ALI/ULI M1695 */
+	{
+	.class		= (PCI_CLASS_BRIDGE_HOST << 8),
+	.class_mask	= ~0,
+	.vendor		= PCI_VENDOR_ID_AL,
+	.device		= 0x1689,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+	},
+
 	{ }
 };
 
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index c825531..50947e3 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -557,6 +557,10 @@ static struct agp_device_ids uninorth_ag
 		.device_id	= PCI_DEVICE_ID_APPLE_U3H_AGP,
 		.chipset_name	= "U3H",
 	},
+	{
+		.device_id	= PCI_DEVICE_ID_APPLE_IPID2_AGP,
+		.chipset_name	= "UniNorth/Intrepid2",
+	},
 };
 
 static int __devinit agp_uninorth_probe(struct pci_dev *pdev,
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 6c4b3f9..f3c3aaf 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -99,7 +99,9 @@ struct smm_regs {
 
 static inline char *i8k_get_dmi_data(int field)
 {
-	return dmi_get_system_info(field) ? : "N/A";
+	char *dmi_data = dmi_get_system_info(field);
+
+	return dmi_data && *dmi_data ? dmi_data : "?";
 }
 
 /*
@@ -396,7 +398,7 @@ static int i8k_proc_show(struct seq_file
 	return seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
 			  I8K_PROC_FMT,
 			  bios_version,
-			  dmi_get_system_info(DMI_PRODUCT_SERIAL) ? : "N/A",
+			  i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
 			  cpu_temp,
 			  left_fan, right_fan, left_speed, right_speed,
 			  ac_power, fn_key);
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index d16bd4b..6b302a9 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -48,7 +48,7 @@
 
 #define PFX "IPMI message handler: "
 
-#define IPMI_DRIVER_VERSION "36.0"
+#define IPMI_DRIVER_VERSION "38.0"
 
 static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
 static int ipmi_init_msghandler(void);
diff --git a/drivers/char/pcmcia/Kconfig b/drivers/char/pcmcia/Kconfig
index d22bfdc..27c1179 100644
--- a/drivers/char/pcmcia/Kconfig
+++ b/drivers/char/pcmcia/Kconfig
@@ -18,5 +18,29 @@ config SYNCLINK_CS
 	  The module will be called synclinkmp.  If you want to do that, say M
 	  here.
 
+config CARDMAN_4000
+	tristate "Omnikey Cardman 4000 support"
+	depends on PCMCIA
+	help
+	  Enable support for the Omnikey Cardman 4000 PCMCIA Smartcard
+	  reader.
+
+	  This kernel driver requires additional userspace support, either
+	  by the vendor-provided PC/SC ifd_handler (http://www.omnikey.com/),
+	  or via the cm4000 backend of OpenCT (http://www.opensc.com/).
+
+config CARDMAN_4040
+	tristate "Omnikey CardMan 4040 support"
+	depends on PCMCIA
+	help
+	  Enable support for the Omnikey CardMan 4040 PCMCIA Smartcard
+	  reader.
+
+	  This card is basically a USB CCID device connected to a FIFO
+	  in I/O space.  To use the kernel driver, you will need either the
+	  PC/SC ifdhandler provided from the Omnikey homepage
+	  (http://www.omnikey.com/), or a current development version of OpenCT
+	  (http://www.opensc.org/).
+
 endmenu
 
diff --git a/drivers/char/pcmcia/Makefile b/drivers/char/pcmcia/Makefile
index 1fcd4c5..0aae209 100644
--- a/drivers/char/pcmcia/Makefile
+++ b/drivers/char/pcmcia/Makefile
@@ -5,3 +5,5 @@
 #
 
 obj-$(CONFIG_SYNCLINK_CS) += synclink_cs.o
+obj-$(CONFIG_CARDMAN_4000) += cm4000_cs.o
+obj-$(CONFIG_CARDMAN_4040) += cm4040_cs.o
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
new file mode 100644
index 0000000..ef011ef
--- /dev/null
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -0,0 +1,2078 @@
+ /*
+  * A driver for the PCMCIA Smartcard Reader "Omnikey CardMan Mobile 4000"
+  *
+  * cm4000_cs.c support.linux@omnikey.com
+  *
+  * Tue Oct 23 11:32:43 GMT 2001 herp - cleaned up header files
+  * Sun Jan 20 10:11:15 MET 2002 herp - added modversion header files
+  * Thu Nov 14 16:34:11 GMT 2002 mh   - added PPS functionality
+  * Tue Nov 19 16:36:27 GMT 2002 mh   - added SUSPEND/RESUME functionailty
+  * Wed Jul 28 12:55:01 CEST 2004 mh  - kernel 2.6 adjustments
+  *
+  * current version: 2.4.0gm4
+  *
+  * (C) 2000,2001,2002,2003,2004 Omnikey AG
+  *
+  * (C) 2005 Harald Welte <laforge@gnumonks.org>
+  * 	- Adhere to Kernel CodingStyle
+  * 	- Port to 2.6.13 "new" style PCMCIA
+  * 	- Check for copy_{from,to}_user return values
+  * 	- Use nonseekable_open()
+  *
+  * All rights reserved. Licensed under dual BSD/GPL license.
+  */
+
+/* #define PCMCIA_DEBUG 6 */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ciscode.h>
+#include <pcmcia/ds.h>
+
+#include <linux/cm4000_cs.h>
+
+/* #define ATR_CSUM */
+
+#ifdef PCMCIA_DEBUG
+#define reader_to_dev(x)	(&handle_to_dev(x->link.handle))
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0600);
+#define DEBUGP(n, rdr, x, args...) do { 				\
+	if (pc_debug >= (n))						\
+		dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, 	\
+			   __FUNCTION__ , ## args);			\
+	} while (0)
+#else
+#define DEBUGP(n, rdr, x, args...)
+#endif
+static char *version = "cm4000_cs.c v2.4.0gm5 - All bugs added by Harald Welte";
+
+#define	T_1SEC		(HZ)
+#define	T_10MSEC	msecs_to_jiffies(10)
+#define	T_20MSEC	msecs_to_jiffies(20)
+#define	T_40MSEC	msecs_to_jiffies(40)
+#define	T_50MSEC	msecs_to_jiffies(50)
+#define	T_100MSEC	msecs_to_jiffies(100)
+#define	T_500MSEC	msecs_to_jiffies(500)
+
+static void cm4000_detach(dev_link_t *link);
+static void cm4000_release(dev_link_t *link);
+
+static int major;		/* major number we get from the kernel */
+
+/* note: the first state has to have number 0 always */
+
+#define	M_FETCH_ATR	0
+#define	M_TIMEOUT_WAIT	1
+#define	M_READ_ATR_LEN	2
+#define	M_READ_ATR	3
+#define	M_ATR_PRESENT	4
+#define	M_BAD_CARD	5
+#define M_CARDOFF	6
+
+#define	LOCK_IO			0
+#define	LOCK_MONITOR		1
+
+#define IS_AUTOPPS_ACT		 6
+#define	IS_PROCBYTE_PRESENT	 7
+#define	IS_INVREV		 8
+#define IS_ANY_T0		 9
+#define	IS_ANY_T1		10
+#define	IS_ATR_PRESENT		11
+#define	IS_ATR_VALID		12
+#define	IS_CMM_ABSENT		13
+#define	IS_BAD_LENGTH		14
+#define	IS_BAD_CSUM		15
+#define	IS_BAD_CARD		16
+
+#define REG_FLAGS0(x)		(x + 0)
+#define REG_FLAGS1(x)		(x + 1)
+#define REG_NUM_BYTES(x)	(x + 2)
+#define REG_BUF_ADDR(x)		(x + 3)
+#define REG_BUF_DATA(x)		(x + 4)
+#define REG_NUM_SEND(x)		(x + 5)
+#define REG_BAUDRATE(x)		(x + 6)
+#define REG_STOPBITS(x)		(x + 7)
+
+struct cm4000_dev {
+	dev_link_t link;		/* pcmcia link */
+	dev_node_t node;		/* OS node (major,minor) */
+
+	unsigned char atr[MAX_ATR];
+	unsigned char rbuf[512];
+	unsigned char sbuf[512];
+
+	wait_queue_head_t devq;		/* when removing cardman must not be
+					   zeroed! */
+
+	wait_queue_head_t ioq;		/* if IO is locked, wait on this Q */
+	wait_queue_head_t atrq;		/* wait for ATR valid */
+	wait_queue_head_t readq;	/* used by write to wake blk.read */
+
+	/* warning: do not move this fields.
+	 * initialising to zero depends on it - see ZERO_DEV below.  */
+	unsigned char atr_csum;
+	unsigned char atr_len_retry;
+	unsigned short atr_len;
+	unsigned short rlen;	/* bytes avail. after write */
+	unsigned short rpos;	/* latest read pos. write zeroes */
+	unsigned char procbyte;	/* T=0 procedure byte */
+	unsigned char mstate;	/* state of card monitor */
+	unsigned char cwarn;	/* slow down warning */
+	unsigned char flags0;	/* cardman IO-flags 0 */
+	unsigned char flags1;	/* cardman IO-flags 1 */
+	unsigned int mdelay;	/* variable monitor speeds, in jiffies */
+
+	unsigned int baudv;	/* baud value for speed */
+	unsigned char ta1;
+	unsigned char proto;	/* T=0, T=1, ... */
+	unsigned long flags;	/* lock+flags (MONITOR,IO,ATR) * for concurrent
+				   access */
+
+	unsigned char pts[4];
+
+	struct timer_list timer;	/* used to keep monitor running */
+	int monitor_running;
+};
+
+#define	ZERO_DEV(dev)  						\
+	memset(&dev->atr_csum,0,				\
+		sizeof(struct cm4000_dev) - 			\
+		/*link*/ sizeof(dev_link_t) - 			\
+		/*node*/ sizeof(dev_node_t) - 			\
+		/*atr*/ MAX_ATR*sizeof(char) - 			\
+		/*rbuf*/ 512*sizeof(char) - 			\
+		/*sbuf*/ 512*sizeof(char) - 			\
+		/*queue*/ 4*sizeof(wait_queue_head_t))
+
+static dev_info_t dev_info = MODULE_NAME;
+static dev_link_t *dev_table[CM4000_MAX_DEV];
+
+/* This table doesn't use spaces after the comma between fields and thus
+ * violates CodingStyle.  However, I don't really think wrapping it around will
+ * make it any clearer to read -HW */
+static unsigned char fi_di_table[10][14] = {
+/*FI     00   01   02   03   04   05   06   07   08   09   10   11   12   13 */
+/*DI */
+/* 0 */ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+/* 1 */ {0x01,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x91,0x11,0x11,0x11,0x11},
+/* 2 */ {0x02,0x12,0x22,0x32,0x11,0x11,0x11,0x11,0x11,0x92,0xA2,0xB2,0x11,0x11},
+/* 3 */ {0x03,0x13,0x23,0x33,0x43,0x53,0x63,0x11,0x11,0x93,0xA3,0xB3,0xC3,0xD3},
+/* 4 */ {0x04,0x14,0x24,0x34,0x44,0x54,0x64,0x11,0x11,0x94,0xA4,0xB4,0xC4,0xD4},
+/* 5 */ {0x00,0x15,0x25,0x35,0x45,0x55,0x65,0x11,0x11,0x95,0xA5,0xB5,0xC5,0xD5},
+/* 6 */ {0x06,0x16,0x26,0x36,0x46,0x56,0x66,0x11,0x11,0x96,0xA6,0xB6,0xC6,0xD6},
+/* 7 */ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+/* 8 */ {0x08,0x11,0x28,0x38,0x48,0x58,0x68,0x11,0x11,0x98,0xA8,0xB8,0xC8,0xD8},
+/* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9}
+};
+
+#ifndef PCMCIA_DEBUG
+#define	xoutb	outb
+#define	xinb	inb
+#else
+static inline void xoutb(unsigned char val, unsigned short port)
+{
+	if (pc_debug >= 7)
+		printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
+	outb(val, port);
+}
+static inline unsigned char xinb(unsigned short port)
+{
+	unsigned char val;
+
+	val = inb(port);
+	if (pc_debug >= 7)
+		printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
+
+	return val;
+}
+#endif
+
+#define	b_0000	15
+#define	b_0001	14
+#define	b_0010	13
+#define	b_0011	12
+#define	b_0100	11
+#define	b_0101	10
+#define	b_0110	9
+#define	b_0111	8
+#define	b_1000	7
+#define	b_1001	6
+#define	b_1010	5
+#define	b_1011	4
+#define	b_1100	3
+#define	b_1101	2
+#define	b_1110	1
+#define	b_1111	0
+
+static unsigned char irtab[16] = {
+	b_0000, b_1000, b_0100, b_1100,
+	b_0010, b_1010, b_0110, b_1110,
+	b_0001, b_1001, b_0101, b_1101,
+	b_0011, b_1011, b_0111, b_1111
+};
+
+static void str_invert_revert(unsigned char *b, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		b[i] = (irtab[b[i] & 0x0f] << 4) | irtab[b[i] >> 4];
+}
+
+static unsigned char invert_revert(unsigned char ch)
+{
+	return (irtab[ch & 0x0f] << 4) | irtab[ch >> 4];
+}
+
+#define	ATRLENCK(dev,pos) \
+	if (pos>=dev->atr_len || pos>=MAX_ATR) \
+		goto return_0;
+
+static unsigned int calc_baudv(unsigned char fidi)
+{
+	unsigned int wcrcf, wbrcf, fi_rfu, di_rfu;
+
+	fi_rfu = 372;
+	di_rfu = 1;
+
+	/* FI */
+	switch ((fidi >> 4) & 0x0F) {
+	case 0x00:
+		wcrcf = 372;
+		break;
+	case 0x01:
+		wcrcf = 372;
+		break;
+	case 0x02:
+		wcrcf = 558;
+		break;
+	case 0x03:
+		wcrcf = 744;
+		break;
+	case 0x04:
+		wcrcf = 1116;
+		break;
+	case 0x05:
+		wcrcf = 1488;
+		break;
+	case 0x06:
+		wcrcf = 1860;
+		break;
+	case 0x07:
+		wcrcf = fi_rfu;
+		break;
+	case 0x08:
+		wcrcf = fi_rfu;
+		break;
+	case 0x09:
+		wcrcf = 512;
+		break;
+	case 0x0A:
+		wcrcf = 768;
+		break;
+	case 0x0B:
+		wcrcf = 1024;
+		break;
+	case 0x0C:
+		wcrcf = 1536;
+		break;
+	case 0x0D:
+		wcrcf = 2048;
+		break;
+	default:
+		wcrcf = fi_rfu;
+		break;
+	}
+
+	/* DI */
+	switch (fidi & 0x0F) {
+	case 0x00:
+		wbrcf = di_rfu;
+		break;
+	case 0x01:
+		wbrcf = 1;
+		break;
+	case 0x02:
+		wbrcf = 2;
+		break;
+	case 0x03:
+		wbrcf = 4;
+		break;
+	case 0x04:
+		wbrcf = 8;
+		break;
+	case 0x05:
+		wbrcf = 16;
+		break;
+	case 0x06:
+		wbrcf = 32;
+		break;
+	case 0x07:
+		wbrcf = di_rfu;
+		break;
+	case 0x08:
+		wbrcf = 12;
+		break;
+	case 0x09:
+		wbrcf = 20;
+		break;
+	default:
+		wbrcf = di_rfu;
+		break;
+	}
+
+	return (wcrcf / wbrcf);
+}
+
+static unsigned short io_read_num_rec_bytes(ioaddr_t iobase, unsigned short *s)
+{
+	unsigned short tmp;
+
+	tmp = *s = 0;
+	do {
+		*s = tmp;
+		tmp = inb(REG_NUM_BYTES(iobase)) |
+				(inb(REG_FLAGS0(iobase)) & 4 ? 0x100 : 0);
+	} while (tmp != *s);
+
+	return *s;
+}
+
+static int parse_atr(struct cm4000_dev *dev)
+{
+	unsigned char any_t1, any_t0;
+	unsigned char ch, ifno;
+	int ix, done;
+
+	DEBUGP(3, dev, "-> parse_atr: dev->atr_len = %i\n", dev->atr_len);
+
+	if (dev->atr_len < 3) {
+		DEBUGP(5, dev, "parse_atr: atr_len < 3\n");
+		return 0;
+	}
+
+	if (dev->atr[0] == 0x3f)
+		set_bit(IS_INVREV, &dev->flags);
+	else
+		clear_bit(IS_INVREV, &dev->flags);
+	ix = 1;
+	ifno = 1;
+	ch = dev->atr[1];
+	dev->proto = 0;		/* XXX PROTO */
+	any_t1 = any_t0 = done = 0;
+	dev->ta1 = 0x11;	/* defaults to 9600 baud */
+	do {
+		if (ifno == 1 && (ch & 0x10)) {
+			/* read first interface byte and TA1 is present */
+			dev->ta1 = dev->atr[2];
+			DEBUGP(5, dev, "Card says FiDi is 0x%.2x\n", dev->ta1);
+			ifno++;
+		} else if ((ifno == 2) && (ch & 0x10)) { /* TA(2) */
+			dev->ta1 = 0x11;
+			ifno++;
+		}
+
+		DEBUGP(5, dev, "Yi=%.2x\n", ch & 0xf0);
+		ix += ((ch & 0x10) >> 4)	/* no of int.face chars */
+		    +((ch & 0x20) >> 5)
+		    + ((ch & 0x40) >> 6)
+		    + ((ch & 0x80) >> 7);
+		/* ATRLENCK(dev,ix); */
+		if (ch & 0x80) {	/* TDi */
+			ch = dev->atr[ix];
+			if ((ch & 0x0f)) {
+				any_t1 = 1;
+				DEBUGP(5, dev, "card is capable of T=1\n");
+			} else {
+				any_t0 = 1;
+				DEBUGP(5, dev, "card is capable of T=0\n");
+			}
+		} else
+			done = 1;
+	} while (!done);
+
+	DEBUGP(5, dev, "ix=%d noHist=%d any_t1=%d\n",
+	      ix, dev->atr[1] & 15, any_t1);
+	if (ix + 1 + (dev->atr[1] & 0x0f) + any_t1 != dev->atr_len) {
+		DEBUGP(5, dev, "length error\n");
+		return 0;
+	}
+	if (any_t0)
+		set_bit(IS_ANY_T0, &dev->flags);
+
+	if (any_t1) {		/* compute csum */
+		dev->atr_csum = 0;
+#ifdef ATR_CSUM
+		for (i = 1; i < dev->atr_len; i++)
+			dev->atr_csum ^= dev->atr[i];
+		if (dev->atr_csum) {
+			set_bit(IS_BAD_CSUM, &dev->flags);
+			DEBUGP(5, dev, "bad checksum\n");
+			goto return_0;
+		}
+#endif
+		if (any_t0 == 0)
+			dev->proto = 1;	/* XXX PROTO */
+		set_bit(IS_ANY_T1, &dev->flags);
+	}
+
+	return 1;
+}
+
+struct card_fixup {
+	char atr[12];
+	u_int8_t atr_len;
+	u_int8_t stopbits;
+};
+
+static struct card_fixup card_fixups[] = {
+	{	/* ACOS */
+		.atr = { 0x3b, 0xb3, 0x11, 0x00, 0x00, 0x41, 0x01 },
+		.atr_len = 7,
+		.stopbits = 0x03,
+	},
+	{	/* Motorola */
+		.atr = {0x3b, 0x76, 0x13, 0x00, 0x00, 0x80, 0x62, 0x07,
+			0x41, 0x81, 0x81 },
+		.atr_len = 11,
+		.stopbits = 0x04,
+	},
+};
+
+static void set_cardparameter(struct cm4000_dev *dev)
+{
+	int i;
+	ioaddr_t iobase = dev->link.io.BasePort1;
+	u_int8_t stopbits = 0x02; /* ISO default */
+
+	DEBUGP(3, dev, "-> set_cardparameter\n");
+
+	dev->flags1 = dev->flags1 | (((dev->baudv - 1) & 0x0100) >> 8);
+	xoutb(dev->flags1, REG_FLAGS1(iobase));
+	DEBUGP(5, dev, "flags1 = 0x%02x\n", dev->flags1);
+
+	/* set baudrate */
+	xoutb((unsigned char)((dev->baudv - 1) & 0xFF), REG_BAUDRATE(iobase));
+
+	DEBUGP(5, dev, "baudv = %i -> write 0x%02x\n", dev->baudv,
+	      ((dev->baudv - 1) & 0xFF));
+
+	/* set stopbits */
+	for (i = 0; i < ARRAY_SIZE(card_fixups); i++) {
+		if (!memcmp(dev->atr, card_fixups[i].atr,
+			    card_fixups[i].atr_len))
+			stopbits = card_fixups[i].stopbits;
+	}
+	xoutb(stopbits, REG_STOPBITS(iobase));
+
+	DEBUGP(3, dev, "<- set_cardparameter\n");
+}
+
+static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
+{
+
+	unsigned long tmp, i;
+	unsigned short num_bytes_read;
+	unsigned char pts_reply[4];
+	ssize_t rc;
+	ioaddr_t iobase = dev->link.io.BasePort1;
+
+	rc = 0;
+
+	DEBUGP(3, dev, "-> set_protocol\n");
+	DEBUGP(5, dev, "ptsreq->Protocol = 0x%.8x, ptsreq->Flags=0x%.8x, "
+		 "ptsreq->pts1=0x%.2x, ptsreq->pts2=0x%.2x, "
+		 "ptsreq->pts3=0x%.2x\n", (unsigned int)ptsreq->protocol,
+		 (unsigned int)ptsreq->flags, ptsreq->pts1, ptsreq->pts2,
+		 ptsreq->pts3);
+
+	/* Fill PTS structure */
+	dev->pts[0] = 0xff;
+	dev->pts[1] = 0x00;
+	tmp = ptsreq->protocol;
+	while ((tmp = (tmp >> 1)) > 0)
+		dev->pts[1]++;
+	dev->proto = dev->pts[1];	/* Set new protocol */
+	dev->pts[1] = (0x01 << 4) | (dev->pts[1]);
+
+	/* Correct Fi/Di according to CM4000 Fi/Di table */
+	DEBUGP(5, dev, "Ta(1) from ATR is 0x%.2x\n", dev->ta1);
+	/* set Fi/Di according to ATR TA(1) */
+	dev->pts[2] = fi_di_table[dev->ta1 & 0x0F][(dev->ta1 >> 4) & 0x0F];
+
+	/* Calculate PCK character */
+	dev->pts[3] = dev->pts[0] ^ dev->pts[1] ^ dev->pts[2];
+
+	DEBUGP(5, dev, "pts0=%.2x, pts1=%.2x, pts2=%.2x, pts3=%.2x\n",
+	       dev->pts[0], dev->pts[1], dev->pts[2], dev->pts[3]);
+
+	/* check card convention */
+	if (test_bit(IS_INVREV, &dev->flags))
+		str_invert_revert(dev->pts, 4);
+
+	/* reset SM */
+	xoutb(0x80, REG_FLAGS0(iobase));
+
+	/* Enable access to the message buffer */
+	DEBUGP(5, dev, "Enable access to the messages buffer\n");
+	dev->flags1 = 0x20	/* T_Active */
+	    | (test_bit(IS_INVREV, &dev->flags) ? 0x02 : 0x00) /* inv parity */
+	    | ((dev->baudv >> 8) & 0x01);	/* MSB-baud */
+	xoutb(dev->flags1, REG_FLAGS1(iobase));
+
+	DEBUGP(5, dev, "Enable message buffer -> flags1 = 0x%.2x\n",
+	       dev->flags1);
+
+	/* write challenge to the buffer */
+	DEBUGP(5, dev, "Write challenge to buffer: ");
+	for (i = 0; i < 4; i++) {
+		xoutb(i, REG_BUF_ADDR(iobase));
+		xoutb(dev->pts[i], REG_BUF_DATA(iobase));	/* buf data */
+#ifdef PCMCIA_DEBUG
+		if (pc_debug >= 5)
+			printk("0x%.2x ", dev->pts[i]);
+	}
+	if (pc_debug >= 5)
+		printk("\n");
+#else
+	}
+#endif
+
+	/* set number of bytes to write */
+	DEBUGP(5, dev, "Set number of bytes to write\n");
+	xoutb(0x04, REG_NUM_SEND(iobase));
+
+	/* Trigger CARDMAN CONTROLLER */
+	xoutb(0x50, REG_FLAGS0(iobase));
+
+	/* Monitor progress */
+	/* wait for xmit done */
+	DEBUGP(5, dev, "Waiting for NumRecBytes getting valid\n");
+
+	for (i = 0; i < 100; i++) {
+		if (inb(REG_FLAGS0(iobase)) & 0x08) {
+			DEBUGP(5, dev, "NumRecBytes is valid\n");
+			break;
+		}
+		mdelay(10);
+	}
+	if (i == 100) {
+		DEBUGP(5, dev, "Timeout waiting for NumRecBytes getting "
+		       "valid\n");
+		rc = -EIO;
+		goto exit_setprotocol;
+	}
+
+	DEBUGP(5, dev, "Reading NumRecBytes\n");
+	for (i = 0; i < 100; i++) {
+		io_read_num_rec_bytes(iobase, &num_bytes_read);
+		if (num_bytes_read >= 4) {
+			DEBUGP(2, dev, "NumRecBytes = %i\n", num_bytes_read);
+			break;
+		}
+		mdelay(10);
+	}
+
+	/* check whether it is a short PTS reply? */
+	if (num_bytes_read == 3)
+		i = 0;
+
+	if (i == 100) {
+		DEBUGP(5, dev, "Timeout reading num_bytes_read\n");
+		rc = -EIO;
+		goto exit_setprotocol;
+	}
+
+	DEBUGP(5, dev, "Reset the CARDMAN CONTROLLER\n");
+	xoutb(0x80, REG_FLAGS0(iobase));
+
+	/* Read PPS reply */
+	DEBUGP(5, dev, "Read PPS reply\n");
+	for (i = 0; i < num_bytes_read; i++) {
+		xoutb(i, REG_BUF_ADDR(iobase));
+		pts_reply[i] = inb(REG_BUF_DATA(iobase));
+	}
+
+#ifdef PCMCIA_DEBUG
+	DEBUGP(2, dev, "PTSreply: ");
+	for (i = 0; i < num_bytes_read; i++) {
+		if (pc_debug >= 5)
+			printk("0x%.2x ", pts_reply[i]);
+	}
+	printk("\n");
+#endif	/* PCMCIA_DEBUG */
+
+	DEBUGP(5, dev, "Clear Tactive in Flags1\n");
+	xoutb(0x20, REG_FLAGS1(iobase));
+
+	/* Compare ptsreq and ptsreply */
+	if ((dev->pts[0] == pts_reply[0]) &&
+	    (dev->pts[1] == pts_reply[1]) &&
+	    (dev->pts[2] == pts_reply[2]) && (dev->pts[3] == pts_reply[3])) {
+		/* setcardparameter according to PPS */
+		dev->baudv = calc_baudv(dev->pts[2]);
+		set_cardparameter(dev);
+	} else if ((dev->pts[0] == pts_reply[0]) &&
+		   ((dev->pts[1] & 0xef) == pts_reply[1]) &&
+		   ((pts_reply[0] ^ pts_reply[1]) == pts_reply[2])) {
+		/* short PTS reply, set card parameter to default values */
+		dev->baudv = calc_baudv(0x11);
+		set_cardparameter(dev);
+	} else
+		rc = -EIO;
+
+exit_setprotocol:
+	DEBUGP(3, dev, "<- set_protocol\n");
+	return rc;
+}
+
+static int io_detect_cm4000(ioaddr_t iobase, struct cm4000_dev *dev)
+{
+
+	/* note: statemachine is assumed to be reset */
+	if (inb(REG_FLAGS0(iobase)) & 8) {
+		clear_bit(IS_ATR_VALID, &dev->flags);
+		set_bit(IS_CMM_ABSENT, &dev->flags);
+		return 0;	/* detect CMM = 1 -> failure */
+	}
+	/* xoutb(0x40, REG_FLAGS1(iobase)); detectCMM */
+	xoutb(dev->flags1 | 0x40, REG_FLAGS1(iobase));
+	if ((inb(REG_FLAGS0(iobase)) & 8) == 0) {
+		clear_bit(IS_ATR_VALID, &dev->flags);
+		set_bit(IS_CMM_ABSENT, &dev->flags);
+		return 0;	/* detect CMM=0 -> failure */
+	}
+	/* clear detectCMM again by restoring original flags1 */
+	xoutb(dev->flags1, REG_FLAGS1(iobase));
+	return 1;
+}
+
+static void terminate_monitor(struct cm4000_dev *dev)
+{
+
+	/* tell the monitor to stop and wait until
+	 * it terminates.
+	 */
+	DEBUGP(3, dev, "-> terminate_monitor\n");
+	wait_event_interruptible(dev->devq,
+				 test_and_set_bit(LOCK_MONITOR,
+						  (void *)&dev->flags));
+
+	/* now, LOCK_MONITOR has been set.
+	 * allow a last cycle in the monitor.
+	 * the monitor will indicate that it has
+	 * finished by clearing this bit.
+	 */
+	DEBUGP(5, dev, "Now allow last cycle of monitor!\n");
+	while (test_bit(LOCK_MONITOR, (void *)&dev->flags))
+		msleep(25);
+
+	DEBUGP(5, dev, "Delete timer\n");
+	del_timer_sync(&dev->timer);
+#ifdef PCMCIA_DEBUG
+	dev->monitor_running = 0;
+#endif
+
+	DEBUGP(3, dev, "<- terminate_monitor\n");
+}
+
+/*
+ * monitor the card every 50msec. as a side-effect, retrieve the
+ * atr once a card is inserted. another side-effect of retrieving the
+ * atr is that the card will be powered on, so there is no need to
+ * power on the card explictely from the application: the driver
+ * is already doing that for you.
+ */
+
+static void monitor_card(unsigned long p)
+{
+	struct cm4000_dev *dev = (struct cm4000_dev *) p;
+	ioaddr_t iobase = dev->link.io.BasePort1;
+	unsigned short s;
+	struct ptsreq ptsreq;
+	int i, atrc;
+
+	DEBUGP(7, dev, "->  monitor_card\n");
+
+	/* if someone has set the lock for us: we're done! */
+	if (test_and_set_bit(LOCK_MONITOR, &dev->flags)) {
+		DEBUGP(4, dev, "About to stop monitor\n");
+		/* no */
+		dev->rlen =
+		    dev->rpos =
+		    dev->atr_csum = dev->atr_len_retry = dev->cwarn = 0;
+		dev->mstate = M_FETCH_ATR;
+		clear_bit(LOCK_MONITOR, &dev->flags);
+		/* close et al. are sleeping on devq, so wake it */
+		wake_up_interruptible(&dev->devq);
+		DEBUGP(2, dev, "<- monitor_card (we are done now)\n");
+		return;
+	}
+
+	/* try to lock io: if it is already locked, just add another timer */
+	if (test_and_set_bit(LOCK_IO, (void *)&dev->flags)) {
+		DEBUGP(4, dev, "Couldn't get IO lock\n");
+		goto return_with_timer;
+	}
+
+	/* is a card/a reader inserted at all ? */
+	dev->flags0 = xinb(REG_FLAGS0(iobase));
+	DEBUGP(7, dev, "dev->flags0 = 0x%2x\n", dev->flags0);
+	DEBUGP(7, dev, "smartcard present: %s\n",
+	       dev->flags0 & 1 ? "yes" : "no");
+	DEBUGP(7, dev, "cardman present: %s\n",
+	       dev->flags0 == 0xff ? "no" : "yes");
+
+	if ((dev->flags0 & 1) == 0	/* no smartcard inserted */
+	    || dev->flags0 == 0xff) {	/* no cardman inserted */
+		/* no */
+		dev->rlen =
+		    dev->rpos =
+		    dev->atr_csum = dev->atr_len_retry = dev->cwarn = 0;
+		dev->mstate = M_FETCH_ATR;
+
+		dev->flags &= 0x000000ff; /* only keep IO and MONITOR locks */
+
+		if (dev->flags0 == 0xff) {
+			DEBUGP(4, dev, "set IS_CMM_ABSENT bit\n");
+			set_bit(IS_CMM_ABSENT, &dev->flags);
+		} else if (test_bit(IS_CMM_ABSENT, &dev->flags)) {
+			DEBUGP(4, dev, "clear IS_CMM_ABSENT bit "
+			       "(card is removed)\n");
+			clear_bit(IS_CMM_ABSENT, &dev->flags);
+		}
+
+		goto release_io;
+	} else if ((dev->flags0 & 1) && test_bit(IS_CMM_ABSENT, &dev->flags)) {
+		/* cardman and card present but cardman was absent before
+		 * (after suspend with inserted card) */
+		DEBUGP(4, dev, "clear IS_CMM_ABSENT bit (card is inserted)\n");
+		clear_bit(IS_CMM_ABSENT, &dev->flags);
+	}
+
+	if (test_bit(IS_ATR_VALID, &dev->flags) == 1) {
+		DEBUGP(7, dev, "believe ATR is already valid (do nothing)\n");
+		goto release_io;
+	}
+
+	switch (dev->mstate) {
+		unsigned char flags0;
+	case M_CARDOFF:
+		DEBUGP(4, dev, "M_CARDOFF\n");
+		flags0 = inb(REG_FLAGS0(iobase));
+		if (flags0 & 0x02) {
+			/* wait until Flags0 indicate power is off */
+			dev->mdelay = T_10MSEC;
+		} else {
+			/* Flags0 indicate power off and no card inserted now;
+			 * Reset CARDMAN CONTROLLER */
+			xoutb(0x80, REG_FLAGS0(iobase));
+
+			/* prepare for fetching ATR again: after card off ATR
+			 * is read again automatically */
+			dev->rlen =
+			    dev->rpos =
+			    dev->atr_csum =
+			    dev->atr_len_retry = dev->cwarn = 0;
+			dev->mstate = M_FETCH_ATR;
+
+			/* minimal gap between CARDOFF and read ATR is 50msec */
+			dev->mdelay = T_50MSEC;
+		}
+		break;
+	case M_FETCH_ATR:
+		DEBUGP(4, dev, "M_FETCH_ATR\n");
+		xoutb(0x80, REG_FLAGS0(iobase));
+		DEBUGP(4, dev, "Reset BAUDV to 9600\n");
+		dev->baudv = 0x173;	/* 9600 */
+		xoutb(0x02, REG_STOPBITS(iobase));	/* stopbits=2 */
+		xoutb(0x73, REG_BAUDRATE(iobase));	/* baud value */
+		xoutb(0x21, REG_FLAGS1(iobase));	/* T_Active=1, baud
+							   value */
+		/* warm start vs. power on: */
+		xoutb(dev->flags0 & 2 ? 0x46 : 0x44, REG_FLAGS0(iobase));
+		dev->mdelay = T_40MSEC;
+		dev->mstate = M_TIMEOUT_WAIT;
+		break;
+	case M_TIMEOUT_WAIT:
+		DEBUGP(4, dev, "M_TIMEOUT_WAIT\n");
+		/* numRecBytes */
+		io_read_num_rec_bytes(iobase, &dev->atr_len);
+		dev->mdelay = T_10MSEC;
+		dev->mstate = M_READ_ATR_LEN;
+		break;
+	case M_READ_ATR_LEN:
+		DEBUGP(4, dev, "M_READ_ATR_LEN\n");
+		/* infinite loop possible, since there is no timeout */
+
+#define	MAX_ATR_LEN_RETRY	100
+
+		if (dev->atr_len == io_read_num_rec_bytes(iobase, &s)) {
+			if (dev->atr_len_retry++ >= MAX_ATR_LEN_RETRY) {					/* + XX msec */
+				dev->mdelay = T_10MSEC;
+				dev->mstate = M_READ_ATR;
+			}
+		} else {
+			dev->atr_len = s;
+			dev->atr_len_retry = 0;	/* set new timeout */
+		}
+
+		DEBUGP(4, dev, "Current ATR_LEN = %i\n", dev->atr_len);
+		break;
+	case M_READ_ATR:
+		DEBUGP(4, dev, "M_READ_ATR\n");
+		xoutb(0x80, REG_FLAGS0(iobase));	/* reset SM */
+		for (i = 0; i < dev->atr_len; i++) {
+			xoutb(i, REG_BUF_ADDR(iobase));
+			dev->atr[i] = inb(REG_BUF_DATA(iobase));
+		}
+		/* Deactivate T_Active flags */
+		DEBUGP(4, dev, "Deactivate T_Active flags\n");
+		dev->flags1 = 0x01;
+		xoutb(dev->flags1, REG_FLAGS1(iobase));
+
+		/* atr is present (which doesnt mean it's valid) */
+		set_bit(IS_ATR_PRESENT, &dev->flags);
+		if (dev->atr[0] == 0x03)
+			str_invert_revert(dev->atr, dev->atr_len);
+		atrc = parse_atr(dev);
+		if (atrc == 0) {	/* atr invalid */
+			dev->mdelay = 0;
+			dev->mstate = M_BAD_CARD;
+		} else {
+			dev->mdelay = T_50MSEC;
+			dev->mstate = M_ATR_PRESENT;
+			set_bit(IS_ATR_VALID, &dev->flags);
+		}
+
+		if (test_bit(IS_ATR_VALID, &dev->flags) == 1) {
+			DEBUGP(4, dev, "monitor_card: ATR valid\n");
+ 			/* if ta1 == 0x11, no PPS necessary (default values) */
+			/* do not do PPS with multi protocol cards */
+			if ((test_bit(IS_AUTOPPS_ACT, &dev->flags) == 0) &&
+			    (dev->ta1 != 0x11) &&
+			    !(test_bit(IS_ANY_T0, &dev->flags) &&
+			    test_bit(IS_ANY_T1, &dev->flags))) {
+				DEBUGP(4, dev, "Perform AUTOPPS\n");
+				set_bit(IS_AUTOPPS_ACT, &dev->flags);
+				ptsreq.protocol = ptsreq.protocol =
+				    (0x01 << dev->proto);
+				ptsreq.flags = 0x01;
+				ptsreq.pts1 = 0x00;
+				ptsreq.pts2 = 0x00;
+				ptsreq.pts3 = 0x00;
+				if (set_protocol(dev, &ptsreq) == 0) {
+					DEBUGP(4, dev, "AUTOPPS ret SUCC\n");
+					clear_bit(IS_AUTOPPS_ACT, &dev->flags);
+					wake_up_interruptible(&dev->atrq);
+				} else {
+					DEBUGP(4, dev, "AUTOPPS failed: "
+					       "repower using defaults\n");
+					/* prepare for repowering  */
+					clear_bit(IS_ATR_PRESENT, &dev->flags);
+					clear_bit(IS_ATR_VALID, &dev->flags);
+					dev->rlen =
+					    dev->rpos =
+					    dev->atr_csum =
+					    dev->atr_len_retry = dev->cwarn = 0;
+					dev->mstate = M_FETCH_ATR;
+
+					dev->mdelay = T_50MSEC;
+				}
+			} else {
+				/* for cards which use slightly different
+				 * params (extra guard time) */
+				set_cardparameter(dev);
+				if (test_bit(IS_AUTOPPS_ACT, &dev->flags) == 1)
+					DEBUGP(4, dev, "AUTOPPS already active "
+					       "2nd try:use default values\n");
+				if (dev->ta1 == 0x11)
+					DEBUGP(4, dev, "No AUTOPPS necessary "
+					       "TA(1)==0x11\n");
+				if (test_bit(IS_ANY_T0, &dev->flags)
+				    && test_bit(IS_ANY_T1, &dev->flags))
+					DEBUGP(4, dev, "Do NOT perform AUTOPPS "
+					       "with multiprotocol cards\n");
+				clear_bit(IS_AUTOPPS_ACT, &dev->flags);
+				wake_up_interruptible(&dev->atrq);
+			}
+		} else {
+			DEBUGP(4, dev, "ATR invalid\n");
+			wake_up_interruptible(&dev->atrq);
+		}
+		break;
+	case M_BAD_CARD:
+		DEBUGP(4, dev, "M_BAD_CARD\n");
+		/* slow down warning, but prompt immediately after insertion */
+		if (dev->cwarn == 0 || dev->cwarn == 10) {
+			set_bit(IS_BAD_CARD, &dev->flags);
+			printk(KERN_WARNING MODULE_NAME ": device %s: ",
+			       dev->node.dev_name);
+			if (test_bit(IS_BAD_CSUM, &dev->flags)) {
+				DEBUGP(4, dev, "ATR checksum (0x%.2x, should "
+				       "be zero) failed\n", dev->atr_csum);
+			}
+#ifdef PCMCIA_DEBUG
+			else if (test_bit(IS_BAD_LENGTH, &dev->flags)) {
+				DEBUGP(4, dev, "ATR length error\n");
+			} else {
+				DEBUGP(4, dev, "card damaged or wrong way "
+					"inserted\n");
+			}
+#endif
+			dev->cwarn = 0;
+			wake_up_interruptible(&dev->atrq);	/* wake open */
+		}
+		dev->cwarn++;
+		dev->mdelay = T_100MSEC;
+		dev->mstate = M_FETCH_ATR;
+		break;
+	default:
+		DEBUGP(7, dev, "Unknown action\n");
+		break;		/* nothing */
+	}
+
+release_io:
+	DEBUGP(7, dev, "release_io\n");
+	clear_bit(LOCK_IO, &dev->flags);
+	wake_up_interruptible(&dev->ioq);	/* whoever needs IO */
+
+return_with_timer:
+	DEBUGP(7, dev, "<- monitor_card (returns with timer)\n");
+	dev->timer.expires = jiffies + dev->mdelay;
+	add_timer(&dev->timer);
+	clear_bit(LOCK_MONITOR, &dev->flags);
+}
+
+/* Interface to userland (file_operations) */
+
+static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
+			loff_t *ppos)
+{
+	struct cm4000_dev *dev = filp->private_data;
+	ioaddr_t iobase = dev->link.io.BasePort1;
+	ssize_t rc;
+	int i, j, k;
+
+	DEBUGP(2, dev, "-> cmm_read(%s,%d)\n", current->comm, current->pid);
+
+	if (count == 0)		/* according to manpage */
+		return 0;
+
+	if ((dev->link.state & DEV_PRESENT) == 0 ||	/* socket removed */
+	    test_bit(IS_CMM_ABSENT, &dev->flags))
+		return -ENODEV;
+
+	if (test_bit(IS_BAD_CSUM, &dev->flags))
+		return -EIO;
+
+	/* also see the note about this in cmm_write */
+	if (wait_event_interruptible
+	    (dev->atrq,
+	     ((filp->f_flags & O_NONBLOCK)
+	      || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) {
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		return -ERESTARTSYS;
+	}
+
+	if (test_bit(IS_ATR_VALID, &dev->flags) == 0)
+		return -EIO;
+
+	/* this one implements blocking IO */
+	if (wait_event_interruptible
+	    (dev->readq,
+	     ((filp->f_flags & O_NONBLOCK) || (dev->rpos < dev->rlen)))) {
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		return -ERESTARTSYS;
+	}
+
+	/* lock io */
+	if (wait_event_interruptible
+	    (dev->ioq,
+	     ((filp->f_flags & O_NONBLOCK)
+	      || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) {
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		return -ERESTARTSYS;
+	}
+
+	rc = 0;
+	dev->flags0 = inb(REG_FLAGS0(iobase));
+	if ((dev->flags0 & 1) == 0	/* no smartcard inserted */
+	    || dev->flags0 == 0xff) {	/* no cardman inserted */
+		clear_bit(IS_ATR_VALID, &dev->flags);
+		if (dev->flags0 & 1) {
+			set_bit(IS_CMM_ABSENT, &dev->flags);
+			rc = -ENODEV;
+		}
+		rc = -EIO;
+		goto release_io;
+	}
+
+	DEBUGP(4, dev, "begin read answer\n");
+	j = min(count, (size_t)(dev->rlen - dev->rpos));
+	k = dev->rpos;
+	if (k + j > 255)
+		j = 256 - k;
+	DEBUGP(4, dev, "read1 j=%d\n", j);
+	for (i = 0; i < j; i++) {
+		xoutb(k++, REG_BUF_ADDR(iobase));
+		dev->rbuf[i] = xinb(REG_BUF_DATA(iobase));
+	}
+	j = min(count, (size_t)(dev->rlen - dev->rpos));
+	if (k + j > 255) {
+		DEBUGP(4, dev, "read2 j=%d\n", j);
+		dev->flags1 |= 0x10;	/* MSB buf addr set */
+		xoutb(dev->flags1, REG_FLAGS1(iobase));
+		for (; i < j; i++) {
+			xoutb(k++, REG_BUF_ADDR(iobase));
+			dev->rbuf[i] = xinb(REG_BUF_DATA(iobase));
+		}
+	}
+
+	if (dev->proto == 0 && count > dev->rlen - dev->rpos) {
+		DEBUGP(4, dev, "T=0 and count > buffer\n");
+		dev->rbuf[i] = dev->rbuf[i - 1];
+		dev->rbuf[i - 1] = dev->procbyte;
+		j++;
+	}
+	count = j;
+
+	dev->rpos = dev->rlen + 1;
+
+	/* Clear T1Active */
+	DEBUGP(4, dev, "Clear T1Active\n");
+	dev->flags1 &= 0xdf;
+	xoutb(dev->flags1, REG_FLAGS1(iobase));
+
+	xoutb(0, REG_FLAGS1(iobase));	/* clear detectCMM */
+	/* last check before exit */
+	if (!io_detect_cm4000(iobase, dev))
+		count = -ENODEV;
+
+	if (test_bit(IS_INVREV, &dev->flags) && count > 0)
+		str_invert_revert(dev->rbuf, count);
+
+	if (copy_to_user(buf, dev->rbuf, count))
+		return -EFAULT;
+
+release_io:
+	clear_bit(LOCK_IO, &dev->flags);
+	wake_up_interruptible(&dev->ioq);
+
+	DEBUGP(2, dev, "<- cmm_read returns: rc = %Zi\n",
+	       (rc < 0 ? rc : count));
+	return rc < 0 ? rc : count;
+}
+
+static ssize_t cmm_write(struct file *filp, const char __user *buf,
+			 size_t count, loff_t *ppos)
+{
+	struct cm4000_dev *dev = (struct cm4000_dev *) filp->private_data;
+	ioaddr_t iobase = dev->link.io.BasePort1;
+	unsigned short s;
+	unsigned char tmp;
+	unsigned char infolen;
+	unsigned char sendT0;
+	unsigned short nsend;
+	unsigned short nr;
+	ssize_t rc;
+	int i;
+
+	DEBUGP(2, dev, "-> cmm_write(%s,%d)\n", current->comm, current->pid);
+
+	if (count == 0)		/* according to manpage */
+		return 0;
+
+	if (dev->proto == 0 && count < 4) {
+		/* T0 must have at least 4 bytes */
+		DEBUGP(4, dev, "T0 short write\n");
+		return -EIO;
+	}
+
+	nr = count & 0x1ff;	/* max bytes to write */
+
+	sendT0 = dev->proto ? 0 : nr > 5 ? 0x08 : 0;
+
+	if ((dev->link.state & DEV_PRESENT) == 0 ||	/* socket removed */
+	    test_bit(IS_CMM_ABSENT, &dev->flags))
+		return -ENODEV;
+
+	if (test_bit(IS_BAD_CSUM, &dev->flags)) {
+		DEBUGP(4, dev, "bad csum\n");
+		return -EIO;
+	}
+
+	/*
+	 * wait for atr to become valid.
+	 * note: it is important to lock this code. if we dont, the monitor
+	 * could be run between test_bit and the the call the sleep on the
+	 * atr-queue.  if *then* the monitor detects atr valid, it will wake up
+	 * any process on the atr-queue, *but* since we have been interrupted,
+	 * we do not yet sleep on this queue. this would result in a missed
+	 * wake_up and the calling process would sleep forever (until
+	 * interrupted).  also, do *not* restore_flags before sleep_on, because
+	 * this could result in the same situation!
+	 */
+	if (wait_event_interruptible
+	    (dev->atrq,
+	     ((filp->f_flags & O_NONBLOCK)
+	      || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) != 0)))) {
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		return -ERESTARTSYS;
+	}
+
+	if (test_bit(IS_ATR_VALID, &dev->flags) == 0) {	/* invalid atr */
+		DEBUGP(4, dev, "invalid ATR\n");
+		return -EIO;
+	}
+
+	/* lock io */
+	if (wait_event_interruptible
+	    (dev->ioq,
+	     ((filp->f_flags & O_NONBLOCK)
+	      || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) == 0)))) {
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+		return -ERESTARTSYS;
+	}
+
+	if (copy_from_user(dev->sbuf, buf, ((count > 512) ? 512 : count)))
+		return -EFAULT;
+
+	rc = 0;
+	dev->flags0 = inb(REG_FLAGS0(iobase));
+	if ((dev->flags0 & 1) == 0	/* no smartcard inserted */
+	    || dev->flags0 == 0xff) {	/* no cardman inserted */
+		clear_bit(IS_ATR_VALID, &dev->flags);
+		if (dev->flags0 & 1) {
+			set_bit(IS_CMM_ABSENT, &dev->flags);
+			rc = -ENODEV;
+		} else {
+			DEBUGP(4, dev, "IO error\n");
+			rc = -EIO;
+		}
+		goto release_io;
+	}
+
+	xoutb(0x80, REG_FLAGS0(iobase));	/* reset SM  */
+
+	if (!io_detect_cm4000(iobase, dev)) {
+		rc = -ENODEV;
+		goto release_io;
+	}
+
+	/* reflect T=0 send/read mode in flags1 */
+	dev->flags1 |= (sendT0);
+
+	set_cardparameter(dev);
+
+	/* dummy read, reset flag procedure received */
+	tmp = inb(REG_FLAGS1(iobase));
+
+	dev->flags1 = 0x20	/* T_Active */
+	    | (sendT0)
+	    | (test_bit(IS_INVREV, &dev->flags) ? 2 : 0)/* inverse parity  */
+	    | (((dev->baudv - 1) & 0x0100) >> 8);	/* MSB-Baud */
+	DEBUGP(1, dev, "set dev->flags1 = 0x%.2x\n", dev->flags1);
+	xoutb(dev->flags1, REG_FLAGS1(iobase));
+
+	/* xmit data */
+	DEBUGP(4, dev, "Xmit data\n");
+	for (i = 0; i < nr; i++) {
+		if (i >= 256) {
+			dev->flags1 = 0x20	/* T_Active */
+			    | (sendT0)	/* SendT0 */
+				/* inverse parity: */
+			    | (test_bit(IS_INVREV, &dev->flags) ? 2 : 0)
+			    | (((dev->baudv - 1) & 0x0100) >> 8) /* MSB-Baud */
+			    | 0x10;	/* set address high */
+			DEBUGP(4, dev, "dev->flags = 0x%.2x - set address "
+			       "high\n", dev->flags1);
+			xoutb(dev->flags1, REG_FLAGS1(iobase));
+		}
+		if (test_bit(IS_INVREV, &dev->flags)) {
+			DEBUGP(4, dev, "Apply inverse convention for 0x%.2x "
+				"-> 0x%.2x\n", (unsigned char)dev->sbuf[i],
+			      invert_revert(dev->sbuf[i]));
+			xoutb(i, REG_BUF_ADDR(iobase));
+			xoutb(invert_revert(dev->sbuf[i]),
+			      REG_BUF_DATA(iobase));
+		} else {
+			xoutb(i, REG_BUF_ADDR(iobase));
+			xoutb(dev->sbuf[i], REG_BUF_DATA(iobase));
+		}
+	}
+	DEBUGP(4, dev, "Xmit done\n");
+
+	if (dev->proto == 0) {
+		/* T=0 proto: 0 byte reply  */
+		if (nr == 4) {
+			DEBUGP(4, dev, "T=0 assumes 0 byte reply\n");
+			xoutb(i, REG_BUF_ADDR(iobase));
+			if (test_bit(IS_INVREV, &dev->flags))
+				xoutb(0xff, REG_BUF_DATA(iobase));
+			else
+				xoutb(0x00, REG_BUF_DATA(iobase));
+		}
+
+		/* numSendBytes */
+		if (sendT0)
+			nsend = nr;
+		else {
+			if (nr == 4)
+				nsend = 5;
+			else {
+				nsend = 5 + (unsigned char)dev->sbuf[4];
+				if (dev->sbuf[4] == 0)
+					nsend += 0x100;
+			}
+		}
+	} else
+		nsend = nr;
+
+	/* T0: output procedure byte */
+	if (test_bit(IS_INVREV, &dev->flags)) {
+		DEBUGP(4, dev, "T=0 set Procedure byte (inverse-reverse) "
+		       "0x%.2x\n", invert_revert(dev->sbuf[1]));
+		xoutb(invert_revert(dev->sbuf[1]), REG_NUM_BYTES(iobase));
+	} else {
+		DEBUGP(4, dev, "T=0 set Procedure byte 0x%.2x\n", dev->sbuf[1]);
+		xoutb(dev->sbuf[1], REG_NUM_BYTES(iobase));
+	}
+
+	DEBUGP(1, dev, "set NumSendBytes = 0x%.2x\n",
+	       (unsigned char)(nsend & 0xff));
+	xoutb((unsigned char)(nsend & 0xff), REG_NUM_SEND(iobase));
+
+	DEBUGP(1, dev, "Trigger CARDMAN CONTROLLER (0x%.2x)\n",
+	       0x40	/* SM_Active */
+	      | (dev->flags0 & 2 ? 0 : 4)	/* power on if needed */
+	      |(dev->proto ? 0x10 : 0x08)	/* T=1/T=0 */
+	      |(nsend & 0x100) >> 8 /* MSB numSendBytes */ );
+	xoutb(0x40		/* SM_Active */
+	      | (dev->flags0 & 2 ? 0 : 4)	/* power on if needed */
+	      |(dev->proto ? 0x10 : 0x08)	/* T=1/T=0 */
+	      |(nsend & 0x100) >> 8,	/* MSB numSendBytes */
+	      REG_FLAGS0(iobase));
+
+	/* wait for xmit done */
+	if (dev->proto == 1) {
+		DEBUGP(4, dev, "Wait for xmit done\n");
+		for (i = 0; i < 1000; i++) {
+			if (inb(REG_FLAGS0(iobase)) & 0x08)
+				break;
+			msleep_interruptible(10);
+		}
+		if (i == 1000) {
+			DEBUGP(4, dev, "timeout waiting for xmit done\n");
+			rc = -EIO;
+			goto release_io;
+		}
+	}
+
+	/* T=1: wait for infoLen */
+
+	infolen = 0;
+	if (dev->proto) {
+		/* wait until infoLen is valid */
+		for (i = 0; i < 6000; i++) {	/* max waiting time of 1 min */
+			io_read_num_rec_bytes(iobase, &s);
+			if (s >= 3) {
+				infolen = inb(REG_FLAGS1(iobase));
+				DEBUGP(4, dev, "infolen=%d\n", infolen);
+				break;
+			}
+			msleep_interruptible(10);
+		}
+		if (i == 6000) {
+			DEBUGP(4, dev, "timeout waiting for infoLen\n");
+			rc = -EIO;
+			goto release_io;
+		}
+	} else
+		clear_bit(IS_PROCBYTE_PRESENT, &dev->flags);
+
+	/* numRecBytes | bit9 of numRecytes */
+	io_read_num_rec_bytes(iobase, &dev->rlen);
+	for (i = 0; i < 600; i++) {	/* max waiting time of 2 sec */
+		if (dev->proto) {
+			if (dev->rlen >= infolen + 4)
+				break;
+		}
+		msleep_interruptible(10);
+		/* numRecBytes | bit9 of numRecytes */
+		io_read_num_rec_bytes(iobase, &s);
+		if (s > dev->rlen) {
+			DEBUGP(1, dev, "NumRecBytes inc (reset timeout)\n");
+			i = 0;	/* reset timeout */
+			dev->rlen = s;
+		}
+		/* T=0: we are done when numRecBytes doesn't
+		 *      increment any more and NoProcedureByte
+		 *      is set and numRecBytes == bytes sent + 6
+		 *      (header bytes + data + 1 for sw2)
+		 *      except when the card replies an error
+		 *      which means, no data will be sent back.
+		 */
+		else if (dev->proto == 0) {
+			if ((inb(REG_BUF_ADDR(iobase)) & 0x80)) {
+				/* no procedure byte received since last read */
+				DEBUGP(1, dev, "NoProcedure byte set\n");
+				/* i=0; */
+			} else {
+				/* procedure byte received since last read */
+				DEBUGP(1, dev, "NoProcedure byte unset "
+					"(reset timeout)\n");
+				dev->procbyte = inb(REG_FLAGS1(iobase));
+				DEBUGP(1, dev, "Read procedure byte 0x%.2x\n",
+				      dev->procbyte);
+				i = 0;	/* resettimeout */
+			}
+			if (inb(REG_FLAGS0(iobase)) & 0x08) {
+				DEBUGP(1, dev, "T0Done flag (read reply)\n");
+				break;
+			}
+		}
+		if (dev->proto)
+			infolen = inb(REG_FLAGS1(iobase));
+	}
+	if (i == 600) {
+		DEBUGP(1, dev, "timeout waiting for numRecBytes\n");
+		rc = -EIO;
+		goto release_io;
+	} else {
+		if (dev->proto == 0) {
+			DEBUGP(1, dev, "Wait for T0Done bit to be  set\n");
+			for (i = 0; i < 1000; i++) {
+				if (inb(REG_FLAGS0(iobase)) & 0x08)
+					break;
+				msleep_interruptible(10);
+			}
+			if (i == 1000) {
+				DEBUGP(1, dev, "timeout waiting for T0Done\n");
+				rc = -EIO;
+				goto release_io;
+			}
+
+			dev->procbyte = inb(REG_FLAGS1(iobase));
+			DEBUGP(4, dev, "Read procedure byte 0x%.2x\n",
+			      dev->procbyte);
+
+			io_read_num_rec_bytes(iobase, &dev->rlen);
+			DEBUGP(4, dev, "Read NumRecBytes = %i\n", dev->rlen);
+
+		}
+	}
+	/* T=1: read offset=zero, T=0: read offset=after challenge */
+	dev->rpos = dev->proto ? 0 : nr == 4 ? 5 : nr > dev->rlen ? 5 : nr;
+	DEBUGP(4, dev, "dev->rlen = %i,  dev->rpos = %i, nr = %i\n",
+	      dev->rlen, dev->rpos, nr);
+
+release_io:
+	DEBUGP(4, dev, "Reset SM\n");
+	xoutb(0x80, REG_FLAGS0(iobase));	/* reset SM */
+
+	if (rc < 0) {
+		DEBUGP(4, dev, "Write failed but clear T_Active\n");
+		dev->flags1 &= 0xdf;
+		xoutb(dev->flags1, REG_FLAGS1(iobase));
+	}
+
+	clear_bit(LOCK_IO, &dev->flags);
+	wake_up_interruptible(&dev->ioq);
+	wake_up_interruptible(&dev->readq);	/* tell read we have data */
+
+	/* ITSEC E2: clear write buffer */
+	memset((char *)dev->sbuf, 0, 512);
+
+	/* return error or actually written bytes */
+	DEBUGP(2, dev, "<- cmm_write\n");
+	return rc < 0 ? rc : nr;
+}
+
+static void start_monitor(struct cm4000_dev *dev)
+{
+	DEBUGP(3, dev, "-> start_monitor\n");
+	if (!dev->monitor_running) {
+		DEBUGP(5, dev, "create, init and add timer\n");
+		init_timer(&dev->timer);
+		dev->monitor_running = 1;
+		dev->timer.expires = jiffies;
+		dev->timer.data = (unsigned long) dev;
+		dev->timer.function = monitor_card;
+		add_timer(&dev->timer);
+	} else
+		DEBUGP(5, dev, "monitor already running\n");
+	DEBUGP(3, dev, "<- start_monitor\n");
+}
+
+static void stop_monitor(struct cm4000_dev *dev)
+{
+	DEBUGP(3, dev, "-> stop_monitor\n");
+	if (dev->monitor_running) {
+		DEBUGP(5, dev, "stopping monitor\n");
+		terminate_monitor(dev);
+		/* reset monitor SM */
+		clear_bit(IS_ATR_VALID, &dev->flags);
+		clear_bit(IS_ATR_PRESENT, &dev->flags);
+	} else
+		DEBUGP(5, dev, "monitor already stopped\n");
+	DEBUGP(3, dev, "<- stop_monitor\n");
+}
+
+static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
+		     unsigned long arg)
+{
+	struct cm4000_dev *dev = filp->private_data;
+	ioaddr_t iobase = dev->link.io.BasePort1;
+	dev_link_t *link;
+	int size;
+	int rc;
+#ifdef PCMCIA_DEBUG
+	char *ioctl_names[CM_IOC_MAXNR + 1] = {
+		[_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS",
+		[_IOC_NR(CM_IOCGATR)] "CM_IOCGATR",
+		[_IOC_NR(CM_IOCARDOFF)] "CM_IOCARDOFF",
+		[_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS",
+		[_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL",
+	};
+#endif
+	DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode),
+	       iminor(inode), ioctl_names[_IOC_NR(cmd)]);
+
+	link = dev_table[iminor(inode)];
+	if (!(DEV_OK(link))) {
+		DEBUGP(4, dev, "DEV_OK false\n");
+		return -ENODEV;
+	}
+
+	if (test_bit(IS_CMM_ABSENT, &dev->flags)) {
+		DEBUGP(4, dev, "CMM_ABSENT flag set\n");
+		return -ENODEV;
+	}
+
+	if (_IOC_TYPE(cmd) != CM_IOC_MAGIC) {
+		DEBUGP(4, dev, "ioctype mismatch\n");
+		return -EINVAL;
+	}
+	if (_IOC_NR(cmd) > CM_IOC_MAXNR) {
+		DEBUGP(4, dev, "iocnr mismatch\n");
+		return -EINVAL;
+	}
+	size = _IOC_SIZE(cmd);
+	rc = 0;
+	DEBUGP(4, dev, "iocdir=%.4x iocr=%.4x iocw=%.4x iocsize=%d cmd=%.4x\n",
+	      _IOC_DIR(cmd), _IOC_READ, _IOC_WRITE, size, cmd);
+
+	if (_IOC_DIR(cmd) & _IOC_READ) {
+		if (!access_ok(VERIFY_WRITE, (void *)arg, size))
+			return -EFAULT;
+	}
+	if (_IOC_DIR(cmd) & _IOC_WRITE) {
+		if (!access_ok(VERIFY_READ, (void *)arg, size))
+			return -EFAULT;
+	}
+
+	switch (cmd) {
+	case CM_IOCGSTATUS:
+		DEBUGP(4, dev, " ... in CM_IOCGSTATUS\n");
+		{
+			int status;
+
+			/* clear other bits, but leave inserted & powered as
+			 * they are */
+			status = dev->flags0 & 3;
+			if (test_bit(IS_ATR_PRESENT, &dev->flags))
+				status |= CM_ATR_PRESENT;
+			if (test_bit(IS_ATR_VALID, &dev->flags))
+				status |= CM_ATR_VALID;
+			if (test_bit(IS_CMM_ABSENT, &dev->flags))
+				status |= CM_NO_READER;
+			if (test_bit(IS_BAD_CARD, &dev->flags))
+				status |= CM_BAD_CARD;
+			if (copy_to_user((int *)arg, &status, sizeof(int)))
+				return -EFAULT;
+		}
+		return 0;
+	case CM_IOCGATR:
+		DEBUGP(4, dev, "... in CM_IOCGATR\n");
+		{
+			struct atreq *atreq = (struct atreq *) arg;
+			int tmp;
+			/* allow nonblocking io and being interrupted */
+			if (wait_event_interruptible
+			    (dev->atrq,
+			     ((filp->f_flags & O_NONBLOCK)
+			      || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags)
+				  != 0)))) {
+				if (filp->f_flags & O_NONBLOCK)
+					return -EAGAIN;
+				return -ERESTARTSYS;
+			}
+
+			if (test_bit(IS_ATR_VALID, &dev->flags) == 0) {
+				tmp = -1;
+				if (copy_to_user(&(atreq->atr_len), &tmp,
+						 sizeof(int)))
+					return -EFAULT;
+			} else {
+				if (copy_to_user(atreq->atr, dev->atr,
+						 dev->atr_len))
+					return -EFAULT;
+
+				tmp = dev->atr_len;
+				if (copy_to_user(&(atreq->atr_len), &tmp, sizeof(int)))
+					return -EFAULT;
+			}
+			return 0;
+		}
+	case CM_IOCARDOFF:
+
+#ifdef PCMCIA_DEBUG
+		DEBUGP(4, dev, "... in CM_IOCARDOFF\n");
+		if (dev->flags0 & 0x01) {
+			DEBUGP(4, dev, "    Card inserted\n");
+		} else {
+			DEBUGP(2, dev, "    No card inserted\n");
+		}
+		if (dev->flags0 & 0x02) {
+			DEBUGP(4, dev, "    Card powered\n");
+		} else {
+			DEBUGP(2, dev, "    Card not powered\n");
+		}
+#endif
+
+		/* is a card inserted and powered? */
+		if ((dev->flags0 & 0x01) && (dev->flags0 & 0x02)) {
+
+			/* get IO lock */
+			if (wait_event_interruptible
+			    (dev->ioq,
+			     ((filp->f_flags & O_NONBLOCK)
+			      || (test_and_set_bit(LOCK_IO, (void *)&dev->flags)
+				  == 0)))) {
+				if (filp->f_flags & O_NONBLOCK)
+					return -EAGAIN;
+				return -ERESTARTSYS;
+			}
+			/* Set Flags0 = 0x42 */
+			DEBUGP(4, dev, "Set Flags0=0x42 \n");
+			xoutb(0x42, REG_FLAGS0(iobase));
+			clear_bit(IS_ATR_PRESENT, &dev->flags);
+			clear_bit(IS_ATR_VALID, &dev->flags);
+			dev->mstate = M_CARDOFF;
+			clear_bit(LOCK_IO, &dev->flags);
+			if (wait_event_interruptible
+			    (dev->atrq,
+			     ((filp->f_flags & O_NONBLOCK)
+			      || (test_bit(IS_ATR_VALID, (void *)&dev->flags) !=
+				  0)))) {
+				if (filp->f_flags & O_NONBLOCK)
+					return -EAGAIN;
+				return -ERESTARTSYS;
+			}
+		}
+		/* release lock */
+		clear_bit(LOCK_IO, &dev->flags);
+		wake_up_interruptible(&dev->ioq);
+
+		return 0;
+	case CM_IOCSPTS:
+		{
+			struct ptsreq krnptsreq;
+
+			if (copy_from_user(&krnptsreq, (struct ptsreq *) arg,
+					   sizeof(struct ptsreq)))
+				return -EFAULT;
+
+			rc = 0;
+			DEBUGP(4, dev, "... in CM_IOCSPTS\n");
+			/* wait for ATR to get valid */
+			if (wait_event_interruptible
+			    (dev->atrq,
+			     ((filp->f_flags & O_NONBLOCK)
+			      || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags)
+				  != 0)))) {
+				if (filp->f_flags & O_NONBLOCK)
+					return -EAGAIN;
+				return -ERESTARTSYS;
+			}
+			/* get IO lock */
+			if (wait_event_interruptible
+			    (dev->ioq,
+			     ((filp->f_flags & O_NONBLOCK)
+			      || (test_and_set_bit(LOCK_IO, (void *)&dev->flags)
+				  == 0)))) {
+				if (filp->f_flags & O_NONBLOCK)
+					return -EAGAIN;
+				return -ERESTARTSYS;
+			}
+
+			if ((rc = set_protocol(dev, &krnptsreq)) != 0) {
+				/* auto power_on again */
+				dev->mstate = M_FETCH_ATR;
+				clear_bit(IS_ATR_VALID, &dev->flags);
+			}
+			/* release lock */
+			clear_bit(LOCK_IO, &dev->flags);
+			wake_up_interruptible(&dev->ioq);
+
+		}
+		return rc;
+#ifdef PCMCIA_DEBUG
+	case CM_IOSDBGLVL:	/* set debug log level */
+		{
+			int old_pc_debug = 0;
+
+			old_pc_debug = pc_debug;
+			if (copy_from_user(&pc_debug, (int *)arg, sizeof(int)))
+				return -EFAULT;
+
+			if (old_pc_debug != pc_debug)
+				DEBUGP(0, dev, "Changed debug log level "
+				       "to %i\n", pc_debug);
+		}
+		return rc;
+#endif
+	default:
+		DEBUGP(4, dev, "... in default (unknown IOCTL code)\n");
+		return -EINVAL;
+	}
+}
+
+static int cmm_open(struct inode *inode, struct file *filp)
+{
+	struct cm4000_dev *dev;
+	dev_link_t *link;
+	int rc, minor = iminor(inode);
+
+	if (minor >= CM4000_MAX_DEV)
+		return -ENODEV;
+
+	link = dev_table[minor];
+	if (link == NULL || !(DEV_OK(link)))
+		return -ENODEV;
+
+	if (link->open)
+		return -EBUSY;
+
+	dev = link->priv;
+	filp->private_data = dev;
+
+	DEBUGP(2, dev, "-> cmm_open(device=%d.%d process=%s,%d)\n",
+	      imajor(inode), minor, current->comm, current->pid);
+
+	/* init device variables, they may be "polluted" after close
+	 * or, the device may never have been closed (i.e. open failed)
+	 */
+
+	ZERO_DEV(dev);
+
+	/* opening will always block since the
+	 * monitor will be started by open, which
+	 * means we have to wait for ATR becoming
+	 * vaild = block until valid (or card
+	 * inserted)
+	 */
+	if (filp->f_flags & O_NONBLOCK)
+		return -EAGAIN;
+
+	dev->mdelay = T_50MSEC;
+
+	/* start monitoring the cardstatus */
+	start_monitor(dev);
+
+	link->open = 1;		/* only one open per device */
+	rc = 0;
+
+	DEBUGP(2, dev, "<- cmm_open\n");
+	return nonseekable_open(inode, filp);
+}
+
+static int cmm_close(struct inode *inode, struct file *filp)
+{
+	struct cm4000_dev *dev;
+	dev_link_t *link;
+	int minor = iminor(inode);
+
+	if (minor >= CM4000_MAX_DEV)
+		return -ENODEV;
+
+	link = dev_table[minor];
+	if (link == NULL)
+		return -ENODEV;
+
+	dev = link->priv;
+
+	DEBUGP(2, dev, "-> cmm_close(maj/min=%d.%d)\n",
+	       imajor(inode), minor);
+
+	stop_monitor(dev);
+
+	ZERO_DEV(dev);
+
+	link->open = 0;		/* only one open per device */
+	wake_up(&dev->devq);	/* socket removed? */
+
+	DEBUGP(2, dev, "cmm_close\n");
+	return 0;
+}
+
+static void cmm_cm4000_release(dev_link_t * link)
+{
+	struct cm4000_dev *dev = link->priv;
+
+	/* dont terminate the monitor, rather rely on
+	 * close doing that for us.
+	 */
+	DEBUGP(3, dev, "-> cmm_cm4000_release\n");
+	while (link->open) {
+		printk(KERN_INFO MODULE_NAME ": delaying release until "
+		       "process has terminated\n");
+		/* note: don't interrupt us:
+		 * close the applications which own
+		 * the devices _first_ !
+		 */
+		wait_event(dev->devq, (link->open == 0));
+	}
+	/* dev->devq=NULL;	this cannot be zeroed earlier */
+	DEBUGP(3, dev, "<- cmm_cm4000_release\n");
+	return;
+}
+
+/*==== Interface to PCMCIA Layer =======================================*/
+
+static void cm4000_config(dev_link_t * link, int devno)
+{
+	client_handle_t handle = link->handle;
+	struct cm4000_dev *dev;
+	tuple_t tuple;
+	cisparse_t parse;
+	config_info_t conf;
+	u_char buf[64];
+	int fail_fn, fail_rc;
+	int rc;
+
+	/* read the config-tuples */
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	tuple.Attributes = 0;
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = sizeof(buf);
+	tuple.TupleOffset = 0;
+
+	if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) {
+		fail_fn = GetFirstTuple;
+		goto cs_failed;
+	}
+	if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) {
+		fail_fn = GetTupleData;
+		goto cs_failed;
+	}
+	if ((fail_rc =
+	     pcmcia_parse_tuple(handle, &tuple, &parse)) != CS_SUCCESS) {
+		fail_fn = ParseTuple;
+		goto cs_failed;
+	}
+	if ((fail_rc =
+	     pcmcia_get_configuration_info(handle, &conf)) != CS_SUCCESS) {
+		fail_fn = GetConfigurationInfo;
+		goto cs_failed;
+	}
+
+	link->state |= DEV_CONFIG;
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present = parse.config.rmask[0];
+	link->conf.Vcc = conf.Vcc;
+
+	link->io.BasePort2 = 0;
+	link->io.NumPorts2 = 0;
+	link->io.Attributes2 = 0;
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	for (rc = pcmcia_get_first_tuple(handle, &tuple);
+	     rc == CS_SUCCESS; rc = pcmcia_get_next_tuple(handle, &tuple)) {
+
+		rc = pcmcia_get_tuple_data(handle, &tuple);
+		if (rc != CS_SUCCESS)
+			continue;
+		rc = pcmcia_parse_tuple(handle, &tuple, &parse);
+		if (rc != CS_SUCCESS)
+			continue;
+
+		link->conf.ConfigIndex = parse.cftable_entry.index;
+
+		if (!parse.cftable_entry.io.nwin)
+			continue;
+
+		/* Get the IOaddr */
+		link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
+		link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
+		link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+		if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT))
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+		if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT))
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+		link->io.IOAddrLines = parse.cftable_entry.io.flags
+		    & CISTPL_IO_LINES_MASK;
+
+		rc = pcmcia_request_io(handle, &link->io);
+		if (rc == CS_SUCCESS)
+			break;	/* we are done */
+	}
+	if (rc != CS_SUCCESS)
+		goto cs_release;
+
+	link->conf.IntType = 00000002;
+
+	if ((fail_rc =
+	     pcmcia_request_configuration(handle, &link->conf)) != CS_SUCCESS) {
+		fail_fn = RequestConfiguration;
+		goto cs_release;
+	}
+
+	dev = link->priv;
+	sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno);
+	dev->node.major = major;
+	dev->node.minor = devno;
+	dev->node.next = NULL;
+	link->dev = &dev->node;
+	link->state &= ~DEV_CONFIG_PENDING;
+
+	return;
+
+cs_failed:
+	cs_error(handle, fail_fn, fail_rc);
+cs_release:
+	cm4000_release(link);
+
+	link->state &= ~DEV_CONFIG_PENDING;
+}
+
+static int cm4000_event(event_t event, int priority,
+			event_callback_args_t *args)
+{
+	dev_link_t *link;
+	struct cm4000_dev *dev;
+	int devno;
+
+	link = args->client_data;
+	dev = link->priv;
+
+	DEBUGP(3, dev, "-> cm4000_event\n");
+	for (devno = 0; devno < CM4000_MAX_DEV; devno++)
+		if (dev_table[devno] == link)
+			break;
+
+	if (devno == CM4000_MAX_DEV)
+		return CS_BAD_ADAPTER;
+
+	switch (event) {
+	case CS_EVENT_CARD_INSERTION:
+		DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n");
+		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+		cm4000_config(link, devno);
+		break;
+	case CS_EVENT_CARD_REMOVAL:
+		DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
+		link->state &= ~DEV_PRESENT;
+		stop_monitor(dev);
+		break;
+	case CS_EVENT_PM_SUSPEND:
+		DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
+		      "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
+		link->state |= DEV_SUSPEND;
+		/* fall-through */
+	case CS_EVENT_RESET_PHYSICAL:
+		DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
+		if (link->state & DEV_CONFIG) {
+			DEBUGP(5, dev, "ReleaseConfiguration\n");
+			pcmcia_release_configuration(link->handle);
+		}
+		stop_monitor(dev);
+		break;
+	case CS_EVENT_PM_RESUME:
+		DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
+		      "(fall-through to CS_EVENT_CARD_RESET)\n");
+		link->state &= ~DEV_SUSPEND;
+		/* fall-through */
+	case CS_EVENT_CARD_RESET:
+		DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
+		if ((link->state & DEV_CONFIG)) {
+			DEBUGP(5, dev, "RequestConfiguration\n");
+			pcmcia_request_configuration(link->handle, &link->conf);
+		}
+		if (link->open)
+			start_monitor(dev);
+		break;
+	default:
+		DEBUGP(5, dev, "unknown event %.2x\n", event);
+		break;
+	}
+	DEBUGP(3, dev, "<- cm4000_event\n");
+	return CS_SUCCESS;
+}
+
+static void cm4000_release(dev_link_t *link)
+{
+	cmm_cm4000_release(link->priv);	/* delay release until device closed */
+	pcmcia_release_configuration(link->handle);
+	pcmcia_release_io(link->handle, &link->io);
+}
+
+static dev_link_t *cm4000_attach(void)
+{
+	struct cm4000_dev *dev;
+	dev_link_t *link;
+	client_reg_t client_reg;
+	int i;
+
+	for (i = 0; i < CM4000_MAX_DEV; i++)
+		if (dev_table[i] == NULL)
+			break;
+
+	if (i == CM4000_MAX_DEV) {
+		printk(KERN_NOTICE MODULE_NAME ": all devices in use\n");
+		return NULL;
+	}
+
+	/* create a new cm4000_cs device */
+	dev = kzalloc(sizeof(struct cm4000_dev), GFP_KERNEL);
+	if (dev == NULL)
+		return NULL;
+
+	link = &dev->link;
+	link->priv = dev;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+	dev_table[i] = link;
+
+	/* register with card services */
+	client_reg.dev_info = &dev_info;
+	client_reg.EventMask =
+	    CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+	    CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+	    CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+	client_reg.Version = 0x0210;
+	client_reg.event_callback_args.client_data = link;
+
+	i = pcmcia_register_client(&link->handle, &client_reg);
+	if (i) {
+		cs_error(link->handle, RegisterClient, i);
+		cm4000_detach(link);
+		return NULL;
+	}
+
+	init_waitqueue_head(&dev->devq);
+	init_waitqueue_head(&dev->ioq);
+	init_waitqueue_head(&dev->atrq);
+	init_waitqueue_head(&dev->readq);
+
+	return link;
+}
+
+static void cm4000_detach_by_devno(int devno, dev_link_t * link)
+{
+	struct cm4000_dev *dev = link->priv;
+
+	DEBUGP(3, dev, "-> detach_by_devno(devno=%d)\n", devno);
+
+	if (link->state & DEV_CONFIG) {
+		DEBUGP(5, dev, "device still configured (try to release it)\n");
+		cm4000_release(link);
+	}
+
+	if (link->handle) {
+		pcmcia_deregister_client(link->handle);
+	}
+
+	dev_table[devno] = NULL;
+	kfree(dev);
+	return;
+}
+
+static void cm4000_detach(dev_link_t * link)
+{
+	int i;
+
+	/* find device */
+	for (i = 0; i < CM4000_MAX_DEV; i++)
+		if (dev_table[i] == link)
+			break;
+
+	if (i == CM4000_MAX_DEV)
+		return;
+
+	cm4000_detach_by_devno(i, link);
+	return;
+}
+
+static struct file_operations cm4000_fops = {
+	.owner	= THIS_MODULE,
+	.read	= cmm_read,
+	.write	= cmm_write,
+	.ioctl	= cmm_ioctl,
+	.open	= cmm_open,
+	.release= cmm_close,
+};
+
+static struct pcmcia_device_id cm4000_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x0223, 0x0002),
+	PCMCIA_DEVICE_PROD_ID12("CardMan", "4000", 0x2FB368CA, 0xA2BD8C39),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, cm4000_ids);
+
+static struct pcmcia_driver cm4000_driver = {
+	.owner	  = THIS_MODULE,
+	.drv	  = {
+		.name = "cm4000_cs",
+		},
+	.attach   = cm4000_attach,
+	.detach   = cm4000_detach,
+	.event	  = cm4000_event,
+	.id_table = cm4000_ids,
+};
+
+static int __init cmm_init(void)
+{
+	printk(KERN_INFO "%s\n", version);
+	pcmcia_register_driver(&cm4000_driver);
+	major = register_chrdev(0, DEVICE_NAME, &cm4000_fops);
+	if (major < 0) {
+		printk(KERN_WARNING MODULE_NAME
+			": could not get major number\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static void __exit cmm_exit(void)
+{
+	int i;
+
+	printk(KERN_INFO MODULE_NAME ": unloading\n");
+	pcmcia_unregister_driver(&cm4000_driver);
+	for (i = 0; i < CM4000_MAX_DEV; i++)
+		if (dev_table[i])
+			cm4000_detach_by_devno(i, dev_table[i]);
+	unregister_chrdev(major, DEVICE_NAME);
+};
+
+module_init(cmm_init);
+module_exit(cmm_exit);
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
new file mode 100644
index 0000000..4c698d9
--- /dev/null
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -0,0 +1,841 @@
+/*
+ * A driver for the Omnikey PCMCIA smartcard reader CardMan 4040
+ *
+ * (c) 2000-2004 Omnikey AG (http://www.omnikey.com/)
+ *
+ * (C) 2005 Harald Welte <laforge@gnumonks.org>
+ * 	- add support for poll()
+ * 	- driver cleanup
+ * 	- add waitqueues
+ * 	- adhere to linux kernel coding style and policies
+ * 	- support 2.6.13 "new style" pcmcia interface
+ *
+ * The device basically is a USB CCID compliant device that has been
+ * attached to an I/O-Mapped FIFO.
+ *
+ * All rights reserved, Dual BSD/GPL Licensed.
+ */
+
+/* #define PCMCIA_DEBUG 6 */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ciscode.h>
+#include <pcmcia/ds.h>
+
+#include "cm4040_cs.h"
+
+
+#ifdef PCMCIA_DEBUG
+#define reader_to_dev(x)	(&handle_to_dev(x->link.handle))
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0600);
+#define DEBUGP(n, rdr, x, args...) do { 				\
+	if (pc_debug >= (n)) 						\
+		dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, 	\
+			   __FUNCTION__ , ##args); 			\
+	} while (0)
+#else
+#define DEBUGP(n, rdr, x, args...)
+#endif
+
+static char *version =
+"OMNIKEY CardMan 4040 v1.1.0gm4 - All bugs added by Harald Welte";
+
+#define	CCID_DRIVER_BULK_DEFAULT_TIMEOUT  	(150*HZ)
+#define	CCID_DRIVER_ASYNC_POWERUP_TIMEOUT 	(35*HZ)
+#define	CCID_DRIVER_MINIMUM_TIMEOUT 		(3*HZ)
+#define READ_WRITE_BUFFER_SIZE 512
+#define POLL_LOOP_COUNT				1000
+
+/* how often to poll for fifo status change */
+#define POLL_PERIOD 				msecs_to_jiffies(10)
+
+static void reader_release(dev_link_t *link);
+static void reader_detach(dev_link_t *link);
+
+static int major;
+
+#define		BS_READABLE	0x01
+#define		BS_WRITABLE	0x02
+
+struct reader_dev {
+	dev_link_t		link;
+	dev_node_t		node;
+	wait_queue_head_t	devq;
+	wait_queue_head_t	poll_wait;
+	wait_queue_head_t	read_wait;
+	wait_queue_head_t	write_wait;
+	unsigned long 	  	buffer_status;
+	unsigned long     	timeout;
+	unsigned char     	s_buf[READ_WRITE_BUFFER_SIZE];
+	unsigned char     	r_buf[READ_WRITE_BUFFER_SIZE];
+	struct timer_list 	poll_timer;
+};
+
+static dev_info_t dev_info = MODULE_NAME;
+static dev_link_t *dev_table[CM_MAX_DEV];
+
+#ifndef PCMCIA_DEBUG
+#define	xoutb	outb
+#define	xinb	inb
+#else
+static inline void xoutb(unsigned char val, unsigned short port)
+{
+	if (pc_debug >= 7)
+		printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
+	outb(val, port);
+}
+
+static inline unsigned char xinb(unsigned short port)
+{
+	unsigned char val;
+
+	val = inb(port);
+	if (pc_debug >= 7)
+		printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
+	return val;
+}
+#endif
+
+/* poll the device fifo status register.  not to be confused with
+ * the poll syscall. */
+static void cm4040_do_poll(unsigned long dummy)
+{
+	struct reader_dev *dev = (struct reader_dev *) dummy;
+	unsigned int obs = xinb(dev->link.io.BasePort1
+				+ REG_OFFSET_BUFFER_STATUS);
+
+	if ((obs & BSR_BULK_IN_FULL)) {
+		set_bit(BS_READABLE, &dev->buffer_status);
+		DEBUGP(4, dev, "waking up read_wait\n");
+		wake_up_interruptible(&dev->read_wait);
+	} else
+		clear_bit(BS_READABLE, &dev->buffer_status);
+
+	if (!(obs & BSR_BULK_OUT_FULL)) {
+		set_bit(BS_WRITABLE, &dev->buffer_status);
+		DEBUGP(4, dev, "waking up write_wait\n");
+		wake_up_interruptible(&dev->write_wait);
+	} else
+		clear_bit(BS_WRITABLE, &dev->buffer_status);
+
+	if (dev->buffer_status)
+		wake_up_interruptible(&dev->poll_wait);
+
+	mod_timer(&dev->poll_timer, jiffies + POLL_PERIOD);
+}
+
+static void cm4040_stop_poll(struct reader_dev *dev)
+{
+	del_timer_sync(&dev->poll_timer);
+}
+
+static int wait_for_bulk_out_ready(struct reader_dev *dev)
+{
+	int i, rc;
+	int iobase = dev->link.io.BasePort1;
+
+	for (i = 0; i < POLL_LOOP_COUNT; i++) {
+		if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS)
+		    & BSR_BULK_OUT_FULL) == 0) {
+			DEBUGP(4, dev, "BulkOut empty (i=%d)\n", i);
+			return 1;
+		}
+	}
+
+	DEBUGP(4, dev, "wait_event_interruptible_timeout(timeout=%ld\n",
+		dev->timeout);
+	rc = wait_event_interruptible_timeout(dev->write_wait,
+					      test_and_clear_bit(BS_WRITABLE,
+						       &dev->buffer_status),
+					      dev->timeout);
+
+	if (rc > 0)
+		DEBUGP(4, dev, "woke up: BulkOut empty\n");
+	else if (rc == 0)
+		DEBUGP(4, dev, "woke up: BulkOut full, returning 0 :(\n");
+	else if (rc < 0)
+		DEBUGP(4, dev, "woke up: signal arrived\n");
+
+	return rc;
+}
+
+/* Write to Sync Control Register */
+static int write_sync_reg(unsigned char val, struct reader_dev *dev)
+{
+	int iobase = dev->link.io.BasePort1;
+	int rc;
+
+	rc = wait_for_bulk_out_ready(dev);
+	if (rc <= 0)
+		return rc;
+
+	xoutb(val, iobase + REG_OFFSET_SYNC_CONTROL);
+	rc = wait_for_bulk_out_ready(dev);
+	if (rc <= 0)
+		return rc;
+
+	return 1;
+}
+
+static int wait_for_bulk_in_ready(struct reader_dev *dev)
+{
+	int i, rc;
+	int iobase = dev->link.io.BasePort1;
+
+	for (i = 0; i < POLL_LOOP_COUNT; i++) {
+		if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS)
+		    & BSR_BULK_IN_FULL) == BSR_BULK_IN_FULL) {
+			DEBUGP(3, dev, "BulkIn full (i=%d)\n", i);
+			return 1;
+		}
+	}
+
+	DEBUGP(4, dev, "wait_event_interruptible_timeout(timeout=%ld\n",
+		dev->timeout);
+	rc = wait_event_interruptible_timeout(dev->read_wait,
+					      test_and_clear_bit(BS_READABLE,
+						 	&dev->buffer_status),
+					      dev->timeout);
+	if (rc > 0)
+		DEBUGP(4, dev, "woke up: BulkIn full\n");
+	else if (rc == 0)
+		DEBUGP(4, dev, "woke up: BulkIn not full, returning 0 :(\n");
+	else if (rc < 0)
+		DEBUGP(4, dev, "woke up: signal arrived\n");
+
+	return rc;
+}
+
+static ssize_t cm4040_read(struct file *filp, char __user *buf,
+			size_t count, loff_t *ppos)
+{
+	struct reader_dev *dev = filp->private_data;
+	int iobase = dev->link.io.BasePort1;
+	size_t bytes_to_read;
+	unsigned long i;
+	size_t min_bytes_to_read;
+	int rc;
+	unsigned char uc;
+
+	DEBUGP(2, dev, "-> cm4040_read(%s,%d)\n", current->comm, current->pid);
+
+	if (count == 0)
+		return 0;
+
+	if (count < 10)
+		return -EFAULT;
+
+	if (filp->f_flags & O_NONBLOCK) {
+		DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n");
+		DEBUGP(2, dev, "<- cm4040_read (failure)\n");
+		return -EAGAIN;
+	}
+
+	if ((dev->link.state & DEV_PRESENT)==0)
+		return -ENODEV;
+
+	for (i = 0; i < 5; i++) {
+		rc = wait_for_bulk_in_ready(dev);
+		if (rc <= 0) {
+			DEBUGP(5, dev, "wait_for_bulk_in_ready rc=%.2x\n", rc);
+			DEBUGP(2, dev, "<- cm4040_read (failed)\n");
+			if (rc == -ERESTARTSYS)
+				return rc;
+			return -EIO;
+		}
+	  	dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN);
+#ifdef PCMCIA_DEBUG
+		if (pc_debug >= 6)
+			printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
+	}
+	printk("\n");
+#else
+	}
+#endif
+
+	bytes_to_read = 5 + le32_to_cpu(*(__le32 *)&dev->r_buf[1]);
+
+	DEBUGP(6, dev, "BytesToRead=%lu\n", bytes_to_read);
+
+	min_bytes_to_read = min(count, bytes_to_read + 5);
+
+	DEBUGP(6, dev, "Min=%lu\n", min_bytes_to_read);
+
+	for (i = 0; i < (min_bytes_to_read-5); i++) {
+		rc = wait_for_bulk_in_ready(dev);
+		if (rc <= 0) {
+			DEBUGP(5, dev, "wait_for_bulk_in_ready rc=%.2x\n", rc);
+			DEBUGP(2, dev, "<- cm4040_read (failed)\n");
+			if (rc == -ERESTARTSYS)
+				return rc;
+			return -EIO;
+		}
+		dev->r_buf[i+5] = xinb(iobase + REG_OFFSET_BULK_IN);
+#ifdef PCMCIA_DEBUG
+		if (pc_debug >= 6)
+			printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
+	}
+	printk("\n");
+#else
+	}
+#endif
+
+	*ppos = min_bytes_to_read;
+	if (copy_to_user(buf, dev->r_buf, min_bytes_to_read))
+		return -EFAULT;
+
+	rc = wait_for_bulk_in_ready(dev);
+	if (rc <= 0) {
+		DEBUGP(5, dev, "wait_for_bulk_in_ready rc=%.2x\n", rc);
+		DEBUGP(2, dev, "<- cm4040_read (failed)\n");
+		if (rc == -ERESTARTSYS)
+			return rc;
+		return -EIO;
+	}
+
+	rc = write_sync_reg(SCR_READER_TO_HOST_DONE, dev);
+	if (rc <= 0) {
+		DEBUGP(5, dev, "write_sync_reg c=%.2x\n", rc);
+		DEBUGP(2, dev, "<- cm4040_read (failed)\n");
+		if (rc == -ERESTARTSYS)
+			return rc;
+		else
+			return -EIO;
+	}
+
+	uc = xinb(iobase + REG_OFFSET_BULK_IN);
+
+	DEBUGP(2, dev, "<- cm4040_read (successfully)\n");
+	return min_bytes_to_read;
+}
+
+static ssize_t cm4040_write(struct file *filp, const char __user *buf,
+			 size_t count, loff_t *ppos)
+{
+	struct reader_dev *dev = filp->private_data;
+	int iobase = dev->link.io.BasePort1;
+	ssize_t rc;
+	int i;
+	unsigned int bytes_to_write;
+
+	DEBUGP(2, dev, "-> cm4040_write(%s,%d)\n", current->comm, current->pid);
+
+	if (count == 0) {
+		DEBUGP(2, dev, "<- cm4040_write empty read (successfully)\n");
+		return 0;
+	}
+
+	if (count < 5) {
+		DEBUGP(2, dev, "<- cm4040_write buffersize=%Zd < 5\n", count);
+		return -EIO;
+	}
+
+	if (filp->f_flags & O_NONBLOCK) {
+		DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n");
+		DEBUGP(4, dev, "<- cm4040_write (failure)\n");
+		return -EAGAIN;
+	}
+
+	if ((dev->link.state & DEV_PRESENT) == 0)
+		return -ENODEV;
+
+	bytes_to_write = count;
+	if (copy_from_user(dev->s_buf, buf, bytes_to_write))
+		return -EFAULT;
+
+	switch (dev->s_buf[0]) {
+		case CMD_PC_TO_RDR_XFRBLOCK:
+		case CMD_PC_TO_RDR_SECURE:
+		case CMD_PC_TO_RDR_TEST_SECURE:
+		case CMD_PC_TO_RDR_OK_SECURE:
+			dev->timeout = CCID_DRIVER_BULK_DEFAULT_TIMEOUT;
+			break;
+
+		case CMD_PC_TO_RDR_ICCPOWERON:
+			dev->timeout = CCID_DRIVER_ASYNC_POWERUP_TIMEOUT;
+			break;
+
+		case CMD_PC_TO_RDR_GETSLOTSTATUS:
+		case CMD_PC_TO_RDR_ICCPOWEROFF:
+		case CMD_PC_TO_RDR_GETPARAMETERS:
+		case CMD_PC_TO_RDR_RESETPARAMETERS:
+		case CMD_PC_TO_RDR_SETPARAMETERS:
+		case CMD_PC_TO_RDR_ESCAPE:
+		case CMD_PC_TO_RDR_ICCCLOCK:
+		default:
+			dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
+			break;
+	}
+
+	rc = write_sync_reg(SCR_HOST_TO_READER_START, dev);
+	if (rc <= 0) {
+		DEBUGP(5, dev, "write_sync_reg c=%.2Zx\n", rc);
+		DEBUGP(2, dev, "<- cm4040_write (failed)\n");
+		if (rc == -ERESTARTSYS)
+			return rc;
+		else
+			return -EIO;
+	}
+
+	DEBUGP(4, dev, "start \n");
+
+	for (i = 0; i < bytes_to_write; i++) {
+		rc = wait_for_bulk_out_ready(dev);
+		if (rc <= 0) {
+			DEBUGP(5, dev, "wait_for_bulk_out_ready rc=%.2Zx\n",
+			       rc);
+			DEBUGP(2, dev, "<- cm4040_write (failed)\n");
+			if (rc == -ERESTARTSYS)
+				return rc;
+			else
+				return -EIO;
+		}
+
+		xoutb(dev->s_buf[i],iobase + REG_OFFSET_BULK_OUT);
+	}
+	DEBUGP(4, dev, "end\n");
+
+	rc = write_sync_reg(SCR_HOST_TO_READER_DONE, dev);
+
+	if (rc <= 0) {
+		DEBUGP(5, dev, "write_sync_reg c=%.2Zx\n", rc);
+		DEBUGP(2, dev, "<- cm4040_write (failed)\n");
+		if (rc == -ERESTARTSYS)
+			return rc;
+		else
+			return -EIO;
+	}
+
+	DEBUGP(2, dev, "<- cm4040_write (successfully)\n");
+	return count;
+}
+
+static unsigned int cm4040_poll(struct file *filp, poll_table *wait)
+{
+	struct reader_dev *dev = filp->private_data;
+	unsigned int mask = 0;
+
+	poll_wait(filp, &dev->poll_wait, wait);
+
+	if (test_and_clear_bit(BS_READABLE, &dev->buffer_status))
+		mask |= POLLIN | POLLRDNORM;
+	if (test_and_clear_bit(BS_WRITABLE, &dev->buffer_status))
+		mask |= POLLOUT | POLLWRNORM;
+
+	DEBUGP(2, dev, "<- cm4040_poll(%u)\n", mask);
+
+	return mask;
+}
+
+static int cm4040_open(struct inode *inode, struct file *filp)
+{
+	struct reader_dev *dev;
+	dev_link_t *link;
+	int minor = iminor(inode);
+
+	if (minor >= CM_MAX_DEV)
+		return -ENODEV;
+
+	link = dev_table[minor];
+	if (link == NULL || !(DEV_OK(link)))
+		return -ENODEV;
+
+	if (link->open)
+		return -EBUSY;
+
+	dev = link->priv;
+	filp->private_data = dev;
+
+	if (filp->f_flags & O_NONBLOCK) {
+		DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n");
+		return -EAGAIN;
+	}
+
+	link->open = 1;
+
+	dev->poll_timer.data = (unsigned long) dev;
+	mod_timer(&dev->poll_timer, jiffies + POLL_PERIOD);
+
+	DEBUGP(2, dev, "<- cm4040_open (successfully)\n");
+	return nonseekable_open(inode, filp);
+}
+
+static int cm4040_close(struct inode *inode, struct file *filp)
+{
+	struct reader_dev *dev = filp->private_data;
+	dev_link_t *link;
+	int minor = iminor(inode);
+
+	DEBUGP(2, dev, "-> cm4040_close(maj/min=%d.%d)\n", imajor(inode),
+	      iminor(inode));
+
+	if (minor >= CM_MAX_DEV)
+		return -ENODEV;
+
+	link = dev_table[minor];
+	if (link == NULL)
+		return -ENODEV;
+
+	cm4040_stop_poll(dev);
+
+	link->open = 0;
+	wake_up(&dev->devq);
+
+	DEBUGP(2, dev, "<- cm4040_close\n");
+	return 0;
+}
+
+static void cm4040_reader_release(dev_link_t *link)
+{
+	struct reader_dev *dev = link->priv;
+
+	DEBUGP(3, dev, "-> cm4040_reader_release\n");
+	while (link->open) {
+		DEBUGP(3, dev, KERN_INFO MODULE_NAME ": delaying release "
+		       "until process has terminated\n");
+ 		wait_event(dev->devq, (link->open == 0));
+	}
+	DEBUGP(3, dev, "<- cm4040_reader_release\n");
+	return;
+}
+
+static void reader_config(dev_link_t *link, int devno)
+{
+	client_handle_t handle;
+	struct reader_dev *dev;
+	tuple_t tuple;
+	cisparse_t parse;
+	config_info_t conf;
+	u_char buf[64];
+	int fail_fn, fail_rc;
+	int rc;
+
+	handle = link->handle;
+
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	tuple.Attributes = 0;
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = sizeof(buf);
+ 	tuple.TupleOffset = 0;
+
+	if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) {
+		fail_fn = GetFirstTuple;
+		goto cs_failed;
+	}
+	if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) {
+		fail_fn = GetTupleData;
+		goto cs_failed;
+	}
+	if ((fail_rc = pcmcia_parse_tuple(handle, &tuple, &parse))
+							!= CS_SUCCESS) {
+		fail_fn = ParseTuple;
+		goto cs_failed;
+	}
+	if ((fail_rc = pcmcia_get_configuration_info(handle, &conf))
+							!= CS_SUCCESS) {
+		fail_fn = GetConfigurationInfo;
+		goto cs_failed;
+	}
+
+	link->state |= DEV_CONFIG;
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present = parse.config.rmask[0];
+	link->conf.Vcc = conf.Vcc;
+
+	link->io.BasePort2 = 0;
+	link->io.NumPorts2 = 0;
+	link->io.Attributes2 = 0;
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	for (rc = pcmcia_get_first_tuple(handle, &tuple);
+	     rc == CS_SUCCESS;
+	     rc = pcmcia_get_next_tuple(handle, &tuple)) {
+		rc = pcmcia_get_tuple_data(handle, &tuple);
+		if (rc != CS_SUCCESS)
+			continue;
+		rc = pcmcia_parse_tuple(handle, &tuple, &parse);
+		if (rc != CS_SUCCESS)
+			continue;
+
+		link->conf.ConfigIndex = parse.cftable_entry.index;
+
+		if (!parse.cftable_entry.io.nwin)
+			continue;
+
+		link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
+		link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
+		link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+		if (!(parse.cftable_entry.io.flags & CISTPL_IO_8BIT))
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+		if (!(parse.cftable_entry.io.flags & CISTPL_IO_16BIT))
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+		link->io.IOAddrLines = parse.cftable_entry.io.flags
+						& CISTPL_IO_LINES_MASK;
+		rc = pcmcia_request_io(handle, &link->io);
+
+		dev_printk(KERN_INFO, &handle_to_dev(handle), "foo");
+		if (rc == CS_SUCCESS)
+			break;
+		else
+			dev_printk(KERN_INFO, &handle_to_dev(handle),
+				   "pcmcia_request_io failed 0x%x\n", rc);
+	}
+	if (rc != CS_SUCCESS)
+		goto cs_release;
+
+	link->conf.IntType = 00000002;
+
+	if ((fail_rc = pcmcia_request_configuration(handle,&link->conf))
+								!=CS_SUCCESS) {
+		fail_fn = RequestConfiguration;
+		dev_printk(KERN_INFO, &handle_to_dev(handle),
+			   "pcmcia_request_configuration failed 0x%x\n",
+			   fail_rc);
+		goto cs_release;
+	}
+
+	dev = link->priv;
+	sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno);
+	dev->node.major = major;
+	dev->node.minor = devno;
+	dev->node.next = NULL;
+	link->dev = &dev->node;
+	link->state &= ~DEV_CONFIG_PENDING;
+
+	DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno,
+	      link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1);
+	DEBUGP(2, dev, "<- reader_config (succ)\n");
+
+	return;
+
+cs_failed:
+	cs_error(handle, fail_fn, fail_rc);
+cs_release:
+	reader_release(link);
+	link->state &= ~DEV_CONFIG_PENDING;
+}
+
+static int reader_event(event_t event, int priority,
+			event_callback_args_t *args)
+{
+	dev_link_t *link;
+	struct reader_dev *dev;
+	int devno;
+
+	link = args->client_data;
+	dev = link->priv;
+	DEBUGP(3, dev, "-> reader_event\n");
+	for (devno = 0; devno < CM_MAX_DEV; devno++) {
+		if (dev_table[devno] == link)
+			break;
+	}
+	if (devno == CM_MAX_DEV)
+		return CS_BAD_ADAPTER;
+
+	switch (event) {
+		case CS_EVENT_CARD_INSERTION:
+			DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n");
+			link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+			reader_config(link, devno);
+			break;
+		case CS_EVENT_CARD_REMOVAL:
+			DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
+			link->state &= ~DEV_PRESENT;
+			break;
+		case CS_EVENT_PM_SUSPEND:
+			DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
+			      "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
+			link->state |= DEV_SUSPEND;
+
+		case CS_EVENT_RESET_PHYSICAL:
+			DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
+			if (link->state & DEV_CONFIG) {
+		  		DEBUGP(5, dev, "ReleaseConfiguration\n");
+		  		pcmcia_release_configuration(link->handle);
+			}
+			break;
+		case CS_EVENT_PM_RESUME:
+			DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
+			      "(fall-through to CS_EVENT_CARD_RESET)\n");
+			link->state &= ~DEV_SUSPEND;
+
+		case CS_EVENT_CARD_RESET:
+			DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
+			if ((link->state & DEV_CONFIG)) {
+				DEBUGP(5, dev, "RequestConfiguration\n");
+		  		pcmcia_request_configuration(link->handle,
+							     &link->conf);
+			}
+			break;
+		default:
+			DEBUGP(5, dev, "reader_event: unknown event %.2x\n",
+			       event);
+			break;
+	}
+	DEBUGP(3, dev, "<- reader_event\n");
+	return CS_SUCCESS;
+}
+
+static void reader_release(dev_link_t *link)
+{
+	cm4040_reader_release(link->priv);
+	pcmcia_release_configuration(link->handle);
+	pcmcia_release_io(link->handle, &link->io);
+}
+
+static dev_link_t *reader_attach(void)
+{
+	struct reader_dev *dev;
+	dev_link_t *link;
+	client_reg_t client_reg;
+	int i;
+
+	for (i = 0; i < CM_MAX_DEV; i++) {
+		if (dev_table[i] == NULL)
+			break;
+	}
+
+	if (i == CM_MAX_DEV)
+		return NULL;
+
+	dev = kzalloc(sizeof(struct reader_dev), GFP_KERNEL);
+	if (dev == NULL)
+		return NULL;
+
+	dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
+	dev->buffer_status = 0;
+
+	link = &dev->link;
+	link->priv = dev;
+
+	link->conf.IntType = INT_MEMORY_AND_IO;
+	dev_table[i] = link;
+
+	client_reg.dev_info = &dev_info;
+	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+	client_reg.EventMask=
+		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+		CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+	client_reg.Version = 0x0210;
+	client_reg.event_callback_args.client_data = link;
+	i = pcmcia_register_client(&link->handle, &client_reg);
+	if (i) {
+		cs_error(link->handle, RegisterClient, i);
+		reader_detach(link);
+		return NULL;
+	}
+	init_waitqueue_head(&dev->devq);
+	init_waitqueue_head(&dev->poll_wait);
+	init_waitqueue_head(&dev->read_wait);
+	init_waitqueue_head(&dev->write_wait);
+	init_timer(&dev->poll_timer);
+	dev->poll_timer.function = &cm4040_do_poll;
+
+	return link;
+}
+
+static void reader_detach_by_devno(int devno, dev_link_t *link)
+{
+	struct reader_dev *dev = link->priv;
+
+	if (link->state & DEV_CONFIG) {
+		DEBUGP(5, dev, "device still configured (try to release it)\n");
+		reader_release(link);
+	}
+
+	pcmcia_deregister_client(link->handle);
+	dev_table[devno] = NULL;
+	DEBUGP(5, dev, "freeing dev=%p\n", dev);
+	cm4040_stop_poll(dev);
+	kfree(dev);
+	return;
+}
+
+static void reader_detach(dev_link_t *link)
+{
+	int i;
+
+	/* find device */
+	for (i = 0; i < CM_MAX_DEV; i++) {
+		if (dev_table[i] == link)
+			break;
+	}
+	if (i == CM_MAX_DEV)
+		return;
+
+	reader_detach_by_devno(i, link);
+	return;
+}
+
+static struct file_operations reader_fops = {
+	.owner		= THIS_MODULE,
+	.read		= cm4040_read,
+	.write		= cm4040_write,
+	.open		= cm4040_open,
+	.release	= cm4040_close,
+	.poll		= cm4040_poll,
+};
+
+static struct pcmcia_device_id cm4040_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x0223, 0x0200),
+	PCMCIA_DEVICE_PROD_ID12("OMNIKEY", "CardMan 4040",
+				0xE32CDD8C, 0x8F23318B),
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, cm4040_ids);
+
+static struct pcmcia_driver reader_driver = {
+  	.owner		= THIS_MODULE,
+  	.drv		= {
+		.name	= "cm4040_cs",
+	},
+	.attach		= reader_attach,
+	.detach		= reader_detach,
+	.event		= reader_event,
+	.id_table	= cm4040_ids,
+};
+
+static int __init cm4040_init(void)
+{
+	printk(KERN_INFO "%s\n", version);
+	pcmcia_register_driver(&reader_driver);
+	major = register_chrdev(0, DEVICE_NAME, &reader_fops);
+	if (major < 0) {
+		printk(KERN_WARNING MODULE_NAME
+			": could not get major number\n");
+		return -1;
+	}
+	return 0;
+}
+
+static void __exit cm4040_exit(void)
+{
+	int i;
+
+	printk(KERN_INFO MODULE_NAME ": unloading\n");
+	pcmcia_unregister_driver(&reader_driver);
+	for (i = 0; i < CM_MAX_DEV; i++) {
+		if (dev_table[i])
+			reader_detach_by_devno(i, dev_table[i]);
+	}
+	unregister_chrdev(major, DEVICE_NAME);
+}
+
+module_init(cm4040_init);
+module_exit(cm4040_exit);
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/char/pcmcia/cm4040_cs.h b/drivers/char/pcmcia/cm4040_cs.h
new file mode 100644
index 0000000..9a8b805
--- /dev/null
+++ b/drivers/char/pcmcia/cm4040_cs.h
@@ -0,0 +1,47 @@
+#ifndef	_CM4040_H_
+#define	_CM4040_H_
+
+#define	CM_MAX_DEV		4
+
+#define	DEVICE_NAME		"cmx"
+#define	MODULE_NAME		"cm4040_cs"
+
+#define REG_OFFSET_BULK_OUT      0
+#define REG_OFFSET_BULK_IN       0
+#define REG_OFFSET_BUFFER_STATUS 1
+#define REG_OFFSET_SYNC_CONTROL  2
+
+#define BSR_BULK_IN_FULL  0x02
+#define BSR_BULK_OUT_FULL 0x01
+
+#define SCR_HOST_TO_READER_START 0x80
+#define SCR_ABORT                0x40
+#define SCR_EN_NOTIFY            0x20
+#define SCR_ACK_NOTIFY           0x10
+#define SCR_READER_TO_HOST_DONE  0x08
+#define SCR_HOST_TO_READER_DONE  0x04
+#define SCR_PULSE_INTERRUPT      0x02
+#define SCR_POWER_DOWN           0x01
+
+
+#define  CMD_PC_TO_RDR_ICCPOWERON       0x62
+#define  CMD_PC_TO_RDR_GETSLOTSTATUS    0x65
+#define  CMD_PC_TO_RDR_ICCPOWEROFF      0x63
+#define  CMD_PC_TO_RDR_SECURE           0x69
+#define  CMD_PC_TO_RDR_GETPARAMETERS    0x6C
+#define  CMD_PC_TO_RDR_RESETPARAMETERS  0x6D
+#define  CMD_PC_TO_RDR_SETPARAMETERS    0x61
+#define  CMD_PC_TO_RDR_XFRBLOCK         0x6F
+#define  CMD_PC_TO_RDR_ESCAPE           0x6B
+#define  CMD_PC_TO_RDR_ICCCLOCK         0x6E
+#define  CMD_PC_TO_RDR_TEST_SECURE      0x74
+#define  CMD_PC_TO_RDR_OK_SECURE        0x89
+
+
+#define  CMD_RDR_TO_PC_SLOTSTATUS         0x81
+#define  CMD_RDR_TO_PC_DATABLOCK          0x80
+#define  CMD_RDR_TO_PC_PARAMETERS         0x82
+#define  CMD_RDR_TO_PC_ESCAPE             0x83
+#define  CMD_RDR_TO_PC_OK_SECURE          0x89
+
+#endif	/* _CM4040_H_ */
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 82c6abd..62aa0e5 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/char/synclink.c
  *
- * $Id: synclink.c,v 4.37 2005/09/07 13:13:19 paulkf Exp $
+ * $Id: synclink.c,v 4.38 2005/11/07 16:30:34 paulkf Exp $
  *
  * Device driver for Microgate SyncLink ISA and PCI
  * high speed multiprotocol serial adapters.
@@ -101,6 +101,7 @@
 #include <linux/termios.h>
 #include <linux/workqueue.h>
 #include <linux/hdlc.h>
+#include <linux/dma-mapping.h>
 
 #ifdef CONFIG_HDLC_MODULE
 #define CONFIG_HDLC 1
@@ -148,6 +149,7 @@ typedef struct _DMABUFFERENTRY
 	u32 link;	/* 32-bit flat link to next buffer entry */
 	char *virt_addr;	/* virtual address of data buffer */
 	u32 phys_entry;	/* physical address of this buffer entry */
+	dma_addr_t dma_addr;
 } DMABUFFERENTRY, *DMAPBUFFERENTRY;
 
 /* The queue of BH actions to be performed */
@@ -233,7 +235,8 @@ struct mgsl_struct {
 	int ri_chkcount;
 
 	char *buffer_list;		/* virtual address of Rx & Tx buffer lists */
-	unsigned long buffer_list_phys;
+	u32 buffer_list_phys;
+	dma_addr_t buffer_list_dma_addr;
 
 	unsigned int rx_buffer_count;	/* count of total allocated Rx buffers */
 	DMABUFFERENTRY *rx_buffer_list;	/* list of receive buffer entries */
@@ -896,7 +899,7 @@ module_param_array(txdmabufs, int, NULL,
 module_param_array(txholdbufs, int, NULL, 0);
 
 static char *driver_name = "SyncLink serial driver";
-static char *driver_version = "$Revision: 4.37 $";
+static char *driver_version = "$Revision: 4.38 $";
 
 static int synclink_init_one (struct pci_dev *dev,
 				     const struct pci_device_id *ent);
@@ -3811,11 +3814,10 @@ static int mgsl_alloc_buffer_list_memory
 		/* inspect portions of the buffer while other portions are being */
 		/* updated by the adapter using Bus Master DMA. */
 
-		info->buffer_list = kmalloc(BUFFERLISTSIZE, GFP_KERNEL | GFP_DMA);
-		if ( info->buffer_list == NULL )
+		info->buffer_list = dma_alloc_coherent(NULL, BUFFERLISTSIZE, &info->buffer_list_dma_addr, GFP_KERNEL);
+		if (info->buffer_list == NULL)
 			return -ENOMEM;
-			
-		info->buffer_list_phys = isa_virt_to_bus(info->buffer_list);
+		info->buffer_list_phys = (u32)(info->buffer_list_dma_addr);
 	}
 
 	/* We got the memory for the buffer entry lists. */
@@ -3882,8 +3884,8 @@ static int mgsl_alloc_buffer_list_memory
  */
 static void mgsl_free_buffer_list_memory( struct mgsl_struct *info )
 {
-	if ( info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI )
-		kfree(info->buffer_list);
+	if (info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI)
+		dma_free_coherent(NULL, BUFFERLISTSIZE, info->buffer_list, info->buffer_list_dma_addr);
 		
 	info->buffer_list = NULL;
 	info->rx_buffer_list = NULL;
@@ -3910,7 +3912,7 @@ static void mgsl_free_buffer_list_memory
 static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *BufferList,int Buffercount)
 {
 	int i;
-	unsigned long phys_addr;
+	u32 phys_addr;
 
 	/* Allocate page sized buffers for the receive buffer list */
 
@@ -3922,11 +3924,10 @@ static int mgsl_alloc_frame_memory(struc
 			info->last_mem_alloc += DMABUFFERSIZE;
 		} else {
 			/* ISA adapter uses system memory. */
-			BufferList[i].virt_addr = 
-				kmalloc(DMABUFFERSIZE, GFP_KERNEL | GFP_DMA);
-			if ( BufferList[i].virt_addr == NULL )
+			BufferList[i].virt_addr = dma_alloc_coherent(NULL, DMABUFFERSIZE, &BufferList[i].dma_addr, GFP_KERNEL);
+			if (BufferList[i].virt_addr == NULL)
 				return -ENOMEM;
-			phys_addr = isa_virt_to_bus(BufferList[i].virt_addr);
+			phys_addr = (u32)(BufferList[i].dma_addr);
 		}
 		BufferList[i].phys_addr = phys_addr;
 	}
@@ -3957,7 +3958,7 @@ static void mgsl_free_frame_memory(struc
 		for ( i = 0 ; i < Buffercount ; i++ ) {
 			if ( BufferList[i].virt_addr ) {
 				if ( info->bus_type != MGSL_BUS_TYPE_PCI )
-					kfree(BufferList[i].virt_addr);
+					dma_free_coherent(NULL, DMABUFFERSIZE, BufferList[i].virt_addr, BufferList[i].dma_addr);
 				BufferList[i].virt_addr = NULL;
 			}
 		}
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 303f158..0b283d2 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -43,6 +43,13 @@ static void user_reader_timeout(unsigned
 {
 	struct tpm_chip *chip = (struct tpm_chip *) ptr;
 
+	schedule_work(&chip->work);
+}
+
+static void timeout_work(void * ptr)
+{
+	struct tpm_chip *chip = ptr;
+
 	down(&chip->buffer_mutex);
 	atomic_set(&chip->data_pending, 0);
 	memset(chip->data_buffer, 0, TPM_BUFSIZE);
@@ -428,8 +435,7 @@ ssize_t tpm_read(struct file * file, cha
 			ret_size = size;
 
 		down(&chip->buffer_mutex);
-		if (copy_to_user
-		    ((void __user *) buf, chip->data_buffer, ret_size))
+		if (copy_to_user(buf, chip->data_buffer, ret_size))
 			ret_size = -EFAULT;
 		up(&chip->buffer_mutex);
 	}
@@ -460,7 +466,7 @@ void tpm_remove_hardware(struct device *
 	sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
 
 	dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
-		!(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
+		~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
 
 	kfree(chip);
 
@@ -528,6 +534,8 @@ int tpm_register_hardware(struct device 
 	init_MUTEX(&chip->tpm_mutex);
 	INIT_LIST_HEAD(&chip->list);
 
+	INIT_WORK(&chip->work, timeout_work, chip);
+
 	init_timer(&chip->user_read_timer);
 	chip->user_read_timer.function = user_reader_timeout;
 	chip->user_read_timer.data = (unsigned long) chip;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 9293bcc..159882c 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -50,7 +50,11 @@ struct tpm_vendor_specific {
 	u8 req_complete_mask;
 	u8 req_complete_val;
 	u8 req_canceled;
-	u16 base;		/* TPM base address */
+	void __iomem *iobase;		/* ioremapped address */
+	unsigned long base;		/* TPM base address */
+
+	int region_size;
+	int have_region;
 
 	int (*recv) (struct tpm_chip *, u8 *, size_t);
 	int (*send) (struct tpm_chip *, u8 *, size_t);
@@ -73,6 +77,7 @@ struct tpm_chip {
 	struct semaphore buffer_mutex;
 
 	struct timer_list user_read_timer;	/* user needs to claim result */
+	struct work_struct work;
 	struct semaphore tpm_mutex;	/* tpm is processing */
 
 	struct tpm_vendor_specific *vendor;
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index 32e0145..deb4b5c 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -19,14 +19,8 @@
  * 
  */
 
-#include <linux/platform_device.h>
 #include "tpm.h"
-
-/* Atmel definitions */
-enum tpm_atmel_addr {
-	TPM_ATMEL_BASE_ADDR_LO = 0x08,
-	TPM_ATMEL_BASE_ADDR_HI = 0x09
-};
+#include "tpm_atmel.h"
 
 /* write status bits */
 enum tpm_atmel_write_status {
@@ -53,13 +47,13 @@ static int tpm_atml_recv(struct tpm_chip
 		return -EIO;
 
 	for (i = 0; i < 6; i++) {
-		status = inb(chip->vendor->base + 1);
+		status = atmel_getb(chip, 1);
 		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
 			dev_err(chip->dev,
 				"error reading header\n");
 			return -EIO;
 		}
-		*buf++ = inb(chip->vendor->base);
+		*buf++ = atmel_getb(chip, 0);
 	}
 
 	/* size of the data received */
@@ -70,7 +64,7 @@ static int tpm_atml_recv(struct tpm_chip
 		dev_err(chip->dev,
 			"Recv size(%d) less than available space\n", size);
 		for (; i < size; i++) {	/* clear the waiting data anyway */
-			status = inb(chip->vendor->base + 1);
+			status = atmel_getb(chip, 1);
 			if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
 				dev_err(chip->dev,
 					"error reading data\n");
@@ -82,17 +76,17 @@ static int tpm_atml_recv(struct tpm_chip
 
 	/* read all the data available */
 	for (; i < size; i++) {
-		status = inb(chip->vendor->base + 1);
+		status = atmel_getb(chip, 1);
 		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
 			dev_err(chip->dev,
 				"error reading data\n");
 			return -EIO;
 		}
-		*buf++ = inb(chip->vendor->base);
+		*buf++ = atmel_getb(chip, 0);
 	}
 
 	/* make sure data available is gone */
-	status = inb(chip->vendor->base + 1);
+	status = atmel_getb(chip, 1);
 	if (status & ATML_STATUS_DATA_AVAIL) {
 		dev_err(chip->dev, "data available is stuck\n");
 		return -EIO;
@@ -108,7 +102,7 @@ static int tpm_atml_send(struct tpm_chip
 	dev_dbg(chip->dev, "tpm_atml_send:\n");
 	for (i = 0; i < count; i++) {
 		dev_dbg(chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
-		outb(buf[i], chip->vendor->base);
+		atmel_putb(buf[i], chip, 0);
 	}
 
 	return count;
@@ -116,12 +110,12 @@ static int tpm_atml_send(struct tpm_chip
 
 static void tpm_atml_cancel(struct tpm_chip *chip)
 {
-	outb(ATML_STATUS_ABORT, chip->vendor->base + 1);
+	atmel_putb(ATML_STATUS_ABORT, chip, 1);
 }
 
 static u8 tpm_atml_status(struct tpm_chip *chip)
 {
-	return inb(chip->vendor->base + 1);
+	return atmel_getb(chip, 1);
 }
 
 static struct file_operations atmel_ops = {
@@ -162,12 +156,16 @@ static struct tpm_vendor_specific tpm_at
 
 static struct platform_device *pdev;
 
-static void __devexit tpm_atml_remove(struct device *dev)
+static void atml_plat_remove(void)
 {
-	struct tpm_chip *chip = dev_get_drvdata(dev);
+	struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
+
 	if (chip) {
-		release_region(chip->vendor->base, 2);
+		if (chip->vendor->have_region)
+			atmel_release_region(chip->vendor->base, chip->vendor->region_size);
+		atmel_put_base_addr(chip->vendor);
 		tpm_remove_hardware(chip->dev);
+		platform_device_unregister(pdev);
 	}
 }
 
@@ -182,72 +180,40 @@ static struct device_driver atml_drv = {
 static int __init init_atmel(void)
 {
 	int rc = 0;
-	int lo, hi;
 
 	driver_register(&atml_drv);
 
-	lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
-	hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
-
-	tpm_atmel.base = (hi<<8)|lo;
-
-	/* verify that it is an Atmel part */
-	if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T'
-	    || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') {
-		return -ENODEV;
+	if (atmel_get_base_addr(&tpm_atmel) != 0) {
+		rc = -ENODEV;
+		goto err_unreg_drv;
 	}
 
-	/* verify chip version number is 1.1 */
-	if (	(tpm_read_index(TPM_ADDR, 0x00) != 0x01) ||
-		(tpm_read_index(TPM_ADDR, 0x01) != 0x01 ))
-		return -ENODEV;
-
-	pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
-	if ( !pdev )
-		return -ENOMEM;
-
-	pdev->name = "tpm_atmel0";
-	pdev->id = -1;
-	pdev->num_resources = 0;
-	pdev->dev.release = tpm_atml_remove;
-	pdev->dev.driver = &atml_drv;
+	tpm_atmel.have_region = (atmel_request_region( tpm_atmel.base, tpm_atmel.region_size, "tpm_atmel0") == NULL) ? 0 : 1;
 
-	if ((rc = platform_device_register(pdev)) < 0) {
-		kfree(pdev);
-		pdev = NULL;
-		return rc;
+	if (IS_ERR(pdev = platform_device_register_simple("tpm_atmel", -1, NULL, 0 ))) {
+		rc = PTR_ERR(pdev);
+		goto err_rel_reg;
 	}
 
-	if (request_region(tpm_atmel.base, 2, "tpm_atmel0") == NULL ) {
-		platform_device_unregister(pdev);
-		kfree(pdev);
-		pdev = NULL;
-		return -EBUSY;
-	}
-
-	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) {
-		release_region(tpm_atmel.base, 2);
-		platform_device_unregister(pdev);
-		kfree(pdev);
-		pdev = NULL;
-		return rc;
-	}
-
-	dev_info(&pdev->dev, "Atmel TPM 1.1, Base Address: 0x%x\n",
-			tpm_atmel.base);
+	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
+		goto err_unreg_dev;
 	return 0;
+
+err_unreg_dev:
+	platform_device_unregister(pdev);
+err_rel_reg:
+	if (tpm_atmel.have_region)
+		atmel_release_region(tpm_atmel.base, tpm_atmel.region_size);
+	atmel_put_base_addr(&tpm_atmel);
+err_unreg_drv:
+	driver_unregister(&atml_drv);
+	return rc;
 }
 
 static void __exit cleanup_atmel(void)
 {
-	if (pdev) {
-		tpm_atml_remove(&pdev->dev);
-		platform_device_unregister(pdev);
-		kfree(pdev);
-		pdev = NULL;
-	}
-
 	driver_unregister(&atml_drv);
+	atml_plat_remove();
 }
 
 module_init(init_atmel);
diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h
new file mode 100644
index 0000000..3c5b9a8
--- /dev/null
+++ b/drivers/char/tpm/tpm_atmel.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Authors:
+ * Kylene Hall <kjhall@us.ibm.com>
+ *
+ * Maintained by: <tpmdd_devel@lists.sourceforge.net>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * These difference are required on power because the device must be
+ * discovered through the device tree and iomap must be used to get
+ * around the need for holes in the io_page_mask.  This does not happen
+ * automatically because the tpm is not a normal pci device and lives
+ * under the root node.
+ *
+ */
+
+#ifdef CONFIG_PPC64
+#define atmel_getb(chip, offset) readb(chip->vendor->iobase + offset);
+#define atmel_putb(val, chip, offset) writeb(val, chip->vendor->iobase + offset)
+#define atmel_request_region request_mem_region
+#define atmel_release_region release_mem_region
+static inline void atmel_put_base_addr(struct tpm_vendor_specific *vendor)
+{
+	iounmap(vendor->iobase);
+}
+
+static int atmel_get_base_addr(struct tpm_vendor_specific *vendor)
+{
+	struct device_node *dn;
+	unsigned long address, size;
+	unsigned int *reg;
+	int reglen;
+	int naddrc;
+	int nsizec;
+
+	dn = of_find_node_by_name(NULL, "tpm");
+
+	if (!dn)
+		return 1;
+
+	if (!device_is_compatible(dn, "AT97SC3201")) {
+		of_node_put(dn);
+		return 1;
+	}
+
+	reg = (unsigned int *) get_property(dn, "reg", &reglen);
+	naddrc = prom_n_addr_cells(dn);
+	nsizec = prom_n_size_cells(dn);
+
+	of_node_put(dn);
+
+
+	if (naddrc == 2)
+		address = ((unsigned long) reg[0] << 32) | reg[1];
+	else
+		address = reg[0];
+
+	if (nsizec == 2)
+		size =
+		    ((unsigned long) reg[naddrc] << 32) | reg[naddrc + 1];
+	else
+		size = reg[naddrc];
+
+	vendor->base = address;
+	vendor->region_size = size;
+	vendor->iobase = ioremap(address, size);
+	return 0;
+}
+#else
+#define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
+#define atmel_putb(val, chip, offset) outb(val, chip->vendor->base + offset)
+#define atmel_request_region request_region
+#define atmel_release_region release_region
+/* Atmel definitions */
+enum tpm_atmel_addr {
+	TPM_ATMEL_BASE_ADDR_LO = 0x08,
+	TPM_ATMEL_BASE_ADDR_HI = 0x09
+};
+
+/* Verify this is a 1.1 Atmel TPM */
+static int atmel_verify_tpm11(void)
+{
+
+	/* verify that it is an Atmel part */
+	if (tpm_read_index(TPM_ADDR, 4) != 'A' ||
+	    tpm_read_index(TPM_ADDR, 5) != 'T' ||
+	    tpm_read_index(TPM_ADDR, 6) != 'M' ||
+	    tpm_read_index(TPM_ADDR, 7) != 'L')
+		return 1;
+
+	/* query chip for its version number */
+	if (tpm_read_index(TPM_ADDR, 0x00) != 1 ||
+	    tpm_read_index(TPM_ADDR, 0x01) != 1)
+		return 1;
+
+	/* This is an atmel supported part */
+	return 0;
+}
+
+static inline void atmel_put_base_addr(struct tpm_vendor_specific *vendor)
+{
+}
+
+/* Determine where to talk to device */
+static unsigned long atmel_get_base_addr(struct tpm_vendor_specific
+					 *vendor)
+{
+	int lo, hi;
+
+	if (atmel_verify_tpm11() != 0)
+		return 1;
+
+	lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
+	hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
+
+	vendor->base = (hi << 8) | lo;
+	vendor->region_size = 2;
+
+	return 0;
+}
+#endif
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c
index abc30cc..65830ec 100644
--- a/drivers/char/watchdog/booke_wdt.c
+++ b/drivers/char/watchdog/booke_wdt.c
@@ -4,7 +4,7 @@
  * Watchdog timer for PowerPC Book-E systems
  *
  * Author: Matthew McClintock
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor Inc.
  *
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index ea0806c..8a5c7b2 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -399,34 +399,6 @@ static unsigned int __devinit init_chips
 	return dev->irq;
 }
 
-static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
-{
-	unsigned int rev;
-	u8 dma_state;
-
-	DBG(("init_dma_sl82c105(hwif: ide%d, dma_base: 0x%08x)\n", hwif->index, dma_base));
-
-	hwif->autodma = 0;
-
-	if (!dma_base)
-		return;
-
-	dma_state = hwif->INB(dma_base + 2);
-	rev = sl82c105_bridge_revision(hwif->pci_dev);
-	if (rev <= 5) {
-		printk("    %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
-		       hwif->name, rev);
-		dma_state &= ~0x60;
-	} else {
-		dma_state |= 0x60;
-		if (!noautodma)
-			hwif->autodma = 1;
-	}
-	hwif->OUTB(dma_state, dma_base + 2);
-
-	ide_setup_dma(hwif, dma_base, 8);
-}
-
 /*
  * Initialise the chip
  */
@@ -434,6 +406,8 @@ static void __devinit init_dma_sl82c105(
 static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
 {
 	struct pci_dev *dev = hwif->pci_dev;
+	unsigned int rev;
+	u8 dma_state;
 	u32 val;
 	
 	DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index));
@@ -455,33 +429,54 @@ static void __devinit init_hwif_sl82c105
 	pci_read_config_dword(dev, 0x40, &val);
 	*((u32 *)&hwif->hwif_data) = val;
 	
+	hwif->atapi_dma = 0;
+	hwif->mwdma_mask = 0;
+	hwif->swdma_mask = 0;
+	hwif->autodma = 0;
+
 	if (!hwif->dma_base)
 		return;
 
-	hwif->atapi_dma = 1;
-	hwif->mwdma_mask = 0x07;
-	hwif->swdma_mask = 0x07;
-
+	dma_state = hwif->INB(hwif->dma_base + 2) & ~0x60;
+	rev = sl82c105_bridge_revision(hwif->pci_dev);
+	if (rev <= 5) {
+		/*
+		 * Never ever EVER under any circumstances enable
+		 * DMA when the bridge is this old.
+		 */
+		printk("    %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
+		       hwif->name, rev);
+	} else {
 #ifdef CONFIG_BLK_DEV_IDEDMA
-	hwif->ide_dma_check = &sl82c105_check_drive;
-	hwif->ide_dma_on = &sl82c105_ide_dma_on;
-	hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly;
-	hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq;
-	hwif->dma_start = &sl82c105_ide_dma_start;
-	hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;
-
-	if (!noautodma)
-		hwif->autodma = 1;
-	hwif->drives[0].autodma = hwif->autodma;
-	hwif->drives[1].autodma = hwif->autodma;
+		dma_state |= 0x60;
+
+		hwif->atapi_dma = 1;
+		hwif->mwdma_mask = 0x07;
+		hwif->swdma_mask = 0x07;
+
+		hwif->ide_dma_check = &sl82c105_check_drive;
+		hwif->ide_dma_on = &sl82c105_ide_dma_on;
+		hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly;
+		hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq;
+		hwif->dma_start = &sl82c105_ide_dma_start;
+		hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;
+
+		if (!noautodma)
+			hwif->autodma = 1;
+		hwif->drives[0].autodma = hwif->autodma;
+		hwif->drives[1].autodma = hwif->autodma;
+
+		if (hwif->mate)
+			hwif->serialized = hwif->mate->serialized = 1;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
+	}
+	hwif->OUTB(dma_state, hwif->dma_base + 2);
 }
 
 static ide_pci_device_t sl82c105_chipset __devinitdata = {
 	.name		= "W82C105",
 	.init_chipset	= init_chipset_sl82c105,
 	.init_hwif	= init_hwif_sl82c105,
-	.init_dma	= init_dma_sl82c105,
 	.channels	= 2,
 	.autodma	= NOAUTODMA,
 	.enablebits	= {{0x40,0x01,0x01}, {0x40,0x10,0x10}},
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index b3e65a6..136911a 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1667,11 +1667,16 @@ static struct macio_driver pmac_ide_maci
 };
 
 static struct pci_device_id pmac_ide_pci_match[] = {
-	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_ATA,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID2_ATA,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 };
 
 static struct pci_driver pmac_ide_pci_driver = {
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index 32bf0d5..f8457ef 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -71,78 +71,68 @@ typedef struct {
 /****************************************/
 static struct usb_device_id hfcusb_idtab[] = {
 	{
-	 .idVendor = 0x0959,
-	 .idProduct = 0x2bd0,
+	 USB_DEVICE(0x0959, 0x2bd0),
 	 .driver_info = (unsigned long) &((hfcsusb_vdata)
 			  {LED_OFF, {4, 0, 2, 1},
 			   "ISDN USB TA (Cologne Chip HFC-S USB based)"}),
 	},
 	{
-	 .idVendor = 0x0675,
-	 .idProduct = 0x1688,
+	 USB_DEVICE(0x0675, 0x1688),
 	 .driver_info = (unsigned long) &((hfcsusb_vdata)
 			  {LED_SCHEME1, {1, 2, 0, 0},
 			   "DrayTek miniVigor 128 USB ISDN TA"}),
 	},
 	{
-	 .idVendor = 0x07b0,
-	 .idProduct = 0x0007,
+	 USB_DEVICE(0x07b0, 0x0007),
 	 .driver_info = (unsigned long) &((hfcsusb_vdata)
 			  {LED_SCHEME1, {0x80, -64, -32, -16},
 			   "Billion tiny USB ISDN TA 128"}),
 	},
 	{
-	 .idVendor = 0x0742,
-	 .idProduct = 0x2008,
+	 USB_DEVICE(0x0742, 0x2008),
 	 .driver_info = (unsigned long) &((hfcsusb_vdata)
 			  {LED_SCHEME1, {4, 0, 2, 1},
 			   "Stollmann USB TA"}),
 	 },
 	{
-	 .idVendor = 0x0742,
-	 .idProduct = 0x2009,
+	 USB_DEVICE(0x0742, 0x2009),
 	 .driver_info = (unsigned long) &((hfcsusb_vdata)
 			  {LED_SCHEME1, {4, 0, 2, 1},
 			   "Aceex USB ISDN TA"}),
 	 },
 	{
-	 .idVendor = 0x0742,
-	 .idProduct = 0x200A,
+	 USB_DEVICE(0x0742, 0x200A),
 	 .driver_info = (unsigned long) &((hfcsusb_vdata)
 			  {LED_SCHEME1, {4, 0, 2, 1},
 			   "OEM USB ISDN TA"}),
 	 },
 	{
-	 .idVendor = 0x08e3,
-	 .idProduct = 0x0301,
+	 USB_DEVICE(0x08e3, 0x0301),
 	 .driver_info = (unsigned long) &((hfcsusb_vdata)
 			  {LED_SCHEME1, {2, 0, 1, 4},
 			   "Olitec USB RNIS"}),
 	 },
 	{
-	 .idVendor = 0x07fa,
-	 .idProduct = 0x0846,
+	 USB_DEVICE(0x07fa, 0x0846),
 	 .driver_info = (unsigned long) &((hfcsusb_vdata)
 			  {LED_SCHEME1, {0x80, -64, -32, -16},
 			   "Bewan Modem RNIS USB"}),
 	 },
 	{
-	 .idVendor = 0x07fa,
-	 .idProduct = 0x0847,
+	 USB_DEVICE(0x07fa, 0x0847),
 	 .driver_info = (unsigned long) &((hfcsusb_vdata)
 			  {LED_SCHEME1, {0x80, -64, -32, -16},
 			   "Djinn Numeris USB"}),
 	 },
 	{
-	 .idVendor = 0x07b0,
-	 .idProduct = 0x0006,
+	 USB_DEVICE(0x07b0, 0x0006),
 	 .driver_info = (unsigned long) &((hfcsusb_vdata)
 			  {LED_SCHEME1, {0x80, -64, -32, -16},
 			   "Twister ISDN TA"}),
 	 },
+	{ }
 };
 
-
 /***************************************************************/
 /* structure defining input+output fifos (interrupt/bulk mode) */
 /***************************************************************/
diff --git a/drivers/md/md.c b/drivers/md/md.c
index adf960d..f3fed66 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3156,7 +3156,7 @@ static int md_ioctl(struct inode *inode,
 		if (cnt > 0 ) {
 			printk(KERN_WARNING
 			       "md: %s(pid %d) used deprecated START_ARRAY ioctl. "
-			       "This will not be supported beyond 2.6\n",
+			       "This will not be supported beyond July 2006\n",
 			       current->comm, current->pid);
 			cnt--;
 		}
@@ -3437,10 +3437,19 @@ static int md_thread(void * arg)
 	allow_signal(SIGKILL);
 	while (!kthread_should_stop()) {
 
-		wait_event_timeout(thread->wqueue,
-				   test_bit(THREAD_WAKEUP, &thread->flags)
-				   || kthread_should_stop(),
-				   thread->timeout);
+		/* We need to wait INTERRUPTIBLE so that
+		 * we don't add to the load-average.
+		 * That means we need to be sure no signals are
+		 * pending
+		 */
+		if (signal_pending(current))
+			flush_signals(current);
+
+		wait_event_interruptible_timeout
+			(thread->wqueue,
+			 test_bit(THREAD_WAKEUP, &thread->flags)
+			 || kthread_should_stop(),
+			 thread->timeout);
 		try_to_freeze();
 
 		clear_bit(THREAD_WAKEUP, &thread->flags);
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index 4b71fd6..7972c73 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -126,6 +126,66 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTA
 };
 EXPORT_SYMBOL_GPL(ir_codes_winfast);
 
+IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
+	[ 0x59 ] = KEY_MUTE,
+	[ 0x4a ] = KEY_POWER,
+
+	[ 0x18 ] = KEY_TEXT,
+	[ 0x26 ] = KEY_TV,
+	[ 0x3d ] = KEY_PRINT,
+
+	[ 0x48 ] = KEY_RED,
+	[ 0x04 ] = KEY_GREEN,
+	[ 0x11 ] = KEY_YELLOW,
+	[ 0x00 ] = KEY_BLUE,
+
+	[ 0x2d ] = KEY_VOLUMEUP,
+	[ 0x1e ] = KEY_VOLUMEDOWN,
+
+	[ 0x49 ] = KEY_MENU,
+
+	[ 0x16 ] = KEY_CHANNELUP,
+	[ 0x17 ] = KEY_CHANNELDOWN,
+
+	[ 0x20 ] = KEY_UP,
+	[ 0x21 ] = KEY_DOWN,
+	[ 0x22 ] = KEY_LEFT,
+	[ 0x23 ] = KEY_RIGHT,
+	[ 0x0d ] = KEY_SELECT,
+
+
+
+	[ 0x08 ] = KEY_BACK,
+	[ 0x07 ] = KEY_REFRESH,
+
+	[ 0x2f ] = KEY_ZOOM,
+	[ 0x29 ] = KEY_RECORD,
+
+	[ 0x4b ] = KEY_PAUSE,
+	[ 0x4d ] = KEY_REWIND,
+	[ 0x2e ] = KEY_PLAY,
+	[ 0x4e ] = KEY_FORWARD,
+	[ 0x53 ] = KEY_PREVIOUS,
+	[ 0x4c ] = KEY_STOP,
+	[ 0x54 ] = KEY_NEXT,
+
+	[ 0x69 ] = KEY_KP0,
+	[ 0x6a ] = KEY_KP1,
+	[ 0x6b ] = KEY_KP2,
+	[ 0x6c ] = KEY_KP3,
+	[ 0x6d ] = KEY_KP4,
+	[ 0x6e ] = KEY_KP5,
+	[ 0x6f ] = KEY_KP6,
+	[ 0x70 ] = KEY_KP7,
+	[ 0x71 ] = KEY_KP8,
+	[ 0x72 ] = KEY_KP9,
+
+	[ 0x74 ] = KEY_CHANNEL,
+	[ 0x0a ] = KEY_BACKSPACE,
+};
+
+EXPORT_SYMBOL_GPL(ir_codes_pinnacle);
+
 /* empty keytable, can be used as placeholder for not-yet created keytables */
 IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE] = {
 	[ 42 ] = KEY_COFFEE,
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index d7417ea..2583a86 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -7,6 +7,7 @@ config DVB_B2C2_FLEXCOP
 	select DVB_NXT2002
 	select DVB_STV0297
 	select DVB_BCM3510
+	select DVB_LGDT330X
 	help
 	  Support for the digital TV receiver chip made by B2C2 Inc. included in
 	  Technisats PCI cards and USB boxes.
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 199b011..1a3b3c7 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -333,4 +333,18 @@ config VIDEO_M32R_AR_M64278
 	  Say Y here to use the Renesas M64278E-800 camera module,
 	  which supports VGA(640x480 pixcels) size of images.
 
+config VIDEO_AUDIO_DECODER
+	tristate "Add support for additional audio chipsets"
+	depends on VIDEO_DEV && I2C && EXPERIMENTAL
+	---help---
+	  Say Y here to compile drivers for WM8775 and CS53L32A audio
+	  decoders.
+
+config VIDEO_DECODER
+	tristate "Add support for additional video chipsets"
+	depends on VIDEO_DEV && I2C && EXPERIMENTAL
+	---help---
+	  Say Y here to compile drivers for SAA7115, SAA7127 and CX25840
+	  video  decoders.
+
 endmenu
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 3ac4659..82060f9 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -36,10 +36,11 @@ obj-$(CONFIG_VIDEO_CPIA) += cpia.o
 obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
 obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
 obj-$(CONFIG_VIDEO_MEYE) += meye.o
-obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
+obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/
 obj-$(CONFIG_VIDEO_CX88) += cx88/
 obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
 obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o
+obj-$(CONFIG_VIDEO_AUDIO_DECODER) += wm8775.o cs53l32a.o
 obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
 obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o
 obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
@@ -55,4 +56,6 @@ obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom
 
 obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
 
+obj-$(CONFIG_VIDEO_DECODER)     += saa7115.o cx25840/ saa7127.o
+
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 3413bac..e31ebb1 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -2133,7 +2133,10 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
 		.has_dvb        = 1,
+		.has_remote	= 1,
+		.gpiomask	= 0x1b,
 		.no_gpioirq     = 1,
+		.any_irq		= 1,
 	},
 	[BTTV_BOARD_PV143] = {
 		/* Jorge Boncompte - DTI2 <jorge@dti2.net> */
@@ -2796,7 +2799,24 @@ struct tvcard bttv_tvcards[] = {
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr     = ADDR_UNSET,
 	},
-
+		/* ---- card 0x8e ---------------------------------- */
+	[BTTV_BOARD_SABRENT_TVFM] = {
+		.name		= "Sabrent TV-FM (bttv version)",
+		.video_inputs	= 3,
+		.audio_inputs	= 1,
+		.tuner		= 0,
+		.svhs		= 2,
+		.gpiomask	= 0x108007,
+		.muxsel		= { 2, 3, 1, 1},
+		.audiomux	= { 100000, 100002, 100002, 100000},
+		.no_msp34xx	= 1,
+		.no_tda9875     = 1,
+		.no_tda7432     = 1,
+		.pll		= PLL_28,
+		.tuner_type	= TUNER_TNF_5335MF,
+		.tuner_addr	= ADDR_UNSET,
+		.has_radio      = 1,
+	},
 };
 
 static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -3367,6 +3387,8 @@ void __devinit bttv_init_card2(struct bt
 		btv->has_remote=1;
 	if (!bttv_tvcards[btv->c.type].no_gpioirq)
 		btv->gpioirq=1;
+	if (bttv_tvcards[btv->c.type].any_irq)
+		btv->any_irq = 1;
 	if (bttv_tvcards[btv->c.type].audio_hook)
 		btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook;
 
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 0005741..709099f 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -3667,6 +3667,10 @@ static irqreturn_t bttv_irq(int irq, voi
 	int handled = 0;
 
 	btv=(struct bttv *)dev_id;
+
+	if (btv->any_irq)
+		handled = bttv_any_irq(&btv->c);
+
 	count=0;
 	while (1) {
 		/* get/clear interrupt status bits */
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c
index 575ce8b..616a5b7 100644
--- a/drivers/media/video/bttv-gpio.c
+++ b/drivers/media/video/bttv-gpio.c
@@ -113,6 +113,24 @@ void bttv_gpio_irq(struct bttv_core *cor
 	}
 }
 
+int bttv_any_irq(struct bttv_core *core)
+{
+	struct bttv_sub_driver *drv;
+	struct bttv_sub_device *dev;
+	struct list_head *item;
+	int handled = 0;
+
+	list_for_each(item,&core->subs) {
+		dev = list_entry(item,struct bttv_sub_device,list);
+		drv = to_bttv_sub_drv(dev->dev.driver);
+		if (drv && drv->any_irq) {
+			if (drv->any_irq(dev))
+				handled = 1;
+		}
+	}
+	return handled;
+}
+
 /* ----------------------------------------------------------------------- */
 /* external: sub-driver register/unregister                                */
 
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index 124ea41..93298f0 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -162,6 +162,7 @@
 #define BTTV_BOARD_PV_M4900                0x8b
 #define BTTV_BOARD_OSPREY440               0x8c
 #define BTTV_BOARD_ASOUND_SKYEYE	   0x8d
+#define BTTV_BOARD_SABRENT_TVFM   	   0x8e
 
 /* i2c address list */
 #define I2C_TSA5522        0xc2
@@ -234,6 +235,7 @@ struct tvcard
 	unsigned int has_dvb:1;
 	unsigned int has_remote:1;
 	unsigned int no_gpioirq:1;
+	unsigned int any_irq:1;
 
 	/* other settings */
 	unsigned int pll;
@@ -333,6 +335,7 @@ struct bttv_sub_driver {
 	struct device_driver   drv;
 	char                   wanted[BUS_ID_SIZE];
 	void                   (*gpio_irq)(struct bttv_sub_device *sub);
+	int                    (*any_irq)(struct bttv_sub_device *sub);
 };
 #define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv)
 
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index 386f546..3aa9c6e 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -208,6 +208,7 @@ extern struct bus_type bttv_sub_bus_type
 int bttv_sub_add_device(struct bttv_core *core, char *name);
 int bttv_sub_del_devices(struct bttv_core *core);
 void bttv_gpio_irq(struct bttv_core *core);
+int bttv_any_irq(struct bttv_core *core);
 
 
 /* ---------------------------------------------------------- */
@@ -273,6 +274,7 @@ struct bttv {
 	struct bttv_pll_info pll;
 	int triton1;
 	int gpioirq;
+	int any_irq;
 	int use_i2c_hw;
 
 	/* old gpio interface */
diff --git a/drivers/media/video/cx25840/Makefile b/drivers/media/video/cx25840/Makefile
new file mode 100644
index 0000000..543ebac
--- /dev/null
+++ b/drivers/media/video/cx25840/Makefile
@@ -0,0 +1,6 @@
+cx25840-objs    := cx25840-core.o cx25840-audio.o cx25840-firmware.o \
+		   cx25840-vbi.o
+
+obj-$(CONFIG_VIDEO_DECODER) += cx25840.o
+
+EXTRA_CFLAGS += -I$(src)/..
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
new file mode 100644
index 0000000..740908f
--- /dev/null
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -0,0 +1,368 @@
+/* cx25840 audio functions
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+#include <media/audiochip.h>
+#include <media/v4l2-common.h>
+
+#include "cx25840.h"
+
+inline static int set_audclk_freq(struct i2c_client *client,
+				 enum v4l2_audio_clock_freq freq)
+{
+	struct cx25840_state *state = i2c_get_clientdata(client);
+
+	/* assert soft reset */
+	cx25840_and_or(client, 0x810, ~0x1, 0x01);
+
+	/* common for all inputs and rates */
+	/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
+	cx25840_write(client, 0x127, 0x50);
+
+	switch (state->audio_input) {
+	case AUDIO_TUNER:
+		switch (freq) {
+		case V4L2_AUDCLK_32_KHZ:
+			/* VID_PLL and AUX_PLL */
+			cx25840_write4(client, 0x108, 0x0f040610);
+
+			/* AUX_PLL_FRAC */
+			cx25840_write4(client, 0x110, 0xee39bb01);
+
+			/* src3/4/6_ctl = 0x0801f77f */
+			cx25840_write4(client, 0x900, 0x7ff70108);
+			cx25840_write4(client, 0x904, 0x7ff70108);
+			cx25840_write4(client, 0x90c, 0x7ff70108);
+			break;
+
+		case V4L2_AUDCLK_441_KHZ:
+			/* VID_PLL and AUX_PLL */
+			cx25840_write4(client, 0x108, 0x0f040910);
+
+			/* AUX_PLL_FRAC */
+			cx25840_write4(client, 0x110, 0xd66bec00);
+
+			/* src3/4/6_ctl = 0x08016d59 */
+			cx25840_write4(client, 0x900, 0x596d0108);
+			cx25840_write4(client, 0x904, 0x596d0108);
+			cx25840_write4(client, 0x90c, 0x596d0108);
+			break;
+
+		case V4L2_AUDCLK_48_KHZ:
+			/* VID_PLL and AUX_PLL */
+			cx25840_write4(client, 0x108, 0x0f040a10);
+
+			/* AUX_PLL_FRAC */
+			cx25840_write4(client, 0x110, 0xe5d69800);
+
+			/* src3/4/6_ctl = 0x08014faa */
+			cx25840_write4(client, 0x900, 0xaa4f0108);
+			cx25840_write4(client, 0x904, 0xaa4f0108);
+			cx25840_write4(client, 0x90c, 0xaa4f0108);
+			break;
+		}
+		break;
+
+	case AUDIO_EXTERN_1:
+	case AUDIO_EXTERN_2:
+	case AUDIO_INTERN:
+	case AUDIO_RADIO:
+		switch (freq) {
+		case V4L2_AUDCLK_32_KHZ:
+			/* VID_PLL and AUX_PLL */
+			cx25840_write4(client, 0x108, 0x0f04081e);
+
+			/* AUX_PLL_FRAC */
+			cx25840_write4(client, 0x110, 0x69082a01);
+
+			/* src1_ctl = 0x08010000 */
+			cx25840_write4(client, 0x8f8, 0x00000108);
+
+			/* src3/4/6_ctl = 0x08020000 */
+			cx25840_write4(client, 0x900, 0x00000208);
+			cx25840_write4(client, 0x904, 0x00000208);
+			cx25840_write4(client, 0x90c, 0x00000208);
+
+			/* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
+			cx25840_write(client, 0x127, 0x54);
+			break;
+
+		case V4L2_AUDCLK_441_KHZ:
+			/* VID_PLL and AUX_PLL */
+			cx25840_write4(client, 0x108, 0x0f040918);
+
+			/* AUX_PLL_FRAC */
+			cx25840_write4(client, 0x110, 0xd66bec00);
+
+			/* src1_ctl = 0x08010000 */
+			cx25840_write4(client, 0x8f8, 0xcd600108);
+
+			/* src3/4/6_ctl = 0x08020000 */
+			cx25840_write4(client, 0x900, 0x85730108);
+			cx25840_write4(client, 0x904, 0x85730108);
+			cx25840_write4(client, 0x90c, 0x85730108);
+			break;
+
+		case V4L2_AUDCLK_48_KHZ:
+			/* VID_PLL and AUX_PLL */
+			cx25840_write4(client, 0x108, 0x0f040a18);
+
+			/* AUX_PLL_FRAC */
+			cx25840_write4(client, 0x110, 0xe5d69800);
+
+			/* src1_ctl = 0x08010000 */
+			cx25840_write4(client, 0x8f8, 0x00800108);
+
+			/* src3/4/6_ctl = 0x08020000 */
+			cx25840_write4(client, 0x900, 0x55550108);
+			cx25840_write4(client, 0x904, 0x55550108);
+			cx25840_write4(client, 0x90c, 0x55550108);
+			break;
+		}
+		break;
+	}
+
+	/* deassert soft reset */
+	cx25840_and_or(client, 0x810, ~0x1, 0x00);
+
+	state->audclk_freq = freq;
+
+	return 0;
+}
+
+static int set_input(struct i2c_client *client, int audio_input)
+{
+	struct cx25840_state *state = i2c_get_clientdata(client);
+
+	cx25840_dbg("set audio input (%d)\n", audio_input);
+
+	/* stop microcontroller */
+	cx25840_and_or(client, 0x803, ~0x10, 0);
+
+	/* Mute everything to prevent the PFFT! */
+	cx25840_write(client, 0x8d3, 0x1f);
+
+	switch (audio_input) {
+	case AUDIO_TUNER:
+		/* Set Path1 to Analog Demod Main Channel */
+		cx25840_write4(client, 0x8d0, 0x7038061f);
+
+		/* When the microcontroller detects the
+		 * audio format, it will unmute the lines */
+		cx25840_and_or(client, 0x803, ~0x10, 0x10);
+		break;
+
+	case AUDIO_EXTERN_1:
+	case AUDIO_EXTERN_2:
+	case AUDIO_INTERN:
+	case AUDIO_RADIO:
+		/* Set Path1 to Serial Audio Input */
+		cx25840_write4(client, 0x8d0, 0x12100101);
+
+		/* The microcontroller should not be started for the
+		 * non-tuner inputs: autodetection is specific for
+		 * TV audio. */
+		break;
+
+	default:
+		cx25840_dbg("Invalid audio input selection %d\n", audio_input);
+		return -EINVAL;
+	}
+
+	state->audio_input = audio_input;
+
+	return set_audclk_freq(client, state->audclk_freq);
+}
+
+inline static int get_volume(struct i2c_client *client)
+{
+	/* Volume runs +18dB to -96dB in 1/2dB steps
+	 * change to fit the msp3400 -114dB to +12dB range */
+
+	/* check PATH1_VOLUME */
+	int vol = 228 - cx25840_read(client, 0x8d4);
+	vol = (vol / 2) + 23;
+	return vol << 9;
+}
+
+inline static void set_volume(struct i2c_client *client, int volume)
+{
+	/* First convert the volume to msp3400 values (0-127) */
+	int vol = volume >> 9;
+	/* now scale it up to cx25840 values
+	 * -114dB to -96dB maps to 0
+	 * this should be 19, but in my testing that was 4dB too loud */
+	if (vol <= 23) {
+		vol = 0;
+	} else {
+		vol -= 23;
+	}
+
+	/* PATH1_VOLUME */
+	cx25840_write(client, 0x8d4, 228 - (vol * 2));
+}
+
+inline static int get_bass(struct i2c_client *client)
+{
+	/* bass is 49 steps +12dB to -12dB */
+
+	/* check PATH1_EQ_BASS_VOL */
+	int bass = cx25840_read(client, 0x8d9) & 0x3f;
+	bass = (((48 - bass) * 0xffff) + 47) / 48;
+	return bass;
+}
+
+inline static void set_bass(struct i2c_client *client, int bass)
+{
+	/* PATH1_EQ_BASS_VOL */
+	cx25840_and_or(client, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
+}
+
+inline static int get_treble(struct i2c_client *client)
+{
+	/* treble is 49 steps +12dB to -12dB */
+
+	/* check PATH1_EQ_TREBLE_VOL */
+	int treble = cx25840_read(client, 0x8db) & 0x3f;
+	treble = (((48 - treble) * 0xffff) + 47) / 48;
+	return treble;
+}
+
+inline static void set_treble(struct i2c_client *client, int treble)
+{
+	/* PATH1_EQ_TREBLE_VOL */
+	cx25840_and_or(client, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
+}
+
+inline static int get_balance(struct i2c_client *client)
+{
+	/* balance is 7 bit, 0 to -96dB */
+
+	/* check PATH1_BAL_LEVEL */
+	int balance = cx25840_read(client, 0x8d5) & 0x7f;
+	/* check PATH1_BAL_LEFT */
+	if ((cx25840_read(client, 0x8d5) & 0x80) == 0)
+		balance = 0x80 - balance;
+	else
+		balance = 0x80 + balance;
+	return balance << 8;
+}
+
+inline static void set_balance(struct i2c_client *client, int balance)
+{
+	int bal = balance >> 8;
+	if (bal > 0x80) {
+		/* PATH1_BAL_LEFT */
+		cx25840_and_or(client, 0x8d5, 0x7f, 0x80);
+		/* PATH1_BAL_LEVEL */
+		cx25840_and_or(client, 0x8d5, ~0x7f, bal & 0x7f);
+	} else {
+		/* PATH1_BAL_LEFT */
+		cx25840_and_or(client, 0x8d5, 0x7f, 0x00);
+		/* PATH1_BAL_LEVEL */
+		cx25840_and_or(client, 0x8d5, ~0x7f, 0x80 - bal);
+	}
+}
+
+inline static int get_mute(struct i2c_client *client)
+{
+	/* check SRC1_MUTE_EN */
+	return cx25840_read(client, 0x8d3) & 0x2 ? 1 : 0;
+}
+
+inline static void set_mute(struct i2c_client *client, int mute)
+{
+	struct cx25840_state *state = i2c_get_clientdata(client);
+
+	if (state->audio_input == AUDIO_TUNER) {
+		/* Must turn off microcontroller in order to mute sound.
+		 * Not sure if this is the best method, but it does work.
+		 * If the microcontroller is running, then it will undo any
+		 * changes to the mute register. */
+		if (mute) {
+			/* disable microcontroller */
+			cx25840_and_or(client, 0x803, ~0x10, 0x00);
+			cx25840_write(client, 0x8d3, 0x1f);
+		} else {
+			/* enable microcontroller */
+			cx25840_and_or(client, 0x803, ~0x10, 0x10);
+		}
+	} else {
+		/* SRC1_MUTE_EN */
+		cx25840_and_or(client, 0x8d3, ~0x2, mute ? 0x02 : 0x00);
+	}
+}
+
+int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+	struct v4l2_control *ctrl = arg;
+
+	switch (cmd) {
+	case AUDC_SET_INPUT:
+		return set_input(client, *(int *)arg);
+	case VIDIOC_INT_AUDIO_CLOCK_FREQ:
+		return set_audclk_freq(client, *(enum v4l2_audio_clock_freq *)arg);
+	case VIDIOC_G_CTRL:
+		switch (ctrl->id) {
+		case V4L2_CID_AUDIO_VOLUME:
+			ctrl->value = get_volume(client);
+			break;
+		case V4L2_CID_AUDIO_BASS:
+			ctrl->value = get_bass(client);
+			break;
+		case V4L2_CID_AUDIO_TREBLE:
+			ctrl->value = get_treble(client);
+			break;
+		case V4L2_CID_AUDIO_BALANCE:
+			ctrl->value = get_balance(client);
+			break;
+		case V4L2_CID_AUDIO_MUTE:
+			ctrl->value = get_mute(client);
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case VIDIOC_S_CTRL:
+		switch (ctrl->id) {
+		case V4L2_CID_AUDIO_VOLUME:
+			set_volume(client, ctrl->value);
+			break;
+		case V4L2_CID_AUDIO_BASS:
+			set_bass(client, ctrl->value);
+			break;
+		case V4L2_CID_AUDIO_TREBLE:
+			set_treble(client, ctrl->value);
+			break;
+		case V4L2_CID_AUDIO_BALANCE:
+			set_balance(client, ctrl->value);
+			break;
+		case V4L2_CID_AUDIO_MUTE:
+			set_mute(client, ctrl->value);
+			break;
+		default:
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
new file mode 100644
index 0000000..f6afeec
--- /dev/null
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -0,0 +1,1020 @@
+/* cx25840 - Conexant CX25840 audio/video decoder driver
+ *
+ * Copyright (C) 2004 Ulf Eklund
+ *
+ * Based on the saa7115 driver and on the first verison of Chris Kennedy's
+ * cx25840 driver.
+ *
+ * Changes by Tyler Trafford <tatrafford@comcast.net>
+ *    - cleanup/rewrite for V4L2 API (2005)
+ *
+ * VBI support by Hans Verkuil <hverkuil@xs4all.nl>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+#include <media/audiochip.h>
+#include <media/v4l2-common.h>
+
+#include "cx25840.h"
+
+MODULE_DESCRIPTION("Conexant CX25840 audio/video decoder driver");
+MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford");
+MODULE_LICENSE("GPL");
+
+static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
+
+
+int cx25840_debug = 0;
+
+module_param(cx25840_debug, bool, 0644);
+
+MODULE_PARM_DESC(cx25840_debug, "Debugging messages [0=Off (default) 1=On]");
+
+I2C_CLIENT_INSMOD;
+
+/* ----------------------------------------------------------------------- */
+
+int cx25840_write(struct i2c_client *client, u16 addr, u8 value)
+{
+	u8 buffer[3];
+	buffer[0] = addr >> 8;
+	buffer[1] = addr & 0xff;
+	buffer[2] = value;
+	return i2c_master_send(client, buffer, 3);
+}
+
+int cx25840_write4(struct i2c_client *client, u16 addr, u32 value)
+{
+	u8 buffer[6];
+	buffer[0] = addr >> 8;
+	buffer[1] = addr & 0xff;
+	buffer[2] = value >> 24;
+	buffer[3] = (value >> 16) & 0xff;
+	buffer[4] = (value >> 8) & 0xff;
+	buffer[5] = value & 0xff;
+	return i2c_master_send(client, buffer, 6);
+}
+
+u8 cx25840_read(struct i2c_client * client, u16 addr)
+{
+	u8 buffer[2];
+	buffer[0] = addr >> 8;
+	buffer[1] = addr & 0xff;
+
+	if (i2c_master_send(client, buffer, 2) < 2)
+		return 0;
+
+	if (i2c_master_recv(client, buffer, 1) < 1)
+		return 0;
+
+	return buffer[0];
+}
+
+u32 cx25840_read4(struct i2c_client * client, u16 addr)
+{
+	u8 buffer[4];
+	buffer[0] = addr >> 8;
+	buffer[1] = addr & 0xff;
+
+	if (i2c_master_send(client, buffer, 2) < 2)
+		return 0;
+
+	if (i2c_master_recv(client, buffer, 4) < 4)
+		return 0;
+
+	return (buffer[0] << 24) | (buffer[1] << 16) |
+	    (buffer[2] << 8) | buffer[3];
+}
+
+int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask,
+		   u8 or_value)
+{
+	return cx25840_write(client, addr,
+			     (cx25840_read(client, addr) & and_mask) |
+			     or_value);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int set_input(struct i2c_client *, enum cx25840_input);
+static void input_change(struct i2c_client *);
+static void log_status(struct i2c_client *client);
+
+/* ----------------------------------------------------------------------- */
+
+static inline void init_dll1(struct i2c_client *client)
+{
+	/* This is the Hauppauge sequence used to
+	 * initialize the Delay Lock Loop 1 (ADC DLL). */
+	cx25840_write(client, 0x159, 0x23);
+	cx25840_write(client, 0x15a, 0x87);
+	cx25840_write(client, 0x15b, 0x06);
+	cx25840_write(client, 0x159, 0xe1);
+	cx25840_write(client, 0x15a, 0x86);
+	cx25840_write(client, 0x159, 0xe0);
+	cx25840_write(client, 0x159, 0xe1);
+	cx25840_write(client, 0x15b, 0x10);
+}
+
+static inline void init_dll2(struct i2c_client *client)
+{
+	/* This is the Hauppauge sequence used to
+	 * initialize the Delay Lock Loop 2 (ADC DLL). */
+	cx25840_write(client, 0x15d, 0xe3);
+	cx25840_write(client, 0x15e, 0x86);
+	cx25840_write(client, 0x15f, 0x06);
+	cx25840_write(client, 0x15d, 0xe1);
+	cx25840_write(client, 0x15d, 0xe0);
+	cx25840_write(client, 0x15d, 0xe1);
+}
+
+static void cx25840_initialize(struct i2c_client *client, int loadfw)
+{
+	struct cx25840_state *state = i2c_get_clientdata(client);
+
+	/* datasheet startup in numbered steps, refer to page 3-77 */
+	/* 2. */
+	cx25840_and_or(client, 0x803, ~0x10, 0x00);
+	/* The default of this register should be 4, but I get 0 instead.
+	 * Set this register to 4 manually. */
+	cx25840_write(client, 0x000, 0x04);
+	/* 3. */
+	init_dll1(client);
+	init_dll2(client);
+	cx25840_write(client, 0x136, 0x0a);
+	/* 4. */
+	cx25840_write(client, 0x13c, 0x01);
+	cx25840_write(client, 0x13c, 0x00);
+	/* 5. */
+	if (loadfw)
+		cx25840_loadfw(client);
+	/* 6. */
+	cx25840_write(client, 0x115, 0x8c);
+	cx25840_write(client, 0x116, 0x07);
+	cx25840_write(client, 0x118, 0x02);
+	/* 7. */
+	cx25840_write(client, 0x4a5, 0x80);
+	cx25840_write(client, 0x4a5, 0x00);
+	cx25840_write(client, 0x402, 0x00);
+	/* 8. */
+	cx25840_write(client, 0x401, 0x18);
+	cx25840_write(client, 0x4a2, 0x10);
+	cx25840_write(client, 0x402, 0x04);
+	/* 10. */
+	cx25840_write(client, 0x8d3, 0x1f);
+	cx25840_write(client, 0x8e3, 0x03);
+
+	cx25840_vbi_setup(client);
+
+	/* trial and error says these are needed to get audio */
+	cx25840_write(client, 0x914, 0xa0);
+	cx25840_write(client, 0x918, 0xa0);
+	cx25840_write(client, 0x919, 0x01);
+
+	/* stereo prefered */
+	cx25840_write(client, 0x809, 0x04);
+	/* AC97 shift */
+	cx25840_write(client, 0x8cf, 0x0f);
+
+	/* (re)set video input */
+	set_input(client, state->input);
+	/* (re)set audio input */
+	cx25840_audio(client, AUDC_SET_INPUT, &state->audio_input);
+
+	/* start microcontroller */
+	cx25840_and_or(client, 0x803, ~0x10, 0x10);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static void input_change(struct i2c_client *client)
+{
+	v4l2_std_id std = cx25840_get_v4lstd(client);
+
+	if (std & V4L2_STD_PAL) {
+		/* Follow tuner change procedure for PAL */
+		cx25840_write(client, 0x808, 0xff);
+		cx25840_write(client, 0x80b, 0x10);
+	} else if (std & V4L2_STD_SECAM) {
+		/* Select autodetect for SECAM */
+		cx25840_write(client, 0x808, 0xff);
+		cx25840_write(client, 0x80b, 0x10);
+	} else if (std & V4L2_STD_NTSC) {
+		/* NTSC */
+		cx25840_write(client, 0x808, 0xf6);
+		cx25840_write(client, 0x80b, 0x00);
+	}
+
+	if (cx25840_read(client, 0x803) & 0x10) {
+		/* restart audio decoder microcontroller */
+		cx25840_and_or(client, 0x803, ~0x10, 0x00);
+		cx25840_and_or(client, 0x803, ~0x10, 0x10);
+	}
+}
+
+static int set_input(struct i2c_client *client, enum cx25840_input input)
+{
+	struct cx25840_state *state = i2c_get_clientdata(client);
+
+	cx25840_dbg("decoder set input (%d)\n", input);
+
+	switch (input) {
+	case CX25840_TUNER:
+		cx25840_dbg("now setting Tuner input\n");
+
+		if (state->cardtype == CARDTYPE_PVR150) {
+			/* CH_SEL_ADC2=1 */
+			cx25840_and_or(client, 0x102, ~0x2, 0x02);
+		}
+
+		/* Video Input Control */
+		if (state->cardtype == CARDTYPE_PG600) {
+			cx25840_write(client, 0x103, 0x11);
+		} else {
+			cx25840_write(client, 0x103, 0x46);
+		}
+
+		/* INPUT_MODE=0 */
+		cx25840_and_or(client, 0x401, ~0x6, 0x00);
+		break;
+
+	case CX25840_COMPOSITE0:
+	case CX25840_COMPOSITE1:
+		cx25840_dbg("now setting Composite input\n");
+
+		/* Video Input Control */
+		if (state->cardtype == CARDTYPE_PG600) {
+			cx25840_write(client, 0x103, 0x00);
+		} else {
+			cx25840_write(client, 0x103, 0x02);
+		}
+
+		/* INPUT_MODE=0 */
+		cx25840_and_or(client, 0x401, ~0x6, 0x00);
+		break;
+
+	case CX25840_SVIDEO0:
+	case CX25840_SVIDEO1:
+		cx25840_dbg("now setting S-Video input\n");
+
+		/* CH_SEL_ADC2=0 */
+		cx25840_and_or(client, 0x102, ~0x2, 0x00);
+
+		/* Video Input Control */
+		if (state->cardtype == CARDTYPE_PG600) {
+			cx25840_write(client, 0x103, 0x02);
+		} else {
+			cx25840_write(client, 0x103, 0x10);
+		}
+
+		/* INPUT_MODE=1 */
+		cx25840_and_or(client, 0x401, ~0x6, 0x02);
+		break;
+
+	default:
+		cx25840_err("%d is not a valid input!\n", input);
+		return -EINVAL;
+	}
+
+	state->input = input;
+	input_change(client);
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
+{
+	u8 fmt;
+
+	switch (std) {
+	/* zero is autodetect */
+	case 0: fmt = 0x0; break;
+	/* default ntsc to ntsc-m */
+	case V4L2_STD_NTSC:
+	case V4L2_STD_NTSC_M: fmt = 0x1; break;
+	case V4L2_STD_NTSC_M_JP: fmt = 0x2; break;
+	case V4L2_STD_NTSC_443: fmt = 0x3; break;
+	case V4L2_STD_PAL: fmt = 0x4; break;
+	case V4L2_STD_PAL_M: fmt = 0x5; break;
+	case V4L2_STD_PAL_N: fmt = 0x6; break;
+	case V4L2_STD_PAL_Nc: fmt = 0x7; break;
+	case V4L2_STD_PAL_60: fmt = 0x8; break;
+	case V4L2_STD_SECAM: fmt = 0xc; break;
+	default:
+		return -ERANGE;
+	}
+
+	cx25840_and_or(client, 0x400, ~0xf, fmt);
+	cx25840_vbi_setup(client);
+	return 0;
+}
+
+v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client)
+{
+	/* check VID_FMT_SEL first */
+	u8 fmt = cx25840_read(client, 0x400) & 0xf;
+
+	if (!fmt) {
+		/* check AFD_FMT_STAT if set to autodetect */
+		fmt = cx25840_read(client, 0x40d) & 0xf;
+	}
+
+	switch (fmt) {
+	case 0x1: return V4L2_STD_NTSC_M;
+	case 0x2: return V4L2_STD_NTSC_M_JP;
+	case 0x3: return V4L2_STD_NTSC_443;
+	case 0x4: return V4L2_STD_PAL;
+	case 0x5: return V4L2_STD_PAL_M;
+	case 0x6: return V4L2_STD_PAL_N;
+	case 0x7: return V4L2_STD_PAL_Nc;
+	case 0x8: return V4L2_STD_PAL_60;
+	case 0xc: return V4L2_STD_SECAM;
+	default: return V4L2_STD_UNKNOWN;
+	}
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+{
+	struct cx25840_state *state = i2c_get_clientdata(client);
+
+	switch (ctrl->id) {
+	case CX25840_CID_CARDTYPE:
+		switch (ctrl->value) {
+		case CARDTYPE_PVR150:
+		case CARDTYPE_PG600:
+			state->cardtype = ctrl->value;
+			break;
+		default:
+			return -ERANGE;
+		}
+
+		set_input(client, state->input);
+		break;
+
+	case V4L2_CID_BRIGHTNESS:
+		if (ctrl->value < 0 || ctrl->value > 255) {
+			cx25840_err("invalid brightness setting %d\n",
+				    ctrl->value);
+			return -ERANGE;
+		}
+
+		cx25840_write(client, 0x414, ctrl->value - 128);
+		break;
+
+	case V4L2_CID_CONTRAST:
+		if (ctrl->value < 0 || ctrl->value > 127) {
+			cx25840_err("invalid contrast setting %d\n",
+				    ctrl->value);
+			return -ERANGE;
+		}
+
+		cx25840_write(client, 0x415, ctrl->value << 1);
+		break;
+
+	case V4L2_CID_SATURATION:
+		if (ctrl->value < 0 || ctrl->value > 127) {
+			cx25840_err("invalid saturation setting %d\n",
+				    ctrl->value);
+			return -ERANGE;
+		}
+
+		cx25840_write(client, 0x420, ctrl->value << 1);
+		cx25840_write(client, 0x421, ctrl->value << 1);
+		break;
+
+	case V4L2_CID_HUE:
+		if (ctrl->value < -127 || ctrl->value > 127) {
+			cx25840_err("invalid hue setting %d\n", ctrl->value);
+			return -ERANGE;
+		}
+
+		cx25840_write(client, 0x422, ctrl->value);
+		break;
+
+	case V4L2_CID_AUDIO_VOLUME:
+	case V4L2_CID_AUDIO_BASS:
+	case V4L2_CID_AUDIO_TREBLE:
+	case V4L2_CID_AUDIO_BALANCE:
+	case V4L2_CID_AUDIO_MUTE:
+		return cx25840_audio(client, VIDIOC_S_CTRL, ctrl);
+	}
+
+	return 0;
+}
+
+static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+{
+	struct cx25840_state *state = i2c_get_clientdata(client);
+
+	switch (ctrl->id) {
+	case CX25840_CID_CARDTYPE:
+		ctrl->value = state->cardtype;
+		break;
+	case V4L2_CID_BRIGHTNESS:
+		ctrl->value = cx25840_read(client, 0x414) + 128;
+		break;
+	case V4L2_CID_CONTRAST:
+		ctrl->value = cx25840_read(client, 0x415) >> 1;
+		break;
+	case V4L2_CID_SATURATION:
+		ctrl->value = cx25840_read(client, 0x420) >> 1;
+		break;
+	case V4L2_CID_HUE:
+		ctrl->value = cx25840_read(client, 0x422);
+		break;
+	case V4L2_CID_AUDIO_VOLUME:
+	case V4L2_CID_AUDIO_BASS:
+	case V4L2_CID_AUDIO_TREBLE:
+	case V4L2_CID_AUDIO_BALANCE:
+	case V4L2_CID_AUDIO_MUTE:
+		return cx25840_audio(client, VIDIOC_G_CTRL, ctrl);
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
+{
+	switch (fmt->type) {
+	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+		return cx25840_vbi(client, VIDIOC_G_FMT, fmt);
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
+{
+	struct v4l2_pix_format *pix;
+	int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
+	int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC);
+
+	switch (fmt->type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		pix = &(fmt->fmt.pix);
+
+		Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4;
+		Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4;
+
+		Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4;
+		Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4;
+
+		Vlines = pix->height + (is_pal ? 4 : 7);
+
+		if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
+		    (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
+			cx25840_err("%dx%d is not a valid size!\n",
+				    pix->width, pix->height);
+			return -ERANGE;
+		}
+
+		HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20);
+		VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9));
+		VSC &= 0x1fff;
+
+		if (pix->width >= 385)
+			filter = 0;
+		else if (pix->width > 192)
+			filter = 1;
+		else if (pix->width > 96)
+			filter = 2;
+		else
+			filter = 3;
+
+		cx25840_dbg("decoder set size %dx%d -> scale  %ux%u\n",
+			    pix->width, pix->height, HSC, VSC);
+
+		/* HSCALE=HSC */
+		cx25840_write(client, 0x418, HSC & 0xff);
+		cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
+		cx25840_write(client, 0x41a, HSC >> 16);
+		/* VSCALE=VSC */
+		cx25840_write(client, 0x41c, VSC & 0xff);
+		cx25840_write(client, 0x41d, VSC >> 8);
+		/* VS_INTRLACE=1 VFILT=filter */
+		cx25840_write(client, 0x41e, 0x8 | filter);
+		break;
+
+	case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+		return cx25840_vbi(client, VIDIOC_S_FMT, fmt);
+
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		return cx25840_vbi(client, VIDIOC_S_FMT, fmt);
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int cx25840_command(struct i2c_client *client, unsigned int cmd,
+			   void *arg)
+{
+	struct cx25840_state *state = i2c_get_clientdata(client);
+	struct v4l2_tuner *vt = arg;
+	int result = 0;
+
+	switch (cmd) {
+	case 0:
+		break;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	/* ioctls to allow direct access to the
+	 * cx25840 registers for testing */
+	case VIDIOC_INT_G_REGISTER:
+	{
+		struct v4l2_register *reg = arg;
+
+		if (reg->i2c_id != I2C_DRIVERID_CX25840)
+			return -EINVAL;
+		reg->val = cx25840_read(client, reg->reg & 0x0fff);
+		break;
+	}
+
+	case VIDIOC_INT_S_REGISTER:
+	{
+		struct v4l2_register *reg = arg;
+
+		if (reg->i2c_id != I2C_DRIVERID_CX25840)
+			return -EINVAL;
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+		cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);
+		break;
+	}
+#endif
+
+	case VIDIOC_INT_DECODE_VBI_LINE:
+		return cx25840_vbi(client, cmd, arg);
+
+	case VIDIOC_INT_AUDIO_CLOCK_FREQ:
+	case AUDC_SET_INPUT:
+		result = cx25840_audio(client, cmd, arg);
+		break;
+
+	case VIDIOC_STREAMON:
+		cx25840_dbg("enable output\n");
+		cx25840_write(client, 0x115, 0x8c);
+		cx25840_write(client, 0x116, 0x07);
+		break;
+
+	case VIDIOC_STREAMOFF:
+		cx25840_dbg("disable output\n");
+		cx25840_write(client, 0x115, 0x00);
+		cx25840_write(client, 0x116, 0x00);
+		break;
+
+	case VIDIOC_LOG_STATUS:
+		log_status(client);
+		break;
+
+	case VIDIOC_G_CTRL:
+		result = get_v4lctrl(client, (struct v4l2_control *)arg);
+		break;
+
+	case VIDIOC_S_CTRL:
+		result = set_v4lctrl(client, (struct v4l2_control *)arg);
+		break;
+
+	case VIDIOC_G_STD:
+		*(v4l2_std_id *)arg = cx25840_get_v4lstd(client);
+		break;
+
+	case VIDIOC_S_STD:
+		result = set_v4lstd(client, *(v4l2_std_id *)arg);
+		break;
+
+	case VIDIOC_G_INPUT:
+		*(int *)arg = state->input;
+		break;
+
+	case VIDIOC_S_INPUT:
+		result = set_input(client, *(int *)arg);
+		break;
+
+	case VIDIOC_S_FREQUENCY:
+		input_change(client);
+		break;
+
+	case VIDIOC_G_TUNER:
+	{
+		u8 mode = cx25840_read(client, 0x804);
+		u8 pref = cx25840_read(client, 0x809) & 0xf;
+		u8 vpres = cx25840_read(client, 0x80a) & 0x10;
+		int val = 0;
+
+		vt->capability |=
+		    V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
+		    V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+
+		vt->signal = vpres ? 0xffff : 0x0;
+
+		/* get rxsubchans and audmode */
+		if ((mode & 0xf) == 1)
+			val |= V4L2_TUNER_SUB_STEREO;
+		else
+			val |= V4L2_TUNER_SUB_MONO;
+
+		if (mode == 2 || mode == 4)
+			val |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+
+		if (mode & 0x10)
+			val |= V4L2_TUNER_SUB_SAP;
+
+		vt->rxsubchans = val;
+
+		switch (pref) {
+		case 0:
+			vt->audmode = V4L2_TUNER_MODE_MONO;
+			break;
+		case 1:
+		case 2:
+			vt->audmode = V4L2_TUNER_MODE_LANG2;
+			break;
+		case 4:
+		default:
+			vt->audmode = V4L2_TUNER_MODE_STEREO;
+		}
+		break;
+	}
+
+	case VIDIOC_S_TUNER:
+		switch (vt->audmode) {
+		case V4L2_TUNER_MODE_MONO:
+		case V4L2_TUNER_MODE_LANG1:
+			/* Force PREF_MODE to MONO */
+			cx25840_and_or(client, 0x809, ~0xf, 0x00);
+			break;
+		case V4L2_TUNER_MODE_STEREO:
+			/* Force PREF_MODE to STEREO */
+			cx25840_and_or(client, 0x809, ~0xf, 0x04);
+			break;
+		case V4L2_TUNER_MODE_LANG2:
+			/* Force PREF_MODE to LANG2 */
+			cx25840_and_or(client, 0x809, ~0xf, 0x01);
+			break;
+		}
+		break;
+
+	case VIDIOC_G_FMT:
+		result = get_v4lfmt(client, (struct v4l2_format *)arg);
+		break;
+
+	case VIDIOC_S_FMT:
+		result = set_v4lfmt(client, (struct v4l2_format *)arg);
+		break;
+
+	case VIDIOC_INT_RESET:
+		cx25840_initialize(client, 0);
+		break;
+
+	case VIDIOC_INT_G_CHIP_IDENT:
+		*(enum v4l2_chip_ident *)arg =
+			V4L2_IDENT_CX25840 + ((cx25840_read(client, 0x100) >> 4) & 0xf);
+		break;
+
+	default:
+		cx25840_err("invalid ioctl %x\n", cmd);
+		return -EINVAL;
+	}
+
+	return result;
+}
+
+/* ----------------------------------------------------------------------- */
+
+struct i2c_driver i2c_driver_cx25840;
+
+static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
+				 int kind)
+{
+	struct i2c_client *client;
+	struct cx25840_state *state;
+	u16 device_id;
+
+	/* Check if the adapter supports the needed features
+	 * Not until kernel version 2.6.11 did the bit-algo
+	 * correctly report that it would do an I2C-level xfer */
+	if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
+		return 0;
+
+	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (client == 0)
+		return -ENOMEM;
+
+	memset(client, 0, sizeof(struct i2c_client));
+	client->addr = address;
+	client->adapter = adapter;
+	client->driver = &i2c_driver_cx25840;
+	client->flags = I2C_CLIENT_ALLOW_USE;
+	snprintf(client->name, sizeof(client->name) - 1, "cx25840");
+
+	cx25840_dbg("detecting cx25840 client on address 0x%x\n", address << 1);
+
+	device_id = cx25840_read(client, 0x101) << 8;
+	device_id |= cx25840_read(client, 0x100);
+
+	/* The high byte of the device ID should be
+	 * 0x84 if chip is present */
+	if ((device_id & 0xff00) != 0x8400) {
+		cx25840_dbg("cx25840 not found\n");
+		kfree(client);
+		return 0;
+	}
+
+	cx25840_info("cx25%3x-2%x found @ 0x%x (%s)\n",
+		    (device_id & 0xfff0) >> 4,
+		    (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3,
+		    address << 1, adapter->name);
+
+	state = kmalloc(sizeof(struct cx25840_state), GFP_KERNEL);
+	if (state == NULL) {
+		kfree(client);
+		return -ENOMEM;
+	}
+
+	i2c_set_clientdata(client, state);
+	memset(state, 0, sizeof(struct cx25840_state));
+	state->input = CX25840_TUNER;
+	state->audclk_freq = V4L2_AUDCLK_48_KHZ;
+	state->audio_input = AUDIO_TUNER;
+	state->cardtype = CARDTYPE_PVR150;
+
+	cx25840_initialize(client, 1);
+
+	i2c_attach_client(client);
+
+	return 0;
+}
+
+static int cx25840_attach_adapter(struct i2c_adapter *adapter)
+{
+#ifdef I2C_CLASS_TV_ANALOG
+	if (adapter->class & I2C_CLASS_TV_ANALOG)
+#else
+	if (adapter->id == I2C_HW_B_BT848)
+#endif
+		return i2c_probe(adapter, &addr_data, &cx25840_detect_client);
+	return 0;
+}
+
+static int cx25840_detach_client(struct i2c_client *client)
+{
+	struct cx25840_state *state = i2c_get_clientdata(client);
+	int err;
+
+	err = i2c_detach_client(client);
+	if (err) {
+		return err;
+	}
+
+	kfree(state);
+	kfree(client);
+
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+struct i2c_driver i2c_driver_cx25840 = {
+	.name = "cx25840",
+
+	.id = I2C_DRIVERID_CX25840,
+	.flags = I2C_DF_NOTIFY,
+
+	.attach_adapter = cx25840_attach_adapter,
+	.detach_client = cx25840_detach_client,
+	.command = cx25840_command,
+	.owner = THIS_MODULE,
+};
+
+
+static int __init m__init(void)
+{
+	return i2c_add_driver(&i2c_driver_cx25840);
+}
+
+static void __exit m__exit(void)
+{
+	i2c_del_driver(&i2c_driver_cx25840);
+}
+
+module_init(m__init);
+module_exit(m__exit);
+
+/* ----------------------------------------------------------------------- */
+
+static void log_status(struct i2c_client *client)
+{
+	static const char *const fmt_strs[] = {
+		"0x0",
+		"NTSC-M", "NTSC-J", "NTSC-4.43",
+		"PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",
+		"0x9", "0xA", "0xB",
+		"SECAM",
+		"0xD", "0xE", "0xF"
+	};
+
+	struct cx25840_state *state = i2c_get_clientdata(client);
+	u8 microctrl_vidfmt = cx25840_read(client, 0x80a);
+	u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf;
+	u8 gen_stat1 = cx25840_read(client, 0x40d);
+	u8 download_ctl = cx25840_read(client, 0x803);
+	u8 mod_det_stat0 = cx25840_read(client, 0x804);
+	u8 mod_det_stat1 = cx25840_read(client, 0x805);
+	u8 audio_config = cx25840_read(client, 0x808);
+	u8 pref_mode = cx25840_read(client, 0x809);
+	u8 afc0 = cx25840_read(client, 0x80b);
+	u8 mute_ctl = cx25840_read(client, 0x8d3);
+	char *p;
+
+	cx25840_info("Video signal:              %spresent\n",
+		    (microctrl_vidfmt & 0x10) ? "" : "not ");
+	cx25840_info("Detected format:           %s\n",
+		    fmt_strs[gen_stat1 & 0xf]);
+
+	switch (mod_det_stat0) {
+	case 0x00: p = "mono"; break;
+	case 0x01: p = "stereo"; break;
+	case 0x02: p = "dual"; break;
+	case 0x04: p = "tri"; break;
+	case 0x10: p = "mono with SAP"; break;
+	case 0x11: p = "stereo with SAP"; break;
+	case 0x12: p = "dual with SAP"; break;
+	case 0x14: p = "tri with SAP"; break;
+	case 0xfe: p = "forced mode"; break;
+	default: p = "not defined";
+	}
+	cx25840_info("Detected audio mode:       %s\n", p);
+
+	switch (mod_det_stat1) {
+	case 0x00: p = "not defined"; break;
+	case 0x01: p = "EIAJ"; break;
+	case 0x02: p = "A2-M"; break;
+	case 0x03: p = "A2-BG"; break;
+	case 0x04: p = "A2-DK1"; break;
+	case 0x05: p = "A2-DK2"; break;
+	case 0x06: p = "A2-DK3"; break;
+	case 0x07: p = "A1 (6.0 MHz FM Mono)"; break;
+	case 0x08: p = "AM-L"; break;
+	case 0x09: p = "NICAM-BG"; break;
+	case 0x0a: p = "NICAM-DK"; break;
+	case 0x0b: p = "NICAM-I"; break;
+	case 0x0c: p = "NICAM-L"; break;
+	case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break;
+	case 0x0e: p = "IF FM Radio"; break;
+	case 0x0f: p = "BTSC"; break;
+	case 0x10: p = "high-deviation FM"; break;
+	case 0x11: p = "very high-deviation FM"; break;
+	case 0xfd: p = "unknown audio standard"; break;
+	case 0xfe: p = "forced audio standard"; break;
+	case 0xff: p = "no detected audio standard"; break;
+	default: p = "not defined";
+	}
+	cx25840_info("Detected audio standard:   %s\n", p);
+	cx25840_info("Audio muted:               %s\n",
+		    (mute_ctl & 0x2) ? "yes" : "no");
+	cx25840_info("Audio microcontroller:     %s\n",
+		    (download_ctl & 0x10) ? "running" : "stopped");
+
+	switch (audio_config >> 4) {
+	case 0x00: p = "undefined"; break;
+	case 0x01: p = "BTSC"; break;
+	case 0x02: p = "EIAJ"; break;
+	case 0x03: p = "A2-M"; break;
+	case 0x04: p = "A2-BG"; break;
+	case 0x05: p = "A2-DK1"; break;
+	case 0x06: p = "A2-DK2"; break;
+	case 0x07: p = "A2-DK3"; break;
+	case 0x08: p = "A1 (6.0 MHz FM Mono)"; break;
+	case 0x09: p = "AM-L"; break;
+	case 0x0a: p = "NICAM-BG"; break;
+	case 0x0b: p = "NICAM-DK"; break;
+	case 0x0c: p = "NICAM-I"; break;
+	case 0x0d: p = "NICAM-L"; break;
+	case 0x0e: p = "FM radio"; break;
+	case 0x0f: p = "automatic detection"; break;
+	default: p = "undefined";
+	}
+	cx25840_info("Configured audio standard: %s\n", p);
+
+	if ((audio_config >> 4) < 0xF) {
+		switch (audio_config & 0xF) {
+		case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break;
+		case 0x01: p = "MONO2 (LANGUAGE B)"; break;
+		case 0x02: p = "MONO3 (STEREO forced MONO)"; break;
+		case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break;
+		case 0x04: p = "STEREO"; break;
+		case 0x05: p = "DUAL1 (AB)"; break;
+		case 0x06: p = "DUAL2 (AC) (FM)"; break;
+		case 0x07: p = "DUAL3 (BC) (FM)"; break;
+		case 0x08: p = "DUAL4 (AC) (AM)"; break;
+		case 0x09: p = "DUAL5 (BC) (AM)"; break;
+		case 0x0a: p = "SAP"; break;
+		default: p = "undefined";
+		}
+		cx25840_info("Configured audio mode:     %s\n", p);
+	} else {
+		switch (audio_config & 0xF) {
+		case 0x00: p = "BG"; break;
+		case 0x01: p = "DK1"; break;
+		case 0x02: p = "DK2"; break;
+		case 0x03: p = "DK3"; break;
+		case 0x04: p = "I"; break;
+		case 0x05: p = "L"; break;
+		case 0x06: p = "BTSC"; break;
+		case 0x07: p = "EIAJ"; break;
+		case 0x08: p = "A2-M"; break;
+		case 0x09: p = "FM Radio"; break;
+		case 0x0f: p = "automatic standard and mode detection"; break;
+		default: p = "undefined";
+		}
+		cx25840_info("Configured audio system:   %s\n", p);
+	}
+
+	cx25840_info("Specified standard:        %s\n",
+		    vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
+
+	switch (state->input) {
+	case CX25840_COMPOSITE0: p = "Composite 0"; break;
+	case CX25840_COMPOSITE1: p = "Composite 1"; break;
+	case CX25840_SVIDEO0: p = "S-Video 0"; break;
+	case CX25840_SVIDEO1: p = "S-Video 1"; break;
+	case CX25840_TUNER: p = "Tuner"; break;
+	}
+	cx25840_info("Specified input:           %s\n", p);
+	cx25840_info("Specified audio input:     %s\n",
+		    state->audio_input == 0 ? "Tuner" : "External");
+
+	switch (state->audclk_freq) {
+	case V4L2_AUDCLK_441_KHZ: p = "44.1 kHz"; break;
+	case V4L2_AUDCLK_48_KHZ: p = "48 kHz"; break;
+	case V4L2_AUDCLK_32_KHZ: p = "32 kHz"; break;
+	default: p = "undefined";
+	}
+	cx25840_info("Specified audioclock freq: %s\n", p);
+
+	switch (pref_mode & 0xf) {
+	case 0: p = "mono/language A"; break;
+	case 1: p = "language B"; break;
+	case 2: p = "language C"; break;
+	case 3: p = "analog fallback"; break;
+	case 4: p = "stereo"; break;
+	case 5: p = "language AC"; break;
+	case 6: p = "language BC"; break;
+	case 7: p = "language AB"; break;
+	default: p = "undefined";
+	}
+	cx25840_info("Preferred audio mode:      %s\n", p);
+
+	if ((audio_config & 0xf) == 0xf) {
+		switch ((afc0 >> 3) & 0x3) {
+		case 0: p = "system DK"; break;
+		case 1: p = "system L"; break;
+		case 2: p = "autodetect"; break;
+		default: p = "undefined";
+		}
+		cx25840_info("Selected 65 MHz format:    %s\n", p);
+
+		switch (afc0 & 0x7) {
+		case 0: p = "chroma"; break;
+		case 1: p = "BTSC"; break;
+		case 2: p = "EIAJ"; break;
+		case 3: p = "A2-M"; break;
+		case 4: p = "autodetect"; break;
+		default: p = "undefined";
+		}
+		cx25840_info("Selected 45 MHz format:    %s\n", p);
+	}
+}
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c
new file mode 100644
index 0000000..df9d50a
--- /dev/null
+++ b/drivers/media/video/cx25840/cx25840-firmware.c
@@ -0,0 +1,167 @@
+/* cx25840 firmware functions
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/firmware.h>
+#include <media/v4l2-common.h>
+
+#include "cx25840.h"
+
+#define FWFILE "v4l-cx25840.fw"
+#define FWSEND 1024
+
+#define FWDEV(x) &((x)->adapter->dev)
+
+static int fastfw = 1;
+static char *firmware = FWFILE;
+
+module_param(fastfw, bool, 0444);
+module_param(firmware, charp, 0444);
+
+MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]");
+MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]");
+
+static inline void set_i2c_delay(struct i2c_client *client, int delay)
+{
+	struct i2c_algo_bit_data *algod = client->adapter->algo_data;
+
+	/* We aren't guaranteed to be using algo_bit,
+	 * so avoid the null pointer dereference
+	 * and disable the 'fast firmware load' */
+	if (algod) {
+		algod->udelay = delay;
+	} else {
+		fastfw = 0;
+	}
+}
+
+static inline void start_fw_load(struct i2c_client *client)
+{
+	/* DL_ADDR_LB=0 DL_ADDR_HB=0 */
+	cx25840_write(client, 0x800, 0x00);
+	cx25840_write(client, 0x801, 0x00);
+	// DL_MAP=3 DL_AUTO_INC=0 DL_ENABLE=1
+	cx25840_write(client, 0x803, 0x0b);
+	/* AUTO_INC_DIS=1 */
+	cx25840_write(client, 0x000, 0x20);
+
+	if (fastfw)
+		set_i2c_delay(client, 3);
+}
+
+static inline void end_fw_load(struct i2c_client *client)
+{
+	if (fastfw)
+		set_i2c_delay(client, 10);
+
+	/* AUTO_INC_DIS=0 */
+	cx25840_write(client, 0x000, 0x00);
+	/* DL_ENABLE=0 */
+	cx25840_write(client, 0x803, 0x03);
+}
+
+static inline int check_fw_load(struct i2c_client *client, int size)
+{
+	/* DL_ADDR_HB DL_ADDR_LB */
+	int s = cx25840_read(client, 0x801) << 8;
+	s |= cx25840_read(client, 0x800);
+
+	if (size != s) {
+		cx25840_err("firmware %s load failed\n", firmware);
+		return -EINVAL;
+	}
+
+	cx25840_info("loaded %s firmware (%d bytes)\n", firmware, size);
+	return 0;
+}
+
+static inline int fw_write(struct i2c_client *client, u8 * data, int size)
+{
+	if (i2c_master_send(client, data, size) < size) {
+
+		if (fastfw) {
+			cx25840_err("333MHz i2c firmware load failed\n");
+			fastfw = 0;
+			set_i2c_delay(client, 10);
+
+			if (i2c_master_send(client, data, size) < size) {
+				cx25840_err
+				    ("100MHz i2c firmware load failed\n");
+				return -ENOSYS;
+			}
+
+		} else {
+			cx25840_err("firmware load i2c failure\n");
+			return -ENOSYS;
+		}
+
+	}
+
+	return 0;
+}
+
+int cx25840_loadfw(struct i2c_client *client)
+{
+	const struct firmware *fw = NULL;
+	u8 buffer[4], *ptr;
+	int size, send, retval;
+
+	if (request_firmware(&fw, firmware, FWDEV(client)) != 0) {
+		cx25840_err("unable to open firmware %s\n", firmware);
+		return -EINVAL;
+	}
+
+	start_fw_load(client);
+
+	buffer[0] = 0x08;
+	buffer[1] = 0x02;
+	buffer[2] = fw->data[0];
+	buffer[3] = fw->data[1];
+	retval = fw_write(client, buffer, 4);
+
+	if (retval < 0) {
+		release_firmware(fw);
+		return retval;
+	}
+
+	size = fw->size - 2;
+	ptr = fw->data;
+	while (size > 0) {
+		ptr[0] = 0x08;
+		ptr[1] = 0x02;
+		send = size > (FWSEND - 2) ? FWSEND : size + 2;
+		retval = fw_write(client, ptr, send);
+
+		if (retval < 0) {
+			release_firmware(fw);
+			return retval;
+		}
+
+		size -= FWSEND - 2;
+		ptr += FWSEND - 2;
+	}
+
+	end_fw_load(client);
+
+	size = fw->size;
+	release_firmware(fw);
+
+	return check_fw_load(client, size);
+}
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c
new file mode 100644
index 0000000..13ba4e1
--- /dev/null
+++ b/drivers/media/video/cx25840/cx25840-vbi.c
@@ -0,0 +1,315 @@
+/* cx25840 VBI functions
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+#include <media/v4l2-common.h>
+
+#include "cx25840.h"
+
+static inline int odd_parity(u8 c)
+{
+	c ^= (c >> 4);
+	c ^= (c >> 2);
+	c ^= (c >> 1);
+
+	return c & 1;
+}
+
+static inline int decode_vps(u8 * dst, u8 * p)
+{
+	static const u8 biphase_tbl[] = {
+		0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+		0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+		0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
+		0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
+		0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
+		0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
+		0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+		0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+		0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
+		0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
+		0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
+		0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
+		0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
+		0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
+		0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
+		0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
+		0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
+		0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
+		0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
+		0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
+		0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
+		0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
+		0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
+		0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
+		0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+		0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+		0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
+		0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
+		0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
+		0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
+		0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+		0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+	};
+
+	u8 c, err = 0;
+	int i;
+
+	for (i = 0; i < 2 * 13; i += 2) {
+		err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
+		c = (biphase_tbl[p[i + 1]] & 0xf) |
+		    ((biphase_tbl[p[i]] & 0xf) << 4);
+		dst[i / 2] = c;
+	}
+
+	return err & 0xf0;
+}
+
+void cx25840_vbi_setup(struct i2c_client *client)
+{
+	v4l2_std_id std = cx25840_get_v4lstd(client);
+
+	if (std & ~V4L2_STD_NTSC) {
+		/* datasheet startup, step 8d */
+		cx25840_write(client, 0x49f, 0x11);
+
+		cx25840_write(client, 0x470, 0x84);
+		cx25840_write(client, 0x471, 0x00);
+		cx25840_write(client, 0x472, 0x2d);
+		cx25840_write(client, 0x473, 0x5d);
+
+		cx25840_write(client, 0x474, 0x24);
+		cx25840_write(client, 0x475, 0x40);
+		cx25840_write(client, 0x476, 0x24);
+		cx25840_write(client, 0x477, 0x28);
+
+		cx25840_write(client, 0x478, 0x1f);
+		cx25840_write(client, 0x479, 0x02);
+
+		if (std & V4L2_STD_SECAM) {
+			cx25840_write(client, 0x47a, 0x80);
+			cx25840_write(client, 0x47b, 0x00);
+			cx25840_write(client, 0x47c, 0x5f);
+			cx25840_write(client, 0x47d, 0x42);
+		} else {
+			cx25840_write(client, 0x47a, 0x90);
+			cx25840_write(client, 0x47b, 0x20);
+			cx25840_write(client, 0x47c, 0x63);
+			cx25840_write(client, 0x47d, 0x82);
+		}
+
+		cx25840_write(client, 0x47e, 0x0a);
+		cx25840_write(client, 0x47f, 0x01);
+	} else {
+		/* datasheet startup, step 8d */
+		cx25840_write(client, 0x49f, 0x14);
+
+		cx25840_write(client, 0x470, 0x7a);
+		cx25840_write(client, 0x471, 0x00);
+		cx25840_write(client, 0x472, 0x2d);
+		cx25840_write(client, 0x473, 0x5b);
+
+		cx25840_write(client, 0x474, 0x1a);
+		cx25840_write(client, 0x475, 0x70);
+		cx25840_write(client, 0x476, 0x1e);
+		cx25840_write(client, 0x477, 0x1e);
+
+		cx25840_write(client, 0x478, 0x1f);
+		cx25840_write(client, 0x479, 0x02);
+		cx25840_write(client, 0x47a, 0x50);
+		cx25840_write(client, 0x47b, 0x66);
+
+		cx25840_write(client, 0x47c, 0x1f);
+		cx25840_write(client, 0x47d, 0x7c);
+		cx25840_write(client, 0x47e, 0x08);
+		cx25840_write(client, 0x47f, 0x00);
+	}
+}
+
+int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+	struct v4l2_format *fmt;
+	struct v4l2_sliced_vbi_format *svbi;
+
+	switch (cmd) {
+	case VIDIOC_G_FMT:
+	{
+		static u16 lcr2vbi[] = {
+			0, V4L2_SLICED_TELETEXT_B, 0,	/* 1 */
+			0, V4L2_SLICED_WSS_625, 0,	/* 4 */
+			V4L2_SLICED_CAPTION_525,	/* 6 */
+			0, 0, V4L2_SLICED_VPS, 0, 0,	/* 9 */
+			0, 0, 0, 0
+		};
+		int i;
+
+		fmt = arg;
+		if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+			return -EINVAL;
+		svbi = &fmt->fmt.sliced;
+		memset(svbi, 0, sizeof(*svbi));
+		/* we're done if raw VBI is active */
+		if ((cx25840_read(client, 0x404) & 0x10) == 0)
+			break;
+
+		for (i = 7; i <= 23; i++) {
+			u8 v = cx25840_read(client, 0x424 + i - 7);
+
+			svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+			svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+			svbi->service_set |=
+				 svbi->service_lines[0][i] | svbi->service_lines[1][i];
+		}
+		break;
+	}
+
+	case VIDIOC_S_FMT:
+	{
+		int is_pal = !(cx25840_get_v4lstd(client) & V4L2_STD_NTSC);
+		int vbi_offset = is_pal ? 1 : 0;
+		int i, x;
+		u8 lcr[24];
+
+		fmt = arg;
+		if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+			return -EINVAL;
+		svbi = &fmt->fmt.sliced;
+		if (svbi->service_set == 0) {
+			/* raw VBI */
+			memset(svbi, 0, sizeof(*svbi));
+
+			/* Setup VBI */
+			cx25840_vbi_setup(client);
+
+			/* VBI Offset */
+			cx25840_write(client, 0x47f, vbi_offset);
+			cx25840_write(client, 0x404, 0x2e);
+			break;
+		}
+
+		for (x = 0; x <= 23; x++)
+			lcr[x] = 0x00;
+
+		/* Setup VBI */
+		cx25840_vbi_setup(client);
+
+		/* Sliced VBI */
+		cx25840_write(client, 0x404, 0x36);	/* Ancillery data */
+		cx25840_write(client, 0x406, 0x13);
+		cx25840_write(client, 0x47f, vbi_offset);
+
+		if (is_pal) {
+			for (i = 0; i <= 6; i++)
+				svbi->service_lines[0][i] =
+					svbi->service_lines[1][i] = 0;
+		} else {
+			for (i = 0; i <= 9; i++)
+				svbi->service_lines[0][i] =
+					svbi->service_lines[1][i] = 0;
+
+			for (i = 22; i <= 23; i++)
+				svbi->service_lines[0][i] =
+					svbi->service_lines[1][i] = 0;
+		}
+
+		for (i = 7; i <= 23; i++) {
+			for (x = 0; x <= 1; x++) {
+				switch (svbi->service_lines[1-x][i]) {
+				case V4L2_SLICED_TELETEXT_B:
+					lcr[i] |= 1 << (4 * x);
+					break;
+				case V4L2_SLICED_WSS_625:
+					lcr[i] |= 4 << (4 * x);
+					break;
+				case V4L2_SLICED_CAPTION_525:
+					lcr[i] |= 6 << (4 * x);
+					break;
+				case V4L2_SLICED_VPS:
+					lcr[i] |= 9 << (4 * x);
+					break;
+				}
+			}
+		}
+
+		for (x = 1, i = 0x424; i <= 0x434; i++, x++) {
+			cx25840_write(client, i, lcr[6 + x]);
+		}
+
+		cx25840_write(client, 0x43c, 0x16);
+
+		if (is_pal) {
+			cx25840_write(client, 0x474, 0x2a);
+		} else {
+			cx25840_write(client, 0x474, 0x1a + 6);
+		}
+		break;
+	}
+
+	case VIDIOC_INT_DECODE_VBI_LINE:
+	{
+		struct v4l2_decode_vbi_line *vbi = arg;
+		u8 *p = vbi->p;
+		int id1, id2, l, err = 0;
+
+		if (p[0] || p[1] != 0xff || p[2] != 0xff ||
+		    (p[3] != 0x55 && p[3] != 0x91)) {
+			vbi->line = vbi->type = 0;
+			break;
+		}
+
+		p += 4;
+		id1 = p[-1];
+		id2 = p[0] & 0xf;
+		l = p[2] & 0x3f;
+		l += 5;
+		p += 4;
+
+		switch (id2) {
+		case 1:
+			id2 = V4L2_SLICED_TELETEXT_B;
+			break;
+		case 4:
+			id2 = V4L2_SLICED_WSS_625;
+			break;
+		case 6:
+			id2 = V4L2_SLICED_CAPTION_525;
+			err = !odd_parity(p[0]) || !odd_parity(p[1]);
+			break;
+		case 9:
+			id2 = V4L2_SLICED_VPS;
+			if (decode_vps(p, p) != 0) {
+				err = 1;
+			}
+			break;
+		default:
+			id2 = 0;
+			err = 1;
+			break;
+		}
+
+		vbi->type = err ? 0 : id2;
+		vbi->line = err ? 0 : l;
+		vbi->is_second_field = err ? 0 : (id1 == 0x55);
+		vbi->p = p;
+		break;
+	}
+	}
+
+	return 0;
+}
diff --git a/drivers/media/video/cx25840/cx25840.h b/drivers/media/video/cx25840/cx25840.h
new file mode 100644
index 0000000..5c3f063
--- /dev/null
+++ b/drivers/media/video/cx25840/cx25840.h
@@ -0,0 +1,85 @@
+/* cx25840 API header
+ *
+ * Copyright (C) 2003-2004 Chris Kennedy
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _CX25840_H_
+#define _CX25840_H_
+
+
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+
+extern int cx25840_debug;
+
+#define cx25840_dbg(fmt, arg...) do { if (cx25840_debug) \
+	printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+
+#define cx25840_err(fmt, arg...) do { \
+	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+
+#define cx25840_info(fmt, arg...) do { \
+	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+
+#define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0)
+
+enum cx25840_cardtype {
+	CARDTYPE_PVR150,
+	CARDTYPE_PG600
+};
+
+enum cx25840_input {
+	CX25840_TUNER,
+	CX25840_COMPOSITE0,
+	CX25840_COMPOSITE1,
+	CX25840_SVIDEO0,
+	CX25840_SVIDEO1
+};
+
+struct cx25840_state {
+	enum cx25840_cardtype cardtype;
+	enum cx25840_input input;
+	int audio_input;
+	enum v4l2_audio_clock_freq audclk_freq;
+};
+
+/* ----------------------------------------------------------------------- */
+/* cx25850-core.c 							   */
+int cx25840_write(struct i2c_client *client, u16 addr, u8 value);
+int cx25840_write4(struct i2c_client *client, u16 addr, u32 value);
+u8 cx25840_read(struct i2c_client *client, u16 addr);
+u32 cx25840_read4(struct i2c_client *client, u16 addr);
+int cx25840_and_or(struct i2c_client *client, u16 addr, u8 mask, u8 value);
+v4l2_std_id cx25840_get_v4lstd(struct i2c_client *client);
+
+/* ----------------------------------------------------------------------- */
+/* cx25850-firmware.c                                                      */
+int cx25840_loadfw(struct i2c_client *client);
+
+/* ----------------------------------------------------------------------- */
+/* cx25850-audio.c                                                         */
+int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg);
+
+/* ----------------------------------------------------------------------- */
+/* cx25850-vbi.c                                                           */
+void cx25840_vbi_setup(struct i2c_client *client);
+int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg);
+
+#endif
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 9cce91e..99ea955 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -439,9 +439,6 @@ static int dvb_register(struct cx8802_de
 	/* Put the analog decoder in standby to keep it quiet */
 	cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
 
-	/* Put the analog decoder in standby to keep it quiet */
-	cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
-
 	/* register everything */
 	return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
 }
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 32c49df..9b94f77 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -120,9 +120,6 @@ static int get_key_em_haup(struct IR_i2c
 	if (buf[1]==0xff)
 		return 0;
 
-	/* avoid fast reapeating */
-	if (buf[1]==ir->old)
-		return 0;
 	ir->old=buf[1];
 
 	/* Rearranges bits to the right order */
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
index ed81934..5abfc0f 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -221,24 +221,99 @@ static IR_KEYTAB_TYPE ir_codes_conceptro
 	[ 24 ] = KEY_MUTE         // mute/unmute
 };
 
+static IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = {
+	[0x00] = KEY_KP0,
+	[0x01] = KEY_KP1,
+	[0x02] = KEY_KP2,
+	[0x03] = KEY_KP3,
+	[0x04] = KEY_KP4,
+	[0x05] = KEY_KP5,
+	[0x06] = KEY_KP6,
+	[0x07] = KEY_KP7,
+	[0x08] = KEY_KP8,
+	[0x09] = KEY_KP9,
+	[0x0a] = KEY_TV,
+	[0x0b] = KEY_AUX,
+	[0x0c] = KEY_DVD,
+	[0x0d] = KEY_POWER,
+	[0x0e] = KEY_MHP,	/* labelled 'Picture' */
+	[0x0f] = KEY_AUDIO,
+	[0x10] = KEY_INFO,
+	[0x11] = KEY_F13,	/* 16:9 */
+	[0x12] = KEY_F14,	/* 14:9 */
+	[0x13] = KEY_EPG,
+	[0x14] = KEY_EXIT,
+	[0x15] = KEY_MENU,
+	[0x16] = KEY_UP,
+	[0x17] = KEY_DOWN,
+	[0x18] = KEY_LEFT,
+	[0x19] = KEY_RIGHT,
+	[0x1a] = KEY_ENTER,
+	[0x1b] = KEY_CHANNELUP,
+	[0x1c] = KEY_CHANNELDOWN,
+	[0x1d] = KEY_VOLUMEUP,
+	[0x1e] = KEY_VOLUMEDOWN,
+	[0x1f] = KEY_RED,
+	[0x20] = KEY_GREEN,
+	[0x21] = KEY_YELLOW,
+	[0x22] = KEY_BLUE,
+	[0x23] = KEY_SUBTITLE,
+	[0x24] = KEY_F15,	/* AD */
+	[0x25] = KEY_TEXT,
+	[0x26] = KEY_MUTE,
+	[0x27] = KEY_REWIND,
+	[0x28] = KEY_STOP,
+	[0x29] = KEY_PLAY,
+	[0x2a] = KEY_FASTFORWARD,
+	[0x2b] = KEY_F16,	/* chapter */
+	[0x2c] = KEY_PAUSE,
+	[0x2d] = KEY_PLAY,
+	[0x2e] = KEY_RECORD,
+	[0x2f] = KEY_F17,	/* picture in picture */
+	[0x30] = KEY_KPPLUS,	/* zoom in */
+	[0x31] = KEY_KPMINUS,	/* zoom out */
+	[0x32] = KEY_F18,	/* capture */
+	[0x33] = KEY_F19,	/* web */
+	[0x34] = KEY_EMAIL,
+	[0x35] = KEY_PHONE,
+	[0x36] = KEY_PC
+};
+
 struct IR {
 	struct bttv_sub_device  *sub;
 	struct input_dev        *input;
 	struct ir_input_state   ir;
 	char                    name[32];
 	char                    phys[32];
+
+	/* Usual gpio signalling */
+
 	u32                     mask_keycode;
 	u32                     mask_keydown;
 	u32                     mask_keyup;
-
-	int                     polling;
+	u32			polling;
 	u32                     last_gpio;
 	struct work_struct      work;
 	struct timer_list       timer;
+
+	/* RC5 gpio */
+
+	u32 rc5_gpio;
+	struct timer_list timer_end;	/* timer_end for code completion */
+	struct timer_list timer_keyup;	/* timer_end for key release */
+	u32 last_rc5;			/* last good rc5 code */
+	u32 last_bit;			/* last raw bit seen */
+	u32 code;			/* raw code under construction */
+	struct timeval base_time;	/* time of last seen code */
+	int active;			/* building raw code */
 };
 
 static int debug;
 module_param(debug, int, 0644);    /* debug level (0,1,2) */
+static int repeat_delay = 500;
+module_param(repeat_delay, int, 0644);
+static int repeat_period = 33;
+module_param(repeat_period, int, 0644);
 
 #define DEVNAME "ir-kbd-gpio"
 #define dprintk(fmt, arg...)	if (debug) \
@@ -254,7 +329,7 @@ static struct bttv_sub_driver driver = {
 		.probe	= ir_probe,
 		.remove	= ir_remove,
 	},
-	.gpio_irq       = ir_irq,
+	.gpio_irq 	= ir_irq,
 };
 
 /* ---------------------------------------------------------------------- */
@@ -327,6 +402,173 @@ static void ir_work(void *data)
 	mod_timer(&ir->timer, timeout);
 }
 
+/* ---------------------------------------------------------------*/
+
+static int rc5_remote_gap = 885;
+module_param(rc5_remote_gap, int, 0644);
+static int rc5_key_timeout = 200;
+module_param(rc5_key_timeout, int, 0644);
+
+#define RC5_START(x)	(((x)>>12)&3)
+#define RC5_TOGGLE(x)	(((x)>>11)&1)
+#define RC5_ADDR(x)	(((x)>>6)&31)
+#define RC5_INSTR(x)	((x)&63)
+
+/* decode raw bit pattern to RC5 code */
+static u32 rc5_decode(unsigned int code)
+{
+	unsigned int org_code = code;
+	unsigned int pair;
+	unsigned int rc5 = 0;
+	int i;
+
+	code = (code << 1) | 1;
+	for (i = 0; i < 14; ++i) {
+		pair = code & 0x3;
+		code >>= 2;
+
+		rc5 <<= 1;
+		switch (pair) {
+		case 0:
+		case 2:
+			break;
+		case 1:
+			rc5 |= 1;
+			break;
+		case 3:
+			dprintk("bad code: %x\n", org_code);
+			return 0;
+		}
+	}
+	dprintk("code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
+		"instr=%x\n", rc5, org_code, RC5_START(rc5),
+		RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
+	return rc5;
+}
+
+static int ir_rc5_irq(struct bttv_sub_device *sub)
+{
+	struct IR *ir = dev_get_drvdata(&sub->dev);
+	struct timeval tv;
+	u32 gpio;
+	u32 gap;
+	unsigned long current_jiffies, timeout;
+
+	/* read gpio port */
+	gpio = bttv_gpio_read(ir->sub->core);
+
+	/* remote IRQ? */
+	if (!(gpio & 0x20))
+		return 0;
+
+	/* get time of bit */
+	current_jiffies = jiffies;
+	do_gettimeofday(&tv);
+
+	/* avoid overflow with gap >1s */
+	if (tv.tv_sec - ir->base_time.tv_sec > 1) {
+		gap = 200000;
+	} else {
+		gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
+		    tv.tv_usec - ir->base_time.tv_usec;
+	}
+
+	/* active code => add bit */
+	if (ir->active) {
+		/* only if in the code (otherwise spurious IRQ or timer
+		   late) */
+		if (ir->last_bit < 28) {
+			ir->last_bit = (gap - rc5_remote_gap / 2) /
+			    rc5_remote_gap;
+			ir->code |= 1 << ir->last_bit;
+		}
+		/* starting new code */
+	} else {
+		ir->active = 1;
+		ir->code = 0;
+		ir->base_time = tv;
+		ir->last_bit = 0;
+
+		timeout = current_jiffies + (500 + 30 * HZ) / 1000;
+		mod_timer(&ir->timer_end, timeout);
+	}
+
+	/* toggle GPIO pin 4 to reset the irq */
+	bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4));
+	bttv_gpio_write(ir->sub->core, gpio | (1 << 4));
+	return 1;
+}
+
+static void ir_rc5_timer_end(unsigned long data)
+{
+	struct IR *ir = (struct IR *)data;
+	struct timeval tv;
+	unsigned long current_jiffies, timeout;
+	u32 gap;
+
+	/* get time */
+	current_jiffies = jiffies;
+	do_gettimeofday(&tv);
+
+	/* avoid overflow with gap >1s */
+	if (tv.tv_sec - ir->base_time.tv_sec > 1) {
+		gap = 200000;
+	} else {
+		gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
+		    tv.tv_usec - ir->base_time.tv_usec;
+	}
+
+	/* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */
+	if (gap < 28000) {
+		dprintk("spurious timer_end\n");
+		return;
+	}
+
+	ir->active = 0;
+	if (ir->last_bit < 20) {
+		/* ignore spurious codes (caused by light/other remotes) */
+		dprintk("short code: %x\n", ir->code);
+	} else {
+		u32 rc5 = rc5_decode(ir->code);
+
+		/* two start bits? */
+		if (RC5_START(rc5) != 3) {
+			dprintk("rc5 start bits invalid: %u\n", RC5_START(rc5));
+
+			/* right address? */
+		} else if (RC5_ADDR(rc5) == 0x0) {
+			u32 toggle = RC5_TOGGLE(rc5);
+			u32 instr = RC5_INSTR(rc5);
+
+			/* Good code, decide if repeat/repress */
+			if (toggle != RC5_TOGGLE(ir->last_rc5) ||
+			    instr != RC5_INSTR(ir->last_rc5)) {
+				dprintk("instruction %x, toggle %x\n", instr,
+					toggle);
+				ir_input_nokey(ir->input, &ir->ir);
+				ir_input_keydown(ir->input, &ir->ir, instr,
+						 instr);
+			}
+
+			/* Set/reset key-up timer */
+			timeout = current_jiffies + (500 + rc5_key_timeout
+						     * HZ) / 1000;
+			mod_timer(&ir->timer_keyup, timeout);
+
+			/* Save code for repeat test */
+			ir->last_rc5 = rc5;
+		}
+	}
+}
+
+static void ir_rc5_timer_keyup(unsigned long data)
+{
+	struct IR *ir = (struct IR *)data;
+
+	dprintk("key released\n");
+	ir_input_nokey(ir->input, &ir->ir);
+}
+
 /* ---------------------------------------------------------------------- */
 
 static int ir_probe(struct device *dev)
@@ -400,6 +642,12 @@ static int ir_probe(struct device *dev)
 		ir->mask_keyup   = 0x006000;
 		ir->polling      = 50; // ms
 		break;
+	case BTTV_BOARD_NEBULA_DIGITV:
+		ir_codes = ir_codes_nebula;
+		driver.any_irq = ir_rc5_irq;
+		driver.gpio_irq = NULL;
+		ir->rc5_gpio = 1;
+		 break;
 	}
 	if (NULL == ir_codes) {
 		kfree(ir);
@@ -407,9 +655,17 @@ static int ir_probe(struct device *dev)
 		return -ENODEV;
 	}
 
-	/* init hardware-specific stuff */
-	bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0);
-	ir->sub = sub;
+	if (ir->rc5_gpio) {
+		u32 gpio;
+		/* enable remote irq */
+		bttv_gpio_inout(sub->core, (1 << 4), 1 << 4);
+		gpio = bttv_gpio_read(sub->core);
+		bttv_gpio_write(sub->core, gpio & ~(1 << 4));
+		bttv_gpio_write(sub->core, gpio | (1 << 4));
+	} else {
+		/* init hardware-specific stuff */
+		bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0);
+	}
 
 	/* init input device */
 	snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
@@ -417,6 +673,7 @@ static int ir_probe(struct device *dev)
 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
 		 pci_name(sub->core->pci));
 
+	ir->sub = sub;
 	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
 	input_dev->name = ir->name;
 	input_dev->phys = ir->phys;
@@ -437,11 +694,25 @@ static int ir_probe(struct device *dev)
 		ir->timer.function = ir_timer;
 		ir->timer.data     = (unsigned long)ir;
 		schedule_work(&ir->work);
+	} else if (ir->rc5_gpio) {
+		/* set timer_end for code completion */
+		init_timer(&ir->timer_end);
+		ir->timer_end.function = ir_rc5_timer_end;
+		ir->timer_end.data = (unsigned long)ir;
+
+		init_timer(&ir->timer_keyup);
+		ir->timer_keyup.function = ir_rc5_timer_keyup;
+		ir->timer_keyup.data = (unsigned long)ir;
 	}
 
 	/* all done */
 	dev_set_drvdata(dev, ir);
 	input_register_device(ir->input);
+	printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys);
+
+	/* the remote isn't as bouncy as a keyboard */
+	ir->input->rep[REP_DELAY] = repeat_delay;
+	ir->input->rep[REP_PERIOD] = repeat_period;
 
 	return 0;
 }
@@ -454,6 +725,15 @@ static int ir_remove(struct device *dev)
 		del_timer(&ir->timer);
 		flush_scheduled_work();
 	}
+	if (ir->rc5_gpio) {
+		u32 gpio;
+
+		del_timer(&ir->timer_end);
+		flush_scheduled_work();
+
+		gpio = bttv_gpio_read(ir->sub->core);
+		bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4));
+	}
 
 	input_unregister_device(ir->input);
 	kfree(ir);
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 0085567..801c736 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -183,6 +183,58 @@ static int get_key_knc1(struct IR_i2c *i
 	return 1;
 }
 
+/* The new pinnacle PCTV remote (with the colored buttons)
+ *
+ * Ricardo Cerqueira <v4l@cerqueira.org>
+ */
+
+int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
+{
+	unsigned char b[4];
+	unsigned int start = 0,parity = 0,code = 0;
+
+	/* poll IR chip */
+	if (4 != i2c_master_recv(&ir->c,b,4)) {
+		dprintk(2,"read error\n");
+		return -EIO;
+	}
+
+	for (start = 0; start<4; start++) {
+		if (b[start] == 0x80) {
+			code=b[(start+3)%4];
+			parity=b[(start+2)%4];
+		}
+	}
+
+	/* Empty Request */
+	if (parity==0)
+		return 0;
+
+	/* Repeating... */
+	if (ir->old == parity)
+		return 0;
+
+
+	ir->old = parity;
+
+	/* Reduce code value to fit inside IR_KEYTAB_SIZE
+	 *
+	 * this is the only value that results in 42 unique
+	 * codes < 128
+	 */
+
+	code %= 0x88;
+
+	*ir_raw = code;
+	*ir_key = code;
+
+	dprintk(1,"Pinnacle PCTV key %02x\n", code);
+
+	return 1;
+}
+
+EXPORT_SYMBOL_GPL(get_key_pinnacle);
+
 /* ----------------------------------------------------------------------- */
 
 static void ir_key_poll(struct IR_i2c *ir)
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
new file mode 100644
index 0000000..0235cef
--- /dev/null
+++ b/drivers/media/video/saa7115.c
@@ -0,0 +1,1376 @@
+/* saa7115 - Philips SAA7114/SAA7115 video decoder driver
+ *
+ * Based on saa7114 driver by Maxim Yevtyushkin, which is based on
+ * the saa7111 driver by Dave Perks.
+ *
+ * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
+ * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
+ *
+ * Slight changes for video timing and attachment output by
+ * Wolfgang Scherr <scherr@net4you.net>
+ *
+ * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003)
+ * by Ronald Bultje <rbultje@ronald.bitfreak.net>
+ *
+ * Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com>
+ * (2/17/2003)
+ *
+ * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+
+MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver");
+MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil");
+MODULE_LICENSE("GPL");
+
+static int debug = 0;
+module_param(debug, int, 0644);
+
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
+#define saa7115_dbg(fmt,arg...) \
+	do { \
+		if (debug) \
+			printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+			       i2c_adapter_id(client->adapter), client->addr , ## arg); \
+	} while (0)
+
+#define saa7115_err(fmt, arg...) do { \
+	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+#define saa7115_info(fmt, arg...) do { \
+	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+
+static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
+
+
+I2C_CLIENT_INSMOD;
+
+struct saa7115_state {
+	v4l2_std_id std;
+	int input;
+	int enable;
+	int bright;
+	int contrast;
+	int hue;
+	int sat;
+	enum v4l2_chip_ident ident;
+	enum v4l2_audio_clock_freq audclk_freq;
+};
+
+/* ----------------------------------------------------------------------- */
+
+static inline int saa7115_write(struct i2c_client *client, u8 reg, u8 value)
+{
+	return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static int saa7115_writeregs(struct i2c_client *client, const unsigned char *regs)
+{
+	unsigned char reg, data;
+
+	while (*regs != 0x00) {
+		reg = *(regs++);
+		data = *(regs++);
+		if (saa7115_write(client, reg, data) < 0)
+			return -1;
+	}
+	return 0;
+}
+
+static inline int saa7115_read(struct i2c_client *client, u8 reg)
+{
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* If a value differs from the Hauppauge driver values, then the comment starts with
+   'was 0xXX' to denote the Hauppauge value. Otherwise the value is identical to what the
+   Hauppauge driver sets. */
+
+static const unsigned char saa7115_init_auto_input[] = {
+	0x01, 0x48,		/* white peak control disabled */
+	0x03, 0x20,		/* was 0x30. 0x20: long vertical blanking */
+	0x04, 0x90,		/* analog gain set to 0 */
+	0x05, 0x90,		/* analog gain set to 0 */
+	0x06, 0xeb,		/* horiz sync begin = -21 */
+	0x07, 0xe0,		/* horiz sync stop = -17 */
+	0x0a, 0x80,		/* was 0x88. decoder brightness, 0x80 is itu standard */
+	0x0b, 0x44,		/* was 0x48. decoder contrast, 0x44 is itu standard */
+	0x0c, 0x40,		/* was 0x47. decoder saturation, 0x40 is itu standard */
+	0x0d, 0x00,		/* chrominance hue control */
+	0x0f, 0x00,		/* chrominance gain control: use automicatic mode */
+	0x10, 0x06,		/* chrominance/luminance control: active adaptive combfilter */
+	0x11, 0x00,		/* delay control */
+	0x12, 0x9d,		/* RTS0 output control: VGATE */
+	0x13, 0x80,		/* X-port output control: ITU656 standard mode, RTCO output enable RTCE */
+	0x14, 0x00,		/* analog/ADC/auto compatibility control */
+	0x18, 0x40,		/* raw data gain 0x00 = nominal */
+	0x19, 0x80,		/* raw data offset 0x80 = 0 LSB */
+	0x1a, 0x77,		/* color killer level control 0x77 = recommended */
+	0x1b, 0x42,		/* misc chroma control 0x42 = recommended */
+	0x1c, 0xa9,		/* combfilter control 0xA9 = recommended */
+	0x1d, 0x01,		/* combfilter control 0x01 = recommended */
+	0x88, 0xd0,		/* reset device */
+	0x88, 0xf0,		/* set device programmed, all in operational mode */
+	0x00, 0x00
+};
+
+static const unsigned char saa7115_cfg_reset_scaler[] = {
+	0x87, 0x00,		/* disable I-port output */
+	0x88, 0xd0,		/* reset scaler */
+	0x88, 0xf0,		/* activate scaler */
+	0x87, 0x01,		/* enable I-port output */
+	0x00, 0x00
+};
+
+/* ============== SAA7715 VIDEO templates =============  */
+
+static const unsigned char saa7115_cfg_60hz_fullres_x[] = {
+	0xcc, 0xd0,		/* hsize low (output), hor. output window size = 0x2d0 = 720 */
+	0xcd, 0x02,		/* hsize hi (output) */
+
+	/* Why not in 60hz-Land, too? */
+	0xd0, 0x01,		/* downscale = 1 */
+	0xd8, 0x00,		/* hor lum scaling 0x0400 = 1 */
+	0xd9, 0x04,
+	0xdc, 0x00,		/* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
+	0xdd, 0x02,		/* H-scaling incr chroma */
+
+	0x00, 0x00
+};
+static const unsigned char saa7115_cfg_60hz_fullres_y[] = {
+	0xce, 0xf8,		/* vsize low (output), ver. output window size = 248 (but 60hz is 240?) */
+	0xcf, 0x00,		/* vsize hi (output) */
+
+	/* Why not in 60hz-Land, too? */
+	0xd5, 0x40,		/* Lum contrast, nominal value = 0x40 */
+	0xd6, 0x40,		/* Chroma satur. nominal value = 0x80 */
+
+	0xe0, 0x00,		/* V-scaling incr luma low */
+	0xe1, 0x04,		/* " hi */
+	0xe2, 0x00,		/* V-scaling incr chroma low */
+	0xe3, 0x04,		/* " hi */
+
+	0x00, 0x00
+};
+
+static const unsigned char saa7115_cfg_60hz_video[] = {
+	0x80, 0x00,		/* reset tasks */
+	0x88, 0xd0,		/* reset scaler */
+
+	0x15, 0x03,		/* VGATE pulse start */
+	0x16, 0x11,		/* VGATE pulse stop */
+	0x17, 0x9c,		/* VGATE MSB and other values */
+
+	0x08, 0x68,		/* 0xBO: auto detection, 0x68 = NTSC */
+	0x0e, 0x07,		/* lots of different stuff... video autodetection is on */
+
+	0x5a, 0x06,		/* Vertical offset, standard 60hz value for ITU656 line counting */
+
+	/* Task A */
+	0x90, 0x80,		/* Task Handling Control */
+	0x91, 0x48,		/* X-port formats/config */
+	0x92, 0x40,		/* Input Ref. signal Def. */
+	0x93, 0x84,		/* I-port config */
+	0x94, 0x01,		/* hoffset low (input), 0x0002 is minimum */
+	0x95, 0x00,		/* hoffset hi (input) */
+	0x96, 0xd0,		/* hsize low (input), 0x02d0 = 720 */
+	0x97, 0x02,		/* hsize hi (input) */
+	0x98, 0x05,		/* voffset low (input) */
+	0x99, 0x00,		/* voffset hi (input) */
+	0x9a, 0x0c,		/* vsize low (input), 0x0c = 12 */
+	0x9b, 0x00,		/* vsize hi (input) */
+	0x9c, 0xa0,		/* hsize low (output), 0x05a0 = 1440 */
+	0x9d, 0x05,		/* hsize hi (output) */
+	0x9e, 0x0c,		/* vsize low (output), 0x0c = 12 */
+	0x9f, 0x00,		/* vsize hi (output) */
+
+	/* Task B */
+	0xc0, 0x00,		/* Task Handling Control */
+	0xc1, 0x08,		/* X-port formats/config */
+	0xc2, 0x00,		/* Input Ref. signal Def. */
+	0xc3, 0x80,		/* I-port config */
+	0xc4, 0x02,		/* hoffset low (input), 0x0002 is minimum */
+	0xc5, 0x00,		/* hoffset hi (input) */
+	0xc6, 0xd0,		/* hsize low (input), 0x02d0 = 720 */
+	0xc7, 0x02,		/* hsize hi (input) */
+	0xc8, 0x12,		/* voffset low (input), 0x12 = 18 */
+	0xc9, 0x00,		/* voffset hi (input) */
+	0xca, 0xf8,		/* vsize low (input), 0xf8 = 248 */
+	0xcb, 0x00,		/* vsize hi (input) */
+	0xcc, 0xd0,		/* hsize low (output), 0x02d0 = 720 */
+	0xcd, 0x02,		/* hsize hi (output) */
+
+	0xf0, 0xad,		/* Set PLL Register. 60hz 525 lines per frame, 27 MHz */
+	0xf1, 0x05,		/* low bit with 0xF0 */
+	0xf5, 0xad,		/* Set pulse generator register */
+	0xf6, 0x01,
+
+	0x87, 0x00,		/* Disable I-port output */
+	0x88, 0xd0,		/* reset scaler */
+	0x80, 0x20,		/* Activate only task "B", continuous mode (was 0xA0) */
+	0x88, 0xf0,		/* activate scaler */
+	0x87, 0x01,		/* Enable I-port output */
+	0x00, 0x00
+};
+
+static const unsigned char saa7115_cfg_50hz_fullres_x[] = {
+	0xcc, 0xd0,		/* hsize low (output), 720 same as 60hz */
+	0xcd, 0x02,		/* hsize hi (output) */
+
+	0xd0, 0x01,		/* down scale = 1 */
+	0xd8, 0x00,		/* hor lum scaling 0x0400 = 1 */
+	0xd9, 0x04,
+	0xdc, 0x00,		/* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
+	0xdd, 0x02,		/* H-scaling incr chroma */
+
+	0x00, 0x00
+};
+static const unsigned char saa7115_cfg_50hz_fullres_y[] = {
+	0xce, 0x20,		/* vsize low (output), 0x0120 = 288 */
+	0xcf, 0x01,		/* vsize hi (output) */
+
+	0xd5, 0x40,		/* Lum contrast, nominal value = 0x40 */
+	0xd6, 0x40,		/* Chroma satur. nominal value = 0x80 */
+
+	0xe0, 0x00,		/* V-scaling incr luma low */
+	0xe1, 0x04,		/* " hi */
+	0xe2, 0x00,		/* V-scaling incr chroma low */
+	0xe3, 0x04,		/* " hi */
+
+	0x00, 0x00
+};
+
+static const unsigned char saa7115_cfg_50hz_video[] = {
+	0x80, 0x00,		/* reset tasks */
+	0x88, 0xd0,		/* reset scaler */
+
+	0x15, 0x37,		/* VGATE start */
+	0x16, 0x16,		/* VGATE stop */
+	0x17, 0x99,		/* VGATE MSB and other values */
+
+	0x08, 0x28,		/* 0x28 = PAL */
+	0x0e, 0x07,		/* chrominance control 1 */
+
+	0x5a, 0x03,		/* Vertical offset, standard 50hz value */
+
+	/* Task A */
+	0x90, 0x81,		/* Task Handling Control */
+	0x91, 0x48,		/* X-port formats/config */
+	0x92, 0x40,		/* Input Ref. signal Def. */
+	0x93, 0x84,		/* I-port config */
+	/* This is weird: the datasheet says that you should use 2 as the minimum value, */
+	/* but Hauppauge uses 0, and changing that to 2 causes indeed problems (for 50hz) */
+	0x94, 0x00,		/* hoffset low (input), 0x0002 is minimum */
+	0x95, 0x00,		/* hoffset hi (input) */
+	0x96, 0xd0,		/* hsize low (input), 0x02d0 = 720 */
+	0x97, 0x02,		/* hsize hi (input) */
+	0x98, 0x03,		/* voffset low (input) */
+	0x99, 0x00,		/* voffset hi (input) */
+	0x9a, 0x12,		/* vsize low (input), 0x12 = 18 */
+	0x9b, 0x00,		/* vsize hi (input) */
+	0x9c, 0xa0,		/* hsize low (output), 0x05a0 = 1440 */
+	0x9d, 0x05,		/* hsize hi (output) */
+	0x9e, 0x12,		/* vsize low (output), 0x12 = 18 */
+	0x9f, 0x00,		/* vsize hi (output) */
+
+	/* Task B */
+	0xc0, 0x00,		/* Task Handling Control */
+	0xc1, 0x08,		/* X-port formats/config */
+	0xc2, 0x00,		/* Input Ref. signal Def. */
+	0xc3, 0x80,		/* I-port config */
+	0xc4, 0x00,		/* hoffset low (input), 0x0002 is minimum. See comment at 0x94 above. */
+	0xc5, 0x00,		/* hoffset hi (input) */
+	0xc6, 0xd0,		/* hsize low (input), 0x02d0 = 720 */
+	0xc7, 0x02,		/* hsize hi (input) */
+	0xc8, 0x16,		/* voffset low (input), 0x16 = 22 */
+	0xc9, 0x00,		/* voffset hi (input) */
+	0xca, 0x20,		/* vsize low (input), 0x0120 = 288 */
+	0xcb, 0x01,		/* vsize hi (input) */
+	0xcc, 0xd0,		/* hsize low (output), 0x02d0 = 720 */
+	0xcd, 0x02,		/* hsize hi (output) */
+	0xce, 0x20,		/* vsize low (output), 0x0120 = 288 */
+	0xcf, 0x01,		/* vsize hi (output) */
+
+	0xf0, 0xb0,		/* Set PLL Register. 50hz 625 lines per frame, 27 MHz */
+	0xf1, 0x05,		/* low bit with 0xF0, (was 0x05) */
+	0xf5, 0xb0,		/* Set pulse generator register */
+	0xf6, 0x01,
+
+	0x87, 0x00,		/* Disable I-port output */
+	0x88, 0xd0,		/* reset scaler (was 0xD0) */
+	0x80, 0x20,		/* Activate only task "B" */
+	0x88, 0xf0,		/* activate scaler */
+	0x87, 0x01,		/* Enable I-port output */
+	0x00, 0x00
+};
+
+/* ============== SAA7715 VIDEO templates (end) =======  */
+
+static const unsigned char saa7115_cfg_vbi_on[] = {
+	0x80, 0x00,		/* reset tasks */
+	0x88, 0xd0,		/* reset scaler */
+	0x80, 0x30,		/* Activate both tasks */
+	0x88, 0xf0,		/* activate scaler */
+	0x87, 0x01,		/* Enable I-port output */
+	0x00, 0x00
+};
+
+static const unsigned char saa7115_cfg_vbi_off[] = {
+	0x80, 0x00,		/* reset tasks */
+	0x88, 0xd0,		/* reset scaler */
+	0x80, 0x20,		/* Activate only task "B" */
+	0x88, 0xf0,		/* activate scaler */
+	0x87, 0x01,		/* Enable I-port output */
+	0x00, 0x00
+};
+
+static const unsigned char saa7115_init_misc[] = {
+	0x38, 0x03,		/* audio stuff */
+	0x39, 0x10,
+	0x3a, 0x08,
+
+	0x81, 0x01,		/* reg 0x15,0x16 define blanking window */
+	0x82, 0x00,
+	0x83, 0x01,		/* I port settings */
+	0x84, 0x20,
+	0x85, 0x21,
+	0x86, 0xc5,
+	0x87, 0x01,
+
+	/* Task A */
+	0xa0, 0x01,		/* down scale = 1 */
+	0xa1, 0x00,		/* prescale accumulation length = 1 */
+	0xa2, 0x00,		/* dc gain and fir prefilter control */
+	0xa4, 0x80,		/* Lum Brightness, nominal value = 0x80 */
+	0xa5, 0x40,		/* Lum contrast, nominal value = 0x40 */
+	0xa6, 0x40,		/* Chroma satur. nominal value = 0x80 */
+	0xa8, 0x00,		/* hor lum scaling 0x0200 = 2 zoom */
+	0xa9, 0x02,		/* note: 2 x zoom ensures that VBI lines have same length as video lines. */
+	0xaa, 0x00,		/* H-phase offset Luma = 0 */
+	0xac, 0x00,		/* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
+	0xad, 0x01,		/* H-scaling incr chroma */
+	0xae, 0x00,		/* H-phase offset chroma. must be offset luma / 2 */
+
+	0xb0, 0x00,		/* V-scaling incr luma low */
+	0xb1, 0x04,		/* " hi */
+	0xb2, 0x00,		/* V-scaling incr chroma low */
+	0xb3, 0x04,		/* " hi */
+	0xb4, 0x01,		/* V-scaling mode control */
+	0xb8, 0x00,		/* V-phase offset chroma 00 */
+	0xb9, 0x00,		/* V-phase offset chroma 01 */
+	0xba, 0x00,		/* V-phase offset chroma 10 */
+	0xbb, 0x00,		/* V-phase offset chroma 11 */
+	0xbc, 0x00,		/* V-phase offset luma 00 */
+	0xbd, 0x00,		/* V-phase offset luma 01 */
+	0xbe, 0x00,		/* V-phase offset luma 10 */
+	0xbf, 0x00,		/* V-phase offset luma 11 */
+
+	/* Task B */
+	0xd0, 0x01,		/* down scale = 1 */
+	0xd1, 0x00,		/* prescale accumulation length = 1 */
+	0xd2, 0x00,		/* dc gain and fir prefilter control */
+	0xd4, 0x80,		/* Lum Brightness, nominal value = 0x80 */
+	0xd5, 0x40,		/* Lum contrast, nominal value = 0x40 */
+	0xd6, 0x40,		/* Chroma satur. nominal value = 0x80 */
+	0xd8, 0x00,		/* hor lum scaling 0x0400 = 1 */
+	0xd9, 0x04,
+	0xda, 0x00,		/* H-phase offset Luma = 0 */
+	0xdc, 0x00,		/* hor chrom scaling 0x0200. must be hor lum scaling / 2 */
+	0xdd, 0x02,		/* H-scaling incr chroma */
+	0xde, 0x00,		/* H-phase offset chroma. must be offset luma / 2 */
+
+	0xe0, 0x00,		/* V-scaling incr luma low */
+	0xe1, 0x04,		/* " hi */
+	0xe2, 0x00,		/* V-scaling incr chroma low */
+	0xe3, 0x04,		/* " hi */
+	0xe4, 0x01,		/* V-scaling mode control */
+	0xe8, 0x00,		/* V-phase offset chroma 00 */
+	0xe9, 0x00,		/* V-phase offset chroma 01 */
+	0xea, 0x00,		/* V-phase offset chroma 10 */
+	0xeb, 0x00,		/* V-phase offset chroma 11 */
+	0xec, 0x00,		/* V-phase offset luma 00 */
+	0xed, 0x00,		/* V-phase offset luma 01 */
+	0xee, 0x00,		/* V-phase offset luma 10 */
+	0xef, 0x00,		/* V-phase offset luma 11 */
+
+	0xf2, 0x50,		/* crystal clock = 24.576 MHz, target = 27MHz */
+	0xf3, 0x46,
+	0xf4, 0x00,
+	0xf7, 0x4b,		/* not the recommended settings! */
+	0xf8, 0x00,
+	0xf9, 0x4b,
+	0xfa, 0x00,
+	0xfb, 0x4b,
+	0xff, 0x88,		/* PLL2 lock detection settings: 71 lines 50% phase error */
+
+	/* Turn off VBI */
+	0x40, 0x20,             /* No framing code errors allowed. */
+	0x41, 0xff,
+	0x42, 0xff,
+	0x43, 0xff,
+	0x44, 0xff,
+	0x45, 0xff,
+	0x46, 0xff,
+	0x47, 0xff,
+	0x48, 0xff,
+	0x49, 0xff,
+	0x4a, 0xff,
+	0x4b, 0xff,
+	0x4c, 0xff,
+	0x4d, 0xff,
+	0x4e, 0xff,
+	0x4f, 0xff,
+	0x50, 0xff,
+	0x51, 0xff,
+	0x52, 0xff,
+	0x53, 0xff,
+	0x54, 0xff,
+	0x55, 0xff,
+	0x56, 0xff,
+	0x57, 0xff,
+	0x58, 0x40,
+	0x59, 0x47,
+	0x5b, 0x83,
+	0x5d, 0xbd,
+	0x5e, 0x35,
+
+	0x02, 0x84,		/* input tuner -> input 4, amplifier active */
+	0x09, 0x53,		/* 0x53, was 0x56 for 60hz. luminance control */
+
+	0x80, 0x20,		/* enable task B */
+	0x88, 0xd0,
+	0x88, 0xf0,
+	0x00, 0x00
+};
+
+/* ============== SAA7715 AUDIO settings ============= */
+
+/* 48.0 kHz */
+static const unsigned char saa7115_cfg_48_audio[] = {
+	0x34, 0xce,
+	0x35, 0xfb,
+	0x36, 0x30,
+	0x00, 0x00
+};
+
+/* 44.1 kHz */
+static const unsigned char saa7115_cfg_441_audio[] = {
+	0x34, 0xf2,
+	0x35, 0x00,
+	0x36, 0x2d,
+	0x00, 0x00
+};
+
+/* 32.0 kHz */
+static const unsigned char saa7115_cfg_32_audio[] = {
+	0x34, 0xdf,
+	0x35, 0xa7,
+	0x36, 0x20,
+	0x00, 0x00
+};
+
+/* 48.0 kHz 60hz */
+static const unsigned char saa7115_cfg_60hz_48_audio[] = {
+	0x30, 0xcd,
+	0x31, 0x20,
+	0x32, 0x03,
+	0x00, 0x00
+};
+
+/* 48.0 kHz 50hz */
+static const unsigned char saa7115_cfg_50hz_48_audio[] = {
+	0x30, 0x00,
+	0x31, 0xc0,
+	0x32, 0x03,
+	0x00, 0x00
+};
+
+/* 44.1 kHz 60hz */
+static const unsigned char saa7115_cfg_60hz_441_audio[] = {
+	0x30, 0xbc,
+	0x31, 0xdf,
+	0x32, 0x02,
+	0x00, 0x00
+};
+
+/* 44.1 kHz 50hz */
+static const unsigned char saa7115_cfg_50hz_441_audio[] = {
+	0x30, 0x00,
+	0x31, 0x72,
+	0x32, 0x03,
+	0x00, 0x00
+};
+
+/* 32.0 kHz 60hz */
+static const unsigned char saa7115_cfg_60hz_32_audio[] = {
+	0x30, 0xde,
+	0x31, 0x15,
+	0x32, 0x02,
+	0x00, 0x00
+};
+
+/* 32.0 kHz 50hz */
+static const unsigned char saa7115_cfg_50hz_32_audio[] = {
+	0x30, 0x00,
+	0x31, 0x80,
+	0x32, 0x02,
+	0x00, 0x00
+};
+
+static int saa7115_odd_parity(u8 c)
+{
+	c ^= (c >> 4);
+	c ^= (c >> 2);
+	c ^= (c >> 1);
+
+	return c & 1;
+}
+
+static int saa7115_decode_vps(u8 * dst, u8 * p)
+{
+	static const u8 biphase_tbl[] = {
+		0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+		0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+		0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
+		0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
+		0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
+		0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
+		0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+		0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+		0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
+		0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
+		0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87,
+		0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3,
+		0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85,
+		0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1,
+		0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5,
+		0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1,
+		0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
+		0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
+		0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86,
+		0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2,
+		0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84,
+		0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0,
+		0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4,
+		0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0,
+		0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+		0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+		0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96,
+		0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2,
+		0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94,
+		0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0,
+		0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
+		0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0,
+	};
+	int i;
+	u8 c, err = 0;
+
+	for (i = 0; i < 2 * 13; i += 2) {
+		err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]];
+		c = (biphase_tbl[p[i + 1]] & 0xf) | ((biphase_tbl[p[i]] & 0xf) << 4);
+		dst[i / 2] = c;
+	}
+	return err & 0xf0;
+}
+
+static int saa7115_decode_wss(u8 * p)
+{
+	static const int wss_bits[8] = {
+		0, 0, 0, 1, 0, 1, 1, 1
+	};
+	unsigned char parity;
+	int wss = 0;
+	int i;
+
+	for (i = 0; i < 16; i++) {
+		int b1 = wss_bits[p[i] & 7];
+		int b2 = wss_bits[(p[i] >> 3) & 7];
+
+		if (b1 == b2)
+			return -1;
+		wss |= b2 << i;
+	}
+	parity = wss & 15;
+	parity ^= parity >> 2;
+	parity ^= parity >> 1;
+
+	if (!(parity & 1))
+		return -1;
+
+	return wss;
+}
+
+
+static int saa7115_set_audio_clock_freq(struct i2c_client *client, enum v4l2_audio_clock_freq freq)
+{
+	struct saa7115_state *state = i2c_get_clientdata(client);
+
+	saa7115_dbg("set audio clock freq: %d\n", freq);
+	switch (freq) {
+		case V4L2_AUDCLK_32_KHZ:
+			saa7115_writeregs(client, saa7115_cfg_32_audio);
+			if (state->std & V4L2_STD_525_60) {
+				saa7115_writeregs(client, saa7115_cfg_60hz_32_audio);
+			} else {
+				saa7115_writeregs(client, saa7115_cfg_50hz_32_audio);
+			}
+			break;
+		case V4L2_AUDCLK_441_KHZ:
+			saa7115_writeregs(client, saa7115_cfg_441_audio);
+			if (state->std & V4L2_STD_525_60) {
+				saa7115_writeregs(client, saa7115_cfg_60hz_441_audio);
+			} else {
+				saa7115_writeregs(client, saa7115_cfg_50hz_441_audio);
+			}
+			break;
+		case V4L2_AUDCLK_48_KHZ:
+			saa7115_writeregs(client, saa7115_cfg_48_audio);
+			if (state->std & V4L2_STD_525_60) {
+				saa7115_writeregs(client, saa7115_cfg_60hz_48_audio);
+			} else {
+				saa7115_writeregs(client, saa7115_cfg_50hz_48_audio);
+			}
+			break;
+		default:
+			saa7115_dbg("invalid audio setting %d\n", freq);
+			return -EINVAL;
+	}
+	state->audclk_freq = freq;
+	return 0;
+}
+
+static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+{
+	struct saa7115_state *state = i2c_get_clientdata(client);
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		if (ctrl->value < 0 || ctrl->value > 255) {
+			saa7115_err("invalid brightness setting %d\n", ctrl->value);
+			return -ERANGE;
+		}
+
+		state->bright = ctrl->value;
+		saa7115_write(client, 0x0a, state->bright);
+		break;
+
+	case V4L2_CID_CONTRAST:
+		if (ctrl->value < 0 || ctrl->value > 127) {
+			saa7115_err("invalid contrast setting %d\n", ctrl->value);
+			return -ERANGE;
+		}
+
+		state->contrast = ctrl->value;
+		saa7115_write(client, 0x0b, state->contrast);
+		break;
+
+	case V4L2_CID_SATURATION:
+		if (ctrl->value < 0 || ctrl->value > 127) {
+			saa7115_err("invalid saturation setting %d\n", ctrl->value);
+			return -ERANGE;
+		}
+
+		state->sat = ctrl->value;
+		saa7115_write(client, 0x0c, state->sat);
+		break;
+
+	case V4L2_CID_HUE:
+		if (ctrl->value < -127 || ctrl->value > 127) {
+			saa7115_err("invalid hue setting %d\n", ctrl->value);
+			return -ERANGE;
+		}
+
+		state->hue = ctrl->value;
+		saa7115_write(client, 0x0d, state->hue);
+		break;
+	}
+
+	return 0;
+}
+
+static int saa7115_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+{
+	struct saa7115_state *state = i2c_get_clientdata(client);
+
+	switch (ctrl->id) {
+	case V4L2_CID_BRIGHTNESS:
+		ctrl->value = state->bright;
+		break;
+	case V4L2_CID_CONTRAST:
+		ctrl->value = state->contrast;
+		break;
+	case V4L2_CID_SATURATION:
+		ctrl->value = state->sat;
+		break;
+	case V4L2_CID_HUE:
+		ctrl->value = state->hue;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
+{
+	struct saa7115_state *state = i2c_get_clientdata(client);
+	int taskb = saa7115_read(client, 0x80) & 0x10;
+
+	// This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
+	if (std & V4L2_STD_525_60) {
+		saa7115_dbg("decoder set standard 60 Hz\n");
+		saa7115_writeregs(client, saa7115_cfg_60hz_video);
+	} else {
+		saa7115_dbg("decoder set standard 50 Hz\n");
+		saa7115_writeregs(client, saa7115_cfg_50hz_video);
+	}
+
+	state->std = std;
+
+	/* restart task B if needed */
+	if (taskb && state->ident == V4L2_IDENT_SAA7114) {
+		saa7115_writeregs(client, saa7115_cfg_vbi_on);
+	}
+
+	/* switch audio mode too! */
+	saa7115_set_audio_clock_freq(client, state->audclk_freq);
+}
+
+static v4l2_std_id saa7115_get_v4lstd(struct i2c_client *client)
+{
+	struct saa7115_state *state = i2c_get_clientdata(client);
+
+	return state->std;
+}
+
+static void saa7115_log_status(struct i2c_client *client)
+{
+	static const char * const audclk_freq_strs[] = {
+		"44.1 kHz",
+		"48 kHz",
+		"32 kHz"
+	};
+	struct saa7115_state *state = i2c_get_clientdata(client);
+	int reg1e, reg1f;
+	int signalOk;
+	int vcr;
+
+	saa7115_info("Audio frequency: %s\n", audclk_freq_strs[state->audclk_freq]);
+	if (client->name[6] == '4') {
+		/* status for the saa7114 */
+		reg1f = saa7115_read(client, 0x1f);
+		signalOk = (reg1f & 0xc1) == 0x81;
+		saa7115_info("Video signal:    %s\n", signalOk ? "ok" : "bad");
+		saa7115_info("Frequency:       %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz");
+		return;
+	}
+
+	/* status for the saa7115 */
+	reg1e = saa7115_read(client, 0x1e);
+	reg1f = saa7115_read(client, 0x1f);
+
+	signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
+	vcr = !(reg1f & 0x10);
+
+	saa7115_info("Video signal:    %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
+	saa7115_info("Frequency:       %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz");
+
+	switch (reg1e & 0x03) {
+		case 1:
+			saa7115_info("Detected format: NTSC\n");
+			break;
+		case 2:
+			saa7115_info("Detected format: PAL\n");
+			break;
+		case 3:
+			saa7115_info("Detected format: SECAM\n");
+			break;
+		default:
+			saa7115_info("Detected format: BW/No color\n");
+			break;
+	}
+}
+
+/* setup the sliced VBI lcr registers according to the sliced VBI format */
+static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt)
+{
+	struct saa7115_state *state = i2c_get_clientdata(client);
+	int is_50hz = (state->std & V4L2_STD_625_50);
+	u8 lcr[24];
+	int i, x;
+
+	/* saa7114 doesn't yet support VBI */
+	if (state->ident == V4L2_IDENT_SAA7114)
+		return;
+
+	for (i = 0; i <= 23; i++)
+		lcr[i] = 0xff;
+
+	if (fmt->service_set == 0) {
+		/* raw VBI */
+		if (is_50hz)
+			for (i = 6; i <= 23; i++)
+				lcr[i] = 0xdd;
+		else
+			for (i = 10; i <= 21; i++)
+				lcr[i] = 0xdd;
+	} else {
+		/* sliced VBI */
+		/* first clear lines that cannot be captured */
+		if (is_50hz) {
+			for (i = 0; i <= 5; i++)
+				fmt->service_lines[0][i] =
+					fmt->service_lines[1][i] = 0;
+		}
+		else {
+			for (i = 0; i <= 9; i++)
+				fmt->service_lines[0][i] =
+					fmt->service_lines[1][i] = 0;
+			for (i = 22; i <= 23; i++)
+				fmt->service_lines[0][i] =
+					fmt->service_lines[1][i] = 0;
+		}
+
+		/* Now set the lcr values according to the specified service */
+		for (i = 6; i <= 23; i++) {
+			lcr[i] = 0;
+			for (x = 0; x <= 1; x++) {
+				switch (fmt->service_lines[1-x][i]) {
+					case 0:
+						lcr[i] |= 0xf << (4 * x);
+						break;
+					case V4L2_SLICED_TELETEXT_B:
+						lcr[i] |= 1 << (4 * x);
+						break;
+					case V4L2_SLICED_CAPTION_525:
+						lcr[i] |= 4 << (4 * x);
+						break;
+					case V4L2_SLICED_WSS_625:
+						lcr[i] |= 5 << (4 * x);
+						break;
+					case V4L2_SLICED_VPS:
+						lcr[i] |= 7 << (4 * x);
+						break;
+				}
+			}
+		}
+	}
+
+	/* write the lcr registers */
+	for (i = 2; i <= 23; i++) {
+		saa7115_write(client, i - 2 + 0x41, lcr[i]);
+	}
+
+	/* enable/disable raw VBI capturing */
+	saa7115_writeregs(client, fmt->service_set == 0 ? saa7115_cfg_vbi_on : saa7115_cfg_vbi_off);
+}
+
+static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
+{
+	static u16 lcr2vbi[] = {
+		0, V4L2_SLICED_TELETEXT_B, 0,	/* 1 */
+		0, V4L2_SLICED_CAPTION_525,	/* 4 */
+		V4L2_SLICED_WSS_625, 0,		/* 5 */
+		V4L2_SLICED_VPS, 0, 0, 0, 0,	/* 7 */
+		0, 0, 0, 0
+	};
+	struct v4l2_sliced_vbi_format *sliced = &fmt->fmt.sliced;
+	int i;
+
+	if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+		return -EINVAL;
+	memset(sliced, 0, sizeof(*sliced));
+	/* done if using raw VBI */
+	if (saa7115_read(client, 0x80) & 0x10)
+		return 0;
+	for (i = 2; i <= 23; i++) {
+		u8 v = saa7115_read(client, i - 2 + 0x41);
+
+		sliced->service_lines[0][i] = lcr2vbi[v >> 4];
+		sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
+		sliced->service_set |=
+			sliced->service_lines[0][i] | sliced->service_lines[1][i];
+	}
+	return 0;
+}
+
+static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
+{
+	struct saa7115_state *state = i2c_get_clientdata(client);
+	struct v4l2_pix_format *pix;
+	int HPSC, HFSC;
+	int VSCY, Vsrc;
+	int is_50hz = state->std & V4L2_STD_625_50;
+
+	if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
+		saa7115_set_lcr(client, &fmt->fmt.sliced);
+		return 0;
+	}
+	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		return -EINVAL;
+
+	pix = &(fmt->fmt.pix);
+
+	saa7115_dbg("decoder set size\n");
+
+	/* FIXME need better bounds checking here */
+	if ((pix->width < 1) || (pix->width > 1440))
+		return -EINVAL;
+	if ((pix->height < 1) || (pix->height > 960))
+		return -EINVAL;
+
+	/* probably have a valid size, let's set it */
+	/* Set output width/height */
+	/* width */
+	saa7115_write(client, 0xcc, (u8) (pix->width & 0xff));
+	saa7115_write(client, 0xcd, (u8) ((pix->width >> 8) & 0xff));
+	/* height */
+	saa7115_write(client, 0xce, (u8) (pix->height & 0xff));
+	saa7115_write(client, 0xcf, (u8) ((pix->height >> 8) & 0xff));
+
+	/* Scaling settings */
+	/* Hprescaler is floor(inres/outres) */
+	/* FIXME hardcoding input res */
+	if (pix->width != 720) {
+		HPSC = (int)(720 / pix->width);
+		/* 0 is not allowed (div. by zero) */
+		HPSC = HPSC ? HPSC : 1;
+		HFSC = (int)((1024 * 720) / (HPSC * pix->width));
+
+		saa7115_dbg("Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
+		/* FIXME hardcodes to "Task B"
+		 * write H prescaler integer */
+		saa7115_write(client, 0xd0, (u8) (HPSC & 0x3f));
+
+		/* write H fine-scaling (luminance) */
+		saa7115_write(client, 0xd8, (u8) (HFSC & 0xff));
+		saa7115_write(client, 0xd9, (u8) ((HFSC >> 8) & 0xff));
+		/* write H fine-scaling (chrominance)
+		 * must be lum/2, so i'll just bitshift :) */
+		saa7115_write(client, 0xDC, (u8) ((HFSC >> 1) & 0xff));
+		saa7115_write(client, 0xDD, (u8) ((HFSC >> 9) & 0xff));
+	} else {
+		if (is_50hz) {
+			saa7115_dbg("Setting full 50hz width\n");
+			saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x);
+		} else {
+			saa7115_dbg("Setting full 60hz width\n");
+			saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
+		}
+	}
+
+	Vsrc = is_50hz ? 576 : 480;
+
+	if (pix->height != Vsrc) {
+		VSCY = (int)((1024 * Vsrc) / pix->height);
+		saa7115_dbg("Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
+
+		/* Correct Contrast and Luminance */
+		saa7115_write(client, 0xd5, (u8) (64 * 1024 / VSCY));
+		saa7115_write(client, 0xd6, (u8) (64 * 1024 / VSCY));
+
+		/* write V fine-scaling (luminance) */
+		saa7115_write(client, 0xe0, (u8) (VSCY & 0xff));
+		saa7115_write(client, 0xe1, (u8) ((VSCY >> 8) & 0xff));
+		/* write V fine-scaling (chrominance) */
+		saa7115_write(client, 0xe2, (u8) (VSCY & 0xff));
+		saa7115_write(client, 0xe3, (u8) ((VSCY >> 8) & 0xff));
+	} else {
+		if (is_50hz) {
+			saa7115_dbg("Setting full 50Hz height\n");
+			saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y);
+		} else {
+			saa7115_dbg("Setting full 60hz height\n");
+			saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
+		}
+	}
+
+	saa7115_writeregs(client, saa7115_cfg_reset_scaler);
+	return 0;
+}
+
+/* Decode the sliced VBI data stream as created by the saa7115.
+   The format is described in the saa7115 datasheet in Tables 25 and 26
+   and in Figure 33.
+   The current implementation uses SAV/EAV codes and not the ancillary data
+   headers. The vbi->p pointer points to the SDID byte right after the SAV
+   code. */
+static void saa7115_decode_vbi_line(struct i2c_client *client,
+				    struct v4l2_decode_vbi_line *vbi)
+{
+	static const char vbi_no_data_pattern[] = {
+		0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
+	};
+	struct saa7115_state *state = i2c_get_clientdata(client);
+	u8 *p = vbi->p;
+	u32 wss;
+	int id1, id2;   /* the ID1 and ID2 bytes from the internal header */
+
+	vbi->type = 0;  /* mark result as a failure */
+	id1 = p[2];
+	id2 = p[3];
+	/* Note: the field bit is inverted for 60 Hz video */
+	if (state->std & V4L2_STD_525_60)
+		id1 ^= 0x40;
+
+	/* Skip internal header, p now points to the start of the payload */
+	p += 4;
+	vbi->p = p;
+
+	/* calculate field and line number of the VBI packet (1-23) */
+	vbi->is_second_field = ((id1 & 0x40) != 0);
+	vbi->line = (id1 & 0x3f) << 3;
+	vbi->line |= (id2 & 0x70) >> 4;
+
+	/* Obtain data type */
+	id2 &= 0xf;
+
+	/* If the VBI slicer does not detect any signal it will fill up
+	   the payload buffer with 0xa0 bytes. */
+	if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
+		return;
+
+	/* decode payloads */
+	switch (id2) {
+	case 1:
+		vbi->type = V4L2_SLICED_TELETEXT_B;
+		break;
+	case 4:
+		if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1]))
+			return;
+		vbi->type = V4L2_SLICED_CAPTION_525;
+		break;
+	case 5:
+		wss = saa7115_decode_wss(p);
+		if (wss == -1)
+			return;
+		p[0] = wss & 0xff;
+		p[1] = wss >> 8;
+		vbi->type = V4L2_SLICED_WSS_625;
+		break;
+	case 7:
+		if (saa7115_decode_vps(p, p) != 0)
+			return;
+		vbi->type = V4L2_SLICED_VPS;
+		break;
+	default:
+		return;
+	}
+}
+
+/* ============ SAA7115 AUDIO settings (end) ============= */
+
+static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+	struct saa7115_state *state = i2c_get_clientdata(client);
+	int *iarg = arg;
+
+	/* ioctls to allow direct access to the saa7115 registers for testing */
+	switch (cmd) {
+	case VIDIOC_S_FMT:
+		return saa7115_set_v4lfmt(client, (struct v4l2_format *)arg);
+
+	case VIDIOC_G_FMT:
+		return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg);
+
+	case VIDIOC_INT_AUDIO_CLOCK_FREQ:
+		return saa7115_set_audio_clock_freq(client, *(enum v4l2_audio_clock_freq *)arg);
+
+	case VIDIOC_G_TUNER:
+	{
+		struct v4l2_tuner *vt = arg;
+		int status;
+
+		status = saa7115_read(client, 0x1f);
+
+		saa7115_dbg("status: 0x%02x\n", status);
+		vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
+		break;
+	}
+
+	case VIDIOC_LOG_STATUS:
+		saa7115_log_status(client);
+		break;
+
+	case VIDIOC_G_CTRL:
+		return saa7115_get_v4lctrl(client, (struct v4l2_control *)arg);
+
+	case VIDIOC_S_CTRL:
+		return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg);
+
+	case VIDIOC_G_STD:
+		*(v4l2_std_id *)arg = saa7115_get_v4lstd(client);
+		break;
+
+	case VIDIOC_S_STD:
+		saa7115_set_v4lstd(client, *(v4l2_std_id *)arg);
+		break;
+
+	case VIDIOC_G_INPUT:
+		*(int *)arg = state->input;
+		break;
+
+	case VIDIOC_S_INPUT:
+		saa7115_dbg("decoder set input %d\n", *iarg);
+		/* inputs from 0-9 are available */
+		if (*iarg < 0 || *iarg > 9) {
+			return -EINVAL;
+		}
+
+		if (state->input == *iarg)
+			break;
+		saa7115_dbg("now setting %s input\n",
+			*iarg >= 6 ? "S-Video" : "Composite");
+		state->input = *iarg;
+
+		/* select mode */
+		saa7115_write(client, 0x02,
+			      (saa7115_read(client, 0x02) & 0xf0) |
+			       state->input);
+
+		/* bypass chrominance trap for modes 6..9 */
+		saa7115_write(client, 0x09,
+			      (saa7115_read(client, 0x09) & 0x7f) |
+			       (state->input < 6 ? 0x0 : 0x80));
+		break;
+
+	case VIDIOC_STREAMON:
+	case VIDIOC_STREAMOFF:
+		saa7115_dbg("%s output\n",
+			(cmd == VIDIOC_STREAMON) ? "enable" : "disable");
+
+		if (state->enable != (cmd == VIDIOC_STREAMON)) {
+			state->enable = (cmd == VIDIOC_STREAMON);
+			saa7115_write(client, 0x87, state->enable);
+		}
+		break;
+
+	case VIDIOC_INT_DECODE_VBI_LINE:
+		saa7115_decode_vbi_line(client, arg);
+		break;
+
+	case VIDIOC_INT_RESET:
+		saa7115_dbg("decoder RESET\n");
+		saa7115_writeregs(client, saa7115_cfg_reset_scaler);
+		break;
+
+	case VIDIOC_INT_G_VBI_DATA:
+	{
+		struct v4l2_sliced_vbi_data *data = arg;
+
+		switch (data->id) {
+		case V4L2_SLICED_WSS_625:
+			if (saa7115_read(client, 0x6b) & 0xc0)
+				return -EIO;
+			data->data[0] = saa7115_read(client, 0x6c);
+			data->data[1] = saa7115_read(client, 0x6d);
+			return 0;
+		case V4L2_SLICED_CAPTION_525:
+			if (data->field == 0) {
+				/* CC */
+				if (saa7115_read(client, 0x66) & 0xc0)
+					return -EIO;
+				data->data[0] = saa7115_read(client, 0x67);
+				data->data[1] = saa7115_read(client, 0x68);
+				return 0;
+			}
+			/* XDS */
+			if (saa7115_read(client, 0x66) & 0x30)
+				return -EIO;
+			data->data[0] = saa7115_read(client, 0x69);
+			data->data[1] = saa7115_read(client, 0x6a);
+			return 0;
+		default:
+			return -EINVAL;
+		}
+		break;
+	}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	case VIDIOC_INT_G_REGISTER:
+	{
+		struct v4l2_register *reg = arg;
+
+		if (reg->i2c_id != I2C_DRIVERID_SAA711X)
+			return -EINVAL;
+		reg->val = saa7115_read(client, reg->reg & 0xff);
+		break;
+	}
+
+	case VIDIOC_INT_S_REGISTER:
+	{
+		struct v4l2_register *reg = arg;
+
+		if (reg->i2c_id != I2C_DRIVERID_SAA711X)
+			return -EINVAL;
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+		saa7115_write(client, reg->reg & 0xff, reg->val & 0xff);
+		break;
+	}
+#endif
+
+	case VIDIOC_INT_G_CHIP_IDENT:
+		*iarg = state->ident;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_driver i2c_driver_saa7115;
+
+static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *client;
+	struct saa7115_state *state;
+	u8 chip_id;
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return 0;
+
+	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (client == 0)
+		return -ENOMEM;
+	memset(client, 0, sizeof(struct i2c_client));
+	client->addr = address;
+	client->adapter = adapter;
+	client->driver = &i2c_driver_saa7115;
+	client->flags = I2C_CLIENT_ALLOW_USE;
+	snprintf(client->name, sizeof(client->name) - 1, "saa7115");
+
+	saa7115_dbg("detecting saa7115 client on address 0x%x\n", address << 1);
+
+	saa7115_write(client, 0, 5);
+	chip_id = saa7115_read(client, 0) & 0x0f;
+	if (chip_id != 4 && chip_id != 5) {
+		saa7115_dbg("saa7115 not found\n");
+		kfree(client);
+		return 0;
+	}
+	if (chip_id == 4) {
+		snprintf(client->name, sizeof(client->name) - 1, "saa7114");
+	}
+	saa7115_info("saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name);
+
+	state = kmalloc(sizeof(struct saa7115_state), GFP_KERNEL);
+	i2c_set_clientdata(client, state);
+	if (state == NULL) {
+		kfree(client);
+		return -ENOMEM;
+	}
+	memset(state, 0, sizeof(struct saa7115_state));
+	state->std = V4L2_STD_NTSC;
+	state->input = -1;
+	state->enable = 1;
+	state->bright = 128;
+	state->contrast = 64;
+	state->hue = 0;
+	state->sat = 64;
+	state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115;
+	state->audclk_freq = V4L2_AUDCLK_48_KHZ;
+
+	saa7115_dbg("writing init values\n");
+
+	/* init to 60hz/48khz */
+	saa7115_writeregs(client, saa7115_init_auto_input);
+	saa7115_writeregs(client, saa7115_init_misc);
+	saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x);
+	saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y);
+	saa7115_writeregs(client, saa7115_cfg_60hz_video);
+	saa7115_writeregs(client, saa7115_cfg_48_audio);
+	saa7115_writeregs(client, saa7115_cfg_60hz_48_audio);
+	saa7115_writeregs(client, saa7115_cfg_reset_scaler);
+
+	i2c_attach_client(client);
+
+	saa7115_dbg("status: (1E) 0x%02x, (1F) 0x%02x\n",
+		saa7115_read(client, 0x1e), saa7115_read(client, 0x1f));
+
+	return 0;
+}
+
+static int saa7115_probe(struct i2c_adapter *adapter)
+{
+#ifdef I2C_CLASS_TV_ANALOG
+	if (adapter->class & I2C_CLASS_TV_ANALOG)
+#else
+	if (adapter->id == I2C_HW_B_BT848)
+#endif
+		return i2c_probe(adapter, &addr_data, &saa7115_attach);
+	return 0;
+}
+
+static int saa7115_detach(struct i2c_client *client)
+{
+	struct saa7115_state *state = i2c_get_clientdata(client);
+	int err;
+
+	err = i2c_detach_client(client);
+	if (err) {
+		return err;
+	}
+
+	kfree(state);
+	kfree(client);
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+static struct i2c_driver i2c_driver_saa7115 = {
+	.name = "saa7115",
+	.id = I2C_DRIVERID_SAA711X,
+	.flags = I2C_DF_NOTIFY,
+	.attach_adapter = saa7115_probe,
+	.detach_client = saa7115_detach,
+	.command = saa7115_command,
+	.owner = THIS_MODULE,
+};
+
+
+static int __init saa7115_init_module(void)
+{
+	return i2c_add_driver(&i2c_driver_saa7115);
+}
+
+static void __exit saa7115_cleanup_module(void)
+{
+	i2c_del_driver(&i2c_driver_saa7115);
+}
+
+module_init(saa7115_init_module);
+module_exit(saa7115_cleanup_module);
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c
index 9aa8827..25b30f3 100644
--- a/drivers/media/video/saa711x.c
+++ b/drivers/media/video/saa711x.c
@@ -36,7 +36,6 @@
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <linux/sched.h>
-#include <asm/segment.h>
 #include <linux/types.h>
 #include <asm/uaccess.h>
 #include <linux/videodev.h>
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
new file mode 100644
index 0000000..843431f
--- /dev/null
+++ b/drivers/media/video/saa7127.c
@@ -0,0 +1,849 @@
+/*
+ * saa7127 - Philips SAA7127/SAA7129 video encoder driver
+ *
+ * Copyright (C) 2003 Roy Bulter <rbulter@hetnet.nl>
+ *
+ * Based on SAA7126 video encoder driver by Gillem & Andreas Oberritter
+ *
+ * Copyright (C) 2000-2001 Gillem <htoa@gmx.net>
+ * Copyright (C) 2002 Andreas Oberritter <obi@saftware.de>
+ *
+ * Based on Stadis 4:2:2 MPEG-2 Decoder Driver by Nathan Laredo
+ *
+ * Copyright (C) 1999 Nathan Laredo <laredo@gnu.org>
+ *
+ * This driver is designed for the Hauppauge 250/350 Linux driver
+ * from the ivtv Project
+ *
+ * Copyright (C) 2003 Kevin Thayer <nufan_wfk@yahoo.com>
+ *
+ * Dual output support:
+ * Copyright (C) 2004 Eric Varsanyi
+ *
+ * NTSC Tuning and 7.5 IRE Setup
+ * Copyright (C) 2004  Chris Kennedy <c@groovy.org>
+ *
+ * VBI additions & cleanup:
+ * Copyright (C) 2004, 2005 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * Note: the saa7126 is identical to the saa7127, and the saa7128 is
+ * identical to the saa7129, except that the saa7126 and saa7128 have
+ * macrovision anti-taping support. This driver will almost certainly
+ * work find for those chips, except of course for the missing anti-taping
+ * support.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+
+static int debug = 0;
+static int test_image = 0;
+
+MODULE_DESCRIPTION("Philips SAA7127/9 video encoder driver");
+MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil");
+MODULE_LICENSE("GPL");
+module_param(debug, int, 0644);
+module_param(test_image, int, 0644);
+MODULE_PARM_DESC(debug, "debug level (0-2)");
+MODULE_PARM_DESC(test_image, "test_image (0-1)");
+
+#define saa7127_dbg(fmt, arg...) \
+	do { \
+		if (debug >= 1) \
+			printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+			       i2c_adapter_id(client->adapter), client->addr , ## arg); \
+	} while (0)
+
+/* High volume debug. Use with care. */
+#define saa7127_dbg_highvol(fmt, arg...) \
+	do { \
+		if (debug == 2) \
+			printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+			       i2c_adapter_id(client->adapter), client->addr , ## arg); \
+	} while (0)
+
+#define saa7127_err(fmt, arg...) do { \
+	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+#define saa7127_info(fmt, arg...) do { \
+	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
+
+static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
+
+
+I2C_CLIENT_INSMOD;
+
+/*
+ * SAA7127 registers
+ */
+
+#define SAA7127_REG_STATUS                           0x00
+#define SAA7127_REG_WIDESCREEN_CONFIG                0x26
+#define SAA7127_REG_WIDESCREEN_ENABLE                0x27
+#define SAA7127_REG_BURST_START                      0x28
+#define SAA7127_REG_BURST_END                        0x29
+#define SAA7127_REG_COPYGEN_0                        0x2a
+#define SAA7127_REG_COPYGEN_1                        0x2b
+#define SAA7127_REG_COPYGEN_2                        0x2c
+#define SAA7127_REG_OUTPUT_PORT_CONTROL              0x2d
+#define SAA7127_REG_GAIN_LUMINANCE_RGB               0x38
+#define SAA7127_REG_GAIN_COLORDIFF_RGB               0x39
+#define SAA7127_REG_INPUT_PORT_CONTROL_1             0x3a
+#define SAA7129_REG_FADE_KEY_COL2		     0x4f
+#define SAA7127_REG_CHROMA_PHASE                     0x5a
+#define SAA7127_REG_GAINU                            0x5b
+#define SAA7127_REG_GAINV                            0x5c
+#define SAA7127_REG_BLACK_LEVEL                      0x5d
+#define SAA7127_REG_BLANKING_LEVEL                   0x5e
+#define SAA7127_REG_VBI_BLANKING                     0x5f
+#define SAA7127_REG_DAC_CONTROL                      0x61
+#define SAA7127_REG_BURST_AMP                        0x62
+#define SAA7127_REG_SUBC3                            0x63
+#define SAA7127_REG_SUBC2                            0x64
+#define SAA7127_REG_SUBC1                            0x65
+#define SAA7127_REG_SUBC0                            0x66
+#define SAA7127_REG_LINE_21_ODD_0                    0x67
+#define SAA7127_REG_LINE_21_ODD_1                    0x68
+#define SAA7127_REG_LINE_21_EVEN_0                   0x69
+#define SAA7127_REG_LINE_21_EVEN_1                   0x6a
+#define SAA7127_REG_RCV_PORT_CONTROL                 0x6b
+#define SAA7127_REG_VTRIG                            0x6c
+#define SAA7127_REG_HTRIG_HI                         0x6d
+#define SAA7127_REG_MULTI                            0x6e
+#define SAA7127_REG_CLOSED_CAPTION                   0x6f
+#define SAA7127_REG_RCV2_OUTPUT_START                0x70
+#define SAA7127_REG_RCV2_OUTPUT_END                  0x71
+#define SAA7127_REG_RCV2_OUTPUT_MSBS                 0x72
+#define SAA7127_REG_TTX_REQUEST_H_START              0x73
+#define SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH       0x74
+#define SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT        0x75
+#define SAA7127_REG_TTX_ODD_REQ_VERT_START           0x76
+#define SAA7127_REG_TTX_ODD_REQ_VERT_END             0x77
+#define SAA7127_REG_TTX_EVEN_REQ_VERT_START          0x78
+#define SAA7127_REG_TTX_EVEN_REQ_VERT_END            0x79
+#define SAA7127_REG_FIRST_ACTIVE                     0x7a
+#define SAA7127_REG_LAST_ACTIVE                      0x7b
+#define SAA7127_REG_MSB_VERTICAL                     0x7c
+#define SAA7127_REG_DISABLE_TTX_LINE_LO_0            0x7e
+#define SAA7127_REG_DISABLE_TTX_LINE_LO_1            0x7f
+
+/*
+ **********************************************************************
+ *
+ *  Arrays with configuration parameters for the SAA7127
+ *
+ **********************************************************************
+ */
+
+struct i2c_reg_value {
+	unsigned char reg;
+	unsigned char value;
+};
+
+static const struct i2c_reg_value saa7129_init_config_extra[] = {
+	{ SAA7127_REG_OUTPUT_PORT_CONTROL, 		0x38 },
+	{ SAA7127_REG_VTRIG, 				0xfa },
+};
+
+static const struct i2c_reg_value saa7127_init_config_common[] = {
+	{ SAA7127_REG_WIDESCREEN_CONFIG, 		0x0d },
+	{ SAA7127_REG_WIDESCREEN_ENABLE, 		0x00 },
+	{ SAA7127_REG_COPYGEN_0, 			0x77 },
+	{ SAA7127_REG_COPYGEN_1, 			0x41 },
+	{ SAA7127_REG_COPYGEN_2, 			0x00 },	/* Macrovision enable/disable */
+	{ SAA7127_REG_OUTPUT_PORT_CONTROL, 		0x9e },
+	{ SAA7127_REG_GAIN_LUMINANCE_RGB, 		0x00 },
+	{ SAA7127_REG_GAIN_COLORDIFF_RGB, 		0x00 },
+	{ SAA7127_REG_INPUT_PORT_CONTROL_1, 		0x80 },	/* for color bars */
+	{ SAA7127_REG_LINE_21_ODD_0, 			0x77 },
+	{ SAA7127_REG_LINE_21_ODD_1, 			0x41 },
+	{ SAA7127_REG_LINE_21_EVEN_0, 			0x88 },
+	{ SAA7127_REG_LINE_21_EVEN_1, 			0x41 },
+	{ SAA7127_REG_RCV_PORT_CONTROL, 		0x12 },
+	{ SAA7127_REG_VTRIG, 				0xf9 },
+	{ SAA7127_REG_HTRIG_HI, 			0x00 },
+	{ SAA7127_REG_RCV2_OUTPUT_START, 		0x41 },
+	{ SAA7127_REG_RCV2_OUTPUT_END, 			0xc3 },
+	{ SAA7127_REG_RCV2_OUTPUT_MSBS, 		0x00 },
+	{ SAA7127_REG_TTX_REQUEST_H_START, 		0x3e },
+	{ SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH, 	0xb8 },
+	{ SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT,  	0x03 },
+	{ SAA7127_REG_TTX_ODD_REQ_VERT_START, 		0x15 },
+	{ SAA7127_REG_TTX_ODD_REQ_VERT_END, 		0x16 },
+	{ SAA7127_REG_TTX_EVEN_REQ_VERT_START, 		0x15 },
+	{ SAA7127_REG_TTX_EVEN_REQ_VERT_END, 		0x16 },
+	{ SAA7127_REG_FIRST_ACTIVE, 			0x1a },
+	{ SAA7127_REG_LAST_ACTIVE, 			0x01 },
+	{ SAA7127_REG_MSB_VERTICAL, 			0xc0 },
+	{ SAA7127_REG_DISABLE_TTX_LINE_LO_0, 		0x00 },
+	{ SAA7127_REG_DISABLE_TTX_LINE_LO_1, 		0x00 },
+	{ 0, 0 }
+};
+
+#define SAA7127_60HZ_DAC_CONTROL 0x15
+static const struct i2c_reg_value saa7127_init_config_60hz[] = {
+	{ SAA7127_REG_BURST_START, 			0x19 },
+	/* BURST_END is also used as a chip ID in saa7127_detect_client */
+	{ SAA7127_REG_BURST_END, 			0x1d },
+	{ SAA7127_REG_CHROMA_PHASE, 			0xa3 },
+	{ SAA7127_REG_GAINU, 				0x98 },
+	{ SAA7127_REG_GAINV, 				0xd3 },
+	{ SAA7127_REG_BLACK_LEVEL, 			0x39 },
+	{ SAA7127_REG_BLANKING_LEVEL, 			0x2e },
+	{ SAA7127_REG_VBI_BLANKING, 			0x2e },
+	{ SAA7127_REG_DAC_CONTROL, 			0x15 },
+	{ SAA7127_REG_BURST_AMP, 			0x4d },
+	{ SAA7127_REG_SUBC3, 				0x1f },
+	{ SAA7127_REG_SUBC2, 				0x7c },
+	{ SAA7127_REG_SUBC1, 				0xf0 },
+	{ SAA7127_REG_SUBC0, 				0x21 },
+	{ SAA7127_REG_MULTI, 				0x90 },
+	{ SAA7127_REG_CLOSED_CAPTION, 			0x11 },
+	{ 0, 0 }
+};
+
+#define SAA7127_50HZ_DAC_CONTROL 0x02
+struct i2c_reg_value saa7127_init_config_50hz[] = {
+	{ SAA7127_REG_BURST_START, 			0x21 },
+	/* BURST_END is also used as a chip ID in saa7127_detect_client */
+	{ SAA7127_REG_BURST_END, 			0x1d },
+	{ SAA7127_REG_CHROMA_PHASE, 			0x3f },
+	{ SAA7127_REG_GAINU, 				0x7d },
+	{ SAA7127_REG_GAINV, 				0xaf },
+	{ SAA7127_REG_BLACK_LEVEL, 			0x33 },
+	{ SAA7127_REG_BLANKING_LEVEL, 			0x35 },
+	{ SAA7127_REG_VBI_BLANKING, 			0x35 },
+	{ SAA7127_REG_DAC_CONTROL, 			0x02 },
+	{ SAA7127_REG_BURST_AMP, 			0x2f },
+	{ SAA7127_REG_SUBC3, 				0xcb },
+	{ SAA7127_REG_SUBC2, 				0x8a },
+	{ SAA7127_REG_SUBC1, 				0x09 },
+	{ SAA7127_REG_SUBC0, 				0x2a },
+	{ SAA7127_REG_MULTI, 				0xa0 },
+	{ SAA7127_REG_CLOSED_CAPTION, 			0x00 },
+	{ 0, 0 }
+};
+
+/* Enumeration for the Supported input types */
+enum saa7127_input_type {
+	SAA7127_INPUT_TYPE_NORMAL,
+	SAA7127_INPUT_TYPE_TEST_IMAGE
+};
+
+/* Enumeration for the Supported Output signal types */
+enum saa7127_output_type {
+	SAA7127_OUTPUT_TYPE_BOTH,
+	SAA7127_OUTPUT_TYPE_COMPOSITE,
+	SAA7127_OUTPUT_TYPE_SVIDEO,
+	SAA7127_OUTPUT_TYPE_RGB,
+	SAA7127_OUTPUT_TYPE_YUV_C,
+	SAA7127_OUTPUT_TYPE_YUV_V
+};
+
+/*
+ **********************************************************************
+ *
+ *  Encoder Struct, holds the configuration state of the encoder
+ *
+ **********************************************************************
+ */
+
+struct saa7127_state {
+	v4l2_std_id std;
+	enum v4l2_chip_ident ident;
+	enum saa7127_input_type input_type;
+	enum saa7127_output_type output_type;
+	int video_enable;
+	int wss_enable;
+	u16 wss_mode;
+	int cc_enable;
+	u16 cc_data;
+	int xds_enable;
+	u16 xds_data;
+	int vps_enable;
+	u8 vps_data[5];
+	u8 reg_2d;
+	u8 reg_3a;
+	u8 reg_3a_cb;   /* colorbar bit */
+	u8 reg_61;
+};
+
+static const char * const output_strs[] =
+{
+	"S-Video + Composite",
+	"Composite",
+	"S-Video",
+	"RGB",
+	"YUV C",
+	"YUV V"
+};
+
+static const char * const wss_strs[] = {
+	"invalid",
+	"letterbox 14:9 center",
+	"letterbox 14:9 top",
+	"invalid",
+	"letterbox 16:9 top",
+	"invalid",
+	"invalid",
+	"16:9 full format anamorphic"
+	"4:3 full format",
+	"invalid",
+	"invalid",
+	"letterbox 16:9 center",
+	"invalid",
+	"letterbox >16:9 center",
+	"14:9 full format center",
+	"invalid",
+};
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_read(struct i2c_client *client, u8 reg)
+{
+	return i2c_smbus_read_byte_data(client, reg);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_write(struct i2c_client *client, u8 reg, u8 val)
+{
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		if (i2c_smbus_write_byte_data(client, reg, val) == 0)
+			return 0;
+	}
+	saa7127_err("I2C Write Problem\n");
+	return -1;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_write_inittab(struct i2c_client *client,
+				 const struct i2c_reg_value *regs)
+{
+	while (regs->reg != 0) {
+		saa7127_write(client, regs->reg, regs->value);
+		regs++;
+	}
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
+{
+	struct saa7127_state *state = i2c_get_clientdata(client);
+	int enable = (data->line != 0);
+
+	if (enable && (data->field != 0 || data->line != 16))
+		return -EINVAL;
+	if (state->vps_enable != enable) {
+		saa7127_dbg("Turn VPS Signal %s\n", enable ? "on" : "off");
+		saa7127_write(client, 0x54, enable << 7);
+		state->vps_enable = enable;
+	}
+	if (!enable)
+		return 0;
+
+	state->vps_data[0] = data->data[4];
+	state->vps_data[1] = data->data[10];
+	state->vps_data[2] = data->data[11];
+	state->vps_data[3] = data->data[12];
+	state->vps_data[4] = data->data[13];
+	saa7127_dbg("Set VPS data %02x %02x %02x %02x %02x\n",
+		state->vps_data[0], state->vps_data[1],
+		state->vps_data[2], state->vps_data[3],
+		state->vps_data[4]);
+	saa7127_write(client, 0x55, state->vps_data[0]);
+	saa7127_write(client, 0x56, state->vps_data[1]);
+	saa7127_write(client, 0x57, state->vps_data[2]);
+	saa7127_write(client, 0x58, state->vps_data[3]);
+	saa7127_write(client, 0x59, state->vps_data[4]);
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
+{
+	struct saa7127_state *state = i2c_get_clientdata(client);
+	u16 cc = data->data[0] << 8 | data->data[1];
+	int enable = (data->line != 0);
+
+	if (enable && (data->field != 0 || data->line != 21))
+		return -EINVAL;
+	if (state->cc_enable != enable) {
+		saa7127_dbg("Turn CC %s\n", enable ? "on" : "off");
+		saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
+				(enable << 6) | 0x11);
+		state->cc_enable = enable;
+	}
+	if (!enable)
+		return 0;
+
+	saa7127_dbg_highvol("CC data: %04x\n", cc);
+	saa7127_write(client, SAA7127_REG_LINE_21_ODD_0, cc & 0xff);
+	saa7127_write(client, SAA7127_REG_LINE_21_ODD_1, cc >> 8);
+	state->cc_data = cc;
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
+{
+	struct saa7127_state *state = i2c_get_clientdata(client);
+	u16 xds = data->data[1] << 8 | data->data[0];
+	int enable = (data->line != 0);
+
+	if (enable && (data->field != 1 || data->line != 21))
+		return -EINVAL;
+	if (state->xds_enable != enable) {
+		saa7127_dbg("Turn XDS %s\n", enable ? "on" : "off");
+		saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
+				(enable << 7) | 0x11);
+		state->xds_enable = enable;
+	}
+	if (!enable)
+		return 0;
+
+	saa7127_dbg_highvol("XDS data: %04x\n", xds);
+	saa7127_write(client, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff);
+	saa7127_write(client, SAA7127_REG_LINE_21_EVEN_1, xds >> 8);
+	state->xds_data = xds;
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
+{
+	struct saa7127_state *state = i2c_get_clientdata(client);
+	int enable = (data->line != 0);
+
+	if (enable && (data->field != 0 || data->line != 23))
+		return -EINVAL;
+	if (state->wss_enable != enable) {
+		saa7127_dbg("Turn WSS %s\n", enable ? "on" : "off");
+		saa7127_write(client, 0x27, enable << 7);
+		state->wss_enable = enable;
+	}
+	if (!enable)
+		return 0;
+
+	saa7127_write(client, 0x26, data->data[0]);
+	saa7127_write(client, 0x27, 0x80 | (data->data[1] & 0x3f));
+	saa7127_dbg("WSS mode: %s\n", wss_strs[data->data[0] & 0xf]);
+	state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0];
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_video_enable(struct i2c_client *client, int enable)
+{
+	struct saa7127_state *state = i2c_get_clientdata(client);
+
+	if (enable) {
+		saa7127_dbg("Enable Video Output\n");
+		saa7127_write(client, 0x2d, state->reg_2d);
+		saa7127_write(client, 0x61, state->reg_61);
+	} else {
+		saa7127_dbg("Disable Video Output\n");
+		saa7127_write(client, 0x2d, (state->reg_2d & 0xf0));
+		saa7127_write(client, 0x61, (state->reg_61 | 0xc0));
+	}
+	state->video_enable = enable;
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_std(struct i2c_client *client, v4l2_std_id std)
+{
+	struct saa7127_state *state = i2c_get_clientdata(client);
+	const struct i2c_reg_value *inittab;
+
+	if (std & V4L2_STD_525_60) {
+		saa7127_dbg("Selecting 60 Hz video Standard\n");
+		inittab = saa7127_init_config_60hz;
+		state->reg_61 = SAA7127_60HZ_DAC_CONTROL;
+	} else {
+		saa7127_dbg("Selecting 50 Hz video Standard\n");
+		inittab = saa7127_init_config_50hz;
+		state->reg_61 = SAA7127_50HZ_DAC_CONTROL;
+	}
+
+	/* Write Table */
+	saa7127_write_inittab(client, inittab);
+	state->std = std;
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_output_type(struct i2c_client *client, int output)
+{
+	struct saa7127_state *state = i2c_get_clientdata(client);
+
+	switch (output) {
+	case SAA7127_OUTPUT_TYPE_RGB:
+		state->reg_2d = 0x0f;	/* RGB + CVBS (for sync) */
+		state->reg_3a = 0x13;	/* by default switch YUV to RGB-matrix on */
+		break;
+
+	case SAA7127_OUTPUT_TYPE_COMPOSITE:
+		state->reg_2d = 0x08;	/* 00001000 CVBS only, RGB DAC's off (high impedance mode) */
+		state->reg_3a = 0x13;	/* by default switch YUV to RGB-matrix on */
+		break;
+
+	case SAA7127_OUTPUT_TYPE_SVIDEO:
+		state->reg_2d = 0xff;	/* 11111111  croma -> R, luma -> CVBS + G + B */
+		state->reg_3a = 0x13;	/* by default switch YUV to RGB-matrix on */
+		break;
+
+	case SAA7127_OUTPUT_TYPE_YUV_V:
+		state->reg_2d = 0x4f;	/* reg 2D = 01001111, all DAC's on, RGB + VBS */
+		state->reg_3a = 0x0b;	/* reg 3A = 00001011, bypass RGB-matrix */
+		break;
+
+	case SAA7127_OUTPUT_TYPE_YUV_C:
+		state->reg_2d = 0x0f;	/* reg 2D = 00001111, all DAC's on, RGB + CVBS */
+		state->reg_3a = 0x0b;	/* reg 3A = 00001011, bypass RGB-matrix */
+		break;
+
+	case SAA7127_OUTPUT_TYPE_BOTH:
+		state->reg_2d = 0xbf;
+		state->reg_3a = 0x13;	/* by default switch YUV to RGB-matrix on */
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	saa7127_dbg("Selecting %s output type\n", output_strs[output]);
+
+	/* Configure Encoder */
+	saa7127_write(client, 0x2d, state->reg_2d);
+	saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb);
+	state->output_type = output;
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_set_input_type(struct i2c_client *client, int input)
+{
+	struct saa7127_state *state = i2c_get_clientdata(client);
+
+	switch (input) {
+	case SAA7127_INPUT_TYPE_NORMAL:	/* avia */
+		saa7127_dbg("Selecting Normal Encoder Input\n");
+		state->reg_3a_cb = 0;
+		break;
+
+	case SAA7127_INPUT_TYPE_TEST_IMAGE:	/* color bar */
+		saa7127_dbg("Selecting Color Bar generator\n");
+		state->reg_3a_cb = 0x80;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	saa7127_write(client, 0x3a, state->reg_3a | state->reg_3a_cb);
+	state->input_type = input;
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_command(struct i2c_client *client,
+			   unsigned int cmd, void *arg)
+{
+	struct saa7127_state *state = i2c_get_clientdata(client);
+	struct v4l2_format *fmt = arg;
+	int *iarg = arg;
+
+	switch (cmd) {
+	case VIDIOC_S_STD:
+		if (state->std == *(v4l2_std_id *)arg)
+			break;
+		return saa7127_set_std(client, *(v4l2_std_id *)arg);
+
+	case VIDIOC_G_STD:
+		*(v4l2_std_id *)arg = state->std;
+		break;
+
+	case VIDIOC_S_INPUT:
+		if (state->input_type == *iarg)
+			break;
+		return saa7127_set_input_type(client, *iarg);
+
+	case VIDIOC_S_OUTPUT:
+		if (state->output_type == *iarg)
+			break;
+		return saa7127_set_output_type(client, *iarg);
+
+	case VIDIOC_STREAMON:
+	case VIDIOC_STREAMOFF:
+		if (state->video_enable == (cmd == VIDIOC_STREAMON))
+			break;
+		return saa7127_set_video_enable(client, cmd == VIDIOC_STREAMON);
+
+	case VIDIOC_G_FMT:
+		if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+			return -EINVAL;
+
+		memset(&fmt->fmt.sliced, 0, sizeof(fmt->fmt.sliced));
+		if (state->vps_enable)
+			fmt->fmt.sliced.service_lines[0][16] = V4L2_SLICED_VPS;
+		if (state->wss_enable)
+			fmt->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
+		if (state->cc_enable) {
+			fmt->fmt.sliced.service_lines[0][21] = V4L2_SLICED_CAPTION_525;
+			fmt->fmt.sliced.service_lines[1][21] = V4L2_SLICED_CAPTION_525;
+		}
+		fmt->fmt.sliced.service_set =
+			(state->vps_enable ? V4L2_SLICED_VPS : 0) |
+			(state->wss_enable ? V4L2_SLICED_WSS_625 : 0) |
+			(state->cc_enable ? V4L2_SLICED_CAPTION_525 : 0);
+		break;
+
+	case VIDIOC_LOG_STATUS:
+		saa7127_info("Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz");
+		saa7127_info("Input:    %s\n", state->input_type ?  "color bars" : "normal");
+		saa7127_info("Output:   %s\n", state->video_enable ?
+			output_strs[state->output_type] : "disabled");
+		saa7127_info("WSS:      %s\n", state->wss_enable ?
+			wss_strs[state->wss_mode] : "disabled");
+		saa7127_info("VPS:      %s\n", state->vps_enable ? "enabled" : "disabled");
+		saa7127_info("CC:       %s\n", state->cc_enable ? "enabled" : "disabled");
+		break;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+	case VIDIOC_INT_G_REGISTER:
+	{
+		struct v4l2_register *reg = arg;
+
+		if (reg->i2c_id != I2C_DRIVERID_SAA7127)
+			return -EINVAL;
+		reg->val = saa7127_read(client, reg->reg & 0xff);
+		break;
+	}
+
+	case VIDIOC_INT_S_REGISTER:
+	{
+		struct v4l2_register *reg = arg;
+
+		if (reg->i2c_id != I2C_DRIVERID_SAA7127)
+			return -EINVAL;
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+		saa7127_write(client, reg->reg & 0xff, reg->val & 0xff);
+		break;
+	}
+#endif
+
+	case VIDIOC_INT_S_VBI_DATA:
+	{
+		struct v4l2_sliced_vbi_data *data = arg;
+
+		switch (data->id) {
+			case V4L2_SLICED_WSS_625:
+				return saa7127_set_wss(client, data);
+			case V4L2_SLICED_VPS:
+				return saa7127_set_vps(client, data);
+			case V4L2_SLICED_CAPTION_525:
+				if (data->field == 0)
+					return saa7127_set_cc(client, data);
+				return saa7127_set_xds(client, data);
+			default:
+				return -EINVAL;
+		}
+		break;
+	}
+
+	case VIDIOC_INT_G_CHIP_IDENT:
+		*(enum v4l2_chip_ident *)arg = state->ident;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+struct i2c_driver i2c_driver_saa7127;
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *client;
+	struct saa7127_state *state;
+	struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 };  /* set to disabled */
+	int read_result = 0;
+
+	/* Check if the adapter supports the needed features */
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return 0;
+
+	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (client == 0)
+		return -ENOMEM;
+
+	memset(client, 0, sizeof(struct i2c_client));
+	client->addr = address;
+	client->adapter = adapter;
+	client->driver = &i2c_driver_saa7127;
+	client->flags = I2C_CLIENT_ALLOW_USE;
+	snprintf(client->name, sizeof(client->name) - 1, "saa7127");
+
+	saa7127_dbg("detecting saa7127 client on address 0x%x\n", address << 1);
+
+	/* First test register 0: Bits 5-7 are a version ID (should be 0),
+	   and bit 2 should also be 0.
+	   This is rather general, so the second test is more specific and
+	   looks at the 'ending point of burst in clock cycles' which is
+	   0x1d after a reset and not expected to ever change. */
+	if ((saa7127_read(client, 0) & 0xe4) != 0 ||
+			(saa7127_read(client, 0x29) & 0x3f) != 0x1d) {
+		saa7127_dbg("saa7127 not found\n");
+		kfree(client);
+		return 0;
+	}
+	state = kmalloc(sizeof(struct saa7127_state), GFP_KERNEL);
+
+	if (state == NULL) {
+		kfree(client);
+		return (-ENOMEM);
+	}
+
+	i2c_set_clientdata(client, state);
+	memset(state, 0, sizeof(struct saa7127_state));
+
+	/* Configure Encoder */
+
+	saa7127_dbg("Configuring encoder\n");
+	saa7127_write_inittab(client, saa7127_init_config_common);
+	saa7127_set_std(client, V4L2_STD_NTSC);
+	saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH);
+	saa7127_set_vps(client, &vbi);
+	saa7127_set_wss(client, &vbi);
+	saa7127_set_cc(client, &vbi);
+	saa7127_set_xds(client, &vbi);
+	if (test_image == 1) {
+		/* The Encoder has an internal Colorbar generator */
+		/* This can be used for debugging */
+		saa7127_set_input_type(client, SAA7127_INPUT_TYPE_TEST_IMAGE);
+	} else {
+		saa7127_set_input_type(client, SAA7127_INPUT_TYPE_NORMAL);
+	}
+	saa7127_set_video_enable(client, 1);
+
+	/* Detect if it's an saa7129 */
+	read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2);
+	saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa);
+	if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) {
+		saa7127_info("saa7129 found @ 0x%x (%s)\n", address << 1, adapter->name);
+		saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result);
+		saa7127_write_inittab(client, saa7129_init_config_extra);
+		state->ident = V4L2_IDENT_SAA7129;
+	} else {
+		saa7127_info("saa7127 found @ 0x%x (%s)\n", address << 1, adapter->name);
+		state->ident = V4L2_IDENT_SAA7127;
+	}
+
+	i2c_attach_client(client);
+
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_probe(struct i2c_adapter *adapter)
+{
+#ifdef I2C_CLASS_TV_ANALOG
+	if (adapter->class & I2C_CLASS_TV_ANALOG)
+#else
+	if (adapter->id == I2C_HW_B_BT848)
+#endif
+		return i2c_probe(adapter, &addr_data, saa7127_attach);
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int saa7127_detach(struct i2c_client *client)
+{
+	struct saa7127_state *state = i2c_get_clientdata(client);
+	int err;
+
+	/* Turn off TV output */
+	saa7127_set_video_enable(client, 0);
+
+	err = i2c_detach_client(client);
+
+	if (err) {
+		return err;
+	}
+
+	kfree(state);
+	kfree(client);
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+struct i2c_driver i2c_driver_saa7127 = {
+	.name = "saa7127",
+	.id = I2C_DRIVERID_SAA7127,
+	.flags = I2C_DF_NOTIFY,
+	.attach_adapter = saa7127_probe,
+	.detach_client = saa7127_detach,
+	.command = saa7127_command,
+	.owner = THIS_MODULE,
+};
+
+
+/* ----------------------------------------------------------------------- */
+
+static int __init saa7127_init_module(void)
+{
+	return i2c_add_driver(&i2c_driver_saa7127);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static void __exit saa7127_cleanup_module(void)
+{
+	i2c_del_driver(&i2c_driver_saa7127);
+}
+
+/* ----------------------------------------------------------------------- */
+
+module_init(saa7127_init_module);
+module_exit(saa7127_cleanup_module);
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 624e880..7bdeabe 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -1,10 +1,11 @@
 config VIDEO_SAA7134
 	tristate "Philips SAA7134 support"
-	depends on VIDEO_DEV && PCI && I2C && SOUND
+	depends on VIDEO_DEV && PCI && I2C && SOUND && SND
 	select VIDEO_BUF
 	select VIDEO_IR
 	select VIDEO_TUNER
 	select CRC32
+	select SND_PCM_OSS
 	---help---
 	  This is a video4linux driver for Philips SAA713x based
 	  TV cards.
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
index e0b28f0..4226b61 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -1,10 +1,11 @@
 
 saa7134-objs :=	saa7134-cards.o saa7134-core.o saa7134-i2c.o	\
-		saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o	\
-		saa7134-vbi.o saa7134-video.o saa7134-input.o
+		saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o    \
+		saa7134-video.o saa7134-input.o
 
 obj-$(CONFIG_VIDEO_SAA7134) +=  saa7134.o saa7134-empress.o \
-				saa6752hs.o saa7134-alsa.o
+				saa6752hs.o saa7134-alsa.o \
+				saa7134-oss.o
 obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
 
 EXTRA_CFLAGS += -I$(src)/..
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index 4f3c423..5707c66 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -30,7 +30,9 @@
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
+#include <sound/pcm_params.h>
 #include <sound/initval.h>
+#include <linux/interrupt.h>
 
 #include "saa7134.h"
 #include "saa7134-reg.h"
@@ -56,6 +58,8 @@ static int enable[SNDRV_CARDS] = {1, [1 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
 
+int position;
+
 #define dprintk(fmt, arg...)    if (debug) \
         printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg)
 
@@ -68,7 +72,7 @@ typedef struct snd_card_saa7134 {
 	int mixer_volume[MIXER_ADDR_LAST+1][2];
 	int capture_source[MIXER_ADDR_LAST+1][2];
 	struct pci_dev *pci;
-	struct saa7134_dev *saadev;
+	struct saa7134_dev *dev;
 
 	unsigned long iobase;
 	int irq;
@@ -83,12 +87,10 @@ typedef struct snd_card_saa7134 {
  */
 
 typedef struct snd_card_saa7134_pcm {
-	struct saa7134_dev *saadev;
+	struct saa7134_dev *dev;
 
 	spinlock_t lock;
-	unsigned int pcm_size;		/* buffer size */
-	unsigned int pcm_count;		/* bytes per period */
-	unsigned int pcm_bps;		/* bytes per second */
+
 	snd_pcm_substream_t *substream;
 } snd_card_saa7134_pcm_t;
 
@@ -100,13 +102,11 @@ static snd_card_t *snd_saa7134_cards[SND
  *
  *   Called when the capture device is released or the buffer overflows
  *
- *   - Copied verbatim from saa7134-oss's dsp_dma_stop. Can be dropped
- *     if we just share dsp_dma_stop and use it here
+ *   - Copied verbatim from saa7134-oss's dsp_dma_stop.
  *
  */
 
 static void saa7134_dma_stop(struct saa7134_dev *dev)
-
 {
 	dev->dmasound.dma_blk     = -1;
 	dev->dmasound.dma_running = 0;
@@ -118,8 +118,7 @@ static void saa7134_dma_stop(struct saa7
  *
  *   Called when preparing the capture device for use
  *
- *   - Copied verbatim from saa7134-oss's dsp_dma_start. Can be dropped
- *     if we just share dsp_dma_start and use it here
+ *   - Copied verbatim from saa7134-oss's dsp_dma_start.
  *
  */
 
@@ -170,9 +169,9 @@ void saa7134_irq_alsa_done(struct saa713
 	if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
 		dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count,
 			dev->dmasound.bufsize, dev->dmasound.blocks);
+		spin_unlock(&dev->slock);
 		snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN);
-		saa7134_dma_stop(dev);
-		goto done;
+		return;
 	}
 
 	/* next block addr */
@@ -194,6 +193,7 @@ void saa7134_irq_alsa_done(struct saa713
 		snd_pcm_period_elapsed(dev->dmasound.substream);
 		spin_lock(&dev->slock);
 	}
+
  done:
 	spin_unlock(&dev->slock);
 
@@ -209,7 +209,9 @@ void saa7134_irq_alsa_done(struct saa713
 
 static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
+        struct saa7134_dmasound *dmasound = dev_id;
+        struct saa7134_dev *dev = dmasound->priv_data;
+
 	unsigned long report, status;
 	int loop, handled = 0;
 
@@ -248,56 +250,23 @@ static int snd_card_saa7134_capture_trig
 					  int cmd)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
-	struct saa7134_dev *dev=saapcm->saadev;
+	snd_card_saa7134_pcm_t *pcm = runtime->private_data;
+	struct saa7134_dev *dev=pcm->dev;
 	int err = 0;
 
-	spin_lock_irq(&dev->slock);
-        if (cmd == SNDRV_PCM_TRIGGER_START) {
+	spin_lock(&dev->slock);
+	if (cmd == SNDRV_PCM_TRIGGER_START) {
 		/* start dma */
 		saa7134_dma_start(dev);
-        } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
+	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
 		/* stop dma */
 		saa7134_dma_stop(dev);
-        } else {
-                err = -EINVAL;
-        }
-	spin_unlock_irq(&dev->slock);
-
-        return err;
-}
-
-/*
- * DMA buffer config
- *
- *   Sets the values that will later be used as the size of the buffer,
- *  size of the fragments, and total number of fragments.
- *   Must be called during the preparation stage, before memory is
- *  allocated
- *
- *   - Copied verbatim from saa7134-oss. Can be dropped
- *     if we just share dsp_buffer_conf from OSS.
- */
-
-static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
-{
-	if (blksize < 0x100)
-		blksize = 0x100;
-	if (blksize > 0x10000)
-		blksize = 0x10000;
-
-	if (blocks < 2)
-		blocks = 2;
-	if ((blksize * blocks) > 1024*1024)
-		blocks = 1024*1024 / blksize;
-
-	dev->dmasound.blocks  = blocks;
-	dev->dmasound.blksize = blksize;
-	dev->dmasound.bufsize = blksize * blocks;
+	} else {
+		err = -EINVAL;
+	}
+	spin_unlock(&dev->slock);
 
-	dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
-		blocks,blksize,blksize * blocks / 1024);
-	return 0;
+	return err;
 }
 
 /*
@@ -307,16 +276,16 @@ static int dsp_buffer_conf(struct saa713
  *  ALSA, but I was unable to use ALSA's own DMA, and had to force the
  *  usage of V4L's
  *
- *   - Copied verbatim from saa7134-oss. Can be dropped
- *     if we just share dsp_buffer_init from OSS.
+ *   - Copied verbatim from saa7134-oss.
+ *
  */
 
 static int dsp_buffer_init(struct saa7134_dev *dev)
 {
 	int err;
 
-	if (!dev->dmasound.bufsize)
-		BUG();
+	BUG_ON(!dev->dmasound.bufsize);
+
 	videobuf_dma_init(&dev->dmasound.dma);
 	err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
 				       (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
@@ -326,6 +295,28 @@ static int dsp_buffer_init(struct saa713
 }
 
 /*
+ * DMA buffer release
+ *
+ *   Called after closing the device, during snd_card_saa7134_capture_close
+ *
+ */
+
+static int dsp_buffer_free(struct saa7134_dev *dev)
+{
+	if (!dev->dmasound.blksize)
+		BUG();
+
+	videobuf_dma_free(&dev->dmasound.dma);
+
+	dev->dmasound.blocks  = 0;
+	dev->dmasound.blksize = 0;
+	dev->dmasound.bufsize = 0;
+
+       return 0;
+}
+
+
+/*
  * ALSA PCM preparation
  *
  *   - One of the ALSA capture callbacks.
@@ -340,84 +331,30 @@ static int dsp_buffer_init(struct saa713
 static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	int err, bswap, sign;
+	int bswap, sign;
 	u32 fmt, control;
 	snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
 	struct saa7134_dev *dev;
-	snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
-	unsigned int bps;
-	unsigned long size;
-	unsigned count;
-
-	size = snd_pcm_lib_buffer_bytes(substream);
-	count = snd_pcm_lib_period_bytes(substream);
-
-	saapcm->saadev->dmasound.substream = substream;
-	bps = runtime->rate * runtime->channels;
-	bps *= snd_pcm_format_width(runtime->format);
-	bps /= 8;
-	if (bps <= 0)
-		return -EINVAL;
-	saapcm->pcm_bps = bps;
-	saapcm->pcm_size = snd_pcm_lib_buffer_bytes(substream);
-	saapcm->pcm_count = snd_pcm_lib_period_bytes(substream);
+	snd_card_saa7134_pcm_t *pcm = runtime->private_data;
 
+	pcm->dev->dmasound.substream = substream;
 
-	dev=saa7134->saadev;
-
-	dsp_buffer_conf(dev,saapcm->pcm_count,(saapcm->pcm_size/saapcm->pcm_count));
-
-	err = dsp_buffer_init(dev);
-	if (0 != err)
-		goto fail2;
+	dev = saa7134->dev;
 
-	/* prepare buffer */
-	if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma)))
-		return err;
-	if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
-		goto fail1;
-	if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
-					      dev->dmasound.dma.sglist,
-					      dev->dmasound.dma.sglen,
-					      0)))
-		goto fail2;
-
-
-
-	switch (runtime->format) {
-	  case SNDRV_PCM_FORMAT_U8:
-	  case SNDRV_PCM_FORMAT_S8:
+	if (snd_pcm_format_width(runtime->format) == 8)
 		fmt = 0x00;
-		break;
-	  case SNDRV_PCM_FORMAT_U16_LE:
-	  case SNDRV_PCM_FORMAT_U16_BE:
-	  case SNDRV_PCM_FORMAT_S16_LE:
-	  case SNDRV_PCM_FORMAT_S16_BE:
+	else
 		fmt = 0x01;
-		break;
-	  default:
-		err = -EINVAL;
-		return 1;
-	}
 
-	switch (runtime->format) {
-	  case SNDRV_PCM_FORMAT_S8:
-	  case SNDRV_PCM_FORMAT_S16_LE:
-	  case SNDRV_PCM_FORMAT_S16_BE:
+	if (snd_pcm_format_signed(runtime->format))
 		sign = 1;
-		break;
-	  default:
+	else
 		sign = 0;
-		break;
-	}
 
-	switch (runtime->format) {
-	  case SNDRV_PCM_FORMAT_U16_BE:
-	  case SNDRV_PCM_FORMAT_S16_BE:
-		bswap = 1; break;
-	  default:
-		bswap = 0; break;
-	}
+	if (snd_pcm_format_big_endian(runtime->format))
+		bswap = 1;
+	else
+		bswap = 0;
 
 	switch (dev->pci->device) {
 	  case PCI_DEVICE_ID_PHILIPS_SAA7134:
@@ -445,7 +382,6 @@ static int snd_card_saa7134_capture_prep
 			fmt |= 0x04;
 		saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1);
 		saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
-		//saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210);
 		break;
 	}
 
@@ -459,12 +395,6 @@ static int snd_card_saa7134_capture_prep
 	if (bswap)
 		control |= SAA7134_RS_CONTROL_BSWAP;
 
-	/* I should be able to use runtime->dma_addr in the control
-	   byte, but it doesn't work. So I allocate the DMA using the
-	   V4L functions, and force ALSA to use that as the DMA area */
-
-	runtime->dma_area = dev->dmasound.dma.vmalloc;
-
 	saa_writel(SAA7134_RS_BA1(6),0);
 	saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
 	saa_writel(SAA7134_RS_PITCH(6),0);
@@ -473,12 +403,6 @@ static int snd_card_saa7134_capture_prep
 	dev->dmasound.rate = runtime->rate;
 
 	return 0;
- fail2:
-	saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
- fail1:
-	videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
-	return err;
-
 
 }
 
@@ -496,10 +420,8 @@ static int snd_card_saa7134_capture_prep
 static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
-	struct saa7134_dev *dev=saapcm->saadev;
-
-
+	snd_card_saa7134_pcm_t *pcm = runtime->private_data;
+	struct saa7134_dev *dev=pcm->dev;
 
 	if (dev->dmasound.read_count) {
 		dev->dmasound.read_count  -= snd_pcm_lib_period_bytes(substream);
@@ -540,9 +462,9 @@ static snd_pcm_hardware_t snd_card_saa71
 
 static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
 {
-	snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
+	snd_card_saa7134_pcm_t *pcm = runtime->private_data;
 
-	kfree(saapcm);
+	kfree(pcm);
 }
 
 
@@ -552,17 +474,76 @@ static void snd_card_saa7134_runtime_fre
  *   - One of the ALSA capture callbacks.
  *
  *   Called on initialization, right before the PCM preparation
- *   Usually used in ALSA to allocate the DMA, but since we don't use the
- *  ALSA DMA it does nothing
  *
  */
 
 static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
 				    snd_pcm_hw_params_t * hw_params)
 {
+	snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
+	struct saa7134_dev *dev;
+	unsigned int period_size, periods;
+	int err;
 
-	return 0;
+	period_size = params_period_bytes(hw_params);
+	periods = params_periods(hw_params);
 
+	snd_assert(period_size >= 0x100 && period_size <= 0x10000,
+		   return -EINVAL);
+	snd_assert(periods >= 2, return -EINVAL);
+	snd_assert(period_size * periods <= 1024 * 1024, return -EINVAL);
+
+	dev = saa7134->dev;
+
+	if (dev->dmasound.blocks == periods &&
+	    dev->dmasound.blksize == period_size)
+		return 0;
+
+	/* release the old buffer */
+	if (substream->runtime->dma_area) {
+		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
+		videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
+		dsp_buffer_free(dev);
+		substream->runtime->dma_area = NULL;
+	}
+	dev->dmasound.blocks  = periods;
+	dev->dmasound.blksize = period_size;
+	dev->dmasound.bufsize = period_size * periods;
+
+	err = dsp_buffer_init(dev);
+	if (0 != err) {
+		dev->dmasound.blocks  = 0;
+		dev->dmasound.blksize = 0;
+		dev->dmasound.bufsize = 0;
+		return err;
+	}
+
+	if (0 != (err = videobuf_dma_pci_map(dev->pci, &dev->dmasound.dma))) {
+		dsp_buffer_free(dev);
+		return err;
+	}
+	if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) {
+		videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
+		dsp_buffer_free(dev);
+		return err;
+	}
+	if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
+						dev->dmasound.dma.sglist,
+						dev->dmasound.dma.sglen,
+						0))) {
+		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
+		videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
+		dsp_buffer_free(dev);
+		return err;
+	}
+
+	/* I should be able to use runtime->dma_addr in the control
+	   byte, but it doesn't work. So I allocate the DMA using the
+	   V4L functions, and force ALSA to use that as the DMA area */
+
+	substream->runtime->dma_area = dev->dmasound.dma.vmalloc;
+
+	return 1;
 
 }
 
@@ -572,33 +553,23 @@ static int snd_card_saa7134_hw_params(sn
  *   - One of the ALSA capture callbacks.
  *
  *   Called after closing the device, but before snd_card_saa7134_capture_close
- *   Usually used in ALSA to free the DMA, but since we don't use the
- *  ALSA DMA I'm almost sure this isn't necessary.
+ *   It stops the DMA audio and releases the buffers.
  *
  */
 
 static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
 {
-	return 0;
-}
-
-/*
- * DMA buffer release
- *
- *   Called after closing the device, during snd_card_saa7134_capture_close
- *
- */
-
-static int dsp_buffer_free(struct saa7134_dev *dev)
-{
-	if (!dev->dmasound.blksize)
-		BUG();
+	snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
+	struct saa7134_dev *dev;
 
-	videobuf_dma_free(&dev->dmasound.dma);
+	dev = saa7134->dev;
 
-	dev->dmasound.blocks  = 0;
-	dev->dmasound.blksize = 0;
-	dev->dmasound.bufsize = 0;
+	if (substream->runtime->dma_area) {
+		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
+		videobuf_dma_pci_unmap(dev->pci, &dev->dmasound.dma);
+		dsp_buffer_free(dev);
+		substream->runtime->dma_area = NULL;
+	}
 
 	return 0;
 }
@@ -608,21 +579,12 @@ static int dsp_buffer_free(struct saa713
  *
  *   - One of the ALSA capture callbacks.
  *
- *   Called after closing the device. It stops the DMA audio and releases
- *  the buffers
+ *   Called after closing the device.
  *
  */
 
 static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
 {
-	snd_card_saa7134_t *chip = snd_pcm_substream_chip(substream);
-	struct saa7134_dev *dev = chip->saadev;
-
-	/* unlock buffer */
-	saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
-	videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
-
-	dsp_buffer_free(dev);
 	return 0;
 }
 
@@ -639,29 +601,28 @@ static int snd_card_saa7134_capture_clos
 static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
 {
 	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_card_saa7134_pcm_t *saapcm;
+	snd_card_saa7134_pcm_t *pcm;
 	snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
-	struct saa7134_dev *dev = saa7134->saadev;
+	struct saa7134_dev *dev = saa7134->dev;
 	int err;
 
 	down(&dev->dmasound.lock);
 
-	dev->dmasound.afmt        = SNDRV_PCM_FORMAT_U8;
-	dev->dmasound.channels    = 2;
 	dev->dmasound.read_count  = 0;
 	dev->dmasound.read_offset = 0;
 
 	up(&dev->dmasound.lock);
 
-	saapcm = kzalloc(sizeof(*saapcm), GFP_KERNEL);
-	if (saapcm == NULL)
+	pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
+	if (pcm == NULL)
 		return -ENOMEM;
-	saapcm->saadev=saa7134->saadev;
 
-	spin_lock_init(&saapcm->lock);
+	pcm->dev=saa7134->dev;
 
-	saapcm->substream = substream;
-	runtime->private_data = saapcm;
+	spin_lock_init(&pcm->lock);
+
+	pcm->substream = substream;
+	runtime->private_data = pcm;
 	runtime->private_free = snd_card_saa7134_runtime_free;
 	runtime->hw = snd_card_saa7134_capture;
 
@@ -736,7 +697,6 @@ static int snd_saa7134_volume_get(snd_kc
 static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
 	int change, addr = kcontrol->private_value;
 	int left, right;
 
@@ -750,12 +710,12 @@ static int snd_saa7134_volume_put(snd_kc
 		right = 0;
 	if (right > 20)
 		right = 20;
-	spin_lock_irqsave(&chip->mixer_lock, flags);
+	spin_lock_irq(&chip->mixer_lock);
 	change = chip->mixer_volume[addr][0] != left ||
 		 chip->mixer_volume[addr][1] != right;
 	chip->mixer_volume[addr][0] = left;
 	chip->mixer_volume[addr][1] = right;
-	spin_unlock_irqrestore(&chip->mixer_lock, flags);
+	spin_unlock_irq(&chip->mixer_lock);
 	return change;
 }
 
@@ -777,38 +737,37 @@ static int snd_saa7134_capsrc_info(snd_k
 static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
 	int addr = kcontrol->private_value;
 
-	spin_lock_irqsave(&chip->mixer_lock, flags);
+	spin_lock_irq(&chip->mixer_lock);
 	ucontrol->value.integer.value[0] = chip->capture_source[addr][0];
 	ucontrol->value.integer.value[1] = chip->capture_source[addr][1];
-	spin_unlock_irqrestore(&chip->mixer_lock, flags);
+	spin_unlock_irq(&chip->mixer_lock);
+
 	return 0;
 }
 
 static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
 	int change, addr = kcontrol->private_value;
 	int left, right;
 	u32 anabar, xbarin;
 	int analog_io, rate;
 	struct saa7134_dev *dev;
 
-	dev = chip->saadev;
+	dev = chip->dev;
 
 	left = ucontrol->value.integer.value[0] & 1;
 	right = ucontrol->value.integer.value[1] & 1;
-	spin_lock_irqsave(&chip->mixer_lock, flags);
+	spin_lock_irq(&chip->mixer_lock);
 
 	change = chip->capture_source[addr][0] != left ||
 		 chip->capture_source[addr][1] != right;
 	chip->capture_source[addr][0] = left;
 	chip->capture_source[addr][1] = right;
 	dev->dmasound.input=addr;
-	spin_unlock_irqrestore(&chip->mixer_lock, flags);
+	spin_unlock_irq(&chip->mixer_lock);
 
 
 	if (change) {
@@ -898,43 +857,44 @@ static int snd_card_saa7134_new_mixer(sn
 	return 0;
 }
 
-static int snd_saa7134_free(snd_card_saa7134_t *chip)
+static void snd_saa7134_free(snd_card_t * card)
 {
-	return 0;
-}
+	snd_card_saa7134_t *chip = card->private_data;
+
+	if (chip->dev->dmasound.priv_data == NULL)
+		return;
+
+	if (chip->irq >= 0) {
+		synchronize_irq(chip->irq);
+		free_irq(chip->irq, &chip->dev->dmasound);
+	}
+
+	chip->dev->dmasound.priv_data = NULL;
 
-static int snd_saa7134_dev_free(snd_device_t *device)
-{
-	snd_card_saa7134_t *chip = device->device_data;
-	return snd_saa7134_free(chip);
 }
 
 /*
  * ALSA initialization
  *
- *   Called by saa7134-core, it creates the basic structures and registers
- *  the ALSA devices
+ *   Called by the init routine, once for each saa7134 device present,
+ *  it creates the basic structures and registers the ALSA devices
  *
  */
 
-int alsa_card_saa7134_create (struct saa7134_dev *saadev)
+int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
 {
-	static int dev;
 
 	snd_card_t *card;
 	snd_card_saa7134_t *chip;
 	int err;
-	static snd_device_ops_t ops = {
-		.dev_free =     snd_saa7134_dev_free,
-	};
 
 
-	if (dev >= SNDRV_CARDS)
+	if (devnum >= SNDRV_CARDS)
 		return -ENODEV;
-	if (!enable[dev])
+	if (!enable[devnum])
 		return -ENODEV;
 
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index[devnum], id[devnum], THIS_MODULE, sizeof(snd_card_saa7134_t));
 
 	if (card == NULL)
 		return -ENOMEM;
@@ -943,34 +903,33 @@ int alsa_card_saa7134_create (struct saa
 
 	/* Card "creation" */
 
-	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
-	if (chip == NULL) {
-		return -ENOMEM;
-	}
+	card->private_free = snd_saa7134_free;
+	chip = (snd_card_saa7134_t *) card->private_data;
 
 	spin_lock_init(&chip->lock);
 	spin_lock_init(&chip->mixer_lock);
 
-	chip->saadev = saadev;
+	chip->dev = dev;
 
 	chip->card = card;
 
-	chip->pci = saadev->pci;
-	chip->irq = saadev->pci->irq;
-	chip->iobase = pci_resource_start(saadev->pci, 0);
+	chip->pci = dev->pci;
+	chip->iobase = pci_resource_start(dev->pci, 0);
 
-	err = request_irq(saadev->pci->irq, saa7134_alsa_irq,
-				SA_SHIRQ | SA_INTERRUPT, saadev->name, saadev);
+
+	err = request_irq(dev->pci->irq, saa7134_alsa_irq,
+				SA_SHIRQ | SA_INTERRUPT, dev->name,
+				(void*) &dev->dmasound);
 
 	if (err < 0) {
 		printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n",
-			saadev->name, saadev->pci->irq);
+			dev->name, dev->pci->irq);
 		goto __nodev;
 	}
 
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
-		goto __nodev;
-	}
+	chip->irq = dev->pci->irq;
+
+	init_MUTEX(&dev->dmasound.lock);
 
 	if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
 		goto __nodev;
@@ -984,16 +943,15 @@ int alsa_card_saa7134_create (struct saa
 
 	strcpy(card->shortname, "SAA7134");
 	sprintf(card->longname, "%s at 0x%lx irq %d",
-		chip->saadev->name, chip->iobase, chip->irq);
+		chip->dev->name, chip->iobase, chip->irq);
 
 	if ((err = snd_card_register(card)) == 0) {
-		snd_saa7134_cards[dev] = card;
+		snd_saa7134_cards[devnum] = card;
 		return 0;
 	}
 
 __nodev:
 	snd_card_free(card);
-	kfree(chip);
 	return err;
 }
 
@@ -1007,21 +965,29 @@ __nodev:
 
 static int saa7134_alsa_init(void)
 {
-        struct saa7134_dev *saadev = NULL;
-        struct list_head *list;
+	struct saa7134_dev *dev = NULL;
+	struct list_head *list;
 
-	printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
+	position = 0;
 
-        list_for_each(list,&saa7134_devlist) {
-                saadev = list_entry(list, struct saa7134_dev, devlist);
-		alsa_card_saa7134_create(saadev);
-        }
+        printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
 
-	if (saadev == NULL)
+	list_for_each(list,&saa7134_devlist) {
+		dev = list_entry(list, struct saa7134_dev, devlist);
+		if (dev->dmasound.priv_data == NULL) {
+			dev->dmasound.priv_data = dev;
+			alsa_card_saa7134_create(dev,position);
+			position++;
+		} else {
+			printk(KERN_ERR "saa7134 ALSA: DMA sound is being handled by OSS. ignoring %s\n",dev->name);
+			return -EBUSY;
+		}
+	}
+
+	if (dev == NULL)
 		printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n");
 
 	return 0;
-
 }
 
 /*
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 663d03e..75abc20 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -2529,6 +2529,32 @@ struct saa7134_board saa7134_boards[] = 
 			.amux   = LINE1,
 		}},
 	},
+	[SAA7134_BOARD_MSI_TVATANYWHERE_PLUS] = {
+		.name           = "MSI TV@Anywhere plus",
+		.audio_clock    = 0x00187de7,
+		.tuner_type     = TUNER_PHILIPS_TDA8290,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.inputs = {{
+			.name   = name_tv,
+			.vmux   = 1,
+			.amux   = TV,
+			.tv     = 1,
+		},{
+			.name   = name_comp1,
+			.vmux   = 3,
+			.amux   = LINE1,
+		},{
+			.name   = name_svideo,
+			.vmux   = 0,
+			.amux   = LINE1,
+		}},
+		.radio = {
+			.name   = name_radio,
+			.amux   = LINE1,
+		},
+	},
 };
 
 const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
@@ -2970,6 +2996,12 @@ struct pci_device_id saa7134_pci_tbl[] =
 		.subdevice    = 0x2018,
 		.driver_data  = SAA7134_BOARD_PHILIPS_TIGER,
 	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x1462,
+		.subdevice    = 0x6231,
+		.driver_data  = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS,
+	},{
 		/* --- boards without eeprom + subsystem ID --- */
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 19b8874..4275d2d 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -53,13 +53,13 @@ static unsigned int gpio_tracking = 0;
 module_param(gpio_tracking, int, 0644);
 MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]");
 
-static unsigned int oss = 0;
-module_param(oss, int, 0444);
-MODULE_PARM_DESC(oss,"register oss devices (default: no)");
-
 static unsigned int alsa = 0;
-module_param(alsa, int, 0444);
-MODULE_PARM_DESC(alsa,"register alsa devices (default: no)");
+module_param(alsa, int, 0644);
+MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]");
+
+static unsigned int oss = 0;
+module_param(oss, int, 0644);
+MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]");
 
 static unsigned int latency = UNSET;
 module_param(latency, int, 0444);
@@ -68,24 +68,18 @@ MODULE_PARM_DESC(latency,"pci latency ti
 static unsigned int video_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 static unsigned int vbi_nr[]   = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 static unsigned int radio_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
-static unsigned int dsp_nr[]   = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
-static unsigned int mixer_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 static unsigned int tuner[]    = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 static unsigned int card[]     = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 
 module_param_array(video_nr, int, NULL, 0444);
 module_param_array(vbi_nr,   int, NULL, 0444);
 module_param_array(radio_nr, int, NULL, 0444);
-module_param_array(dsp_nr,   int, NULL, 0444);
-module_param_array(mixer_nr, int, NULL, 0444);
 module_param_array(tuner,    int, NULL, 0444);
 module_param_array(card,     int, NULL, 0444);
 
 MODULE_PARM_DESC(video_nr, "video device number");
 MODULE_PARM_DESC(vbi_nr,   "vbi device number");
 MODULE_PARM_DESC(radio_nr, "radio device number");
-MODULE_PARM_DESC(dsp_nr,   "oss dsp device number");
-MODULE_PARM_DESC(mixer_nr, "oss mixer device number");
 MODULE_PARM_DESC(tuner,    "tuner type");
 MODULE_PARM_DESC(card,     "card type");
 
@@ -195,6 +189,7 @@ void saa7134_track_gpio(struct saa7134_d
 static int need_empress;
 static int need_dvb;
 static int need_alsa;
+static int need_oss;
 
 static int pending_call(struct notifier_block *self, unsigned long state,
 			void *module)
@@ -208,6 +203,8 @@ static int pending_call(struct notifier_
 		request_module("saa7134-dvb");
 	if (need_alsa)
 		request_module("saa7134-alsa");
+	if (need_oss)
+		request_module("saa7134-oss");
 	return NOTIFY_DONE;
 }
 
@@ -218,10 +215,11 @@ static struct notifier_block pending_not
 
 static void request_module_depend(char *name, int *flag)
 {
+	int err;
 	switch (THIS_MODULE->state) {
 	case MODULE_STATE_COMING:
 		if (!pending_registered) {
-			register_module_notifier(&pending_notifier);
+			err = register_module_notifier(&pending_notifier);
 			pending_registered = 1;
 		}
 		*flag = 1;
@@ -578,12 +576,14 @@ static irqreturn_t saa7134_irq(int irq, 
 			goto out;
 		}
 
-		/* If alsa support is active and we get a sound report, exit
-		   and let the saa7134-alsa module deal with it */
+		/* If dmasound support is active and we get a sound report, exit
+		   and let the saa7134-alsa/oss module deal with it */
 
-		if ((report & SAA7134_IRQ_REPORT_DONE_RA3) && alsa)  {
+		if ((report & SAA7134_IRQ_REPORT_DONE_RA3) &&
+			(dev->dmasound.priv_data != NULL) )
+		{
 			if (irq_debug > 1)
-				printk(KERN_DEBUG "%s/irq: ignoring interrupt for ALSA\n",
+				printk(KERN_DEBUG "%s/irq: ignoring interrupt for DMA sound\n",
 				       dev->name);
 			goto out;
 		}
@@ -609,12 +609,6 @@ static irqreturn_t saa7134_irq(int irq, 
 		    card_has_mpeg(dev))
 			saa7134_irq_ts_done(dev,status);
 
-		if ((report & SAA7134_IRQ_REPORT_DONE_RA3))  {
-			if (oss) {
-				saa7134_irq_oss_done(dev,status);
-			}
-		}
-
 		if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
 			       SAA7134_IRQ_REPORT_GPIO18)) &&
 		    dev->remote)
@@ -689,14 +683,6 @@ static int saa7134_hwinit1(struct saa713
 	 * audio will not work.
 	 */
 
-	switch (dev->pci->device) {
-	case PCI_DEVICE_ID_PHILIPS_SAA7134:
-	case PCI_DEVICE_ID_PHILIPS_SAA7133:
-	case PCI_DEVICE_ID_PHILIPS_SAA7135:
-		saa7134_oss_init1(dev);
-		break;
-	}
-
 	/* enable peripheral devices */
 	saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
 
@@ -728,8 +714,6 @@ static int saa7134_hwinit2(struct saa713
 		irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18  |
 			      SAA7134_IRQ2_INTE_GPIO18A |
 			      SAA7134_IRQ2_INTE_GPIO16  );
-	else if (dev->has_remote == SAA7134_REMOTE_I2C)
-		request_module("ir-kbd-i2c");
 
 	saa_writel(SAA7134_IRQ1, 0);
 	saa_writel(SAA7134_IRQ2, irq2_mask);
@@ -742,13 +726,6 @@ static int saa7134_hwfini(struct saa7134
 {
 	dprintk("hwfini\n");
 
-	switch (dev->pci->device) {
-	case PCI_DEVICE_ID_PHILIPS_SAA7134:
-	case PCI_DEVICE_ID_PHILIPS_SAA7133:
-	case PCI_DEVICE_ID_PHILIPS_SAA7135:
-		saa7134_oss_fini(dev);
-		break;
-	}
 	if (card_has_mpeg(dev))
 		saa7134_ts_fini(dev);
 	saa7134_input_fini(dev);
@@ -986,11 +963,12 @@ static int __devinit saa7134_initdev(str
 	if (card_is_dvb(dev))
 		request_module_depend("saa7134-dvb",&need_dvb);
 
-	if (!oss && alsa) {
-		dprintk("Requesting ALSA module\n");
+
+	if (alsa)
 		request_module_depend("saa7134-alsa",&need_alsa);
-	}
 
+	if (oss)
+		request_module_depend("saa7134-oss",&need_oss);
 
 	v4l2_prio_init(&dev->prio);
 
@@ -1024,32 +1002,6 @@ static int __devinit saa7134_initdev(str
 		       dev->name,dev->radio_dev->minor & 0x1f);
 	}
 
-	/* register oss devices */
-	switch (dev->pci->device) {
-	case PCI_DEVICE_ID_PHILIPS_SAA7134:
-	case PCI_DEVICE_ID_PHILIPS_SAA7133:
-	case PCI_DEVICE_ID_PHILIPS_SAA7135:
-		if (oss) {
-			err = dev->dmasound.minor_dsp =
-				register_sound_dsp(&saa7134_dsp_fops,
-						   dsp_nr[dev->nr]);
-			if (err < 0) {
-				goto fail4;
-			}
-			printk(KERN_INFO "%s: registered device dsp%d\n",
-			       dev->name,dev->dmasound.minor_dsp >> 4);
-
-			err = dev->dmasound.minor_mixer =
-				register_sound_mixer(&saa7134_mixer_fops,
-						     mixer_nr[dev->nr]);
-			if (err < 0)
-				goto fail5;
-			printk(KERN_INFO "%s: registered device mixer%d\n",
-			       dev->name,dev->dmasound.minor_mixer >> 4);
-		}
-		break;
-	}
-
 	/* everything worked */
 	pci_set_drvdata(pci_dev,dev);
 	saa7134_devcount++;
@@ -1064,17 +1016,9 @@ static int __devinit saa7134_initdev(str
 
 	/* check for signal */
 	saa7134_irq_video_intl(dev);
+
 	return 0;
 
- fail5:
-	switch (dev->pci->device) {
-	case PCI_DEVICE_ID_PHILIPS_SAA7134:
-	case PCI_DEVICE_ID_PHILIPS_SAA7133:
-	case PCI_DEVICE_ID_PHILIPS_SAA7135:
-		if (oss)
-			unregister_sound_dsp(dev->dmasound.minor_dsp);
-		break;
-	}
  fail4:
 	saa7134_unregister_video(dev);
 	saa7134_i2c_unregister(dev);
@@ -1125,19 +1069,16 @@ static void __devexit saa7134_finidev(st
 	saa7134_devcount--;
 
 	saa7134_i2c_unregister(dev);
-	switch (dev->pci->device) {
-	case PCI_DEVICE_ID_PHILIPS_SAA7134:
-	case PCI_DEVICE_ID_PHILIPS_SAA7133:
-	case PCI_DEVICE_ID_PHILIPS_SAA7135:
-		if (oss) {
-			unregister_sound_mixer(dev->dmasound.minor_mixer);
-			unregister_sound_dsp(dev->dmasound.minor_dsp);
-		}
-		break;
-	}
 	saa7134_unregister_video(dev);
 
-	/* release ressources */
+	/* the DMA sound modules should be unloaded before reaching
+	   this, but just in case they are still present... */
+	if (dev->dmasound.priv_data != NULL) {
+		free_irq(pci_dev->irq, &dev->dmasound);
+		dev->dmasound.priv_data = NULL;
+	}
+
+	/* release resources */
 	free_irq(pci_dev->irq, dev);
 	iounmap(dev->lmmio);
 	release_mem_region(pci_resource_start(pci_dev,0),
@@ -1225,7 +1166,7 @@ EXPORT_SYMBOL(saa7134_i2c_call_clients);
 EXPORT_SYMBOL(saa7134_devlist);
 EXPORT_SYMBOL(saa7134_boards);
 
-/* ----------------- For ALSA -------------------------------- */
+/* ----------------- for the DMA sound modules --------------- */
 
 EXPORT_SYMBOL(saa7134_pgtable_free);
 EXPORT_SYMBOL(saa7134_pgtable_build);
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 329accd..e648cc3 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -485,64 +485,6 @@ static IR_KEYTAB_TYPE ir_codes_purpletv[
 
 };
 
-static IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
-	[ 0x59 ] = KEY_MUTE,
-	[ 0x4a ] = KEY_POWER,
-
-	[ 0x18 ] = KEY_TEXT,
-	[ 0x26 ] = KEY_TV,
-	[ 0x3d ] = KEY_PRINT,
-
-	[ 0x48 ] = KEY_RED,
-	[ 0x04 ] = KEY_GREEN,
-	[ 0x11 ] = KEY_YELLOW,
-	[ 0x00 ] = KEY_BLUE,
-
-	[ 0x2d ] = KEY_VOLUMEUP,
-	[ 0x1e ] = KEY_VOLUMEDOWN,
-
-	[ 0x49 ] = KEY_MENU,
-
-	[ 0x16 ] = KEY_CHANNELUP,
-	[ 0x17 ] = KEY_CHANNELDOWN,
-
-	[ 0x20 ] = KEY_UP,
-	[ 0x21 ] = KEY_DOWN,
-	[ 0x22 ] = KEY_LEFT,
-	[ 0x23 ] = KEY_RIGHT,
-	[ 0x0d ] = KEY_SELECT,
-
-
-
-	[ 0x08 ] = KEY_BACK,
-	[ 0x07 ] = KEY_REFRESH,
-
-	[ 0x2f ] = KEY_ZOOM,
-	[ 0x29 ] = KEY_RECORD,
-
-	[ 0x4b ] = KEY_PAUSE,
-	[ 0x4d ] = KEY_REWIND,
-	[ 0x2e ] = KEY_PLAY,
-	[ 0x4e ] = KEY_FORWARD,
-	[ 0x53 ] = KEY_PREVIOUS,
-	[ 0x4c ] = KEY_STOP,
-	[ 0x54 ] = KEY_NEXT,
-
-	[ 0x69 ] = KEY_KP0,
-	[ 0x6a ] = KEY_KP1,
-	[ 0x6b ] = KEY_KP2,
-	[ 0x6c ] = KEY_KP3,
-	[ 0x6d ] = KEY_KP4,
-	[ 0x6e ] = KEY_KP5,
-	[ 0x6f ] = KEY_KP6,
-	[ 0x70 ] = KEY_KP7,
-	[ 0x71 ] = KEY_KP8,
-	[ 0x72 ] = KEY_KP9,
-
-	[ 0x74 ] = KEY_CHANNEL,
-	[ 0x0a ] = KEY_BACKSPACE,
-};
-
 /* Mapping for the 28 key remote control as seen at
    http://www.sednacomputer.com/photo/cardbus-tv.jpg
    Pavel Mihaylov <bin@bash.info> */
@@ -635,57 +577,6 @@ static int get_key_purpletv(struct IR_i2
 	return 1;
 }
 
-/* The new pinnacle PCTV remote (with the colored buttons)
- *
- * Ricardo Cerqueira <v4l@cerqueira.org>
- */
-
-static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
-{
-	unsigned char b[4];
-	unsigned int start = 0,parity = 0,code = 0;
-
-	/* poll IR chip */
-	if (4 != i2c_master_recv(&ir->c,b,4)) {
-		i2cdprintk("read error\n");
-		return -EIO;
-	}
-
-	for (start = 0; start<4; start++) {
-		if (b[start] == 0x80) {
-			code=b[(start+3)%4];
-			parity=b[(start+2)%4];
-		}
-	}
-
-	/* Empty Request */
-	if (parity==0)
-		return 0;
-
-	/* Repeating... */
-	if (ir->old == parity)
-		return 0;
-
-
-	ir->old = parity;
-
-	/* Reduce code value to fit inside IR_KEYTAB_SIZE
-	 *
-	 * this is the only value that results in 42 unique
-	 * codes < 128
-	 */
-
-	code %= 0x88;
-
-	*ir_raw = code;
-	*ir_key = code;
-
-	i2cdprintk("Pinnacle PCTV key %02x\n", code);
-
-	return 1;
-}
-
-
 void saa7134_input_irq(struct saa7134_dev *dev)
 {
 	struct saa7134_ir *ir = dev->remote;
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index fd53dfc..fd9ed11 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -4,6 +4,8 @@
  * oss dsp interface
  *
  * (c) 2001,02 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+ *     2005 conversion to standalone module:
+ *         Ricardo Cerqueira <v4l@cerqueira.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -25,7 +27,9 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
+#include <linux/interrupt.h>
 #include <linux/slab.h>
+#include <linux/sound.h>
 #include <linux/soundcard.h>
 
 #include "saa7134-reg.h"
@@ -33,15 +37,23 @@
 
 /* ------------------------------------------------------------------ */
 
-static unsigned int oss_debug  = 0;
-module_param(oss_debug, int, 0644);
-MODULE_PARM_DESC(oss_debug,"enable debug messages [oss]");
-
-static unsigned int oss_rate  = 0;
-module_param(oss_rate, int, 0444);
-MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
+static unsigned int debug  = 0;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,"enable debug messages [oss]");
+
+static unsigned int rate  = 0;
+module_param(rate, int, 0444);
+MODULE_PARM_DESC(rate,"sample rate (valid are: 32000,48000)");
+
+static unsigned int dsp_nr[]   = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
+MODULE_PARM_DESC(dsp_nr, "device numbers for SAA7134 capture interface(s).");
+module_param_array(dsp_nr,   int, NULL, 0444);
+
+static unsigned int mixer_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
+MODULE_PARM_DESC(mixer_nr, "mixer numbers for SAA7134 capture interface(s).");
+module_param_array(mixer_nr, int, NULL, 0444);
 
-#define dprintk(fmt, arg...)	if (oss_debug) \
+#define dprintk(fmt, arg...)	if (debug) \
 	printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg)
 
 
@@ -369,7 +381,7 @@ static int dsp_ioctl(struct inode *inode
 	int __user *p = argp;
 	int val = 0;
 
-	if (oss_debug > 1)
+	if (debug > 1)
 		saa7134_print_ioctl(dev->name,cmd);
 	switch (cmd) {
 	case OSS_GETVERSION:
@@ -665,7 +677,7 @@ static int mixer_ioctl(struct inode *ino
 	void __user *argp = (void __user *) arg;
 	int __user *p = argp;
 
-	if (oss_debug > 1)
+	if (debug > 1)
 		saa7134_print_ioctl(dev->name,cmd);
 	switch (cmd) {
 	case OSS_GETVERSION:
@@ -768,8 +780,41 @@ struct file_operations saa7134_mixer_fop
 
 /* ------------------------------------------------------------------ */
 
+static irqreturn_t saa7134_oss_irq(int irq, void *dev_id, struct pt_regs *regs)
+{
+        struct saa7134_dmasound *dmasound = dev_id;
+        struct saa7134_dev *dev = dmasound->priv_data;
+        unsigned long report, status;
+        int loop, handled = 0;
+
+        for (loop = 0; loop < 10; loop++) {
+                report = saa_readl(SAA7134_IRQ_REPORT);
+                status = saa_readl(SAA7134_IRQ_STATUS);
+
+                if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
+                        handled = 1;
+                        saa_writel(SAA7134_IRQ_REPORT,report);
+                        saa7134_irq_oss_done(dev, status);
+                } else {
+                        goto out;
+                }
+        }
+
+        if (loop == 10) {
+                dprintk("error! looping IRQ!");
+        }
+out:
+        return IRQ_RETVAL(handled);
+}
+
 int saa7134_oss_init1(struct saa7134_dev *dev)
 {
+
+        if ((request_irq(dev->pci->irq, saa7134_oss_irq,
+                         SA_SHIRQ | SA_INTERRUPT, dev->name,
+			(void*) &dev->dmasound)) < 0)
+		return -1;
+
 	/* general */
 	init_MUTEX(&dev->dmasound.lock);
 	init_waitqueue_head(&dev->dmasound.wq);
@@ -785,8 +830,8 @@ int saa7134_oss_init1(struct saa7134_dev
 
 	/* dsp */
 	dev->dmasound.rate = 32000;
-	if (oss_rate)
-		dev->dmasound.rate = oss_rate;
+	if (rate)
+		dev->dmasound.rate = rate;
 	dev->dmasound.rate = (dev->dmasound.rate > 40000) ? 48000 : 32000;
 
 	/* mixer */
@@ -840,7 +885,7 @@ void saa7134_irq_oss_done(struct saa7134
 	/* next block addr */
 	next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
 	saa_writel(reg,next_blk * dev->dmasound.blksize);
-	if (oss_debug > 2)
+	if (debug > 2)
 		dprintk("irq: ok, %s, next_blk=%d, addr=%x\n",
 			(status & 0x10000000) ? "even" : "odd ", next_blk,
 			next_blk * dev->dmasound.blksize);
@@ -854,6 +899,98 @@ void saa7134_irq_oss_done(struct saa7134
 	spin_unlock(&dev->slock);
 }
 
+int saa7134_dsp_create(struct saa7134_dev *dev)
+{
+	int err;
+
+                        err = dev->dmasound.minor_dsp =
+                                register_sound_dsp(&saa7134_dsp_fops,
+                                                   dsp_nr[dev->nr]);
+                        if (err < 0) {
+                                goto fail;
+                        }
+                        printk(KERN_INFO "%s: registered device dsp%d\n",
+                               dev->name,dev->dmasound.minor_dsp >> 4);
+
+                        err = dev->dmasound.minor_mixer =
+                                register_sound_mixer(&saa7134_mixer_fops,
+                                                     mixer_nr[dev->nr]);
+                        if (err < 0)
+                                goto fail;
+                        printk(KERN_INFO "%s: registered device mixer%d\n",
+                               dev->name,dev->dmasound.minor_mixer >> 4);
+
+	return 0;
+
+fail:
+        unregister_sound_dsp(dev->dmasound.minor_dsp);
+	return 0;
+
+
+}
+
+static int saa7134_oss_init(void)
+{
+        struct saa7134_dev *dev = NULL;
+        struct list_head *list;
+
+        printk(KERN_INFO "saa7134 OSS driver for DMA sound loaded\n");
+
+        list_for_each(list,&saa7134_devlist) {
+                dev = list_entry(list, struct saa7134_dev, devlist);
+		if (dev->dmasound.priv_data == NULL) {
+			dev->dmasound.priv_data = dev;
+			saa7134_oss_init1(dev);
+			saa7134_dsp_create(dev);
+		} else {
+                	printk(KERN_ERR "saa7134 OSS: DMA sound is being handled by ALSA, ignoring %s\n",dev->name);
+			return -EBUSY;
+		}
+        }
+
+        if (dev == NULL)
+                printk(KERN_INFO "saa7134 OSS: no saa7134 cards found\n");
+
+        return 0;
+
+}
+
+void saa7134_oss_exit(void)
+{
+        struct saa7134_dev *dev = NULL;
+        struct list_head *list;
+
+        list_for_each(list,&saa7134_devlist) {
+                dev = list_entry(list, struct saa7134_dev, devlist);
+
+		/* Device isn't registered by OSS, probably ALSA's */
+		if (!dev->dmasound.minor_dsp)
+			continue;
+
+                unregister_sound_mixer(dev->dmasound.minor_mixer);
+                unregister_sound_dsp(dev->dmasound.minor_dsp);
+
+		saa7134_oss_fini(dev);
+
+		if (dev->pci->irq > 0) {
+			synchronize_irq(dev->pci->irq);
+			free_irq(dev->pci->irq,&dev->dmasound);
+		}
+
+        	dev->dmasound.priv_data = NULL;
+
+        }
+
+        printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n");
+
+        return;
+}
+
+module_init(saa7134_oss_init);
+module_exit(saa7134_oss_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
+
 /* ----------------------------------------------------------- */
 /*
  * Local variables:
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index fb97274..244e197 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -208,6 +208,7 @@ struct saa7134_format {
 #define SAA7134_BOARD_SEDNA_PC_TV_CARDBUS     79
 #define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80
 #define SAA7134_BOARD_PHILIPS_TIGER  81
+#define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS  82
 
 #define SAA7134_MAXBOARDS 8
 #define SAA7134_INPUT_MAX 8
@@ -383,6 +384,7 @@ struct saa7134_dmasound {
 	unsigned int               dma_blk;
 	unsigned int               read_offset;
 	unsigned int               read_count;
+	void *			   priv_data;
 	snd_pcm_substream_t 	   *substream;
 };
 
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index b2dfe07..61d94dd 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -437,6 +437,10 @@ static void set_audio(struct tuner *t)
 		t->sgIF = 124;
 		t->tda8290_easy_mode = 0x20;
 		mode = "L";
+	} else if (t->std & V4L2_STD_SECAM_LC) {
+		t->sgIF = 20;
+		t->tda8290_easy_mode = 0x40;
+		mode = "LC";
 	}
     tuner_dbg("setting tda8290 to system %s\n", mode);
 }
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 73c4041..e58abdf 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -251,7 +251,7 @@ static inline int check_mode(struct tune
 
 static char pal[] = "-";
 module_param_string(pal, pal, sizeof(pal), 0644);
-static char secam[] = "-";
+static char secam[] = "--";
 module_param_string(secam, secam, sizeof(secam), 0644);
 
 /* get more precise norm info from insmod option */
@@ -307,8 +307,13 @@ static int tuner_fixup_std(struct tuner 
 			break;
 		case 'l':
 		case 'L':
-			tuner_dbg ("insmod fixup: SECAM => SECAM-L\n");
-			t->std = V4L2_STD_SECAM_L;
+			if ((secam[1]=='C')||(secam[1]=='c')) {
+				tuner_dbg ("insmod fixup: SECAM => SECAM-L'\n");
+				t->std = V4L2_STD_SECAM_LC;
+			} else {
+				tuner_dbg ("insmod fixup: SECAM => SECAM-L\n");
+				t->std = V4L2_STD_SECAM_L;
+			}
 			break;
 		case '-':
 			/* default parameter, do nothing */
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index d832205..e0c9fdb 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -233,7 +233,7 @@ static struct tunertype tuners[] = {
 	{ "Ymec TVision TVF-5533MF", Philips, NTSC,
 	  16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
 
-	/* 60-68 */
+	/* 60-69 */
 	{ "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
 	  16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
 	{ "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL,
@@ -252,6 +252,8 @@ static struct tunertype tuners[] = {
 	  16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 },
 	{ "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC,
 	  16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 },
+	{ "Tena TNF 5335 MF", Philips, NTSC,
+	  16*157.25,16*454.00,0x01,0x02,0x04,0x8e,732 },
 };
 
 unsigned const int tuner_count = ARRAY_SIZE(tuners);
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index 22f2862..a6936ad 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -5,6 +5,11 @@
  *
  * Based on saa7115 driver
  *
+ * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl>
+ * - Cleanup
+ * - V4L2 API update
+ * - sound fixes
+ *
  * 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
@@ -31,7 +36,7 @@
 #include <media/audiochip.h>
 
 MODULE_DESCRIPTION("wm8775 driver");
-MODULE_AUTHOR("Ulf Eklund");
+MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
 MODULE_LICENSE("GPL");
 
 #define wm8775_err(fmt, arg...) do { \
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 1e6bdba..166c9b0 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -22,7 +22,6 @@
 
 #include <asm/div64.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/scatterlist.h>
 #include <asm/sizes.h>
 #include <asm/hardware/amba.h>
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 48638c8..846a533 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -94,7 +94,7 @@ config MTD_NETSC520
 
 config MTD_TS5500
 	tristate "JEDEC Flash device mapped on Technologic Systems TS-5500"
-	depends on ELAN
+	depends on X86
 	select MTD_PARTITIONS
 	select MTD_JEDECPROBE
 	select MTD_CFI_AMDSTD
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index 977935a..824e430 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -84,6 +84,7 @@ static int max_interrupt_work = 10;
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/skbuff.h>
 #include <linux/delay.h>	/* for udelay() */
 #include <linux/spinlock.h>
@@ -173,7 +174,7 @@ struct el3_private {
 	/* skb send-queue */
 	int head, size;
 	struct sk_buff *queue[SKB_QUEUE_SIZE];
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
 	struct pm_dev *pmdev;
 #endif
 	enum {
@@ -200,7 +201,7 @@ static void el3_tx_timeout (struct net_d
 static void el3_down(struct net_device *dev);
 static void el3_up(struct net_device *dev);
 static struct ethtool_ops ethtool_ops;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
 static int el3_suspend(struct pm_dev *pdev);
 static int el3_resume(struct pm_dev *pdev);
 static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data);
@@ -361,7 +362,7 @@ static void el3_common_remove (struct ne
 	struct el3_private *lp = netdev_priv(dev);
 
 	(void) lp;				/* Keep gcc quiet... */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
 	if (lp->pmdev)
 		pm_unregister(lp->pmdev);
 #endif
@@ -571,7 +572,7 @@ no_pnp:
 	if (err)
 		goto out1;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
 	/* register power management */
 	lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback);
 	if (lp->pmdev) {
@@ -1479,7 +1480,7 @@ el3_up(struct net_device *dev)
 }
 
 /* Power Management support functions */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
 
 static int
 el3_suspend(struct pm_dev *pdev)
@@ -1548,7 +1549,7 @@ el3_pm_callback(struct pm_dev *pdev, pm_
 	return 0;
 }
 
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_LEGACY */
 
 /* Parameters that may be passed into the module. */
 static int debug = -1;
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index e3a3295..0f030b7 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -6,7 +6,7 @@
  * Based on 8260_io/fcc_enet.c
  *
  * Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ * Maintainer: Kumar Gala
  *
  * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
  *
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 220084e..5065ba8 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -6,7 +6,7 @@
  * Based on 8260_io/fcc_enet.c
  *
  * Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ * Maintainer: Kumar Gala
  *
  * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
  *
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 5a2d810..cfa3cd7 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -6,7 +6,7 @@
  *  Based on e1000 ethtool support
  *
  *  Author: Andy Fleming
- *  Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ *  Maintainer: Kumar Gala
  *
  *  Copyright (c) 2003,2004 Freescale Semiconductor, Inc.
  *
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index 9544279..04a462c 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -5,7 +5,7 @@
  * Provides Bus interface for MIIM regs
  *
  * Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ * Maintainer: Kumar Gala
  *
  * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
  *
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h
index 56e5665..e85eb21 100644
--- a/drivers/net/gianfar_mii.h
+++ b/drivers/net/gianfar_mii.h
@@ -5,7 +5,7 @@
  * Driver for the MDIO bus controller in the Gianfar register space
  *
  * Author: Andy Fleming
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ * Maintainer: Kumar Gala
  *
  * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
  *
diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c
index 9bf3468..2e7882e 100644
--- a/drivers/net/irda/ali-ircc.c
+++ b/drivers/net/irda/ali-ircc.c
@@ -40,6 +40,7 @@
 #include <asm/byteorder.h>
 
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 
 #include <net/irda/wrapper.h>
 #include <net/irda/irda.h>
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index 805714e..ee717d0 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -59,6 +59,7 @@
 #include <asm/byteorder.h>
 
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 
 #include <net/irda/wrapper.h>
 #include <net/irda/irda.h>
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index a10cd18..5c2824b 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -100,14 +100,14 @@
 #define SMC_IO_SHIFT		0
 #define SMC_NOWAIT		1
 
-#define SMC_inb(a, r)		inb((a) + (r))
-#define SMC_insb(a, r, p, l)	insb((a) + (r), p, (l))
-#define SMC_inw(a, r)		inw((a) + (r))
-#define SMC_insw(a, r, p, l)	insw((a) + (r), p, l)
-#define SMC_outb(v, a, r)	outb(v, (a) + (r))
-#define SMC_outsb(a, r, p, l)	outsb((a) + (r), p, (l))
-#define SMC_outw(v, a, r)	outw(v, (a) + (r))
-#define SMC_outsw(a, r, p, l)	outsw((a) + (r), p, l)
+#define SMC_inb(a, r)		readb((a) + (r))
+#define SMC_insb(a, r, p, l)	readsb((a) + (r), p, (l))
+#define SMC_inw(a, r)		readw((a) + (r))
+#define SMC_insw(a, r, p, l)	readsw((a) + (r), p, l)
+#define SMC_outb(v, a, r)	writeb(v, (a) + (r))
+#define SMC_outsb(a, r, p, l)	writesb((a) + (r), p, (l))
+#define SMC_outw(v, a, r)	writew(v, (a) + (r))
+#define SMC_outsw(a, r, p, l)	writesw((a) + (r), p, l)
 
 #define set_irq_type(irq, type) do {} while (0)
 
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index de39956..081717d 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -128,6 +128,8 @@ static struct pci_device_id gem_pci_tbl[
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_SUNGEM,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID2_GMAC,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{0, }
 };
 
diff --git a/drivers/net/wan/sdladrv.c b/drivers/net/wan/sdladrv.c
index 7c2cf2e..032c0f8 100644
--- a/drivers/net/wan/sdladrv.c
+++ b/drivers/net/wan/sdladrv.c
@@ -1994,7 +1994,7 @@ static int detect_s514 (sdlahw_t* hw)
 		modname, hw->irq);
 
 	/* map the physical PCI memory to virtual memory */
-	(void *)hw->dpmbase = ioremap((unsigned long)S514_mem_base_addr,
+	hw->dpmbase = ioremap((unsigned long)S514_mem_base_addr,
 		(unsigned long)MAX_SIZEOF_S514_MEMORY);
     	/* map the physical control register memory to virtual memory */
 	hw->vector = (unsigned long)ioremap(
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 4a3cecc..2387e75 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -31,6 +31,8 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/interrupt.h>
+
 #include "../pci.h"
 #include "pciehp.h"
 
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
index a7859a8..4b35097 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -253,7 +253,7 @@ rpaphp_pci_config_slot(struct pci_bus *b
 	if (!dn || !dn->child)
 		return NULL;
 
-	if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
+	if (_machine == PLATFORM_PSERIES_LPAR) {
 		of_scan_bus(dn, bus);
 		if (list_empty(&bus->devices)) {
 			err("%s: No new device found\n", __FUNCTION__);
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 40905a6..9987a6f 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -31,6 +31,8 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/interrupt.h>
+
 #include "shpchp.h"
 
 #ifdef DEBUG
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 234cdca..a30aa74 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -513,6 +513,11 @@ static int socket_insert(struct pcmcia_s
 	ret = socket_setup(skt, setup_delay);
 	if (ret == CS_SUCCESS) {
 		skt->state |= SOCKET_PRESENT;
+
+		printk(KERN_NOTICE "pccard: %s card inserted into slot %d\n",
+		       (skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
+		       skt->sock);
+
 #ifdef CONFIG_CARDBUS
 		if (skt->state & SOCKET_CARDBUS) {
 			cb_alloc(skt);
@@ -598,6 +603,7 @@ static int socket_resume(struct pcmcia_s
 
 static void socket_remove(struct pcmcia_socket *skt)
 {
+	printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock);
 	socket_shutdown(skt);
 	cs_socket_put(skt);
 }
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 39d096b..7f8219f 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -544,6 +544,9 @@ struct pcmcia_device * pcmcia_device_add
 	list_add_tail(&p_dev->socket_device_list, &s->devices_list);
 	spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 
+	printk(KERN_NOTICE "pcmcia: registering new device %s\n",
+	       p_dev->devname);
+
 	pcmcia_device_query(p_dev);
 
 	if (device_register(&p_dev->dev)) {
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 4ddd762..4d56bc9 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -1339,10 +1339,7 @@ static struct device_driver i82365_drive
 	.resume = pcmcia_socket_dev_resume,
 };
 
-static struct platform_device i82365_device = {
-	.name = "i82365",
-	.id = 0,
-};
+static struct platform_device *i82365_device;
 
 static int __init init_i82365(void)
 {
@@ -1352,7 +1349,14 @@ static int __init init_i82365(void)
     if (ret)
 	return ret;
 
-    ret = platform_device_register(&i82365_device);
+    i82365_device = platform_device_alloc("i82365", 0);
+    if (i82365_device) {
+	    ret = platform_device_add(i82365_device);
+	    if (ret)
+		    platform_device_put(i82365_device);
+    } else
+	    ret = -ENOMEM;
+
     if (ret) {
 	driver_unregister(&i82365_driver);
 	return ret;
@@ -1365,7 +1369,7 @@ static int __init init_i82365(void)
 
     if (sockets == 0) {
 	printk("not found.\n");
-	platform_device_unregister(&i82365_device);
+	platform_device_unregister(i82365_device);
 	release_region(i365_base, 2);
 	driver_unregister(&i82365_driver);
 	return -ENODEV;
@@ -1377,7 +1381,7 @@ static int __init init_i82365(void)
     
     /* register sockets with the pcmcia core */
     for (i = 0; i < sockets; i++) {
-	    socket[i].socket.dev.dev = &i82365_device.dev;
+	    socket[i].socket.dev.dev = &i82365_device->dev;
 	    socket[i].socket.ops = &pcic_operations;
 	    socket[i].socket.resource_ops = &pccard_nonstatic_ops;
 	    socket[i].socket.owner = THIS_MODULE;
@@ -1415,7 +1419,7 @@ static void __exit exit_i82365(void)
 	    if (socket[i].flags & IS_REGISTERED)
 		    pcmcia_unregister_socket(&socket[i].socket);
     }
-    platform_device_unregister(&i82365_device);
+    platform_device_unregister(i82365_device);
     if (poll_interval != 0)
 	del_timer_sync(&poll_timer);
     if (grab_irq != 0)
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index 5774bdd..9b988ba 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -210,27 +210,6 @@ static int rtc_ioctl(struct inode *inode
 	}
 }
 
-static long rtc_compat_ioctl(struct file *file, unsigned int cmd,
-	unsigned long arg)
-{
-	int rval = -ENOIOCTLCMD;
-
-	switch (cmd) {
-	/*
-	 * These two are specific to this driver, the generic rtc ioctls
-	 * are hanlded elsewhere.
-	 */
-	case RTCGET:
-	case RTCSET:
-		lock_kernel();
-		rval = rtc_ioctl(file->f_dentry->d_inode, file, cmd, arg);
-		unlock_kernel();
-		break;
-	}
-
-	return rval;
-}
-
 static int rtc_open(struct inode *inode, struct file *file)
 {
 	int ret;
@@ -258,7 +237,6 @@ static struct file_operations rtc_fops =
 	.owner =	THIS_MODULE,
 	.llseek =	no_llseek,
 	.ioctl =	rtc_ioctl,
-	.compat_ioctl =	rtc_compat_ioctl,
 	.open =		rtc_open,
 	.release =	rtc_release,
 };
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 57ef7ae..894e711 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -134,6 +134,7 @@ enum {
 				  PORT_IRQ_D2H_REG_FIS,
 
 	/* PORT_CMD bits */
+	PORT_CMD_ATAPI		= (1 << 24), /* Device is ATAPI */
 	PORT_CMD_LIST_ON	= (1 << 15), /* cmd list DMA engine running */
 	PORT_CMD_FIS_ON		= (1 << 14), /* FIS DMA engine running */
 	PORT_CMD_FIS_RX		= (1 << 4), /* Enable FIS receive DMA engine */
@@ -441,7 +442,7 @@ static void ahci_phy_reset(struct ata_po
 	void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
 	struct ata_taskfile tf;
 	struct ata_device *dev = &ap->device[0];
-	u32 tmp;
+	u32 new_tmp, tmp;
 
 	__sata_phy_reset(ap);
 
@@ -455,8 +456,21 @@ static void ahci_phy_reset(struct ata_po
 	tf.nsect	= (tmp)		& 0xff;
 
 	dev->class = ata_dev_classify(&tf);
-	if (!ata_dev_present(dev))
+	if (!ata_dev_present(dev)) {
 		ata_port_disable(ap);
+		return;
+	}
+
+	/* Make sure port's ATAPI bit is set appropriately */
+	new_tmp = tmp = readl(port_mmio + PORT_CMD);
+	if (dev->class == ATA_DEV_ATAPI)
+		new_tmp |= PORT_CMD_ATAPI;
+	else
+		new_tmp &= ~PORT_CMD_ATAPI;
+	if (new_tmp != tmp) {
+		writel(new_tmp, port_mmio + PORT_CMD);
+		readl(port_mmio + PORT_CMD); /* flush */
+	}
 }
 
 static u8 ahci_check_status(struct ata_port *ap)
@@ -474,11 +488,12 @@ static void ahci_tf_read(struct ata_port
 	ata_tf_from_fis(d2h_fis, tf);
 }
 
-static void ahci_fill_sg(struct ata_queued_cmd *qc)
+static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc)
 {
 	struct ahci_port_priv *pp = qc->ap->private_data;
 	struct scatterlist *sg;
 	struct ahci_sg *ahci_sg;
+	unsigned int n_sg = 0;
 
 	VPRINTK("ENTER\n");
 
@@ -493,8 +508,12 @@ static void ahci_fill_sg(struct ata_queu
 		ahci_sg->addr = cpu_to_le32(addr & 0xffffffff);
 		ahci_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16);
 		ahci_sg->flags_size = cpu_to_le32(sg_len - 1);
+
 		ahci_sg++;
+		n_sg++;
 	}
+
+	return n_sg;
 }
 
 static void ahci_qc_prep(struct ata_queued_cmd *qc)
@@ -503,13 +522,14 @@ static void ahci_qc_prep(struct ata_queu
 	struct ahci_port_priv *pp = ap->private_data;
 	u32 opts;
 	const u32 cmd_fis_len = 5; /* five dwords */
+	unsigned int n_elem;
 
 	/*
 	 * Fill in command slot information (currently only one slot,
 	 * slot 0, is currently since we don't do queueing)
 	 */
 
-	opts = (qc->n_elem << 16) | cmd_fis_len;
+	opts = cmd_fis_len;
 	if (qc->tf.flags & ATA_TFLAG_WRITE)
 		opts |= AHCI_CMD_WRITE;
 	if (is_atapi_taskfile(&qc->tf))
@@ -533,7 +553,9 @@ static void ahci_qc_prep(struct ata_queu
 	if (!(qc->flags & ATA_QCFLAG_DMAMAP))
 		return;
 
-	ahci_fill_sg(qc);
+	n_elem = ahci_fill_sg(qc);
+
+	pp->cmd_slot[0].opts |= cpu_to_le32(n_elem << 16);
 }
 
 static void ahci_intr_error(struct ata_port *ap, u32 irq_stat)
@@ -543,6 +565,17 @@ static void ahci_intr_error(struct ata_p
 	u32 tmp;
 	int work;
 
+	printk(KERN_WARNING "ata%u: port reset, "
+	       "p_is %x is %x pis %x cmd %x tf %x ss %x se %x\n",
+		ap->id,
+		irq_stat,
+		readl(mmio + HOST_IRQ_STAT),
+		readl(port_mmio + PORT_IRQ_STAT),
+		readl(port_mmio + PORT_CMD),
+		readl(port_mmio + PORT_TFDATA),
+		readl(port_mmio + PORT_SCR_STAT),
+		readl(port_mmio + PORT_SCR_ERR));
+
 	/* stop DMA */
 	tmp = readl(port_mmio + PORT_CMD);
 	tmp &= ~PORT_CMD_START;
@@ -580,8 +613,6 @@ static void ahci_intr_error(struct ata_p
 	tmp |= PORT_CMD_START;
 	writel(tmp, port_mmio + PORT_CMD);
 	readl(port_mmio + PORT_CMD); /* flush */
-
-	printk(KERN_WARNING "ata%u: error occurred, port reset\n", ap->id);
 }
 
 static void ahci_eng_timeout(struct ata_port *ap)
@@ -592,17 +623,17 @@ static void ahci_eng_timeout(struct ata_
 	struct ata_queued_cmd *qc;
 	unsigned long flags;
 
-	DPRINTK("ENTER\n");
+	printk(KERN_WARNING "ata%u: handling error/timeout\n", ap->id);
 
 	spin_lock_irqsave(&host_set->lock, flags);
 
-	ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT));
-
 	qc = ata_qc_from_tag(ap, ap->active_tag);
 	if (!qc) {
 		printk(KERN_ERR "ata%u: BUG: timeout without command\n",
 		       ap->id);
 	} else {
+		ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT));
+
 		/* hack alert!  We cannot use the supplied completion
 	 	 * function from inside the ->eh_strategy_handler() thread.
 	 	 * libata is the only user of ->eh_strategy_handler() in
@@ -637,9 +668,19 @@ static inline int ahci_host_intr(struct 
 	}
 
 	if (status & PORT_IRQ_FATAL) {
+		unsigned int err_mask;
+		if (status & PORT_IRQ_TF_ERR)
+			err_mask = AC_ERR_DEV;
+		else if (status & PORT_IRQ_IF_ERR)
+			err_mask = AC_ERR_ATA_BUS;
+		else
+			err_mask = AC_ERR_HOST_BUS;
+
+		/* command processing has stopped due to error; restart */
 		ahci_intr_error(ap, status);
+
 		if (qc)
-			ata_qc_complete(qc, AC_ERR_OTHER);
+			ata_qc_complete(qc, err_mask);
 	}
 
 	return 1;
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index e51d9a8..ba1eb8b 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -532,8 +532,7 @@ void ata_tf_to_fis(const struct ata_task
  *	@fis: Buffer from which data will be input
  *	@tf: Taskfile to output
  *
- *	Converts a standard ATA taskfile to a Serial ATA
- *	FIS structure (Register - Host to Device).
+ *	Converts a serial ATA FIS structure to a standard ATA taskfile.
  *
  *	LOCKING:
  *	Inherited from caller.
@@ -1264,7 +1263,7 @@ retry:
 	}
 
 	/* ATAPI-specific feature tests */
-	else {
+	else if (dev->class == ATA_DEV_ATAPI) {
 		if (ata_id_is_ata(dev->id))		/* sanity check */
 			goto err_out_nosup;
 
@@ -2400,7 +2399,7 @@ static void ata_sg_clean(struct ata_queu
 	if (qc->flags & ATA_QCFLAG_SINGLE)
 		assert(qc->n_elem == 1);
 
-	DPRINTK("unmapping %u sg elements\n", qc->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
@@ -2410,7 +2409,8 @@ static void ata_sg_clean(struct ata_queu
 		pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ);
 
 	if (qc->flags & ATA_QCFLAG_SG) {
-		dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir);
+		if (qc->n_elem)
+			dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir);
 		/* restore last sg */
 		sg[qc->orig_n_elem - 1].length += qc->pad_len;
 		if (pad_buf) {
@@ -2420,8 +2420,10 @@ static void ata_sg_clean(struct ata_queu
 			kunmap_atomic(psg->page, KM_IRQ0);
 		}
 	} else {
-		dma_unmap_single(ap->host_set->dev, sg_dma_address(&sg[0]),
-				 sg_dma_len(&sg[0]), dir);
+		if (sg_dma_len(&sg[0]) > 0)
+			dma_unmap_single(ap->host_set->dev,
+				sg_dma_address(&sg[0]), sg_dma_len(&sg[0]),
+				dir);
 		/* restore sg */
 		sg->length += qc->pad_len;
 		if (pad_buf)
@@ -2620,6 +2622,11 @@ static int ata_sg_setup_one(struct ata_q
 			sg->length, qc->pad_len);
 	}
 
+	if (!sg->length) {
+		sg_dma_address(sg) = 0;
+		goto skip_map;
+	}
+
 	dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt,
 				     sg->length, dir);
 	if (dma_mapping_error(dma_address)) {
@@ -2629,6 +2636,7 @@ static int ata_sg_setup_one(struct ata_q
 	}
 
 	sg_dma_address(sg) = dma_address;
+skip_map:
 	sg_dma_len(sg) = sg->length;
 
 	DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg),
@@ -2656,7 +2664,7 @@ static int ata_sg_setup(struct ata_queue
 	struct ata_port *ap = qc->ap;
 	struct scatterlist *sg = qc->__sg;
 	struct scatterlist *lsg = &sg[qc->n_elem - 1];
-	int n_elem, dir;
+	int n_elem, pre_n_elem, dir, trim_sg = 0;
 
 	VPRINTK("ENTER, ata%u\n", ap->id);
 	assert(qc->flags & ATA_QCFLAG_SG);
@@ -2690,13 +2698,24 @@ static int ata_sg_setup(struct ata_queue
 		sg_dma_len(psg) = ATA_DMA_PAD_SZ;
 		/* trim last sg */
 		lsg->length -= qc->pad_len;
+		if (lsg->length == 0)
+			trim_sg = 1;
 
 		DPRINTK("padding done, sg[%d].length=%u pad_len=%u\n",
 			qc->n_elem - 1, lsg->length, qc->pad_len);
 	}
 
+	pre_n_elem = qc->n_elem;
+	if (trim_sg && pre_n_elem)
+		pre_n_elem--;
+
+	if (!pre_n_elem) {
+		n_elem = 0;
+		goto skip_map;
+	}
+
 	dir = qc->dma_dir;
-	n_elem = dma_map_sg(ap->host_set->dev, sg, qc->n_elem, dir);
+	n_elem = dma_map_sg(ap->host_set->dev, sg, pre_n_elem, dir);
 	if (n_elem < 1) {
 		/* restore last sg */
 		lsg->length += qc->pad_len;
@@ -2705,6 +2724,7 @@ static int ata_sg_setup(struct ata_queue
 
 	DPRINTK("%d sg elements mapped\n", n_elem);
 
+skip_map:
 	qc->n_elem = n_elem;
 
 	return 0;
@@ -3264,32 +3284,11 @@ static void ata_qc_timeout(struct ata_qu
 {
 	struct ata_port *ap = qc->ap;
 	struct ata_host_set *host_set = ap->host_set;
-	struct ata_device *dev = qc->dev;
 	u8 host_stat = 0, drv_stat;
 	unsigned long flags;
 
 	DPRINTK("ENTER\n");
 
-	/* FIXME: doesn't this conflict with timeout handling? */
-	if (qc->dev->class == ATA_DEV_ATAPI && qc->scsicmd) {
-		struct scsi_cmnd *cmd = qc->scsicmd;
-
-		if (!(cmd->eh_eflags & SCSI_EH_CANCEL_CMD)) {
-
-			/* finish completing original command */
-			spin_lock_irqsave(&host_set->lock, flags);
-			__ata_qc_complete(qc);
-			spin_unlock_irqrestore(&host_set->lock, flags);
-
-			atapi_request_sense(ap, dev, cmd);
-
-			cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16);
-			scsi_finish_command(cmd);
-
-			goto out;
-		}
-	}
-
 	spin_lock_irqsave(&host_set->lock, flags);
 
 	/* hack alert!  We cannot use the supplied completion
@@ -3328,7 +3327,6 @@ static void ata_qc_timeout(struct ata_qu
 
 	spin_unlock_irqrestore(&host_set->lock, flags);
 
-out:
 	DPRINTK("EXIT\n");
 }
 
@@ -3412,16 +3410,11 @@ struct ata_queued_cmd *ata_qc_new_init(s
 
 	qc = ata_qc_new(ap);
 	if (qc) {
-		qc->__sg = NULL;
-		qc->flags = 0;
 		qc->scsicmd = NULL;
 		qc->ap = ap;
 		qc->dev = dev;
-		qc->cursect = qc->cursg = qc->cursg_ofs = 0;
-		qc->nsect = 0;
-		qc->nbytes = qc->curbytes = 0;
 
-		ata_tf_init(ap, &qc->tf, dev->devno);
+		ata_qc_reinit(qc);
 	}
 
 	return qc;
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 261be24..3b4ca55 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -1955,22 +1955,44 @@ void ata_scsi_badcmd(struct scsi_cmnd *c
 	done(cmd);
 }
 
-void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
-			 struct scsi_cmnd *cmd)
+static int atapi_sense_complete(struct ata_queued_cmd *qc,unsigned int err_mask)
 {
-	DECLARE_COMPLETION(wait);
-	struct ata_queued_cmd *qc;
-	unsigned long flags;
-	int rc;
+	if (err_mask && ((err_mask & AC_ERR_DEV) == 0))
+		/* FIXME: not quite right; we don't want the
+		 * translation of taskfile registers into
+		 * a sense descriptors, since that's only
+		 * correct for ATA, not ATAPI
+		 */
+		ata_gen_ata_desc_sense(qc);
 
-	DPRINTK("ATAPI request sense\n");
+	qc->scsidone(qc->scsicmd);
+	return 0;
+}
+
+/* is it pointless to prefer PIO for "safety reasons"? */
+static inline int ata_pio_use_silly(struct ata_port *ap)
+{
+	return (ap->flags & ATA_FLAG_PIO_DMA);
+}
 
-	qc = ata_qc_new_init(ap, dev);
-	BUG_ON(qc == NULL);
+static void atapi_request_sense(struct ata_queued_cmd *qc)
+{
+	struct ata_port *ap = qc->ap;
+	struct scsi_cmnd *cmd = qc->scsicmd;
+
+	DPRINTK("ATAPI request sense\n");
 
 	/* FIXME: is this needed? */
 	memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
 
+	ap->ops->tf_read(ap, &qc->tf);
+
+	/* fill these in, for the case where they are -not- overwritten */
+	cmd->sense_buffer[0] = 0x70;
+	cmd->sense_buffer[2] = qc->tf.feature >> 4;
+
+	ata_qc_reinit(qc);
+
 	ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer));
 	qc->dma_dir = DMA_FROM_DEVICE;
 
@@ -1981,22 +2003,20 @@ void atapi_request_sense(struct ata_port
 	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
 	qc->tf.command = ATA_CMD_PACKET;
 
-	qc->tf.protocol = ATA_PROT_ATAPI;
-	qc->tf.lbam = (8 * 1024) & 0xff;
-	qc->tf.lbah = (8 * 1024) >> 8;
+	if (ata_pio_use_silly(ap)) {
+		qc->tf.protocol = ATA_PROT_ATAPI_DMA;
+		qc->tf.feature |= ATAPI_PKT_DMA;
+	} else {
+		qc->tf.protocol = ATA_PROT_ATAPI;
+		qc->tf.lbam = (8 * 1024) & 0xff;
+		qc->tf.lbah = (8 * 1024) >> 8;
+	}
 	qc->nbytes = SCSI_SENSE_BUFFERSIZE;
 
-	qc->waiting = &wait;
-	qc->complete_fn = ata_qc_complete_noop;
-
-	spin_lock_irqsave(&ap->host_set->lock, flags);
-	rc = ata_qc_issue(qc);
-	spin_unlock_irqrestore(&ap->host_set->lock, flags);
+	qc->complete_fn = atapi_sense_complete;
 
-	if (rc)
-		ata_port_disable(ap);
-	else
-		wait_for_completion(&wait);
+	if (ata_qc_issue(qc))
+		ata_qc_complete(qc, AC_ERR_OTHER);
 
 	DPRINTK("EXIT\n");
 }
@@ -2008,19 +2028,8 @@ static int atapi_qc_complete(struct ata_
 	VPRINTK("ENTER, err_mask 0x%X\n", err_mask);
 
 	if (unlikely(err_mask & AC_ERR_DEV)) {
-		DPRINTK("request check condition\n");
-
-		/* FIXME: command completion with check condition
-		 * but no sense causes the error handler to run,
-		 * which then issues REQUEST SENSE, fills in the sense 
-		 * buffer, and completes the command (for the second
-		 * time).  We need to issue REQUEST SENSE some other
-		 * way, to avoid completing the command twice.
-		 */
 		cmd->result = SAM_STAT_CHECK_CONDITION;
-
-		qc->scsidone(cmd);
-
+		atapi_request_sense(qc);
 		return 1;
 	}
 
@@ -2276,6 +2285,12 @@ ata_scsi_pass_thru(struct ata_queued_cmd
 		tf->device = scsicmd[8];
 		tf->command = scsicmd[9];
 	}
+	/*
+	 * If slave is possible, enforce correct master/slave bit
+	*/
+	if (qc->ap->flags & ATA_FLAG_SLAVE_POSS)
+		tf->device = qc->dev->devno ?
+			tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
 
 	/*
 	 * Filter SET_FEATURES - XFER MODE command -- otherwise,
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index fad051c..74a84e0 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -54,8 +54,6 @@ extern int ata_cmd_ioctl(struct scsi_dev
 
 
 /* libata-scsi.c */
-extern void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
-			 struct scsi_cmnd *cmd);
 extern void ata_scsi_scan_host(struct ata_port *ap);
 extern int ata_scsi_error(struct Scsi_Host *host);
 extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index b2f6324..4a6d306 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -268,7 +268,7 @@ static void qs_scr_write (struct ata_por
 	writel(val, (void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8)));
 }
 
-static void qs_fill_sg(struct ata_queued_cmd *qc)
+static unsigned int qs_fill_sg(struct ata_queued_cmd *qc)
 {
 	struct scatterlist *sg;
 	struct ata_port *ap = qc->ap;
@@ -296,6 +296,8 @@ static void qs_fill_sg(struct ata_queued
 					(unsigned long long)addr, len);
 		nelem++;
 	}
+
+	return nelem;
 }
 
 static void qs_qc_prep(struct ata_queued_cmd *qc)
@@ -304,6 +306,7 @@ static void qs_qc_prep(struct ata_queued
 	u8 dflags = QS_DF_PORD, *buf = pp->pkt;
 	u8 hflags = QS_HF_DAT | QS_HF_IEN | QS_HF_VLD;
 	u64 addr;
+	unsigned int nelem;
 
 	VPRINTK("ENTER\n");
 
@@ -313,7 +316,7 @@ static void qs_qc_prep(struct ata_queued
 		return;
 	}
 
-	qs_fill_sg(qc);
+	nelem = qs_fill_sg(qc);
 
 	if ((qc->tf.flags & ATA_TFLAG_WRITE))
 		hflags |= QS_HF_DIRO;
@@ -324,7 +327,7 @@ static void qs_qc_prep(struct ata_queued
 	buf[ 0] = QS_HCB_HDR;
 	buf[ 1] = hflags;
 	*(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nsect * ATA_SECT_SIZE);
-	*(__le32 *)(&buf[ 8]) = cpu_to_le32(qc->n_elem);
+	*(__le32 *)(&buf[ 8]) = cpu_to_le32(nelem);
 	addr = ((u64)pp->pkt_dma) + QS_CPB_BYTES;
 	*(__le64 *)(&buf[16]) = cpu_to_le64(addr);
 
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index d3198d9..55e744d 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -687,6 +687,7 @@ static void sil24_port_stop(struct ata_p
 	struct sil24_port_priv *pp = ap->private_data;
 
 	sil24_cblk_free(pp, dev);
+	ata_pad_free(ap, dev);
 	kfree(pp);
 }
 
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 2efb317..67e9afa 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -34,6 +34,7 @@
 #include <linux/keyboard.h>
 #include <linux/init.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
 
@@ -1343,7 +1344,7 @@ static void show_serial_version(void)
 	printk("MC68328 serial driver version 1.00\n");
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
 /* Serial Power management
  *  The console (currently fixed at line 0) is a special case for power
  *  management because the kernel is so chatty. The console will be 
@@ -1393,7 +1394,7 @@ void startup_console(void)
 	struct m68k_serial *info = &m68k_soft[0];
 	startup(info);
 }
-#endif
+#endif /* CONFIG_PM_LEGACY */
 
 
 static struct tty_operations rs_ops = {
@@ -1486,7 +1487,7 @@ rs68328_init(void)
 			    IRQ_FLG_STD,
 			    "M68328_UART", NULL))
                 panic("Unable to attach 68328 serial interrupt\n");
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
 	    serial_pm[i] = pm_register(PM_SYS_DEV, PM_SYS_COM, serial_pm_callback);
 	    if (serial_pm[i])
 		    serial_pm[i]->data = info;
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 3742753..e08510d 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -999,7 +999,10 @@ static void autoconfig(struct uart_8250_
 	serial_outp(up, UART_MCR, save_mcr);
 	serial8250_clear_fifos(up);
 	(void)serial_in(up, UART_RX);
-	serial_outp(up, UART_IER, 0);
+	if (up->capabilities & UART_CAP_UUE)
+		serial_outp(up, UART_IER, UART_IER_UUE);
+	else
+		serial_outp(up, UART_IER, 0);
 
  out:	
 	spin_unlock_irqrestore(&up->port.lock, flags);
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 5d8660a..b79ed06 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -323,6 +323,8 @@ static const struct pnp_device_id pnp_de
 	{	"USR9180",		0	},
 	/* U.S. Robotics 56K Voice INT PnP*/
 	{	"USR9190",		0	},
+	/* HP Compaq Tablet PC tc1100 Wacom tablet */
+	{	"WACF005",		0	},
 	/* Rockwell's (PORALiNK) 33600 INT PNP */
 	{	"WCI0003",		0	},
 	/* Unkown PnP modems */
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 25825f2..987d22b 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -7,7 +7,7 @@
  *  Based on ppc8xx.c by Thomas Gleixner
  *  Based on drivers/serial/amba.c by Russell King
  *
- *  Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2)
+ *  Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
  *              Pantelis Antoniou (panto@intracom.gr) (CPM1)
  *
  *  Copyright (C) 2004 Freescale Semiconductor, Inc.
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index 4b0786e..d789ee5 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -3,7 +3,7 @@
  *
  *  Driver for CPM (SCC/SMC) serial ports; CPM1 definitions
  *
- *  Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2)
+ *  Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
  *              Pantelis Antoniou (panto@intracom.gr) (CPM1)
  *
  *  Copyright (C) 2004 Freescale Semiconductor, Inc.
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index 15ad58d..fd9e53e 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -3,7 +3,7 @@
  *
  *  Driver for CPM (SCC/SMC) serial ports; CPM2 definitions
  *
- *  Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2)
+ *  Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
  *              Pantelis Antoniou (panto@intracom.gr) (CPM1)
  * 
  *  Copyright (C) 2004 Freescale Semiconductor, Inc.
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index e63b9df..4d8516d 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -1,9 +1,9 @@
 /*
- * dz.c: Serial port driver for DECStations equiped 
+ * dz.c: Serial port driver for DECStations equiped
  *       with the DZ chipset.
  *
- * Copyright (C) 1998 Olivier A. D. Lebaillif 
- *             
+ * Copyright (C) 1998 Olivier A. D. Lebaillif
+ *
  * Email: olivier.lebaillif@ifrsys.com
  *
  * [31-AUG-98] triemer
@@ -11,14 +11,14 @@
  * removed base_addr code - moving address assignment to setup.c
  * Changed name of dz_init to rs_init to be consistent with tc code
  * [13-NOV-98] triemer fixed code to receive characters
- *    after patches by harald to irq code.  
+ *    after patches by harald to irq code.
  * [09-JAN-99] triemer minor fix for schedule - due to removal of timeout
  *            field from "current" - somewhere between 2.1.121 and 2.1.131
  Qua Jun 27 15:02:26 BRT 2001
  * [27-JUN-2001] Arnaldo Carvalho de Melo <acme@conectiva.com.br> - cleanups
- *  
- * Parts (C) 1999 David Airlie, airlied@linux.ie 
- * [07-SEP-99] Bugfixes 
+ *
+ * Parts (C) 1999 David Airlie, airlied@linux.ie
+ * [07-SEP-99] Bugfixes
  *
  * [06-Jan-2002] Russell King <rmk@arm.linux.org.uk>
  * Converted to new serial core
@@ -64,7 +64,7 @@ static struct dz_port dz_ports[DZ_NB_POR
 
 #ifdef DEBUG_DZ
 /*
- * debugging code to send out chars via prom 
+ * debugging code to send out chars via prom
  */
 static void debug_console(const char *s, int count)
 {
@@ -82,7 +82,7 @@ static void debug_console(const char *s,
  * ------------------------------------------------------------
  * dz_in () and dz_out ()
  *
- * These routines are used to access the registers of the DZ 
+ * These routines are used to access the registers of the DZ
  * chip, hiding relocation differences between implementation.
  * ------------------------------------------------------------
  */
@@ -106,8 +106,8 @@ static inline void dz_out(struct dz_port
  * ------------------------------------------------------------
  * rs_stop () and rs_start ()
  *
- * These routines are called before setting or resetting 
- * tty->stopped. They enable or disable transmitter interrupts, 
+ * These routines are called before setting or resetting
+ * tty->stopped. They enable or disable transmitter interrupts,
  * as necessary.
  * ------------------------------------------------------------
  */
@@ -156,17 +156,17 @@ static void dz_enable_ms(struct uart_por
 
 /*
  * ------------------------------------------------------------
- * Here starts the interrupt handling routines.  All of the 
- * following subroutines are declared as inline and are folded 
- * into dz_interrupt.  They were separated out for readability's 
- * sake. 
+ * Here starts the interrupt handling routines.  All of the
+ * following subroutines are declared as inline and are folded
+ * into dz_interrupt.  They were separated out for readability's
+ * sake.
  *
  * Note: rs_interrupt() is a "fast" interrupt, which means that it
  * runs with interrupts turned off.  People who may want to modify
  * rs_interrupt() should try to keep the interrupt handler as fast as
  * possible.  After you are done making modifications, it is not a bad
  * idea to do:
- * 
+ *
  *	make drivers/serial/dz.s
  *
  * and look at the resulting assemble code in dz.s.
@@ -403,7 +403,7 @@ static void dz_set_mctrl(struct uart_por
  * startup ()
  *
  * various initialization tasks
- * ------------------------------------------------------------------- 
+ * -------------------------------------------------------------------
  */
 static int dz_startup(struct uart_port *uport)
 {
@@ -430,13 +430,13 @@ static int dz_startup(struct uart_port *
 	return 0;
 }
 
-/* 
+/*
  * -------------------------------------------------------------------
  * shutdown ()
  *
  * This routine will shutdown a serial port; interrupts are disabled, and
  * DTR is dropped if the hangup on close termio flag is on.
- * ------------------------------------------------------------------- 
+ * -------------------------------------------------------------------
  */
 static void dz_shutdown(struct uart_port *uport)
 {
@@ -451,7 +451,7 @@ static void dz_shutdown(struct uart_port
  *          release the bus after transmitting. This must be done when
  *          the transmit shift register is empty, not be done when the
  *          transmit holding register is empty.  This functionality
- *          allows an RS485 driver to be written in user space. 
+ *          allows an RS485 driver to be written in user space.
  */
 static unsigned int dz_tx_empty(struct uart_port *uport)
 {
@@ -645,9 +645,9 @@ static void __init dz_init_ports(void)
 
 	if (mips_machtype == MACH_DS23100 ||
 	    mips_machtype == MACH_DS5100)
-		base = (unsigned long) KN01_DZ11_BASE;
+		base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_DZ11);
 	else
-		base = (unsigned long) KN02_DZ11_BASE;
+		base = CKSEG1ADDR(KN02_SLOT_BASE + KN02_DZ11);
 
 	for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) {
 		spin_lock_init(&dport->port.lock);
@@ -695,13 +695,13 @@ static void dz_console_put_char(struct d
 
 	spin_unlock_irqrestore(&dport->port.lock, flags);
 }
-/* 
+/*
  * -------------------------------------------------------------------
  * dz_console_print ()
  *
  * dz_console_print is registered for printk.
  * The console must be locked when we get here.
- * ------------------------------------------------------------------- 
+ * -------------------------------------------------------------------
  */
 static void dz_console_print(struct console *cons,
 			     const char *str,
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 5d3cb84..b8727d9 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -725,7 +725,7 @@ mpc52xx_uart_probe(struct platform_devic
 	int i, idx, ret;
 
 	/* Check validity & presence */
-	idx = pdev->id;
+	idx = dev->id;
 	if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM)
 		return -EINVAL;
 
@@ -748,7 +748,7 @@ mpc52xx_uart_probe(struct platform_devic
 	port->ops	= &mpc52xx_uart_ops;
 
 	/* Search for IRQ and mapbase */
-	for (i=0 ; i<pdev->num_resources ; i++, res++) {
+	for (i=0 ; i<dev->num_resources ; i++, res++) {
 		if (res->flags & IORESOURCE_MEM)
 			port->mapbase = res->start;
 		else if (res->flags & IORESOURCE_IRQ)
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index fd9deee..0e3daf6 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -156,7 +156,7 @@ static void sa1100_stop_tx(struct uart_p
 }
 
 /*
- * interrupts may not be disabled on entry
+ * port locked and interrupts disabled
  */
 static void sa1100_start_tx(struct uart_port *port)
 {
@@ -164,11 +164,9 @@ static void sa1100_start_tx(struct uart_
 	unsigned long flags;
 	u32 utcr3;
 
-	spin_lock_irqsave(&sport->port.lock, flags);
 	utcr3 = UART_GET_UTCR3(sport);
 	sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_TFS);
 	UART_PUT_UTCR3(sport, utcr3 | UTCR3_TIE);
-	spin_unlock_irqrestore(&sport->port.lock, flags);
 }
 
 /*
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 427a238..2331296 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -209,33 +209,45 @@ static void uart_shutdown(struct uart_st
 	struct uart_info *info = state->info;
 	struct uart_port *port = state->port;
 
-	if (!(info->flags & UIF_INITIALIZED))
-		return;
-
 	/*
-	 * Turn off DTR and RTS early.
+	 * Set the TTY IO error marker
 	 */
-	if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
-		uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
 
-	/*
-	 * clear delta_msr_wait queue to avoid mem leaks: we may free
-	 * the irq here so the queue might never be woken up.  Note
-	 * that we won't end up waiting on delta_msr_wait again since
-	 * any outstanding file descriptors should be pointing at
-	 * hung_up_tty_fops now.
-	 */
-	wake_up_interruptible(&info->delta_msr_wait);
+	if (info->flags & UIF_INITIALIZED) {
+		info->flags &= ~UIF_INITIALIZED;
 
-	/*
-	 * Free the IRQ and disable the port.
-	 */
-	port->ops->shutdown(port);
+		/*
+		 * Turn off DTR and RTS early.
+		 */
+		if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
+			uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
+
+		/*
+		 * clear delta_msr_wait queue to avoid mem leaks: we may free
+		 * the irq here so the queue might never be woken up.  Note
+		 * that we won't end up waiting on delta_msr_wait again since
+		 * any outstanding file descriptors should be pointing at
+		 * hung_up_tty_fops now.
+		 */
+		wake_up_interruptible(&info->delta_msr_wait);
+
+		/*
+		 * Free the IRQ and disable the port.
+		 */
+		port->ops->shutdown(port);
+
+		/*
+		 * Ensure that the IRQ handler isn't running on another CPU.
+		 */
+		synchronize_irq(port->irq);
+	}
 
 	/*
-	 * Ensure that the IRQ handler isn't running on another CPU.
+	 * kill off our tasklet
 	 */
-	synchronize_irq(port->irq);
+	tasklet_kill(&info->tlet);
 
 	/*
 	 * Free the transmit buffer page.
@@ -244,15 +256,6 @@ static void uart_shutdown(struct uart_st
 		free_page((unsigned long)info->xmit.buf);
 		info->xmit.buf = NULL;
 	}
-
-	/*
-	 * kill off our tasklet
-	 */
-	tasklet_kill(&info->tlet);
-	if (info->tty)
-		set_bit(TTY_IO_ERROR, &info->tty->flags);
-
-	info->flags &= ~UIF_INITIALIZED;
 }
 
 /**
@@ -1928,14 +1931,25 @@ int uart_resume_port(struct uart_driver 
 
 	if (state->info && state->info->flags & UIF_INITIALIZED) {
 		struct uart_ops *ops = port->ops;
+		int ret;
 
 		ops->set_mctrl(port, 0);
-		ops->startup(port);
-		uart_change_speed(state, NULL);
-		spin_lock_irq(&port->lock);
-		ops->set_mctrl(port, port->mctrl);
-		ops->start_tx(port);
-		spin_unlock_irq(&port->lock);
+		ret = ops->startup(port);
+		if (ret == 0) {
+			uart_change_speed(state, NULL);
+			spin_lock_irq(&port->lock);
+			ops->set_mctrl(port, port->mctrl);
+			ops->start_tx(port);
+			spin_unlock_irq(&port->lock);
+		} else {
+			/*
+			 * Failed to resume - maybe hardware went away?
+			 * Clear the "initialized" flag so we won't try
+			 * to call the low level drivers shutdown method.
+			 */
+			state->info->flags &= ~UIF_INITIALIZED;
+			uart_shutdown(state);
+		}
 	}
 
 	up(&state->sem);
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index f53bf3b..d3728f6 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -51,6 +51,9 @@ static struct fb_ops bw2_ops = {
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= bw2_mmap,
 	.fb_ioctl		= bw2_ioctl,
+#ifdef CONFIG_COMPAT
+	.fb_compat_ioctl	= sbusfb_compat_ioctl,
+#endif
 };
 
 /* OBio addresses for the bwtwo registers */
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index 030d4b1..1bed50f 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -49,6 +49,9 @@ static struct fb_ops cg14_ops = {
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= cg14_mmap,
 	.fb_ioctl		= cg14_ioctl,
+#ifdef CONFIG_COMPAT
+	.fb_compat_ioctl	= sbusfb_compat_ioctl,
+#endif
 };
 
 #define CG14_MCR_INTENABLE_SHIFT	7
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index b94eee8..a1354e7 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -50,6 +50,9 @@ static struct fb_ops cg3_ops = {
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= cg3_mmap,
 	.fb_ioctl		= cg3_ioctl,
+#ifdef CONFIG_COMPAT
+	.fb_compat_ioctl	= sbusfb_compat_ioctl,
+#endif
 };
 
 
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 414c440..9debe64 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -54,6 +54,9 @@ static struct fb_ops cg6_ops = {
 	.fb_sync		= cg6_sync,
 	.fb_mmap		= cg6_mmap,
 	.fb_ioctl		= cg6_ioctl,
+#ifdef CONFIG_COMPAT
+	.fb_compat_ioctl	= sbusfb_compat_ioctl,
+#endif
 };
 
 /* Offset of interesting structures in the OBIO space */
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 94c5f13..5f74df9 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -215,12 +215,5 @@ config FONT_10x18
 	  big letters. It fits between the sun 12x22 and the normal 8x16 font.
 	  If other fonts are too big or too small for you, say Y, otherwise say N.
 
-config FONT_RL
-	bool "console Roman Large 8x16 font" if FONTS
-	depends on FRAMEBUFFER_CONSOLE
-	help
-	  This is the visually-appealing "RL" console font that is
-	  included with the kbd package.
-
 endmenu
 
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index fed600c..9b26dda 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -15,7 +15,6 @@ font-objs-$(CONFIG_FONT_10x18)     += fo
 font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
 font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
 font-objs-$(CONFIG_FONT_MINI_4x6)  += font_mini_4x6.o
-font-objs-$(CONFIG_FONT_RL)  += font_rl.o
 
 font-objs += $(font-objs-y)
 
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index e7802ff..bcea87c 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -106,8 +106,7 @@ enum {
 	FBCON_LOGO_DONTSHOW	= -3	/* do not show the logo */
 };
 
-struct display fb_display[MAX_NR_CONSOLES];
-EXPORT_SYMBOL(fb_display);
+static struct display fb_display[MAX_NR_CONSOLES];
 
 static signed char con2fb_map[MAX_NR_CONSOLES];
 static signed char con2fb_map_boot[MAX_NR_CONSOLES];
@@ -653,13 +652,12 @@ static void set_blitting_type(struct vc_
 {
 	struct fbcon_ops *ops = info->fbcon_par;
 
+	ops->p = (p) ? p : &fb_display[vc->vc_num];
+
 	if ((info->flags & FBINFO_MISC_TILEBLITTING))
 		fbcon_set_tileops(vc, info, p, ops);
 	else {
-		struct display *disp;
-
-		disp = (p) ? p : &fb_display[vc->vc_num];
-		fbcon_set_rotation(info, disp);
+		fbcon_set_rotation(info, ops->p);
 		fbcon_set_bitops(ops);
 	}
 }
@@ -668,11 +666,10 @@ static void set_blitting_type(struct vc_
 			      struct display *p)
 {
 	struct fbcon_ops *ops = info->fbcon_par;
-	struct display *disp;
 
 	info->flags &= ~FBINFO_MISC_TILEBLITTING;
-	disp = (p) ? p : &fb_display[vc->vc_num];
-	fbcon_set_rotation(info, disp);
+	ops->p = (p) ? p : &fb_display[vc->vc_num];
+	fbcon_set_rotation(info, ops->p);
 	fbcon_set_bitops(ops);
 }
 #endif /* CONFIG_MISC_TILEBLITTING */
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index accfd7b..6892e7f 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -52,8 +52,6 @@ struct display {
     struct fb_videomode *mode;
 };
 
-extern struct display fb_display[];
-
 struct fbcon_ops {
 	void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
 		      int sx, int dy, int dx, int height, int width);
@@ -73,6 +71,7 @@ struct fbcon_ops {
 	struct fb_var_screeninfo var;  /* copy of the current fb_var_screeninfo */
 	struct timer_list cursor_timer; /* Cursor timer */
 	struct fb_cursor cursor_state;
+	struct display *p;
         int    currcon;	                /* Current VC. */
 	int    cursor_flash;
 	int    cursor_reset;
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
index 680aaba..3afd1ee 100644
--- a/drivers/video/console/fbcon_ccw.c
+++ b/drivers/video/console/fbcon_ccw.c
@@ -63,9 +63,9 @@ static inline void ccw_update_attr(u8 *d
 static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
 		     int sx, int dy, int dx, int height, int width)
 {
-	struct display *p = &fb_display[vc->vc_num];
+	struct fbcon_ops *ops = info->fbcon_par;
 	struct fb_copyarea area;
-	u32 vyres = GETVYRES(p->scrollmode, info);
+	u32 vyres = GETVYRES(ops->p->scrollmode, info);
 
 	area.sx = sy * vc->vc_font.height;
 	area.sy = vyres - ((sx + width) * vc->vc_font.width);
@@ -80,10 +80,10 @@ static void ccw_bmove(struct vc_data *vc
 static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
 		     int sx, int height, int width)
 {
-	struct display *p = &fb_display[vc->vc_num];
+	struct fbcon_ops *ops = info->fbcon_par;
 	struct fb_fillrect region;
 	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
-	u32 vyres = GETVYRES(p->scrollmode, info);
+	u32 vyres = GETVYRES(ops->p->scrollmode, info);
 
 	region.color = attr_bgcol_ec(bgshift,vc);
 	region.dx = sy * vc->vc_font.height;
@@ -131,7 +131,6 @@ static void ccw_putcs(struct vc_data *vc
 		      int fg, int bg)
 {
 	struct fb_image image;
-	struct display *p = &fb_display[vc->vc_num];
 	struct fbcon_ops *ops = info->fbcon_par;
 	u32 width = (vc->vc_font.height + 7)/8;
 	u32 cellsize = width * vc->vc_font.width;
@@ -141,7 +140,7 @@ static void ccw_putcs(struct vc_data *vc
 	u32 cnt, pitch, size;
 	u32 attribute = get_attribute(info, scr_readw(s));
 	u8 *dst, *buf = NULL;
-	u32 vyres = GETVYRES(p->scrollmode, info);
+	u32 vyres = GETVYRES(ops->p->scrollmode, info);
 
 	if (!ops->fontbuffer)
 		return;
@@ -397,9 +396,8 @@ static void ccw_cursor(struct vc_data *v
 int ccw_update_start(struct fb_info *info)
 {
 	struct fbcon_ops *ops = info->fbcon_par;
-	struct display *p = &fb_display[ops->currcon];
 	u32 yoffset;
-	u32 vyres = GETVYRES(p->scrollmode, info);
+	u32 vyres = GETVYRES(ops->p->scrollmode, info);
 	int err;
 
 	yoffset = (vyres - info->var.yres) - ops->var.xoffset;
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
index 6c6f3b6..6d92b84 100644
--- a/drivers/video/console/fbcon_cw.c
+++ b/drivers/video/console/fbcon_cw.c
@@ -49,9 +49,9 @@ static inline void cw_update_attr(u8 *ds
 static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
 		     int sx, int dy, int dx, int height, int width)
 {
-	struct display *p = &fb_display[vc->vc_num];
+	struct fbcon_ops *ops = info->fbcon_par;
 	struct fb_copyarea area;
-	u32 vxres = GETVXRES(p->scrollmode, info);
+	u32 vxres = GETVXRES(ops->p->scrollmode, info);
 
 	area.sx = vxres - ((sy + height) * vc->vc_font.height);
 	area.sy = sx * vc->vc_font.width;
@@ -66,10 +66,10 @@ static void cw_bmove(struct vc_data *vc,
 static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
 		     int sx, int height, int width)
 {
-	struct display *p = &fb_display[vc->vc_num];
+	struct fbcon_ops *ops = info->fbcon_par;
 	struct fb_fillrect region;
 	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
-	u32 vxres = GETVXRES(p->scrollmode, info);
+	u32 vxres = GETVXRES(ops->p->scrollmode, info);
 
 	region.color = attr_bgcol_ec(bgshift,vc);
 	region.dx = vxres - ((sy + height) * vc->vc_font.height);
@@ -117,7 +117,6 @@ static void cw_putcs(struct vc_data *vc,
 		      int fg, int bg)
 {
 	struct fb_image image;
-	struct display *p = &fb_display[vc->vc_num];
 	struct fbcon_ops *ops = info->fbcon_par;
 	u32 width = (vc->vc_font.height + 7)/8;
 	u32 cellsize = width * vc->vc_font.width;
@@ -127,7 +126,7 @@ static void cw_putcs(struct vc_data *vc,
 	u32 cnt, pitch, size;
 	u32 attribute = get_attribute(info, scr_readw(s));
 	u8 *dst, *buf = NULL;
-	u32 vxres = GETVXRES(p->scrollmode, info);
+	u32 vxres = GETVXRES(ops->p->scrollmode, info);
 
 	if (!ops->fontbuffer)
 		return;
@@ -381,8 +380,7 @@ static void cw_cursor(struct vc_data *vc
 int cw_update_start(struct fb_info *info)
 {
 	struct fbcon_ops *ops = info->fbcon_par;
-	struct display *p = &fb_display[ops->currcon];
-	u32 vxres = GETVXRES(p->scrollmode, info);
+	u32 vxres = GETVXRES(ops->p->scrollmode, info);
 	u32 xoffset;
 	int err;
 
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
index 2e1d9d4..c4d7c89 100644
--- a/drivers/video/console/fbcon_ud.c
+++ b/drivers/video/console/fbcon_ud.c
@@ -48,10 +48,10 @@ static inline void ud_update_attr(u8 *ds
 static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
 		     int sx, int dy, int dx, int height, int width)
 {
-	struct display *p = &fb_display[vc->vc_num];
+	struct fbcon_ops *ops = info->fbcon_par;
 	struct fb_copyarea area;
-	u32 vyres = GETVYRES(p->scrollmode, info);
-	u32 vxres = GETVXRES(p->scrollmode, info);
+	u32 vyres = GETVYRES(ops->p->scrollmode, info);
+	u32 vxres = GETVXRES(ops->p->scrollmode, info);
 
 	area.sy = vyres - ((sy + height) * vc->vc_font.height);
 	area.sx = vxres - ((sx + width) * vc->vc_font.width);
@@ -66,11 +66,11 @@ static void ud_bmove(struct vc_data *vc,
 static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
 		     int sx, int height, int width)
 {
-	struct display *p = &fb_display[vc->vc_num];
+	struct fbcon_ops *ops = info->fbcon_par;
 	struct fb_fillrect region;
 	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
-	u32 vyres = GETVYRES(p->scrollmode, info);
-	u32 vxres = GETVXRES(p->scrollmode, info);
+	u32 vyres = GETVYRES(ops->p->scrollmode, info);
+	u32 vxres = GETVXRES(ops->p->scrollmode, info);
 
 	region.color = attr_bgcol_ec(bgshift,vc);
 	region.dy = vyres - ((sy + height) * vc->vc_font.height);
@@ -153,7 +153,6 @@ static void ud_putcs(struct vc_data *vc,
 		      int fg, int bg)
 {
 	struct fb_image image;
-	struct display *p = &fb_display[vc->vc_num];
 	struct fbcon_ops *ops = info->fbcon_par;
 	u32 width = (vc->vc_font.width + 7)/8;
 	u32 cellsize = width * vc->vc_font.height;
@@ -163,8 +162,8 @@ static void ud_putcs(struct vc_data *vc,
 	u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
 	u32 attribute = get_attribute(info, scr_readw(s));
 	u8 *dst, *buf = NULL;
-	u32 vyres = GETVYRES(p->scrollmode, info);
-	u32 vxres = GETVXRES(p->scrollmode, info);
+	u32 vyres = GETVYRES(ops->p->scrollmode, info);
+	u32 vxres = GETVXRES(ops->p->scrollmode, info);
 
 	if (!ops->fontbuffer)
 		return;
@@ -421,10 +420,9 @@ static void ud_cursor(struct vc_data *vc
 int ud_update_start(struct fb_info *info)
 {
 	struct fbcon_ops *ops = info->fbcon_par;
-	struct display *p = &fb_display[ops->currcon];
 	u32 xoffset, yoffset;
-	u32 vyres = GETVYRES(p->scrollmode, info);
-	u32 vxres = GETVXRES(p->scrollmode, info);
+	u32 vyres = GETVYRES(ops->p->scrollmode, info);
+	u32 vxres = GETVXRES(ops->p->scrollmode, info);
 	int err;
 
 	xoffset = (vxres - info->var.xres) - ops->var.xoffset;
diff --git a/drivers/video/console/font_rl.c b/drivers/video/console/font_rl.c
deleted file mode 100644
index dfecc27..0000000
--- a/drivers/video/console/font_rl.c
+++ /dev/null
@@ -1,4374 +0,0 @@
-
-/* This font is simply the "rl.fnt" console font from the kbd utility.
- * Converted by Zack T Smith, fbui@comcast.net.
- * The original binary file is covered under the GNU Public License.
- */
-
-#include <linux/font.h>
-
-#define FONTDATAMAX 4096
-
-static unsigned char patterns[4096] = {
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x3c,
-0x42,
-0x81,
-0xe7,
-0xa5,
-0x99,
-0x81,
-0x81,
-0x99,
-0x42,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x3c,
-0x7e,
-0xff,
-0x99,
-0xdb,
-0xe7,
-0xff,
-0xff,
-0xe7,
-0x7e,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x6c,
-0xfe,
-0xfe,
-0xfe,
-0xfe,
-0xfe,
-0x7c,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x7c,
-0xfe,
-0x7c,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x38,
-0x38,
-0x10,
-0xd6,
-0xfe,
-0xd6,
-0x10,
-0x10,
-0x38,
-0x7c,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x10,
-0x38,
-0x7c,
-0xfe,
-0xfe,
-0x54,
-0x10,
-0x10,
-0x38,
-0x7c,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x18,
-0x3c,
-0x3c,
-0x18,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xe7,
-0xc3,
-0xc3,
-0xe7,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x3c,
-0x66,
-0x42,
-0x42,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xc3,
-0x99,
-0xbd,
-0xbd,
-0x99,
-0xc3,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-
-0x00,
-0x00,
-0x0f,
-0x07,
-0x0d,
-0x18,
-0x78,
-0xcc,
-0xcc,
-0xcc,
-0xcc,
-0x78,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x3c,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x18,
-0x7e,
-0x18,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x08,
-0x0c,
-0x0a,
-0x0a,
-0x0a,
-0x08,
-0x08,
-0x08,
-0x38,
-0x78,
-0x30,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x10,
-0x18,
-0x1c,
-0x1e,
-0x1e,
-0x16,
-0x12,
-0x72,
-0xf2,
-0x62,
-0x0e,
-0x1e,
-0x0c,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x10,
-0x92,
-0x54,
-0x38,
-0xfe,
-0x38,
-0x54,
-0x92,
-0x10,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x80,
-0xc0,
-0xe0,
-0xb8,
-0x8e,
-0xb8,
-0xe0,
-0xc0,
-0x80,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x02,
-0x06,
-0x0e,
-0x3a,
-0xe2,
-0x3a,
-0x0e,
-0x06,
-0x02,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x10,
-0x38,
-0x7c,
-0xd6,
-0x10,
-0x10,
-0x10,
-0x10,
-0xd6,
-0x7c,
-0x38,
-0x10,
-0x00,
-0x00,
-
-0x00,
-0x42,
-0xe7,
-0xe7,
-0xe7,
-0xe7,
-0x42,
-0x42,
-0x42,
-0x00,
-0x66,
-0x66,
-0x66,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x7f,
-0xca,
-0xca,
-0xca,
-0xca,
-0x7a,
-0x0a,
-0x0a,
-0x0a,
-0x0a,
-0x0a,
-0x1b,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x1e,
-0x31,
-0x78,
-0xcc,
-0xc6,
-0xc3,
-0x63,
-0x33,
-0x1e,
-0x8c,
-0x78,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xfe,
-0xfe,
-0xfe,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x10,
-0x38,
-0x7c,
-0xd6,
-0x10,
-0x10,
-0x10,
-0x10,
-0xd6,
-0x7c,
-0x38,
-0x10,
-0xfe,
-0x00,
-
-0x00,
-0x00,
-0x10,
-0x38,
-0x7c,
-0xd6,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0x10,
-0xd6,
-0x7c,
-0x38,
-0x10,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x08,
-0x0c,
-0x06,
-0xff,
-0x06,
-0x0c,
-0x08,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x10,
-0x30,
-0x60,
-0xff,
-0x60,
-0x30,
-0x10,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x22,
-0x44,
-0x88,
-0xcc,
-0xee,
-0x44,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x24,
-0x42,
-0xff,
-0x42,
-0x24,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x38,
-0x6c,
-0x6c,
-0xc6,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0xfe,
-0xc6,
-0x6c,
-0x6c,
-0x38,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x18,
-0x3c,
-0x3c,
-0x3c,
-0x3c,
-0x18,
-0x18,
-0x18,
-0x10,
-0x00,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-
-0x22,
-0x77,
-0x33,
-0x11,
-0x22,
-0x44,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x12,
-0x12,
-0x12,
-0x7f,
-0x24,
-0x24,
-0x24,
-0xfe,
-0x48,
-0x48,
-0x48,
-0x00,
-0x00,
-0x00,
-
-0x10,
-0x10,
-0x7c,
-0xd2,
-0xd0,
-0xd0,
-0xd0,
-0x7c,
-0x16,
-0x16,
-0x16,
-0x96,
-0x7c,
-0x10,
-0x10,
-0x00,
-
-0x00,
-0x42,
-0xbe,
-0x44,
-0x0c,
-0x08,
-0x18,
-0x10,
-0x30,
-0x20,
-0x64,
-0x4a,
-0xc4,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x38,
-0x6c,
-0x6c,
-0x6c,
-0x38,
-0x37,
-0x72,
-0xdc,
-0xcc,
-0xcc,
-0xcc,
-0x77,
-0x00,
-0x00,
-0x00,
-
-0x10,
-0x38,
-0x18,
-0x08,
-0x10,
-0x20,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x04,
-0x08,
-0x10,
-0x10,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x10,
-0x10,
-0x08,
-0x04,
-0x00,
-0x00,
-
-0x00,
-0x20,
-0x10,
-0x08,
-0x08,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x08,
-0x08,
-0x10,
-0x20,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x44,
-0x28,
-0x38,
-0xfe,
-0x38,
-0x28,
-0x44,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x18,
-0x18,
-0x7e,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x18,
-0x08,
-0x10,
-0x20,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7e,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x06,
-0x06,
-0x0c,
-0x0c,
-0x18,
-0x18,
-0x30,
-0x30,
-0x60,
-0x60,
-0xc0,
-0xc0,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x3c,
-0x46,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc4,
-0x78,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x08,
-0x18,
-0x78,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x7e,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x7c,
-0x86,
-0x06,
-0x0c,
-0x18,
-0x20,
-0x40,
-0xc1,
-0xfe,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x3c,
-0x46,
-0x04,
-0x08,
-0x1c,
-0x06,
-0x06,
-0x06,
-0x06,
-0x0c,
-0x70,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x04,
-0x08,
-0x10,
-0x2c,
-0x4c,
-0x8c,
-0x8c,
-0xfe,
-0x0c,
-0x0c,
-0x0c,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x02,
-0x3c,
-0x20,
-0x20,
-0x70,
-0x0c,
-0x06,
-0x06,
-0x06,
-0x06,
-0x0c,
-0x70,
-0x00,
-
-0x00,
-0x00,
-0x18,
-0x20,
-0x40,
-0xc0,
-0xdc,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0x44,
-0x38,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x40,
-0x7e,
-0x82,
-0x06,
-0x04,
-0x0c,
-0x18,
-0x18,
-0x30,
-0x30,
-0x30,
-0x30,
-0x00,
-
-0x00,
-0x00,
-0x7c,
-0xc6,
-0xc6,
-0x64,
-0x38,
-0x4c,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0x7c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x38,
-0x44,
-0xc6,
-0xc6,
-0x76,
-0x06,
-0x06,
-0x06,
-0x04,
-0x08,
-0x30,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x18,
-0x08,
-0x10,
-0x20,
-
-0x00,
-0x06,
-0x0c,
-0x18,
-0x30,
-0x60,
-0xa0,
-0xa0,
-0x60,
-0x30,
-0x18,
-0x0c,
-0x06,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7e,
-0x00,
-0x00,
-0x7e,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x60,
-0x30,
-0x18,
-0x0c,
-0x06,
-0x05,
-0x05,
-0x06,
-0x0c,
-0x18,
-0x30,
-0x60,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x7c,
-0x86,
-0xc6,
-0x06,
-0x04,
-0x08,
-0x10,
-0x10,
-0x18,
-0x00,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x3c,
-0x46,
-0xc6,
-0xce,
-0xd6,
-0xd6,
-0xd6,
-0xdc,
-0xc0,
-0xc4,
-0x78,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x2c,
-0x2c,
-0x2c,
-0x7e,
-0x46,
-0x46,
-0x46,
-0xef,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xfc,
-0x66,
-0x66,
-0x66,
-0x66,
-0x7c,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xfc,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3a,
-0x66,
-0xc2,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xfc,
-0x66,
-0x63,
-0x63,
-0x63,
-0x63,
-0x63,
-0x63,
-0x63,
-0x63,
-0x66,
-0xfc,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xff,
-0x61,
-0x60,
-0x60,
-0x64,
-0x7c,
-0x64,
-0x60,
-0x60,
-0x60,
-0x61,
-0xfe,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xff,
-0x61,
-0x61,
-0x60,
-0x64,
-0x7c,
-0x64,
-0x60,
-0x60,
-0x60,
-0x60,
-0xf0,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3a,
-0x66,
-0xc2,
-0xc0,
-0xc0,
-0xc0,
-0xcf,
-0xc6,
-0xc6,
-0xc6,
-0x66,
-0x38,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xf7,
-0x62,
-0x62,
-0x62,
-0x62,
-0x7e,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0xf7,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3c,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x1e,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x08,
-0xf0,
-
-0x00,
-0xf7,
-0x64,
-0x6c,
-0x68,
-0x68,
-0x78,
-0x6c,
-0x6c,
-0x6c,
-0x66,
-0x66,
-0xf7,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xf8,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x61,
-0xfe,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xc3,
-0x66,
-0x76,
-0x7e,
-0x56,
-0x56,
-0x46,
-0x46,
-0x46,
-0x46,
-0x46,
-0xef,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xe7,
-0x62,
-0x62,
-0x72,
-0x52,
-0x5a,
-0x4a,
-0x4e,
-0x46,
-0x46,
-0x42,
-0xe2,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3c,
-0x66,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xfc,
-0x66,
-0x66,
-0x66,
-0x66,
-0x6c,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0xf0,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3c,
-0x66,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0x66,
-0x3c,
-0x10,
-0x39,
-0x0e,
-
-0x00,
-0xfc,
-0x66,
-0x66,
-0x66,
-0x66,
-0x7c,
-0x6c,
-0x66,
-0x66,
-0x66,
-0x66,
-0xf3,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x7a,
-0xc6,
-0xc2,
-0xc0,
-0x70,
-0x3c,
-0x0e,
-0x06,
-0x06,
-0x86,
-0xc6,
-0xbc,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xff,
-0x99,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xf7,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xf7,
-0x62,
-0x62,
-0x62,
-0x76,
-0x34,
-0x34,
-0x34,
-0x3c,
-0x18,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xf7,
-0x62,
-0x62,
-0x62,
-0x62,
-0x6a,
-0x6a,
-0x6a,
-0x6a,
-0x7e,
-0x7e,
-0x34,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xf7,
-0x62,
-0x62,
-0x34,
-0x34,
-0x18,
-0x18,
-0x2c,
-0x2c,
-0x46,
-0x46,
-0xef,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xf7,
-0x62,
-0x62,
-0x62,
-0x34,
-0x34,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x7f,
-0x46,
-0x86,
-0x0c,
-0x0c,
-0x18,
-0x18,
-0x30,
-0x30,
-0x61,
-0x62,
-0xfe,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3c,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xc0,
-0xc0,
-0x60,
-0x60,
-0x30,
-0x30,
-0x18,
-0x18,
-0x0c,
-0x0c,
-0x06,
-0x06,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x10,
-0x38,
-0x4c,
-0x86,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-
-0x00,
-0x18,
-0x20,
-0x30,
-0x38,
-0x10,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x78,
-0x8c,
-0x0c,
-0x3c,
-0xcc,
-0xcc,
-0xcd,
-0x76,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x20,
-0xe0,
-0x60,
-0x60,
-0x6c,
-0x76,
-0x66,
-0x66,
-0x66,
-0x66,
-0x76,
-0x6c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x3c,
-0x66,
-0x60,
-0x60,
-0x60,
-0x60,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x04,
-0x1c,
-0x0c,
-0x0c,
-0x6c,
-0xdc,
-0xcc,
-0xcc,
-0xcc,
-0xcc,
-0xdc,
-0x66,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x3c,
-0x66,
-0x7e,
-0x60,
-0x60,
-0x60,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x1e,
-0x31,
-0x33,
-0x30,
-0x30,
-0x78,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x78,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7b,
-0xce,
-0xcc,
-0xcc,
-0xcc,
-0x78,
-0x60,
-0x7c,
-0x86,
-0xc6,
-0x7c,
-
-0x00,
-0x20,
-0xe0,
-0x60,
-0x60,
-0x6c,
-0x76,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xf7,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x10,
-0x38,
-0x10,
-0x00,
-0x18,
-0x38,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x08,
-0x1c,
-0x08,
-0x00,
-0x0c,
-0x1c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x0c,
-0x6c,
-0x4c,
-0x38,
-0x00,
-
-0x00,
-0x20,
-0xe0,
-0x60,
-0x60,
-0x67,
-0x66,
-0x6c,
-0x78,
-0x6c,
-0x6c,
-0x66,
-0xe7,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x08,
-0x38,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x6a,
-0xfe,
-0x6a,
-0x6a,
-0x6a,
-0x62,
-0x62,
-0xf7,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x5c,
-0xf6,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xf7,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x3c,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x5c,
-0xe6,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x7c,
-0x60,
-0x60,
-0xf0,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x76,
-0xcc,
-0xcc,
-0xcc,
-0xcc,
-0xcc,
-0xcc,
-0x7c,
-0x0c,
-0x0c,
-0x1e,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x5e,
-0xf6,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0xf0,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7a,
-0xc6,
-0x72,
-0x1c,
-0x06,
-0x86,
-0xc6,
-0xbc,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x10,
-0x30,
-0x7c,
-0x30,
-0x30,
-0x30,
-0x30,
-0x30,
-0x34,
-0x18,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xee,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x67,
-0x3a,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xf7,
-0x62,
-0x76,
-0x34,
-0x34,
-0x3c,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xf7,
-0x62,
-0x6a,
-0x6a,
-0x6a,
-0x6a,
-0x7e,
-0x24,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xf7,
-0x62,
-0x34,
-0x18,
-0x2c,
-0x46,
-0x46,
-0xef,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xf7,
-0x62,
-0x62,
-0x34,
-0x34,
-0x18,
-0x18,
-0x18,
-0x10,
-0xb0,
-0xe0,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xfe,
-0x8c,
-0x18,
-0x30,
-0x30,
-0x60,
-0xc2,
-0xfe,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x0e,
-0x18,
-0x10,
-0x10,
-0x08,
-0x70,
-0x70,
-0x08,
-0x10,
-0x10,
-0x18,
-0x0e,
-0x00,
-0x00,
-0x00,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x00,
-0x00,
-
-0x00,
-0x70,
-0x18,
-0x08,
-0x08,
-0x10,
-0x0e,
-0x0e,
-0x10,
-0x08,
-0x08,
-0x18,
-0x70,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x76,
-0xdc,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x10,
-0x38,
-0x6c,
-0xc6,
-0xc6,
-0xc6,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x3a,
-0x66,
-0xc2,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0x62,
-0x3c,
-0x18,
-0x0c,
-0x24,
-0x18,
-
-0x00,
-0x00,
-0x66,
-0x00,
-0x00,
-0xee,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3b,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x0c,
-0x18,
-0x20,
-0x00,
-0x3c,
-0x66,
-0x7e,
-0x60,
-0x60,
-0x60,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x30,
-0x58,
-0x8c,
-0x00,
-0x78,
-0x8c,
-0x0c,
-0x3c,
-0xcc,
-0xcc,
-0xcd,
-0x76,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x66,
-0x00,
-0x00,
-0x78,
-0x8c,
-0x0c,
-0x3c,
-0xcc,
-0xcc,
-0xcd,
-0x76,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x30,
-0x18,
-0x04,
-0x00,
-0x78,
-0x8c,
-0x0c,
-0x3c,
-0xcc,
-0xcc,
-0xcd,
-0x76,
-0x00,
-0x00,
-0x00,
-
-0x38,
-0x44,
-0x44,
-0x38,
-0x00,
-0x78,
-0x8c,
-0x0c,
-0x3c,
-0xcc,
-0xcc,
-0xcd,
-0x76,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x3c,
-0x66,
-0x60,
-0x60,
-0x60,
-0x60,
-0x62,
-0x3c,
-0x08,
-0x24,
-0x18,
-
-0x00,
-0x18,
-0x2c,
-0x46,
-0x00,
-0x3c,
-0x66,
-0x7e,
-0x60,
-0x60,
-0x60,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x66,
-0x00,
-0x00,
-0x3c,
-0x66,
-0x7e,
-0x60,
-0x60,
-0x60,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x30,
-0x18,
-0x04,
-0x00,
-0x3c,
-0x66,
-0x7e,
-0x60,
-0x60,
-0x60,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x66,
-0x00,
-0x00,
-0x38,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x18,
-0x2c,
-0x46,
-0x00,
-0x38,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x60,
-0x30,
-0x08,
-0x00,
-0x38,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x66,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x2c,
-0x2c,
-0x2c,
-0x7e,
-0x46,
-0x46,
-0x46,
-0xef,
-0x00,
-0x00,
-0x00,
-
-0x18,
-0x24,
-0x18,
-0x18,
-0x3c,
-0x2c,
-0x2c,
-0x2c,
-0x7e,
-0x46,
-0x46,
-0x46,
-0xef,
-0x00,
-0x00,
-0x00,
-
-0x0c,
-0x18,
-0xff,
-0x61,
-0x60,
-0x60,
-0x64,
-0x7c,
-0x64,
-0x60,
-0x60,
-0x61,
-0xfe,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x76,
-0x9b,
-0x1b,
-0x3f,
-0xd8,
-0xd8,
-0xd9,
-0x6e,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x1f,
-0x1d,
-0x1d,
-0x3c,
-0x2c,
-0x2e,
-0x2c,
-0x7c,
-0x4c,
-0x4c,
-0x4d,
-0xef,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x18,
-0x2c,
-0x46,
-0x00,
-0x3c,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x66,
-0x00,
-0x00,
-0x3c,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x30,
-0x18,
-0x04,
-0x00,
-0x3c,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x18,
-0x2c,
-0x46,
-0x00,
-0xee,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x67,
-0x3a,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x30,
-0x18,
-0x04,
-0x00,
-0xee,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x67,
-0x3a,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x66,
-0x00,
-0x00,
-0xf7,
-0x62,
-0x62,
-0x34,
-0x34,
-0x18,
-0x18,
-0x18,
-0x10,
-0xb0,
-0xe0,
-
-0x66,
-0x00,
-0x3c,
-0x66,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x66,
-0x00,
-0xf7,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x62,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x10,
-0x10,
-0x10,
-0x7c,
-0xc6,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0xc2,
-0x7c,
-0x10,
-0x10,
-0x00,
-
-0x00,
-0x38,
-0x64,
-0x6c,
-0x60,
-0x60,
-0xf0,
-0x60,
-0x60,
-0x60,
-0x60,
-0x66,
-0xfc,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x81,
-0xc3,
-0x66,
-0x3c,
-0x18,
-0xff,
-0x18,
-0x18,
-0xff,
-0x18,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xfe,
-0x63,
-0x63,
-0x63,
-0x63,
-0x6e,
-0x60,
-0x64,
-0x6e,
-0x64,
-0x64,
-0xf5,
-0x06,
-0x00,
-0x00,
-
-0x00,
-0x0e,
-0x19,
-0x1b,
-0x18,
-0x18,
-0x3c,
-0x18,
-0x18,
-0x18,
-0x18,
-0xd8,
-0x98,
-0x70,
-0x00,
-0x00,
-
-0x00,
-0x0c,
-0x18,
-0x20,
-0x00,
-0x78,
-0x8c,
-0x0c,
-0x3c,
-0xcc,
-0xcc,
-0xcd,
-0x76,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x06,
-0x0c,
-0x10,
-0x00,
-0x38,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x0c,
-0x18,
-0x20,
-0x00,
-0x3c,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x0c,
-0x18,
-0x20,
-0x00,
-0xee,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x67,
-0x3a,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x32,
-0x4c,
-0x00,
-0x5c,
-0xf6,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xf7,
-0x00,
-0x00,
-0x00,
-
-0x32,
-0x4c,
-0x00,
-0xe7,
-0x72,
-0x52,
-0x5a,
-0x4a,
-0x4e,
-0x46,
-0x46,
-0x42,
-0xe2,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x78,
-0x8c,
-0x0c,
-0x3c,
-0xcc,
-0xcc,
-0xcd,
-0x76,
-0x00,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3c,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x00,
-0x7e,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x30,
-0x30,
-0x00,
-0x30,
-0x10,
-0x10,
-0x20,
-0x40,
-0xc0,
-0xc6,
-0xc2,
-0x7c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xfe,
-0xc0,
-0xc0,
-0xc0,
-0xc0,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xfe,
-0x06,
-0x06,
-0x06,
-0x06,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x20,
-0xe0,
-0x63,
-0x66,
-0xfc,
-0x18,
-0x30,
-0x60,
-0xce,
-0x93,
-0x06,
-0x0c,
-0x1f,
-0x00,
-0x00,
-
-0x00,
-0x20,
-0xe0,
-0x63,
-0x66,
-0xfc,
-0x18,
-0x30,
-0x64,
-0xc8,
-0x96,
-0x3f,
-0x06,
-0x06,
-0x00,
-0x00,
-
-0x00,
-0x18,
-0x18,
-0x00,
-0x08,
-0x18,
-0x18,
-0x18,
-0x3c,
-0x3c,
-0x3c,
-0x3c,
-0x18,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x36,
-0x6c,
-0xd8,
-0xd8,
-0x6c,
-0x36,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xd8,
-0x6c,
-0x36,
-0x36,
-0x6c,
-0xd8,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x82,
-0x10,
-0x82,
-0x10,
-0x82,
-0x10,
-0x82,
-0x10,
-0x82,
-0x10,
-0x82,
-0x10,
-0x82,
-0x10,
-0x82,
-0x10,
-
-0x00,
-0x95,
-0x00,
-0xa9,
-0x00,
-0x95,
-0x00,
-0xa9,
-0x00,
-0x95,
-0x00,
-0xa9,
-0x00,
-0x95,
-0x00,
-0xa9,
-
-0x92,
-0x49,
-0x92,
-0x49,
-0x92,
-0x49,
-0x92,
-0x49,
-0x92,
-0x49,
-0x92,
-0x49,
-0x92,
-0x49,
-0x92,
-0x49,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xf8,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xf8,
-0x18,
-0x18,
-0xf8,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xe6,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xfe,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xf8,
-0x18,
-0x18,
-0xf8,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xe6,
-0x06,
-0x06,
-0xe6,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xfe,
-0x06,
-0x06,
-0xe6,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xe6,
-0x06,
-0x06,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xf8,
-0x18,
-0x18,
-0xf8,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xf8,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x1f,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xff,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x1f,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xff,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x1f,
-0x18,
-0x18,
-0x1f,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x67,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x67,
-0x60,
-0x60,
-0x7f,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7f,
-0x60,
-0x60,
-0x67,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xe7,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-0xe7,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x67,
-0x60,
-0x60,
-0x67,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xe7,
-0x00,
-0x00,
-0xe7,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xff,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xff,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0x00,
-0x00,
-0xff,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x7f,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x1f,
-0x18,
-0x18,
-0x1f,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x1f,
-0x18,
-0x18,
-0x1f,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7f,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0xff,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xff,
-0x00,
-0x00,
-0xff,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xf8,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x1f,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-0xf0,
-
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-0x0f,
-
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x77,
-0xcc,
-0xcc,
-0xcc,
-0xcc,
-0xde,
-0x73,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x7c,
-0xc6,
-0xc6,
-0xc6,
-0xc4,
-0xc8,
-0xc4,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xdc,
-0xc0,
-0xc0,
-0x00,
-
-0x00,
-0xff,
-0x61,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0x60,
-0xf0,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x01,
-0x7e,
-0xa4,
-0x24,
-0x2c,
-0x6c,
-0x6c,
-0x6c,
-0x48,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xff,
-0xc1,
-0x60,
-0x30,
-0x18,
-0x0c,
-0x18,
-0x30,
-0x60,
-0xc0,
-0xc1,
-0xfe,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7f,
-0xc8,
-0xc8,
-0xc8,
-0xc8,
-0xc8,
-0xc8,
-0x70,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x22,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x7c,
-0x60,
-0x60,
-0x60,
-0xc0,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x76,
-0xdc,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x10,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x38,
-0x10,
-0x7c,
-0xd6,
-0xd6,
-0xd6,
-0xd6,
-0xd6,
-0xd6,
-0x7c,
-0x10,
-0x38,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x38,
-0x6c,
-0xc6,
-0xc6,
-0xc6,
-0xfe,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0x6c,
-0x38,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x3c,
-0x66,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0xc3,
-0x66,
-0x24,
-0x24,
-0xa5,
-0xe7,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x1e,
-0x31,
-0x30,
-0x18,
-0x0c,
-0x3e,
-0x66,
-0x66,
-0x66,
-0x66,
-0x66,
-0x3c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x6e,
-0xff,
-0x99,
-0x99,
-0x99,
-0x99,
-0xff,
-0x76,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x02,
-0x04,
-0x7c,
-0xca,
-0x92,
-0xa6,
-0x7c,
-0x40,
-0x80,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x1c,
-0x30,
-0x60,
-0x60,
-0x60,
-0x7c,
-0x60,
-0x60,
-0x60,
-0x60,
-0x30,
-0x1c,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x7c,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0xc6,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x7c,
-0x00,
-0x00,
-0x00,
-0xfe,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x18,
-0x18,
-0x7e,
-0x18,
-0x18,
-0x00,
-0x00,
-0x7e,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x30,
-0x18,
-0x0c,
-0x06,
-0x0c,
-0x18,
-0x30,
-0x00,
-0x7e,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x0c,
-0x18,
-0x30,
-0x60,
-0x30,
-0x18,
-0x0c,
-0x00,
-0x7e,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x0e,
-0x19,
-0x1b,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0x18,
-0xd8,
-0x98,
-0x70,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x18,
-0x18,
-0x00,
-0x7e,
-0x00,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x76,
-0xdc,
-0x00,
-0x00,
-0x76,
-0xdc,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x38,
-0x44,
-0x44,
-0x44,
-0x38,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x18,
-0x18,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x18,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x07,
-0x06,
-0x06,
-0x0c,
-0x0c,
-0x08,
-0x98,
-0xd0,
-0xf0,
-0x60,
-0x20,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0xcc,
-0x76,
-0x66,
-0x66,
-0x66,
-0x66,
-0xf7,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x70,
-0x98,
-0x18,
-0x30,
-0x60,
-0x88,
-0xf8,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x7c,
-0x64,
-0x64,
-0x64,
-0x64,
-0x64,
-0x7c,
-0x00,
-0x00,
-0x00,
-0x00,
-
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-
-};
-
-
-const struct font_desc font_rl = {
-	RL_IDX,
-	"RomanLarge",
-	8,
-	16,
-	patterns,
-	-1
-};
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
index 9be83be..4fd07d9 100644
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -64,10 +64,6 @@ static const struct font_desc *fonts[] =
 #undef NO_FONTS
     &font_mini_4x6,
 #endif
-#ifdef CONFIG_FONT_RL
-#undef NO_FONTS
-    &font_rl,
-#endif
 };
 
 #define num_fonts (sizeof(fonts)/sizeof(*fonts))
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 04417dc..2584dae 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -57,6 +57,9 @@ static struct fb_ops ffb_ops = {
 	.fb_sync		= ffb_sync,
 	.fb_mmap		= ffb_mmap,
 	.fb_ioctl		= ffb_ioctl,
+#ifdef CONFIG_COMPAT
+	.fb_compat_ioctl	= sbusfb_compat_ioctl,
+#endif
 };
 
 /* Register layout and definitions */
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index 84a7fe4..376d4a1 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -51,6 +51,9 @@ static struct fb_ops leo_ops = {
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= leo_mmap,
 	.fb_ioctl		= leo_ioctl,
+#ifdef CONFIG_COMPAT
+	.fb_compat_ioctl	= sbusfb_compat_ioctl,
+#endif
 };
 
 #define LEO_OFF_LC_SS0_KRN	0x00200000UL
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index f60b1f4..3353103 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/nvidia/nv_proto.h
@@ -42,7 +42,7 @@ int nvidia_probe_i2c_connector(struct fb
 #define nvidia_probe_i2c_connector(p, c, edid) (-1)
 #endif
 
-#ifdef CONFIG_FB_OF
+#ifdef CONFIG_PPC_OF
 int nvidia_probe_of_connector(struct fb_info *info, int conn,
 			      u8 ** out_edid);
 #else
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 0b40a2a..bee09c6 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -1301,7 +1301,7 @@ static int nvidiafb_pan_display(struct f
 	struct nvidia_par *par = info->par;
 	u32 total;
 
-	total = info->var.yoffset * info->fix.line_length + info->var.xoffset;
+	total = var->yoffset * info->fix.line_length + var->xoffset;
 
 	NVSetStartAddress(par, total);
 
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index 9aaf65f..18bcda2 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -48,6 +48,9 @@ static struct fb_ops p9100_ops = {
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= p9100_mmap,
 	.fb_ioctl		= p9100_ioctl,
+#ifdef CONFIG_COMPAT
+	.fb_compat_ioctl	= sbusfb_compat_ioctl,
+#endif
 };
 
 /* P9100 control registers */
diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
index 34f72ed..646c43f 100644
--- a/drivers/video/sbuslib.c
+++ b/drivers/video/sbuslib.c
@@ -3,6 +3,7 @@
  * Copyright (C) 2003 David S. Miller (davem@redhat.com)
  */
 
+#include <linux/compat.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/string.h>
@@ -182,3 +183,109 @@ int sbusfb_ioctl_helper(unsigned long cm
 	};
 }
 EXPORT_SYMBOL(sbusfb_ioctl_helper);
+
+#ifdef CONFIG_COMPAT
+struct  fbcmap32 {
+	int             index;          /* first element (0 origin) */
+	int             count;
+	u32		red;
+	u32		green;
+	u32		blue;
+};
+
+#define FBIOPUTCMAP32	_IOW('F', 3, struct fbcmap32)
+#define FBIOGETCMAP32	_IOW('F', 4, struct fbcmap32)
+
+static int fbiogetputcmap(struct file *file, struct fb_info *info,
+		unsigned int cmd, unsigned long arg)
+{
+	struct fbcmap32 __user *argp = (void __user *)arg;
+	struct fbcmap __user *p = compat_alloc_user_space(sizeof(*p));
+	u32 addr;
+	int ret;
+
+	ret = copy_in_user(p, argp, 2 * sizeof(int));
+	ret |= get_user(addr, &argp->red);
+	ret |= put_user(compat_ptr(addr), &p->red);
+	ret |= get_user(addr, &argp->green);
+	ret |= put_user(compat_ptr(addr), &p->green);
+	ret |= get_user(addr, &argp->blue);
+	ret |= put_user(compat_ptr(addr), &p->blue);
+	if (ret)
+		return -EFAULT;
+	return info->fbops->fb_ioctl(file->f_dentry->d_inode, file,
+			(cmd == FBIOPUTCMAP32) ?
+			FBIOPUTCMAP_SPARC : FBIOGETCMAP_SPARC,
+			(unsigned long)p, info);
+}
+
+struct fbcursor32 {
+	short set;		/* what to set, choose from the list above */
+	short enable;		/* cursor on/off */
+	struct fbcurpos pos;	/* cursor position */
+	struct fbcurpos hot;	/* cursor hot spot */
+	struct fbcmap32 cmap;	/* color map info */
+	struct fbcurpos size;	/* cursor bit map size */
+	u32	image;		/* cursor image bits */
+	u32	mask;		/* cursor mask bits */
+};
+
+#define FBIOSCURSOR32	_IOW('F', 24, struct fbcursor32)
+#define FBIOGCURSOR32	_IOW('F', 25, struct fbcursor32)
+
+static int fbiogscursor(struct file *file, struct fb_info *info,
+		unsigned long arg)
+{
+	struct fbcursor __user *p = compat_alloc_user_space(sizeof(*p));
+	struct fbcursor32 __user *argp =  (void __user *)arg;
+	compat_uptr_t addr;
+	int ret;
+
+	ret = copy_in_user(p, argp,
+			      2 * sizeof (short) + 2 * sizeof(struct fbcurpos));
+	ret |= copy_in_user(&p->size, &argp->size, sizeof(struct fbcurpos));
+	ret |= copy_in_user(&p->cmap, &argp->cmap, 2 * sizeof(int));
+	ret |= get_user(addr, &argp->cmap.red);
+	ret |= put_user(compat_ptr(addr), &p->cmap.red);
+	ret |= get_user(addr, &argp->cmap.green);
+	ret |= put_user(compat_ptr(addr), &p->cmap.green);
+	ret |= get_user(addr, &argp->cmap.blue);
+	ret |= put_user(compat_ptr(addr), &p->cmap.blue);
+	ret |= get_user(addr, &argp->mask);
+	ret |= put_user(compat_ptr(addr), &p->mask);
+	ret |= get_user(addr, &argp->image);
+	ret |= put_user(compat_ptr(addr), &p->image);
+	if (ret)
+		return -EFAULT;
+	return info->fbops->fb_ioctl(file->f_dentry->d_inode, file,
+			FBIOSCURSOR, (unsigned long)p, info);
+}
+
+long sbusfb_compat_ioctl(struct file *file, unsigned int cmd,
+		unsigned long arg, struct fb_info *info)
+{
+	switch (cmd) {
+	case FBIOGTYPE:
+	case FBIOSATTR:
+	case FBIOGATTR:
+	case FBIOSVIDEO:
+	case FBIOGVIDEO:
+	case FBIOGCURSOR32:	/* This is not implemented yet.
+				   Later it should be converted... */
+	case FBIOSCURPOS:
+	case FBIOGCURPOS:
+	case FBIOGCURMAX:
+		return info->fbops->fb_ioctl(file->f_dentry->d_inode,
+				file, cmd, arg, info);
+	case FBIOPUTCMAP32:
+		return fbiogetputcmap(file, info, cmd, arg);
+	case FBIOGETCMAP32:
+		return fbiogetputcmap(file, info, cmd, arg);
+	case FBIOSCURSOR32:
+		return fbiogscursor(file, info, arg);
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+EXPORT_SYMBOL(sbusfb_compat_ioctl);
+#endif
diff --git a/drivers/video/sbuslib.h b/drivers/video/sbuslib.h
index a6aa33b..b470e52 100644
--- a/drivers/video/sbuslib.h
+++ b/drivers/video/sbuslib.h
@@ -20,5 +20,7 @@ extern int sbusfb_mmap_helper(struct sbu
 int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,
 			struct fb_info *info,
 			int type, int fb_depth, unsigned long fb_size);
+long sbusfb_compat_ioctl(struct file *file, unsigned int cmd,
+		unsigned long arg, struct fb_info *info);
 
 #endif /* _SBUSLIB_H */
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 59fff29..fe4f63f 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -52,6 +52,9 @@ static struct fb_ops tcx_ops = {
 	.fb_imageblit		= cfb_imageblit,
 	.fb_mmap		= tcx_mmap,
 	.fb_ioctl		= tcx_ioctl,
+#ifdef CONFIG_COMPAT
+	.fb_compat_ioctl	= sbusfb_compat_ioctl,
+#endif
 };
 
 /* THC definitions */
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 2c3aa2f..3e58ddc 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -413,6 +413,7 @@ static int __init vesafb_probe(struct pl
 	 * region already (FIXME) */
 	request_region(0x3c0, 32, "vesafb");
 
+#ifdef CONFIG_MTRR
 	if (mtrr) {
 		unsigned int temp_size = size_total;
 		unsigned int type = 0;
@@ -450,6 +451,7 @@ static int __init vesafb_probe(struct pl
 			} while (temp_size >= PAGE_SIZE && rc == -EINVAL);
 		}
 	}
+#endif
 	
 	info->fbops = &vesafb_ops;
 	info->var = vesafb_defined;
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index daa4605..f6e24ee 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -514,7 +514,7 @@ int __init w100fb_probe(struct platform_
 	if (remapped_fbuf == NULL)
 		goto out;
 
-	info=framebuffer_alloc(sizeof(struct w100fb_par), dev);
+	info=framebuffer_alloc(sizeof(struct w100fb_par), &pdev->dev);
 	if (!info) {
 		err = -ENOMEM;
 		goto out;
diff --git a/fs/aio.c b/fs/aio.c
index 20bb919..5a28b69 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -457,6 +457,8 @@ static inline struct kiocb *aio_get_req(
 
 static inline void really_put_req(struct kioctx *ctx, struct kiocb *req)
 {
+	assert_spin_locked(&ctx->ctx_lock);
+
 	if (req->ki_dtor)
 		req->ki_dtor(req);
 	kmem_cache_free(kiocb_cachep, req);
@@ -498,6 +500,8 @@ static int __aio_put_req(struct kioctx *
 	dprintk(KERN_DEBUG "aio_put(%p): f_count=%d\n",
 		req, atomic_read(&req->ki_filp->f_count));
 
+	assert_spin_locked(&ctx->ctx_lock);
+
 	req->ki_users --;
 	if (unlikely(req->ki_users < 0))
 		BUG();
@@ -619,14 +623,13 @@ static void unuse_mm(struct mm_struct *m
  * the kiocb (to tell the caller to activate the work
  * queue to process it), or 0, if it found that it was
  * already queued.
- *
- * Should be called with the spin lock iocb->ki_ctx->ctx_lock
- * held
  */
 static inline int __queue_kicked_iocb(struct kiocb *iocb)
 {
 	struct kioctx *ctx = iocb->ki_ctx;
 
+	assert_spin_locked(&ctx->ctx_lock);
+
 	if (list_empty(&iocb->ki_run_list)) {
 		list_add_tail(&iocb->ki_run_list,
 			&ctx->run_list);
@@ -771,13 +774,15 @@ out:
  * 	Process all pending retries queued on the ioctx
  * 	run list.
  * Assumes it is operating within the aio issuer's mm
- * context. Expects to be called with ctx->ctx_lock held
+ * context.
  */
 static int __aio_run_iocbs(struct kioctx *ctx)
 {
 	struct kiocb *iocb;
 	LIST_HEAD(run_list);
 
+	assert_spin_locked(&ctx->ctx_lock);
+
 	list_splice_init(&ctx->run_list, &run_list);
 	while (!list_empty(&run_list)) {
 		iocb = list_entry(run_list.next, struct kiocb,
@@ -937,28 +942,19 @@ int fastcall aio_complete(struct kiocb *
 	unsigned long	tail;
 	int		ret;
 
-	/* Special case handling for sync iocbs: events go directly
-	 * into the iocb for fast handling.  Note that this will not 
-	 * work if we allow sync kiocbs to be cancelled. in which
-	 * case the usage count checks will have to move under ctx_lock
-	 * for all cases.
+	/*
+	 * Special case handling for sync iocbs:
+	 *  - events go directly into the iocb for fast handling
+	 *  - the sync task with the iocb in its stack holds the single iocb
+	 *    ref, no other paths have a way to get another ref
+	 *  - the sync task helpfully left a reference to itself in the iocb
 	 */
 	if (is_sync_kiocb(iocb)) {
-		int ret;
-
+		BUG_ON(iocb->ki_users != 1);
 		iocb->ki_user_data = res;
-		if (iocb->ki_users == 1) {
-			iocb->ki_users = 0;
-			ret = 1;
-		} else {
-			spin_lock_irq(&ctx->ctx_lock);
-			iocb->ki_users--;
-			ret = (0 == iocb->ki_users);
-			spin_unlock_irq(&ctx->ctx_lock);
-		}
-		/* sync iocbs put the task here for us */
+		iocb->ki_users = 0;
 		wake_up_process(iocb->ki_obj.tsk);
-		return ret;
+		return 1;
 	}
 
 	info = &ctx->ring_info;
@@ -1613,12 +1609,14 @@ asmlinkage long sys_io_submit(aio_contex
 
 /* lookup_kiocb
  *	Finds a given iocb for cancellation.
- *	MUST be called with ctx->ctx_lock held.
  */
 static struct kiocb *lookup_kiocb(struct kioctx *ctx, struct iocb __user *iocb,
 				  u32 key)
 {
 	struct list_head *pos;
+
+	assert_spin_locked(&ctx->ctx_lock);
+
 	/* TODO: use a hash or array, this sucks. */
 	list_for_each(pos, &ctx->active_reqs) {
 		struct kiocb *kiocb = list_kiocb(pos);
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index e4ed4b3..522fa70 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -881,7 +881,7 @@ static int ext2_fill_super(struct super_
 	}
 	if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL))
 		ext2_warning(sb, __FUNCTION__,
-			"mounting ext3 filesystem as ext2\n");
+			"mounting ext3 filesystem as ext2");
 	ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY);
 	percpu_counter_mod(&sbi->s_freeblocks_counter,
 				ext2_count_free_blocks(sb));
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 5d9b00e..8824e84 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1384,8 +1384,10 @@ static int ext3_journalled_writepage(str
 		ClearPageChecked(page);
 		ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE,
 					ext3_get_block);
-		if (ret != 0)
+		if (ret != 0) {
+			ext3_journal_stop(handle);
 			goto out_unlock;
+		}
 		ret = walk_page_buffers(handle, page_buffers(page), 0,
 			PAGE_CACHE_SIZE, NULL, do_journal_get_write_access);
 
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 0e7456e..3e51dd1 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -284,9 +284,6 @@ int jffs2_fill_scan_buf (struct jffs2_sb
 		D1(printk(KERN_WARNING "Read at 0x%x gave only 0x%zx bytes\n", ofs, retlen));
 		return -EIO;
 	}
-	D2(printk(KERN_DEBUG "Read 0x%x bytes from 0x%08x into buf\n", len, ofs));
-	D2(printk(KERN_DEBUG "000: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
-		  buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]));
 	return 0;
 }
 
diff --git a/fs/locks.c b/fs/locks.c
index a1e8b22..250ef53 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1105,7 +1105,6 @@ static void time_out_leases(struct inode
 			before = &fl->fl_next;
 			continue;
 		}
-		printk(KERN_INFO "lease broken - owner pid = %d\n", fl->fl_pid);
 		lease_modify(before, fl->fl_type & ~F_INPROGRESS);
 		if (fl == *before)	/* lease_modify may have freed fl */
 			before = &fl->fl_next;
@@ -1430,7 +1429,7 @@ int fcntl_setlease(unsigned int fd, stru
 	lock_kernel();
 
 	error = __setlease(filp, arg, &flp);
-	if (error)
+	if (error || arg == F_UNLCK)
 		goto out_unlock;
 
 	error = fasync_helper(fd, filp, 1, &flp->fl_fasync);
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index d2fa420..9ab97ce 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -195,7 +195,7 @@ static int show_map_internal(struct seq_
 
 static int show_map(struct seq_file *m, void *v)
 {
-	return show_map_internal(m, v, 0);
+	return show_map_internal(m, v, NULL);
 }
 
 static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h
index 20ac3d9..36505bb 100644
--- a/include/asm-alpha/atomic.h
+++ b/include/asm-alpha/atomic.h
@@ -177,6 +177,18 @@ static __inline__ long atomic64_sub_retu
 	return result;
 }
 
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
+#define atomic_add_unless(v, a, u)				\
+({								\
+	int c, old;						\
+	c = atomic_read(v);					\
+	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+		c = old;					\
+	c != (u);						\
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 #define atomic_dec_return(v) atomic_sub_return(1,(v))
 #define atomic64_dec_return(v) atomic64_sub_return(1,(v))
 
diff --git a/include/asm-arm/arch-pxa/akita.h b/include/asm-arm/arch-pxa/akita.h
index 4a1fbcf..5d8cc1d 100644
--- a/include/asm-arm/arch-pxa/akita.h
+++ b/include/asm-arm/arch-pxa/akita.h
@@ -25,6 +25,8 @@
 /* Default Values */
 #define AKITA_IOEXP_IO_OUT	(AKITA_IOEXP_IR_ON | AKITA_IOEXP_AKIN_PULLUP)
 
+extern struct platform_device akitaioexp_device;
+
 void akita_set_ioexp(struct device *dev, unsigned char bitmask);
 void akita_reset_ioexp(struct device *dev, unsigned char bitmask);
 
diff --git a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h
index 2885972..75b8027 100644
--- a/include/asm-arm/atomic.h
+++ b/include/asm-arm/atomic.h
@@ -80,6 +80,23 @@ static inline int atomic_sub_return(int 
 	return result;
 }
 
+static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
+{
+	u32 oldval, res;
+
+	do {
+		__asm__ __volatile__("@ atomic_cmpxchg\n"
+		"ldrex	%1, [%2]\n"
+		"teq	%1, %3\n"
+		"strexeq %0, %4, [%2]\n"
+		    : "=&r" (res), "=&r" (oldval)
+		    : "r" (&ptr->counter), "Ir" (old), "r" (new)
+		    : "cc");
+	} while (res);
+
+	return oldval;
+}
+
 static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
 {
 	unsigned long tmp, tmp2;
@@ -131,6 +148,20 @@ static inline int atomic_sub_return(int 
 	return val;
 }
 
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+	int ret;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ret = v->counter;
+	if (likely(ret == old))
+		v->counter = new;
+	local_irq_restore(flags);
+
+	return ret;
+}
+
 static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
 {
 	unsigned long flags;
@@ -142,6 +173,17 @@ static inline void atomic_clear_mask(uns
 
 #endif /* __LINUX_ARM_ARCH__ */
 
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int c, old;
+
+	c = atomic_read(v);
+	while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
+		c = old;
+	return c != u;
+}
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 #define atomic_add(i, v)	(void) atomic_add_return(i, v)
 #define atomic_inc(v)		(void) atomic_add_return(1, v)
 #define atomic_sub(i, v)	(void) atomic_sub_return(i, v)
diff --git a/include/asm-arm26/atomic.h b/include/asm-arm26/atomic.h
index 4a88235..a47cadc 100644
--- a/include/asm-arm26/atomic.h
+++ b/include/asm-arm26/atomic.h
@@ -62,6 +62,35 @@ static inline int atomic_sub_return(int 
         return val;
 }
 
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+	int ret;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ret = v->counter;
+	if (likely(ret == old))
+		v->counter = new;
+	local_irq_restore(flags);
+
+	return ret;
+}
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int ret;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ret = v->counter;
+	if (ret != u)
+		v->counter += a;
+	local_irq_restore(flags);
+
+	return ret != u;
+}
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
 {
         unsigned long flags;
diff --git a/include/asm-cris/atomic.h b/include/asm-cris/atomic.h
index 8c2e783..683b05a 100644
--- a/include/asm-cris/atomic.h
+++ b/include/asm-cris/atomic.h
@@ -123,6 +123,33 @@ static inline int atomic_inc_and_test(vo
 	return retval;
 }
 
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+	int ret;
+	unsigned long flags;
+
+	cris_atomic_save(v, flags);
+	ret = v->counter;
+	if (likely(ret == old))
+		v->counter = new;
+	cris_atomic_restore(v, flags);
+	return ret;
+}
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int ret;
+	unsigned long flags;
+
+	cris_atomic_save(v, flags);
+	ret = v->counter;
+	if (ret != u)
+		v->counter += a;
+	cris_atomic_restore(v, flags);
+	return ret != u;
+}
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 /* Atomic operations are already serializing */
 #define smp_mb__before_atomic_dec()    barrier()
 #define smp_mb__after_atomic_dec()     barrier()
diff --git a/include/asm-frv/atomic.h b/include/asm-frv/atomic.h
index e759684..f6539ff 100644
--- a/include/asm-frv/atomic.h
+++ b/include/asm-frv/atomic.h
@@ -414,4 +414,16 @@ extern uint32_t __cmpxchg_32(uint32_t *v
 
 #endif
 
+#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+
+#define atomic_add_unless(v, a, u)				\
+({								\
+	int c, old;						\
+	c = atomic_read(v);					\
+	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+		c = old;					\
+	c != (u);						\
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 #endif /* _ASM_ATOMIC_H */
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index 886dbd1..0b49f9e 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -13,5 +13,6 @@ extern char _eextratext[] __attribute__(
 extern char _end[];
 extern char __per_cpu_start[], __per_cpu_end[];
 extern char __kprobes_text_start[], __kprobes_text_end[];
+extern char __initdata_begin[], __initdata_end[];
 
 #endif /* _ASM_GENERIC_SECTIONS_H_ */
diff --git a/include/asm-h8300/atomic.h b/include/asm-h8300/atomic.h
index 7230f65..f23d868 100644
--- a/include/asm-h8300/atomic.h
+++ b/include/asm-h8300/atomic.h
@@ -82,6 +82,33 @@ static __inline__ int atomic_dec_and_tes
 	return ret == 0;
 }
 
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+	int ret;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ret = v->counter;
+	if (likely(ret == old))
+		v->counter = new;
+	local_irq_restore(flags);
+	return ret;
+}
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int ret;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ret = v->counter;
+	if (ret != u)
+		v->counter += a;
+	local_irq_restore(flags);
+	return ret != u;
+}
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 static __inline__ void atomic_clear_mask(unsigned long mask, unsigned long *v)
 {
 	__asm__ __volatile__("stc ccr,r1l\n\t"
diff --git a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h
index 509720b..c68557a 100644
--- a/include/asm-i386/atomic.h
+++ b/include/asm-i386/atomic.h
@@ -215,6 +215,27 @@ static __inline__ int atomic_sub_return(
 	return atomic_add_return(-i,v);
 }
 
+#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+
+/**
+ * atomic_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+#define atomic_add_unless(v, a, u)				\
+({								\
+	int c, old;						\
+	c = atomic_read(v);					\
+	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+		c = old;					\
+	c != (u);						\
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 #define atomic_inc_return(v)  (atomic_add_return(1,v))
 #define atomic_dec_return(v)  (atomic_sub_return(1,v))
 
diff --git a/include/asm-i386/mach-default/mach_reboot.h b/include/asm-i386/mach-default/mach_reboot.h
index 06ae4d8..a955e57 100644
--- a/include/asm-i386/mach-default/mach_reboot.h
+++ b/include/asm-i386/mach-default/mach_reboot.h
@@ -19,7 +19,7 @@ static inline void kb_wait(void)
 static inline void mach_reboot(void)
 {
 	int i;
-	for (i = 0; i < 100; i++) {
+	for (i = 0; i < 10; i++) {
 		kb_wait();
 		udelay(50);
 		outb(0x60, 0x64);	/* write Controller Command Byte */
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 8c02b03..5c96cf6 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -65,7 +65,9 @@ struct cpuinfo_x86 {
 	int	f00f_bug;
 	int	coma_bug;
 	unsigned long loops_per_jiffy;
-	unsigned char x86_num_cores;
+	unsigned char x86_max_cores;	/* cpuid returned max cores value */
+	unsigned char booted_cores;	/* number of cores as seen by OS */
+	unsigned char apicid;
 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
 
 #define X86_VENDOR_INTEL 0
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
index 97d52ac..772f85d 100644
--- a/include/asm-i386/system.h
+++ b/include/asm-i386/system.h
@@ -263,6 +263,10 @@ static inline unsigned long __xchg(unsig
 
 #ifdef CONFIG_X86_CMPXCHG
 #define __HAVE_ARCH_CMPXCHG 1
+#define cmpxchg(ptr,o,n)\
+	((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
+					(unsigned long)(n),sizeof(*(ptr))))
+#endif
 
 static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
 				      unsigned long new, int size)
@@ -291,10 +295,42 @@ static inline unsigned long __cmpxchg(vo
 	return old;
 }
 
-#define cmpxchg(ptr,o,n)\
-	((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
-					(unsigned long)(n),sizeof(*(ptr))))
+#ifndef CONFIG_X86_CMPXCHG
+/*
+ * Building a kernel capable running on 80386. It may be necessary to
+ * simulate the cmpxchg on the 80386 CPU. For that purpose we define
+ * a function for each of the sizes we support.
+ */
 
+extern unsigned long cmpxchg_386_u8(volatile void *, u8, u8);
+extern unsigned long cmpxchg_386_u16(volatile void *, u16, u16);
+extern unsigned long cmpxchg_386_u32(volatile void *, u32, u32);
+
+static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
+				      unsigned long new, int size)
+{
+	switch (size) {
+	case 1:
+		return cmpxchg_386_u8(ptr, old, new);
+	case 2:
+		return cmpxchg_386_u16(ptr, old, new);
+	case 4:
+		return cmpxchg_386_u32(ptr, old, new);
+	}
+	return old;
+}
+
+#define cmpxchg(ptr,o,n)						\
+({									\
+	__typeof__(*(ptr)) __ret;					\
+	if (likely(boot_cpu_data.x86 > 3))				\
+		__ret = __cmpxchg((ptr), (unsigned long)(o),		\
+					(unsigned long)(n), sizeof(*(ptr))); \
+	else								\
+		__ret = cmpxchg_386((ptr), (unsigned long)(o),		\
+					(unsigned long)(n), sizeof(*(ptr))); \
+	__ret;								\
+})
 #endif
 
 #ifdef CONFIG_X86_CMPXCHG64
diff --git a/include/asm-ia64/atomic.h b/include/asm-ia64/atomic.h
index 874a6f8..2fbebf8 100644
--- a/include/asm-ia64/atomic.h
+++ b/include/asm-ia64/atomic.h
@@ -88,6 +88,18 @@ ia64_atomic64_sub (__s64 i, atomic64_t *
 	return new;
 }
 
+#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+
+#define atomic_add_unless(v, a, u)				\
+({								\
+	int c, old;						\
+	c = atomic_read(v);					\
+	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+		c = old;					\
+	c != (u);						\
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 #define atomic_add_return(i,v)						\
 ({									\
 	int __ia64_aar_i = (i);						\
diff --git a/include/asm-m68k/atomic.h b/include/asm-m68k/atomic.h
index 38f3043..e3c962e 100644
--- a/include/asm-m68k/atomic.h
+++ b/include/asm-m68k/atomic.h
@@ -139,6 +139,18 @@ static inline void atomic_set_mask(unsig
 	__asm__ __volatile__("orl %1,%0" : "+m" (*v) : "id" (mask));
 }
 
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
+#define atomic_add_unless(v, a, u)				\
+({								\
+	int c, old;						\
+	c = atomic_read(v);					\
+	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+		c = old;					\
+	c != (u);						\
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 /* Atomic operations are already serializing */
 #define smp_mb__before_atomic_dec()	barrier()
 #define smp_mb__after_atomic_dec()	barrier()
diff --git a/include/asm-m68k/processor.h b/include/asm-m68k/processor.h
index df1575d..7982285 100644
--- a/include/asm-m68k/processor.h
+++ b/include/asm-m68k/processor.h
@@ -14,6 +14,7 @@
 #define current_text_addr() ({ __label__ _l; _l: &&_l;})
 
 #include <linux/config.h>
+#include <linux/thread_info.h>
 #include <asm/segment.h>
 #include <asm/fpu.h>
 #include <asm/ptrace.h>
@@ -55,17 +56,6 @@ static inline void wrusp(unsigned long u
 #endif
 #define TASK_UNMAPPED_ALIGN(addr, off)	PAGE_ALIGN(addr)
 
-struct task_work {
-	unsigned char sigpending;
-	unsigned char notify_resume;	/* request for notification on
-					   userspace execution resumption */
-	char          need_resched;
-	unsigned char delayed_trace;	/* single step a syscall */
-	unsigned char syscall_trace;	/* count of syscall interceptors */
-	unsigned char memdie;		/* task was selected to be killed */
-	unsigned char pad[2];
-};
-
 struct thread_struct {
 	unsigned long  ksp;		/* kernel stack pointer */
 	unsigned long  usp;		/* user stack pointer */
@@ -78,7 +68,7 @@ struct thread_struct {
 	unsigned long  fp[8*3];
 	unsigned long  fpcntl[3];	/* fp control regs */
 	unsigned char  fpstate[FPSTATESIZE];  /* floating point state */
-	struct task_work work;
+	struct thread_info info;
 };
 
 #define INIT_THREAD  {							\
diff --git a/include/asm-m68k/thread_info.h b/include/asm-m68k/thread_info.h
index 2aed24f..9532ca3 100644
--- a/include/asm-m68k/thread_info.h
+++ b/include/asm-m68k/thread_info.h
@@ -2,17 +2,15 @@
 #define _ASM_M68K_THREAD_INFO_H
 
 #include <asm/types.h>
-#include <asm/processor.h>
 #include <asm/page.h>
 
 struct thread_info {
 	struct task_struct	*task;		/* main task structure */
+	unsigned long		flags;
 	struct exec_domain	*exec_domain;	/* execution domain */
 	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
 	__u32 cpu; /* should always be 0 on m68k */
 	struct restart_block    restart_block;
-
-	__u8			supervisor_stack[0];
 };
 
 #define PREEMPT_ACTIVE		0x4000000
@@ -35,84 +33,29 @@ struct thread_info {
 #define free_thread_info(ti)  free_pages((unsigned long)(ti),1)
 #endif /* PAGE_SHIFT == 13 */
 
-//#define init_thread_info	(init_task.thread.info)
+#define init_thread_info	(init_task.thread.info)
 #define init_stack		(init_thread_union.stack)
 
-#define current_thread_info()	(current->thread_info)
-
+#define task_thread_info(tsk)	(&(tsk)->thread.info)
+#define current_thread_info()	task_thread_info(current)
 
 #define __HAVE_THREAD_FUNCTIONS
 
-#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
-#define TIF_DELAYED_TRACE	1	/* single step a syscall */
-#define TIF_NOTIFY_RESUME	2	/* resumption notification requested */
-#define TIF_SIGPENDING		3	/* signal pending */
-#define TIF_NEED_RESCHED	4	/* rescheduling necessary */
-#define TIF_MEMDIE		5
-
-extern int thread_flag_fixme(void);
-
-/*
- * flag set/clear/test wrappers
- * - pass TIF_xxxx constants to these functions
- */
-
-#define __set_tsk_thread_flag(tsk, flag, val) ({	\
-	switch (flag) {					\
-	case TIF_SIGPENDING:				\
-		tsk->thread.work.sigpending = val;	\
-		break;					\
-	case TIF_NEED_RESCHED:				\
-		tsk->thread.work.need_resched = val;	\
-		break;					\
-	case TIF_SYSCALL_TRACE:				\
-		tsk->thread.work.syscall_trace = val;	\
-		break;					\
-	case TIF_MEMDIE:				\
-		tsk->thread.work.memdie = val;		\
-		break;					\
-	default:					\
-		thread_flag_fixme();			\
-	}						\
+#define setup_thread_stack(p, org) ({			\
+	*(struct task_struct **)(p)->thread_info = (p);	\
+	task_thread_info(p)->task = (p);		\
 })
 
-#define __get_tsk_thread_flag(tsk, flag) ({		\
-	int ___res;					\
-	switch (flag) {					\
-	case TIF_SIGPENDING:				\
-		___res = tsk->thread.work.sigpending;	\
-		break;					\
-	case TIF_NEED_RESCHED:				\
-		___res = tsk->thread.work.need_resched;	\
-		break;					\
-	case TIF_SYSCALL_TRACE:				\
-		___res = tsk->thread.work.syscall_trace;\
-		break;					\
-	case TIF_MEMDIE:				\
-		___res = tsk->thread.work.memdie;\
-		break;					\
-	default:					\
-		___res = thread_flag_fixme();		\
-	}						\
-	___res;						\
-})
+#define end_of_stack(p) ((unsigned long *)(p)->thread_info + 1)
 
-#define __get_set_tsk_thread_flag(tsk, flag, val) ({	\
-	int __res = __get_tsk_thread_flag(tsk, flag);	\
-	__set_tsk_thread_flag(tsk, flag, val);		\
-	__res;						\
-})
-
-#define set_tsk_thread_flag(tsk, flag) __set_tsk_thread_flag(tsk, flag, ~0)
-#define clear_tsk_thread_flag(tsk, flag) __set_tsk_thread_flag(tsk, flag, 0)
-#define test_and_set_tsk_thread_flag(tsk, flag) __get_set_tsk_thread_flag(tsk, flag, ~0)
-#define test_tsk_thread_flag(tsk, flag) __get_tsk_thread_flag(tsk, flag)
-
-#define set_thread_flag(flag) set_tsk_thread_flag(current, flag)
-#define clear_thread_flag(flag) clear_tsk_thread_flag(current, flag)
-#define test_thread_flag(flag) test_tsk_thread_flag(current, flag)
-
-#define set_need_resched() set_thread_flag(TIF_NEED_RESCHED)
-#define clear_need_resched() clear_thread_flag(TIF_NEED_RESCHED)
+/* entry.S relies on these definitions!
+ * bits 0-7 are tested at every exception exit
+ * bits 8-15 are also tested at syscall exit
+ */
+#define TIF_SIGPENDING		6	/* signal pending */
+#define TIF_NEED_RESCHED	7	/* rescheduling necessary */
+#define TIF_DELAYED_TRACE	14	/* single step a syscall */
+#define TIF_SYSCALL_TRACE	15	/* syscall trace active */
+#define TIF_MEMDIE		16
 
 #endif	/* _ASM_M68K_THREAD_INFO_H */
diff --git a/include/asm-m68knommu/atomic.h b/include/asm-m68knommu/atomic.h
index a83631e..3c1cc15 100644
--- a/include/asm-m68knommu/atomic.h
+++ b/include/asm-m68knommu/atomic.h
@@ -128,6 +128,18 @@ static inline int atomic_sub_return(int 
 	return temp;
 }
 
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
+#define atomic_add_unless(v, a, u)				\
+({								\
+	int c, old;						\
+	c = atomic_read(v);					\
+	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+		c = old;					\
+	c != (u);						\
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 #define atomic_dec_return(v) atomic_sub_return(1,(v))
 #define atomic_inc_return(v) atomic_add_return(1,(v))
 
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index 6202eb8..2c87b41 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -287,6 +287,27 @@ static __inline__ int atomic_sub_if_posi
 	return result;
 }
 
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
+/**
+ * atomic_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+#define atomic_add_unless(v, a, u)				\
+({								\
+	int c, old;						\
+	c = atomic_read(v);					\
+	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+		c = old;					\
+	c != (u);						\
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 #define atomic_dec_return(v) atomic_sub_return(1,(v))
 #define atomic_inc_return(v) atomic_add_return(1,(v))
 
diff --git a/include/asm-parisc/atomic.h b/include/asm-parisc/atomic.h
index 048a2c7..983e9a2 100644
--- a/include/asm-parisc/atomic.h
+++ b/include/asm-parisc/atomic.h
@@ -164,6 +164,26 @@ static __inline__ int atomic_read(const 
 }
 
 /* exported interface */
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
+/**
+ * atomic_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+#define atomic_add_unless(v, a, u)				\
+({								\
+	int c, old;						\
+	c = atomic_read(v);					\
+	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+		c = old;					\
+	c != (u);						\
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 
 #define atomic_add(i,v)	((void)(__atomic_add_return( ((int)i),(v))))
 #define atomic_sub(i,v)	((void)(__atomic_add_return(-((int)i),(v))))
diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h
index 9c0b372..ec4b144 100644
--- a/include/asm-powerpc/atomic.h
+++ b/include/asm-powerpc/atomic.h
@@ -164,6 +164,33 @@ static __inline__ int atomic_dec_return(
 	return t;
 }
 
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
+/**
+ * atomic_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+#define atomic_add_unless(v, a, u)							 \
+({															 \
+	   int c, old;											 \
+	   c = atomic_read(v);									 \
+	   for (;;) {											  \
+			   if (unlikely(c == (u)))						 \
+					   break;								  \
+			   old = atomic_cmpxchg((v), c, c + (a));		  \
+			   if (likely(old == c))						   \
+					   break;								  \
+			   c = old;										\
+	   }													   \
+	   c != (u);											   \
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 #define atomic_sub_and_test(a, v)	(atomic_sub_return((a), (v)) == 0)
 #define atomic_dec_and_test(v)		(atomic_dec_return((v)) == 0)
 
diff --git a/include/asm-powerpc/btext.h b/include/asm-powerpc/btext.h
new file mode 100644
index 0000000..71cce36
--- /dev/null
+++ b/include/asm-powerpc/btext.h
@@ -0,0 +1,27 @@
+/*
+ * Definitions for using the procedures in btext.c.
+ *
+ * Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ */
+#ifndef __PPC_BTEXT_H
+#define __PPC_BTEXT_H
+#ifdef __KERNEL__
+
+extern void btext_clearscreen(void);
+extern void btext_flushscreen(void);
+
+extern int boot_text_mapped;
+
+extern int btext_initialize(struct device_node *np);
+
+extern void map_boot_text(void);
+extern void init_boot_display(void);
+extern void btext_update_display(unsigned long phys, int width, int height,
+				 int depth, int pitch);
+
+extern void btext_drawchar(char c);
+extern void btext_drawstring(const char *str);
+extern void btext_drawhex(unsigned long v);
+
+#endif /* __KERNEL__ */
+#endif /* __PPC_BTEXT_H */
diff --git a/include/asm-powerpc/delay.h b/include/asm-powerpc/delay.h
new file mode 100644
index 0000000..1492aa9
--- /dev/null
+++ b/include/asm-powerpc/delay.h
@@ -0,0 +1,55 @@
+#ifndef _ASM_POWERPC_DELAY_H
+#define _ASM_POWERPC_DELAY_H
+
+/*
+ * Copyright 1996, Paul Mackerras.
+ *
+ * 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.
+ *
+ * PPC64 Support added by Dave Engebretsen, Todd Inglett, Mike Corrigan,
+ * Anton Blanchard.
+ */
+
+extern unsigned long tb_ticks_per_usec;
+
+#ifdef CONFIG_PPC64
+/* define these here to prevent circular dependencies */
+/* these instructions control the thread priority on multi-threaded cpus */
+#define __HMT_low()	asm volatile("or 1,1,1")
+#define __HMT_medium()	asm volatile("or 2,2,2")
+#else
+#define __HMT_low()
+#define __HMT_medium()
+#endif
+
+#define __barrier()	asm volatile("" ::: "memory")
+
+static inline unsigned long __get_tb(void)
+{
+	unsigned long rval;
+
+	asm volatile("mftb %0" : "=r" (rval));
+	return rval;
+}
+
+static inline void __delay(unsigned long loops)
+{
+	unsigned long start = __get_tb();
+
+	while((__get_tb() - start) < loops)
+		__HMT_low();
+	__HMT_medium();
+	__barrier();
+}
+
+static inline void udelay(unsigned long usecs)
+{
+	unsigned long loops = tb_ticks_per_usec * usecs;
+
+	__delay(loops);
+}
+
+#endif /* _ASM_POWERPC_DELAY_H */
diff --git a/include/asm-powerpc/eeh.h b/include/asm-powerpc/eeh.h
new file mode 100644
index 0000000..89f26ab
--- /dev/null
+++ b/include/asm-powerpc/eeh.h
@@ -0,0 +1,364 @@
+/*
+ * eeh.h
+ * Copyright (C) 2001  Dave Engebretsen & Todd Inglett IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef _PPC64_EEH_H
+#define _PPC64_EEH_H
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/string.h>
+
+struct pci_dev;
+struct device_node;
+
+#ifdef CONFIG_EEH
+
+/* Values for eeh_mode bits in device_node */
+#define EEH_MODE_SUPPORTED	(1<<0)
+#define EEH_MODE_NOCHECK	(1<<1)
+#define EEH_MODE_ISOLATED	(1<<2)
+
+/* Max number of EEH freezes allowed before we consider the device
+ * to be permanently disabled. */
+#define EEH_MAX_ALLOWED_FREEZES 5
+
+void __init eeh_init(void);
+unsigned long eeh_check_failure(const volatile void __iomem *token,
+				unsigned long val);
+int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev);
+void __init pci_addr_cache_build(void);
+
+/**
+ * eeh_add_device_early
+ * eeh_add_device_late
+ *
+ * Perform eeh initialization for devices added after boot.
+ * Call eeh_add_device_early before doing any i/o to the
+ * device (including config space i/o).  Call eeh_add_device_late
+ * to finish the eeh setup for this device.
+ */
+void eeh_add_device_early(struct device_node *);
+void eeh_add_device_late(struct pci_dev *);
+
+/**
+ * eeh_remove_device - undo EEH setup for the indicated pci device
+ * @dev: pci device to be removed
+ *
+ * This routine should be called when a device is removed from
+ * a running system (e.g. by hotplug or dlpar).  It unregisters
+ * the PCI device from the EEH subsystem.  I/O errors affecting
+ * this device will no longer be detected after this call; thus,
+ * i/o errors affecting this slot may leave this device unusable.
+ */
+void eeh_remove_device(struct pci_dev *);
+
+/**
+ * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
+ *
+ * If this macro yields TRUE, the caller relays to eeh_check_failure()
+ * which does further tests out of line.
+ */
+#define EEH_POSSIBLE_ERROR(val, type)	((val) == (type)~0)
+
+/*
+ * Reads from a device which has been isolated by EEH will return
+ * all 1s.  This macro gives an all-1s value of the given size (in
+ * bytes: 1, 2, or 4) for comparing with the result of a read.
+ */
+#define EEH_IO_ERROR_VALUE(size)	(~0U >> ((4 - (size)) * 8))
+
+#else /* !CONFIG_EEH */
+static inline void eeh_init(void) { }
+
+static inline unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val)
+{
+	return val;
+}
+
+static inline int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
+{
+	return 0;
+}
+
+static inline void pci_addr_cache_build(void) { }
+
+static inline void eeh_add_device_early(struct device_node *dn) { }
+
+static inline void eeh_add_device_late(struct pci_dev *dev) { }
+
+static inline void eeh_remove_device(struct pci_dev *dev) { }
+
+#define EEH_POSSIBLE_ERROR(val, type) (0)
+#define EEH_IO_ERROR_VALUE(size) (-1UL)
+#endif /* CONFIG_EEH */
+
+/*
+ * MMIO read/write operations with EEH support.
+ */
+static inline u8 eeh_readb(const volatile void __iomem *addr)
+{
+	u8 val = in_8(addr);
+	if (EEH_POSSIBLE_ERROR(val, u8))
+		return eeh_check_failure(addr, val);
+	return val;
+}
+static inline void eeh_writeb(u8 val, volatile void __iomem *addr)
+{
+	out_8(addr, val);
+}
+
+static inline u16 eeh_readw(const volatile void __iomem *addr)
+{
+	u16 val = in_le16(addr);
+	if (EEH_POSSIBLE_ERROR(val, u16))
+		return eeh_check_failure(addr, val);
+	return val;
+}
+static inline void eeh_writew(u16 val, volatile void __iomem *addr)
+{
+	out_le16(addr, val);
+}
+static inline u16 eeh_raw_readw(const volatile void __iomem *addr)
+{
+	u16 val = in_be16(addr);
+	if (EEH_POSSIBLE_ERROR(val, u16))
+		return eeh_check_failure(addr, val);
+	return val;
+}
+static inline void eeh_raw_writew(u16 val, volatile void __iomem *addr) {
+	volatile u16 __iomem *vaddr = (volatile u16 __iomem *) addr;
+	out_be16(vaddr, val);
+}
+
+static inline u32 eeh_readl(const volatile void __iomem *addr)
+{
+	u32 val = in_le32(addr);
+	if (EEH_POSSIBLE_ERROR(val, u32))
+		return eeh_check_failure(addr, val);
+	return val;
+}
+static inline void eeh_writel(u32 val, volatile void __iomem *addr)
+{
+	out_le32(addr, val);
+}
+static inline u32 eeh_raw_readl(const volatile void __iomem *addr)
+{
+	u32 val = in_be32(addr);
+	if (EEH_POSSIBLE_ERROR(val, u32))
+		return eeh_check_failure(addr, val);
+	return val;
+}
+static inline void eeh_raw_writel(u32 val, volatile void __iomem *addr)
+{
+	out_be32(addr, val);
+}
+
+static inline u64 eeh_readq(const volatile void __iomem *addr)
+{
+	u64 val = in_le64(addr);
+	if (EEH_POSSIBLE_ERROR(val, u64))
+		return eeh_check_failure(addr, val);
+	return val;
+}
+static inline void eeh_writeq(u64 val, volatile void __iomem *addr)
+{
+	out_le64(addr, val);
+}
+static inline u64 eeh_raw_readq(const volatile void __iomem *addr)
+{
+	u64 val = in_be64(addr);
+	if (EEH_POSSIBLE_ERROR(val, u64))
+		return eeh_check_failure(addr, val);
+	return val;
+}
+static inline void eeh_raw_writeq(u64 val, volatile void __iomem *addr)
+{
+	out_be64(addr, val);
+}
+
+#define EEH_CHECK_ALIGN(v,a) \
+	((((unsigned long)(v)) & ((a) - 1)) == 0)
+
+static inline void eeh_memset_io(volatile void __iomem *addr, int c,
+				 unsigned long n)
+{
+	void *p = (void __force *)addr;
+	u32 lc = c;
+	lc |= lc << 8;
+	lc |= lc << 16;
+
+	while(n && !EEH_CHECK_ALIGN(p, 4)) {
+		*((volatile u8 *)p) = c;
+		p++;
+		n--;
+	}
+	while(n >= 4) {
+		*((volatile u32 *)p) = lc;
+		p += 4;
+		n -= 4;
+	}
+	while(n) {
+		*((volatile u8 *)p) = c;
+		p++;
+		n--;
+	}
+	__asm__ __volatile__ ("sync" : : : "memory");
+}
+static inline void eeh_memcpy_fromio(void *dest, const volatile void __iomem *src,
+				     unsigned long n)
+{
+	void *vsrc = (void __force *) src;
+	void *destsave = dest;
+	unsigned long nsave = n;
+
+	while(n && (!EEH_CHECK_ALIGN(vsrc, 4) || !EEH_CHECK_ALIGN(dest, 4))) {
+		*((u8 *)dest) = *((volatile u8 *)vsrc);
+		__asm__ __volatile__ ("eieio" : : : "memory");
+		vsrc++;
+		dest++;
+		n--;
+	}
+	while(n > 4) {
+		*((u32 *)dest) = *((volatile u32 *)vsrc);
+		__asm__ __volatile__ ("eieio" : : : "memory");
+		vsrc += 4;
+		dest += 4;
+		n -= 4;
+	}
+	while(n) {
+		*((u8 *)dest) = *((volatile u8 *)vsrc);
+		__asm__ __volatile__ ("eieio" : : : "memory");
+		vsrc++;
+		dest++;
+		n--;
+	}
+	__asm__ __volatile__ ("sync" : : : "memory");
+
+	/* Look for ffff's here at dest[n].  Assume that at least 4 bytes
+	 * were copied. Check all four bytes.
+	 */
+	if ((nsave >= 4) &&
+		(EEH_POSSIBLE_ERROR((*((u32 *) destsave+nsave-4)), u32))) {
+		eeh_check_failure(src, (*((u32 *) destsave+nsave-4)));
+	}
+}
+
+static inline void eeh_memcpy_toio(volatile void __iomem *dest, const void *src,
+				   unsigned long n)
+{
+	void *vdest = (void __force *) dest;
+
+	while(n && (!EEH_CHECK_ALIGN(vdest, 4) || !EEH_CHECK_ALIGN(src, 4))) {
+		*((volatile u8 *)vdest) = *((u8 *)src);
+		src++;
+		vdest++;
+		n--;
+	}
+	while(n > 4) {
+		*((volatile u32 *)vdest) = *((volatile u32 *)src);
+		src += 4;
+		vdest += 4;
+		n-=4;
+	}
+	while(n) {
+		*((volatile u8 *)vdest) = *((u8 *)src);
+		src++;
+		vdest++;
+		n--;
+	}
+	__asm__ __volatile__ ("sync" : : : "memory");
+}
+
+#undef EEH_CHECK_ALIGN
+
+static inline u8 eeh_inb(unsigned long port)
+{
+	u8 val;
+	if (!_IO_IS_VALID(port))
+		return ~0;
+	val = in_8((u8 __iomem *)(port+pci_io_base));
+	if (EEH_POSSIBLE_ERROR(val, u8))
+		return eeh_check_failure((void __iomem *)(port), val);
+	return val;
+}
+
+static inline void eeh_outb(u8 val, unsigned long port)
+{
+	if (_IO_IS_VALID(port))
+		out_8((u8 __iomem *)(port+pci_io_base), val);
+}
+
+static inline u16 eeh_inw(unsigned long port)
+{
+	u16 val;
+	if (!_IO_IS_VALID(port))
+		return ~0;
+	val = in_le16((u16 __iomem *)(port+pci_io_base));
+	if (EEH_POSSIBLE_ERROR(val, u16))
+		return eeh_check_failure((void __iomem *)(port), val);
+	return val;
+}
+
+static inline void eeh_outw(u16 val, unsigned long port)
+{
+	if (_IO_IS_VALID(port))
+		out_le16((u16 __iomem *)(port+pci_io_base), val);
+}
+
+static inline u32 eeh_inl(unsigned long port)
+{
+	u32 val;
+	if (!_IO_IS_VALID(port))
+		return ~0;
+	val = in_le32((u32 __iomem *)(port+pci_io_base));
+	if (EEH_POSSIBLE_ERROR(val, u32))
+		return eeh_check_failure((void __iomem *)(port), val);
+	return val;
+}
+
+static inline void eeh_outl(u32 val, unsigned long port)
+{
+	if (_IO_IS_VALID(port))
+		out_le32((u32 __iomem *)(port+pci_io_base), val);
+}
+
+/* in-string eeh macros */
+static inline void eeh_insb(unsigned long port, void * buf, int ns)
+{
+	_insb((u8 __iomem *)(port+pci_io_base), buf, ns);
+	if (EEH_POSSIBLE_ERROR((*(((u8*)buf)+ns-1)), u8))
+		eeh_check_failure((void __iomem *)(port), *(u8*)buf);
+}
+
+static inline void eeh_insw_ns(unsigned long port, void * buf, int ns)
+{
+	_insw_ns((u16 __iomem *)(port+pci_io_base), buf, ns);
+	if (EEH_POSSIBLE_ERROR((*(((u16*)buf)+ns-1)), u16))
+		eeh_check_failure((void __iomem *)(port), *(u16*)buf);
+}
+
+static inline void eeh_insl_ns(unsigned long port, void * buf, int nl)
+{
+	_insl_ns((u32 __iomem *)(port+pci_io_base), buf, nl);
+	if (EEH_POSSIBLE_ERROR((*(((u32*)buf)+nl-1)), u32))
+		eeh_check_failure((void __iomem *)(port), *(u32*)buf);
+}
+
+#endif /* _PPC64_EEH_H */
diff --git a/include/asm-powerpc/floppy.h b/include/asm-powerpc/floppy.h
new file mode 100644
index 0000000..64276a3
--- /dev/null
+++ b/include/asm-powerpc/floppy.h
@@ -0,0 +1,105 @@
+/*
+ * Architecture specific parts of the Floppy driver
+ *
+ * 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) 1995
+ */
+#ifndef __ASM_POWERPC_FLOPPY_H
+#define __ASM_POWERPC_FLOPPY_H
+
+#include <linux/config.h>
+#include <asm/machdep.h>
+
+#define fd_inb(port)		inb_p(port)
+#define fd_outb(value,port)	outb_p(value,port)
+
+#define fd_enable_dma()         enable_dma(FLOPPY_DMA)
+#define fd_disable_dma()        disable_dma(FLOPPY_DMA)
+#define fd_request_dma()        request_dma(FLOPPY_DMA, "floppy")
+#define fd_free_dma()           free_dma(FLOPPY_DMA)
+#define fd_clear_dma_ff()       clear_dma_ff(FLOPPY_DMA)
+#define fd_set_dma_mode(mode)   set_dma_mode(FLOPPY_DMA, mode)
+#define fd_set_dma_count(count) set_dma_count(FLOPPY_DMA, count)
+#define fd_enable_irq()         enable_irq(FLOPPY_IRQ)
+#define fd_disable_irq()        disable_irq(FLOPPY_IRQ)
+#define fd_cacheflush(addr,size) /* nothing */
+#define fd_request_irq()        request_irq(FLOPPY_IRQ, floppy_interrupt, \
+					    SA_INTERRUPT|SA_SAMPLE_RANDOM, \
+				            "floppy", NULL)
+#define fd_free_irq()           free_irq(FLOPPY_IRQ, NULL);
+
+#ifdef CONFIG_PCI
+
+#include <linux/pci.h>
+
+#define fd_dma_setup(addr,size,mode,io) powerpc_fd_dma_setup(addr,size,mode,io)
+
+static __inline__ int powerpc_fd_dma_setup(char *addr, unsigned long size,
+					   int mode, int io)
+{
+	static unsigned long prev_size;
+	static dma_addr_t bus_addr = 0;
+	static char *prev_addr;
+	static int prev_dir;
+	int dir;
+
+	dir = (mode == DMA_MODE_READ) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE;
+
+	if (bus_addr 
+	    && (addr != prev_addr || size != prev_size || dir != prev_dir)) {
+		/* different from last time -- unmap prev */
+		pci_unmap_single(NULL, bus_addr, prev_size, prev_dir);
+		bus_addr = 0;
+	}
+
+	if (!bus_addr)	/* need to map it */
+		bus_addr = pci_map_single(NULL, addr, size, dir);
+
+	/* remember this one as prev */
+	prev_addr = addr;
+	prev_size = size;
+	prev_dir = dir;
+
+	fd_clear_dma_ff();
+	fd_cacheflush(addr, size);
+	fd_set_dma_mode(mode);
+	set_dma_addr(FLOPPY_DMA, bus_addr);
+	fd_set_dma_count(size);
+	virtual_dma_port = io;
+	fd_enable_dma();
+
+	return 0;
+}
+
+#endif /* CONFIG_PCI */
+
+__inline__ void virtual_dma_init(void)
+{
+	/* Nothing to do on PowerPC */
+}
+
+static int FDC1 = 0x3f0;
+static int FDC2 = -1;
+
+/*
+ * Again, the CMOS information not available
+ */
+#define FLOPPY0_TYPE 6
+#define FLOPPY1_TYPE 0
+
+#define N_FDC 2			/* Don't change this! */
+#define N_DRIVE 8
+
+#define FLOPPY_MOTOR_MASK 0xf0
+
+/*
+ * The PowerPC has no problems with floppy DMA crossing 64k borders.
+ */
+#define CROSS_64KB(a,s)	(0)
+
+#define EXTRA_FLOPPY_PARAMS
+
+#endif /* __ASM_POWERPC_FLOPPY_H */
diff --git a/include/asm-powerpc/hvconsole.h b/include/asm-powerpc/hvconsole.h
new file mode 100644
index 0000000..6da93ce
--- /dev/null
+++ b/include/asm-powerpc/hvconsole.h
@@ -0,0 +1,49 @@
+/*
+ * hvconsole.h
+ * Copyright (C) 2004 Ryan S Arnold, IBM Corporation
+ *
+ * LPAR console support.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef _PPC64_HVCONSOLE_H
+#define _PPC64_HVCONSOLE_H
+
+/*
+ * This is the max number of console adapters that can/will be found as
+ * console devices on first stage console init.  Any number beyond this range
+ * can't be used as a console device but is still a valid tty device.
+ */
+#define MAX_NR_HVC_CONSOLES	16
+
+/* implemented by a low level driver */
+struct hv_ops {
+	int (*get_chars)(uint32_t vtermno, char *buf, int count);
+	int (*put_chars)(uint32_t vtermno, const char *buf, int count);
+};
+extern int hvc_get_chars(uint32_t vtermno, char *buf, int count);
+extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count);
+
+struct hvc_struct;
+
+/* Register a vterm and a slot index for use as a console (console_init) */
+extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
+/* register a vterm for hvc tty operation (module_init or hotplug add) */
+extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
+						 struct hv_ops *ops);
+/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
+extern int __devexit hvc_remove(struct hvc_struct *hp);
+#endif /* _PPC64_HVCONSOLE_H */
diff --git a/include/asm-powerpc/hvcserver.h b/include/asm-powerpc/hvcserver.h
new file mode 100644
index 0000000..aecba96
--- /dev/null
+++ b/include/asm-powerpc/hvcserver.h
@@ -0,0 +1,57 @@
+/*
+ * hvcserver.h
+ * Copyright (C) 2004 Ryan S Arnold, IBM Corporation
+ *
+ * PPC64 virtual I/O console server support.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef _PPC64_HVCSERVER_H
+#define _PPC64_HVCSERVER_H
+
+#include <linux/list.h>
+
+/* Converged Location Code length */
+#define HVCS_CLC_LENGTH	79
+
+/**
+ * hvcs_partner_info - an element in a list of partner info
+ * @node: list_head denoting this partner_info struct's position in the list of
+ *	partner info.
+ * @unit_address: The partner unit address of this entry.
+ * @partition_ID: The partner partition ID of this entry.
+ * @location_code: The converged location code of this entry + 1 char for the
+ *	null-term.
+ *
+ * This structure outlines the format that partner info is presented to a caller
+ * of the hvcs partner info fetching functions.  These are strung together into
+ * a list using linux kernel lists.
+ */
+struct hvcs_partner_info {
+	struct list_head node;
+	uint32_t unit_address;
+	uint32_t partition_ID;
+	char location_code[HVCS_CLC_LENGTH + 1]; /* CLC + 1 null-term char */
+};
+
+extern int hvcs_free_partner_info(struct list_head *head);
+extern int hvcs_get_partner_info(uint32_t unit_address,
+		struct list_head *head, unsigned long *pi_buff);
+extern int hvcs_register_connection(uint32_t unit_address,
+		uint32_t p_partition_ID, uint32_t p_unit_address);
+extern int hvcs_free_connection(uint32_t unit_address);
+
+#endif /* _PPC64_HVCSERVER_H */
diff --git a/include/asm-powerpc/kexec.h b/include/asm-powerpc/kexec.h
index 062ab9b..c72ffc7 100644
--- a/include/asm-powerpc/kexec.h
+++ b/include/asm-powerpc/kexec.h
@@ -40,6 +40,7 @@ extern note_buf_t crash_notes[];
 #ifdef __powerpc64__
 extern void kexec_smp_wait(void);	/* get and clear naca physid, wait for
 					  master to copy new code to 0 */
+extern void __init kexec_setup(void);
 #else
 struct kimage;
 extern void machine_kexec_simple(struct kimage *image);
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index 5670f0c..c011abb 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -93,7 +93,9 @@ struct machdep_calls {
 
 	void		(*init_IRQ)(void);
 	int		(*get_irq)(struct pt_regs *);
-	void		(*cpu_irq_down)(int secondary);
+#ifdef CONFIG_KEXEC
+	void		(*kexec_cpu_down)(int crash_shutdown, int secondary);
+#endif
 
 	/* PCI stuff */
 	/* Called after scanning the bus, before allocating resources */
diff --git a/include/asm-powerpc/nvram.h b/include/asm-powerpc/nvram.h
new file mode 100644
index 0000000..24bd8c2
--- /dev/null
+++ b/include/asm-powerpc/nvram.h
@@ -0,0 +1,119 @@
+/*
+ * NVRAM definitions and access functions.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_POWERPC_NVRAM_H
+#define _ASM_POWERPC_NVRAM_H
+
+#define NVRW_CNT 0x20
+#define NVRAM_HEADER_LEN 16 /* sizeof(struct nvram_header) */
+#define NVRAM_BLOCK_LEN 16
+#define NVRAM_MAX_REQ (2080/NVRAM_BLOCK_LEN)
+#define NVRAM_MIN_REQ (1056/NVRAM_BLOCK_LEN)
+
+#define NVRAM_AS0  0x74
+#define NVRAM_AS1  0x75
+#define NVRAM_DATA 0x77
+
+
+/* RTC Offsets */
+
+#define MOTO_RTC_SECONDS	0x1FF9
+#define MOTO_RTC_MINUTES	0x1FFA
+#define MOTO_RTC_HOURS		0x1FFB
+#define MOTO_RTC_DAY_OF_WEEK	0x1FFC
+#define MOTO_RTC_DAY_OF_MONTH	0x1FFD
+#define MOTO_RTC_MONTH		0x1FFE
+#define MOTO_RTC_YEAR		0x1FFF
+#define MOTO_RTC_CONTROLA       0x1FF8
+#define MOTO_RTC_CONTROLB       0x1FF9
+
+#define NVRAM_SIG_SP	0x02	/* support processor */
+#define NVRAM_SIG_OF	0x50	/* open firmware config */
+#define NVRAM_SIG_FW	0x51	/* general firmware */
+#define NVRAM_SIG_HW	0x52	/* hardware (VPD) */
+#define NVRAM_SIG_FLIP	0x5a	/* Apple flip/flop header */
+#define NVRAM_SIG_APPL	0x5f	/* Apple "system" (???) */
+#define NVRAM_SIG_SYS	0x70	/* system env vars */
+#define NVRAM_SIG_CFG	0x71	/* config data */
+#define NVRAM_SIG_ELOG	0x72	/* error log */
+#define NVRAM_SIG_VEND	0x7e	/* vendor defined */
+#define NVRAM_SIG_FREE	0x7f	/* Free space */
+#define NVRAM_SIG_OS	0xa0	/* OS defined */
+#define NVRAM_SIG_PANIC	0xa1	/* Apple OSX "panic" */
+
+/* If change this size, then change the size of NVNAME_LEN */
+struct nvram_header {
+	unsigned char signature;
+	unsigned char checksum;
+	unsigned short length;
+	char name[12];
+};
+
+struct nvram_partition {
+	struct list_head partition;
+	struct nvram_header header;
+	unsigned int index;
+};
+
+
+extern int nvram_write_error_log(char * buff, int length, unsigned int err_type);
+extern int nvram_read_error_log(char * buff, int length, unsigned int * err_type);
+extern int nvram_clear_error_log(void);
+extern struct nvram_partition *nvram_find_partition(int sig, const char *name);
+
+extern int pSeries_nvram_init(void);
+extern int mmio_nvram_init(void);
+
+/* PowerMac specific nvram stuffs */
+
+enum {
+	pmac_nvram_OF,		/* Open Firmware partition */
+	pmac_nvram_XPRAM,	/* MacOS XPRAM partition */
+	pmac_nvram_NR		/* MacOS Name Registry partition */
+};
+
+/* Return partition offset in nvram */
+extern int	pmac_get_partition(int partition);
+
+/* Direct access to XPRAM on PowerMacs */
+extern u8	pmac_xpram_read(int xpaddr);
+extern void	pmac_xpram_write(int xpaddr, u8 data);
+
+/* Synchronize NVRAM */
+extern void	nvram_sync(void);
+
+/* Normal access to NVRAM */
+extern unsigned char nvram_read_byte(int i);
+extern void nvram_write_byte(unsigned char c, int i);
+
+/* Some offsets in XPRAM */
+#define PMAC_XPRAM_MACHINE_LOC	0xe4
+#define PMAC_XPRAM_SOUND_VOLUME	0x08
+
+/* Machine location structure in PowerMac XPRAM */
+struct pmac_machine_location {
+	unsigned int	latitude;	/* 2+30 bit Fractional number */
+	unsigned int	longitude;	/* 2+30 bit Fractional number */
+	unsigned int	delta;		/* mix of GMT delta and DLS */
+};
+
+/*
+ * /dev/nvram ioctls
+ *
+ * Note that PMAC_NVRAM_GET_OFFSET is still supported, but is
+ * definitely obsolete. Do not use it if you can avoid it
+ */
+
+#define OBSOLETE_PMAC_NVRAM_GET_OFFSET \
+				_IOWR('p', 0x40, int)
+
+#define IOC_NVRAM_GET_OFFSET	_IOWR('p', 0x42, int)	/* Get NVRAM partition offset */
+#define IOC_NVRAM_SYNC		_IO('p', 0x43)		/* Sync NVRAM image */
+
+#endif /* _ASM_POWERPC_NVRAM_H */
diff --git a/include/asm-powerpc/page.h b/include/asm-powerpc/page.h
new file mode 100644
index 0000000..18c1e5e
--- /dev/null
+++ b/include/asm-powerpc/page.h
@@ -0,0 +1,179 @@
+#ifndef _ASM_POWERPC_PAGE_H
+#define _ASM_POWERPC_PAGE_H
+
+/*
+ * Copyright (C) 2001,2005 IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifdef __KERNEL__
+#include <linux/config.h>
+#include <asm/asm-compat.h>
+
+/*
+ * On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software
+ * page size. When using 64K pages however, whether we are really supporting
+ * 64K pages in HW or not is irrelevant to those definitions.
+ */
+#ifdef CONFIG_PPC_64K_PAGES
+#define PAGE_SHIFT		16
+#else
+#define PAGE_SHIFT		12
+#endif
+
+#define PAGE_SIZE		(ASM_CONST(1) << PAGE_SHIFT)
+
+/* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
+#define __HAVE_ARCH_GATE_AREA		1
+
+/*
+ * Subtle: (1 << PAGE_SHIFT) is an int, not an unsigned long. So if we
+ * assign PAGE_MASK to a larger type it gets extended the way we want
+ * (i.e. with 1s in the high bits)
+ */
+#define PAGE_MASK      (~((1 << PAGE_SHIFT) - 1))
+
+#define PAGE_OFFSET     ASM_CONST(CONFIG_KERNEL_START)
+#define KERNELBASE      PAGE_OFFSET
+
+#ifdef CONFIG_DISCONTIGMEM
+#define page_to_pfn(page)	discontigmem_page_to_pfn(page)
+#define pfn_to_page(pfn)	discontigmem_pfn_to_page(pfn)
+#define pfn_valid(pfn)		discontigmem_pfn_valid(pfn)
+#endif
+
+#ifdef CONFIG_FLATMEM
+#define pfn_to_page(pfn)	(mem_map + (pfn))
+#define page_to_pfn(page)	((unsigned long)((page) - mem_map))
+#define pfn_valid(pfn)		((pfn) < max_mapnr)
+#endif
+
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
+#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+
+#define __va(x) ((void *)((unsigned long)(x) + KERNELBASE))
+#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET)
+
+/*
+ * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI,
+ * and needs to be executable.  This means the whole heap ends
+ * up being executable.
+ */
+#define VM_DATA_DEFAULT_FLAGS32	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#define VM_DATA_DEFAULT_FLAGS64	(VM_READ | VM_WRITE | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#ifdef __powerpc64__
+#include <asm/page_64.h>
+#else
+#include <asm/page_32.h>
+#endif
+
+/* align addr on a size boundary - adjust address up/down if needed */
+#define _ALIGN_UP(addr,size)	(((addr)+((size)-1))&(~((size)-1)))
+#define _ALIGN_DOWN(addr,size)	((addr)&(~((size)-1)))
+
+/* align addr on a size boundary - adjust address up if needed */
+#define _ALIGN(addr,size)     _ALIGN_UP(addr,size)
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	_ALIGN(addr, PAGE_SIZE)
+
+#ifndef __ASSEMBLY__
+
+#undef STRICT_MM_TYPECHECKS
+
+#ifdef STRICT_MM_TYPECHECKS
+/* These are used to make use of C type-checking. */
+
+/* PTE level */
+typedef struct { pte_basic_t pte; } pte_t;
+#define pte_val(x)	((x).pte)
+#define __pte(x)	((pte_t) { (x) })
+
+/* 64k pages additionally define a bigger "real PTE" type that gathers
+ * the "second half" part of the PTE for pseudo 64k pages
+ */
+#ifdef CONFIG_PPC_64K_PAGES
+typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
+#else
+typedef struct { pte_t pte; } real_pte_t;
+#endif
+
+/* PMD level */
+typedef struct { unsigned long pmd; } pmd_t;
+#define pmd_val(x)	((x).pmd)
+#define __pmd(x)	((pmd_t) { (x) })
+
+/* PUD level exusts only on 4k pages */
+#ifndef CONFIG_PPC_64K_PAGES
+typedef struct { unsigned long pud; } pud_t;
+#define pud_val(x)	((x).pud)
+#define __pud(x)	((pud_t) { (x) })
+#endif
+
+/* PGD level */
+typedef struct { unsigned long pgd; } pgd_t;
+#define pgd_val(x)	((x).pgd)
+#define __pgd(x)	((pgd_t) { (x) })
+
+/* Page protection bits */
+typedef struct { unsigned long pgprot; } pgprot_t;
+#define pgprot_val(x)	((x).pgprot)
+#define __pgprot(x)	((pgprot_t) { (x) })
+
+#else
+
+/*
+ * .. while these make it easier on the compiler
+ */
+
+typedef pte_basic_t pte_t;
+#define pte_val(x)	(x)
+#define __pte(x)	(x)
+
+#ifdef CONFIG_PPC_64K_PAGES
+typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
+#else
+typedef unsigned long real_pte_t;
+#endif
+
+
+typedef unsigned long pmd_t;
+#define pmd_val(x)	(x)
+#define __pmd(x)	(x)
+
+#ifndef CONFIG_PPC_64K_PAGES
+typedef unsigned long pud_t;
+#define pud_val(x)	(x)
+#define __pud(x)	(x)
+#endif
+
+typedef unsigned long pgd_t;
+#define pgd_val(x)	(x)
+#define pgprot_val(x)	(x)
+
+typedef unsigned long pgprot_t;
+#define __pgd(x)	(x)
+#define __pgprot(x)	(x)
+
+#endif
+
+struct page;
+extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
+extern void copy_user_page(void *to, void *from, unsigned long vaddr,
+		struct page *p);
+extern int page_is_ram(unsigned long pfn);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_POWERPC_PAGE_H */
diff --git a/include/asm-powerpc/page_32.h b/include/asm-powerpc/page_32.h
new file mode 100644
index 0000000..7259cfd
--- /dev/null
+++ b/include/asm-powerpc/page_32.h
@@ -0,0 +1,40 @@
+#ifndef _ASM_POWERPC_PAGE_32_H
+#define _ASM_POWERPC_PAGE_32_H
+
+#define VM_DATA_DEFAULT_FLAGS	VM_DATA_DEFAULT_FLAGS32
+
+#define PPC_MEMSTART	0
+
+#ifndef __ASSEMBLY__
+/*
+ * The basic type of a PTE - 64 bits for those CPUs with > 32 bit
+ * physical addressing.  For now this just the IBM PPC440.
+ */
+#ifdef CONFIG_PTE_64BIT
+typedef unsigned long long pte_basic_t;
+#define PTE_SHIFT	(PAGE_SHIFT - 3)	/* 512 ptes per page */
+#define PTE_FMT		"%16Lx"
+#else
+typedef unsigned long pte_basic_t;
+#define PTE_SHIFT	(PAGE_SHIFT - 2)	/* 1024 ptes per page */
+#define PTE_FMT		"%.8lx"
+#endif
+
+struct page;
+extern void clear_pages(void *page, int order);
+static inline void clear_page(void *page) { clear_pages(page, 0); }
+extern void copy_page(void *to, void *from);
+
+/* Pure 2^n version of get_order */
+extern __inline__ int get_order(unsigned long size)
+{
+	int lz;
+
+	size = (size-1) >> PAGE_SHIFT;
+	asm ("cntlzw %0,%1" : "=r" (lz) : "r" (size));
+	return 32 - lz;
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_POWERPC_PAGE_32_H */
diff --git a/include/asm-powerpc/page_64.h b/include/asm-powerpc/page_64.h
new file mode 100644
index 0000000..c16f106
--- /dev/null
+++ b/include/asm-powerpc/page_64.h
@@ -0,0 +1,174 @@
+#ifndef _ASM_POWERPC_PAGE_64_H
+#define _ASM_POWERPC_PAGE_64_H
+
+/*
+ * Copyright (C) 2001 PPC64 Team, IBM Corp
+ *
+ * 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.
+ */
+
+/*
+ * We always define HW_PAGE_SHIFT to 12 as use of 64K pages remains Linux
+ * specific, every notion of page number shared with the firmware, TCEs,
+ * iommu, etc... still uses a page size of 4K.
+ */
+#define HW_PAGE_SHIFT		12
+#define HW_PAGE_SIZE		(ASM_CONST(1) << HW_PAGE_SHIFT)
+#define HW_PAGE_MASK		(~(HW_PAGE_SIZE-1))
+
+/*
+ * PAGE_FACTOR is the number of bits factor between PAGE_SHIFT and
+ * HW_PAGE_SHIFT, that is 4K pages.
+ */
+#define PAGE_FACTOR		(PAGE_SHIFT - HW_PAGE_SHIFT)
+
+#define REGION_SIZE   4UL
+#define REGION_SHIFT  60UL
+#define REGION_MASK   (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT)
+
+#define VMALLOCBASE		ASM_CONST(0xD000000000000000)
+#define VMALLOC_REGION_ID	(VMALLOCBASE >> REGION_SHIFT)
+#define KERNEL_REGION_ID	(KERNELBASE >> REGION_SHIFT)
+#define USER_REGION_ID		(0UL)
+#define REGION_ID(ea)		(((unsigned long)(ea)) >> REGION_SHIFT)
+
+/* Segment size */
+#define SID_SHIFT		28
+#define SID_MASK		0xfffffffffUL
+#define ESID_MASK		0xfffffffff0000000UL
+#define GET_ESID(x)		(((x) >> SID_SHIFT) & SID_MASK)
+
+#ifndef __ASSEMBLY__
+#include <asm/cache.h>
+
+typedef unsigned long pte_basic_t;
+
+static __inline__ void clear_page(void *addr)
+{
+	unsigned long lines, line_size;
+
+	line_size = ppc64_caches.dline_size;
+	lines = ppc64_caches.dlines_per_page;
+
+	__asm__ __volatile__(
+	"mtctr	%1	# clear_page\n\
+1:      dcbz	0,%0\n\
+	add	%0,%0,%3\n\
+	bdnz+	1b"
+        : "=r" (addr)
+        : "r" (lines), "0" (addr), "r" (line_size)
+	: "ctr", "memory");
+}
+
+extern void copy_4K_page(void *to, void *from);
+
+#ifdef CONFIG_PPC_64K_PAGES
+static inline void copy_page(void *to, void *from)
+{
+	unsigned int i;
+	for (i=0; i < (1 << (PAGE_SHIFT - 12)); i++) {
+		copy_4K_page(to, from);
+		to += 4096;
+		from += 4096;
+	}
+}
+#else /* CONFIG_PPC_64K_PAGES */
+static inline void copy_page(void *to, void *from)
+{
+	copy_4K_page(to, from);
+}
+#endif /* CONFIG_PPC_64K_PAGES */
+
+/* Log 2 of page table size */
+extern u64 ppc64_pft_size;
+
+/* Large pages size */
+extern unsigned int HPAGE_SHIFT;
+#define HPAGE_SIZE		((1UL) << HPAGE_SHIFT)
+#define HPAGE_MASK		(~(HPAGE_SIZE - 1))
+#define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
+
+#endif /* __ASSEMBLY__ */
+
+#ifdef CONFIG_HUGETLB_PAGE
+
+#define HTLB_AREA_SHIFT		40
+#define HTLB_AREA_SIZE		(1UL << HTLB_AREA_SHIFT)
+#define GET_HTLB_AREA(x)	((x) >> HTLB_AREA_SHIFT)
+
+#define LOW_ESID_MASK(addr, len)    (((1U << (GET_ESID(addr+len-1)+1)) \
+		                      - (1U << GET_ESID(addr))) & 0xffff)
+#define HTLB_AREA_MASK(addr, len)   (((1U << (GET_HTLB_AREA(addr+len-1)+1)) \
+		                      - (1U << GET_HTLB_AREA(addr))) & 0xffff)
+
+#define ARCH_HAS_HUGEPAGE_ONLY_RANGE
+#define ARCH_HAS_PREPARE_HUGEPAGE_RANGE
+#define ARCH_HAS_SETCLEAR_HUGE_PTE
+
+#define touches_hugepage_low_range(mm, addr, len) \
+	(LOW_ESID_MASK((addr), (len)) & (mm)->context.low_htlb_areas)
+#define touches_hugepage_high_range(mm, addr, len) \
+	(HTLB_AREA_MASK((addr), (len)) & (mm)->context.high_htlb_areas)
+
+#define __within_hugepage_low_range(addr, len, segmask) \
+	((LOW_ESID_MASK((addr), (len)) | (segmask)) == (segmask))
+#define within_hugepage_low_range(addr, len) \
+	__within_hugepage_low_range((addr), (len), \
+				    current->mm->context.low_htlb_areas)
+#define __within_hugepage_high_range(addr, len, zonemask) \
+	((HTLB_AREA_MASK((addr), (len)) | (zonemask)) == (zonemask))
+#define within_hugepage_high_range(addr, len) \
+	__within_hugepage_high_range((addr), (len), \
+				    current->mm->context.high_htlb_areas)
+
+#define is_hugepage_only_range(mm, addr, len) \
+	(touches_hugepage_high_range((mm), (addr), (len)) || \
+	  touches_hugepage_low_range((mm), (addr), (len)))
+#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+
+#define in_hugepage_area(context, addr) \
+	(cpu_has_feature(CPU_FTR_16M_PAGE) && \
+	 ( ((1 << GET_HTLB_AREA(addr)) & (context).high_htlb_areas) || \
+	   ( ((addr) < 0x100000000L) && \
+	     ((1 << GET_ESID(addr)) & (context).low_htlb_areas) ) ) )
+
+#else /* !CONFIG_HUGETLB_PAGE */
+
+#define in_hugepage_area(mm, addr)	0
+
+#endif /* !CONFIG_HUGETLB_PAGE */
+
+#ifdef MODULE
+#define __page_aligned __attribute__((__aligned__(PAGE_SIZE)))
+#else
+#define __page_aligned \
+	__attribute__((__aligned__(PAGE_SIZE), \
+		__section__(".data.page_aligned")))
+#endif
+
+#define VM_DATA_DEFAULT_FLAGS \
+	(test_thread_flag(TIF_32BIT) ? \
+	 VM_DATA_DEFAULT_FLAGS32 : VM_DATA_DEFAULT_FLAGS64)
+
+/*
+ * This is the default if a program doesn't have a PT_GNU_STACK
+ * program header entry. The PPC64 ELF ABI has a non executable stack
+ * stack by default, so in the absense of a PT_GNU_STACK program header
+ * we turn execute permission off.
+ */
+#define VM_STACK_DEFAULT_FLAGS32	(VM_READ | VM_WRITE | VM_EXEC | \
+					 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#define VM_STACK_DEFAULT_FLAGS64	(VM_READ | VM_WRITE | \
+					 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#define VM_STACK_DEFAULT_FLAGS \
+	(test_thread_flag(TIF_32BIT) ? \
+	 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
+
+#include <asm-generic/page.h>
+
+#endif /* _ASM_POWERPC_PAGE_64_H */
diff --git a/include/asm-powerpc/serial.h b/include/asm-powerpc/serial.h
new file mode 100644
index 0000000..b273d63
--- /dev/null
+++ b/include/asm-powerpc/serial.h
@@ -0,0 +1,18 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _ASM_POWERPC_SERIAL_H
+#define _ASM_POWERPC_SERIAL_H
+
+/*
+ * Serial ports are not listed here, because they are discovered
+ * through the device tree.
+ */
+
+/* Default baud base if not found in device-tree */
+#define BASE_BAUD ( 1843200 / 16 )
+
+#endif /* _PPC64_SERIAL_H */
diff --git a/include/asm-powerpc/vdso_datapage.h b/include/asm-powerpc/vdso_datapage.h
index fc323b5..411832d 100644
--- a/include/asm-powerpc/vdso_datapage.h
+++ b/include/asm-powerpc/vdso_datapage.h
@@ -73,7 +73,7 @@ struct vdso_data {
 	/* those additional ones don't have to be located anywhere
 	 * special as they were not part of the original systemcfg
 	 */
-	__s64 wtom_clock_sec;			/* Wall to monotonic clock */
+	__s32 wtom_clock_sec;			/* Wall to monotonic clock */
 	__s32 wtom_clock_nsec;
    	__u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls  */
    	__u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
diff --git a/include/asm-ppc/immap_85xx.h b/include/asm-ppc/immap_85xx.h
index 50fb5e4..9383d0c 100644
--- a/include/asm-ppc/immap_85xx.h
+++ b/include/asm-ppc/immap_85xx.h
@@ -3,7 +3,7 @@
  *
  * MPC85xx Internal Memory Map
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor, Inc
  *
diff --git a/include/asm-ppc/ipic.h b/include/asm-ppc/ipic.h
index 9092b92..0fe396a 100644
--- a/include/asm-ppc/ipic.h
+++ b/include/asm-ppc/ipic.h
@@ -3,7 +3,7 @@
  *
  * IPIC external definitions and structure.
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor, Inc
  *
diff --git a/include/asm-ppc/mpc83xx.h b/include/asm-ppc/mpc83xx.h
index ce21220..7cdf60f 100644
--- a/include/asm-ppc/mpc83xx.h
+++ b/include/asm-ppc/mpc83xx.h
@@ -3,7 +3,7 @@
  *
  * MPC83xx definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor, Inc
  *
diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
index d98db98..9d14bae 100644
--- a/include/asm-ppc/mpc85xx.h
+++ b/include/asm-ppc/mpc85xx.h
@@ -3,7 +3,7 @@
  *
  * MPC85xx definitions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor, Inc
  *
diff --git a/include/asm-ppc/nvram.h b/include/asm-ppc/nvram.h
deleted file mode 100644
index 31ef16e..0000000
--- a/include/asm-ppc/nvram.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * PreP compliant NVRAM access
- */
-
-#ifdef __KERNEL__
-#ifndef _PPC_NVRAM_H
-#define _PPC_NVRAM_H
-
-#define NVRAM_AS0  0x74
-#define NVRAM_AS1  0x75
-#define NVRAM_DATA 0x77
-
-
-/* RTC Offsets */
-
-#define MOTO_RTC_SECONDS		0x1FF9
-#define MOTO_RTC_MINUTES		0x1FFA
-#define MOTO_RTC_HOURS		0x1FFB
-#define MOTO_RTC_DAY_OF_WEEK		0x1FFC
-#define MOTO_RTC_DAY_OF_MONTH	0x1FFD
-#define MOTO_RTC_MONTH		0x1FFE
-#define MOTO_RTC_YEAR		0x1FFF
-#define MOTO_RTC_CONTROLA            0x1FF8
-#define MOTO_RTC_CONTROLB            0x1FF9
-
-/* PowerMac specific nvram stuffs */
-
-enum {
-	pmac_nvram_OF,		/* Open Firmware partition */
-	pmac_nvram_XPRAM,	/* MacOS XPRAM partition */
-	pmac_nvram_NR		/* MacOS Name Registry partition */
-};
-
-/* Return partition offset in nvram */
-extern int	pmac_get_partition(int partition);
-
-/* Direct access to XPRAM on PowerMacs */
-extern u8	pmac_xpram_read(int xpaddr);
-extern void	pmac_xpram_write(int xpaddr, u8 data);
-
-/* Synchronize NVRAM */
-extern void	nvram_sync(void);
-
-/* Normal access to NVRAM */
-extern unsigned char nvram_read_byte(int i);
-extern void nvram_write_byte(unsigned char c, int i);
-
-/* Some offsets in XPRAM */
-#define PMAC_XPRAM_MACHINE_LOC	0xe4
-#define PMAC_XPRAM_SOUND_VOLUME	0x08
-
-/* Machine location structure in PowerMac XPRAM */
-struct pmac_machine_location {
-	unsigned int	latitude;	/* 2+30 bit Fractional number */
-	unsigned int	longitude;	/* 2+30 bit Fractional number */
-	unsigned int	delta;		/* mix of GMT delta and DLS */
-};
-
-/*
- * /dev/nvram ioctls
- *
- * Note that PMAC_NVRAM_GET_OFFSET is still supported, but is
- * definitely obsolete. Do not use it if you can avoid it
- */
-
-#define OBSOLETE_PMAC_NVRAM_GET_OFFSET \
-				_IOWR('p', 0x40, int)
-
-#define IOC_NVRAM_GET_OFFSET	_IOWR('p', 0x42, int)	/* Get NVRAM partition offset */
-#define IOC_NVRAM_SYNC		_IO('p', 0x43)		/* Sync NVRAM image */
-
-#endif
-#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
index bba5305..83d8c77 100644
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -3,7 +3,7 @@
  *
  * PPC system definitions and library functions
  *
- * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2005 Freescale Semiconductor, Inc
  *
diff --git a/include/asm-ppc64/btext.h b/include/asm-ppc64/btext.h
deleted file mode 100644
index 71cce36..0000000
--- a/include/asm-ppc64/btext.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Definitions for using the procedures in btext.c.
- *
- * Benjamin Herrenschmidt <benh@kernel.crashing.org>
- */
-#ifndef __PPC_BTEXT_H
-#define __PPC_BTEXT_H
-#ifdef __KERNEL__
-
-extern void btext_clearscreen(void);
-extern void btext_flushscreen(void);
-
-extern int boot_text_mapped;
-
-extern int btext_initialize(struct device_node *np);
-
-extern void map_boot_text(void);
-extern void init_boot_display(void);
-extern void btext_update_display(unsigned long phys, int width, int height,
-				 int depth, int pitch);
-
-extern void btext_drawchar(char c);
-extern void btext_drawstring(const char *str);
-extern void btext_drawhex(unsigned long v);
-
-#endif /* __KERNEL__ */
-#endif /* __PPC_BTEXT_H */
diff --git a/include/asm-ppc64/delay.h b/include/asm-ppc64/delay.h
deleted file mode 100644
index 05f198c..0000000
--- a/include/asm-ppc64/delay.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef _PPC64_DELAY_H
-#define _PPC64_DELAY_H
-
-/*
- * Copyright 1996, Paul Mackerras.
- *
- * 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.
- *
- * PPC64 Support added by Dave Engebretsen, Todd Inglett, Mike Corrigan,
- * Anton Blanchard.
- */
-
-extern unsigned long tb_ticks_per_usec;
-
-/* define these here to prevent circular dependencies */ 
-#define __HMT_low()	asm volatile("or 1,1,1")
-#define __HMT_medium()	asm volatile("or 2,2,2")
-#define __barrier()	asm volatile("":::"memory")
-
-static inline unsigned long __get_tb(void)
-{
-	unsigned long rval;
-
-	asm volatile("mftb %0" : "=r" (rval));
-	return rval;
-}
-
-static inline void __delay(unsigned long loops)
-{
-	unsigned long start = __get_tb();
-
-	while((__get_tb()-start) < loops)
-		__HMT_low();
-	__HMT_medium();
-	__barrier();
-}
-
-static inline void udelay(unsigned long usecs)
-{
-	unsigned long loops = tb_ticks_per_usec * usecs;
-
-	__delay(loops);
-}
-
-#endif /* _PPC64_DELAY_H */
diff --git a/include/asm-ppc64/eeh.h b/include/asm-ppc64/eeh.h
deleted file mode 100644
index 89f26ab..0000000
--- a/include/asm-ppc64/eeh.h
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * eeh.h
- * Copyright (C) 2001  Dave Engebretsen & Todd Inglett IBM Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifndef _PPC64_EEH_H
-#define _PPC64_EEH_H
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/string.h>
-
-struct pci_dev;
-struct device_node;
-
-#ifdef CONFIG_EEH
-
-/* Values for eeh_mode bits in device_node */
-#define EEH_MODE_SUPPORTED	(1<<0)
-#define EEH_MODE_NOCHECK	(1<<1)
-#define EEH_MODE_ISOLATED	(1<<2)
-
-/* Max number of EEH freezes allowed before we consider the device
- * to be permanently disabled. */
-#define EEH_MAX_ALLOWED_FREEZES 5
-
-void __init eeh_init(void);
-unsigned long eeh_check_failure(const volatile void __iomem *token,
-				unsigned long val);
-int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev);
-void __init pci_addr_cache_build(void);
-
-/**
- * eeh_add_device_early
- * eeh_add_device_late
- *
- * Perform eeh initialization for devices added after boot.
- * Call eeh_add_device_early before doing any i/o to the
- * device (including config space i/o).  Call eeh_add_device_late
- * to finish the eeh setup for this device.
- */
-void eeh_add_device_early(struct device_node *);
-void eeh_add_device_late(struct pci_dev *);
-
-/**
- * eeh_remove_device - undo EEH setup for the indicated pci device
- * @dev: pci device to be removed
- *
- * This routine should be called when a device is removed from
- * a running system (e.g. by hotplug or dlpar).  It unregisters
- * the PCI device from the EEH subsystem.  I/O errors affecting
- * this device will no longer be detected after this call; thus,
- * i/o errors affecting this slot may leave this device unusable.
- */
-void eeh_remove_device(struct pci_dev *);
-
-/**
- * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
- *
- * If this macro yields TRUE, the caller relays to eeh_check_failure()
- * which does further tests out of line.
- */
-#define EEH_POSSIBLE_ERROR(val, type)	((val) == (type)~0)
-
-/*
- * Reads from a device which has been isolated by EEH will return
- * all 1s.  This macro gives an all-1s value of the given size (in
- * bytes: 1, 2, or 4) for comparing with the result of a read.
- */
-#define EEH_IO_ERROR_VALUE(size)	(~0U >> ((4 - (size)) * 8))
-
-#else /* !CONFIG_EEH */
-static inline void eeh_init(void) { }
-
-static inline unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val)
-{
-	return val;
-}
-
-static inline int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
-{
-	return 0;
-}
-
-static inline void pci_addr_cache_build(void) { }
-
-static inline void eeh_add_device_early(struct device_node *dn) { }
-
-static inline void eeh_add_device_late(struct pci_dev *dev) { }
-
-static inline void eeh_remove_device(struct pci_dev *dev) { }
-
-#define EEH_POSSIBLE_ERROR(val, type) (0)
-#define EEH_IO_ERROR_VALUE(size) (-1UL)
-#endif /* CONFIG_EEH */
-
-/*
- * MMIO read/write operations with EEH support.
- */
-static inline u8 eeh_readb(const volatile void __iomem *addr)
-{
-	u8 val = in_8(addr);
-	if (EEH_POSSIBLE_ERROR(val, u8))
-		return eeh_check_failure(addr, val);
-	return val;
-}
-static inline void eeh_writeb(u8 val, volatile void __iomem *addr)
-{
-	out_8(addr, val);
-}
-
-static inline u16 eeh_readw(const volatile void __iomem *addr)
-{
-	u16 val = in_le16(addr);
-	if (EEH_POSSIBLE_ERROR(val, u16))
-		return eeh_check_failure(addr, val);
-	return val;
-}
-static inline void eeh_writew(u16 val, volatile void __iomem *addr)
-{
-	out_le16(addr, val);
-}
-static inline u16 eeh_raw_readw(const volatile void __iomem *addr)
-{
-	u16 val = in_be16(addr);
-	if (EEH_POSSIBLE_ERROR(val, u16))
-		return eeh_check_failure(addr, val);
-	return val;
-}
-static inline void eeh_raw_writew(u16 val, volatile void __iomem *addr) {
-	volatile u16 __iomem *vaddr = (volatile u16 __iomem *) addr;
-	out_be16(vaddr, val);
-}
-
-static inline u32 eeh_readl(const volatile void __iomem *addr)
-{
-	u32 val = in_le32(addr);
-	if (EEH_POSSIBLE_ERROR(val, u32))
-		return eeh_check_failure(addr, val);
-	return val;
-}
-static inline void eeh_writel(u32 val, volatile void __iomem *addr)
-{
-	out_le32(addr, val);
-}
-static inline u32 eeh_raw_readl(const volatile void __iomem *addr)
-{
-	u32 val = in_be32(addr);
-	if (EEH_POSSIBLE_ERROR(val, u32))
-		return eeh_check_failure(addr, val);
-	return val;
-}
-static inline void eeh_raw_writel(u32 val, volatile void __iomem *addr)
-{
-	out_be32(addr, val);
-}
-
-static inline u64 eeh_readq(const volatile void __iomem *addr)
-{
-	u64 val = in_le64(addr);
-	if (EEH_POSSIBLE_ERROR(val, u64))
-		return eeh_check_failure(addr, val);
-	return val;
-}
-static inline void eeh_writeq(u64 val, volatile void __iomem *addr)
-{
-	out_le64(addr, val);
-}
-static inline u64 eeh_raw_readq(const volatile void __iomem *addr)
-{
-	u64 val = in_be64(addr);
-	if (EEH_POSSIBLE_ERROR(val, u64))
-		return eeh_check_failure(addr, val);
-	return val;
-}
-static inline void eeh_raw_writeq(u64 val, volatile void __iomem *addr)
-{
-	out_be64(addr, val);
-}
-
-#define EEH_CHECK_ALIGN(v,a) \
-	((((unsigned long)(v)) & ((a) - 1)) == 0)
-
-static inline void eeh_memset_io(volatile void __iomem *addr, int c,
-				 unsigned long n)
-{
-	void *p = (void __force *)addr;
-	u32 lc = c;
-	lc |= lc << 8;
-	lc |= lc << 16;
-
-	while(n && !EEH_CHECK_ALIGN(p, 4)) {
-		*((volatile u8 *)p) = c;
-		p++;
-		n--;
-	}
-	while(n >= 4) {
-		*((volatile u32 *)p) = lc;
-		p += 4;
-		n -= 4;
-	}
-	while(n) {
-		*((volatile u8 *)p) = c;
-		p++;
-		n--;
-	}
-	__asm__ __volatile__ ("sync" : : : "memory");
-}
-static inline void eeh_memcpy_fromio(void *dest, const volatile void __iomem *src,
-				     unsigned long n)
-{
-	void *vsrc = (void __force *) src;
-	void *destsave = dest;
-	unsigned long nsave = n;
-
-	while(n && (!EEH_CHECK_ALIGN(vsrc, 4) || !EEH_CHECK_ALIGN(dest, 4))) {
-		*((u8 *)dest) = *((volatile u8 *)vsrc);
-		__asm__ __volatile__ ("eieio" : : : "memory");
-		vsrc++;
-		dest++;
-		n--;
-	}
-	while(n > 4) {
-		*((u32 *)dest) = *((volatile u32 *)vsrc);
-		__asm__ __volatile__ ("eieio" : : : "memory");
-		vsrc += 4;
-		dest += 4;
-		n -= 4;
-	}
-	while(n) {
-		*((u8 *)dest) = *((volatile u8 *)vsrc);
-		__asm__ __volatile__ ("eieio" : : : "memory");
-		vsrc++;
-		dest++;
-		n--;
-	}
-	__asm__ __volatile__ ("sync" : : : "memory");
-
-	/* Look for ffff's here at dest[n].  Assume that at least 4 bytes
-	 * were copied. Check all four bytes.
-	 */
-	if ((nsave >= 4) &&
-		(EEH_POSSIBLE_ERROR((*((u32 *) destsave+nsave-4)), u32))) {
-		eeh_check_failure(src, (*((u32 *) destsave+nsave-4)));
-	}
-}
-
-static inline void eeh_memcpy_toio(volatile void __iomem *dest, const void *src,
-				   unsigned long n)
-{
-	void *vdest = (void __force *) dest;
-
-	while(n && (!EEH_CHECK_ALIGN(vdest, 4) || !EEH_CHECK_ALIGN(src, 4))) {
-		*((volatile u8 *)vdest) = *((u8 *)src);
-		src++;
-		vdest++;
-		n--;
-	}
-	while(n > 4) {
-		*((volatile u32 *)vdest) = *((volatile u32 *)src);
-		src += 4;
-		vdest += 4;
-		n-=4;
-	}
-	while(n) {
-		*((volatile u8 *)vdest) = *((u8 *)src);
-		src++;
-		vdest++;
-		n--;
-	}
-	__asm__ __volatile__ ("sync" : : : "memory");
-}
-
-#undef EEH_CHECK_ALIGN
-
-static inline u8 eeh_inb(unsigned long port)
-{
-	u8 val;
-	if (!_IO_IS_VALID(port))
-		return ~0;
-	val = in_8((u8 __iomem *)(port+pci_io_base));
-	if (EEH_POSSIBLE_ERROR(val, u8))
-		return eeh_check_failure((void __iomem *)(port), val);
-	return val;
-}
-
-static inline void eeh_outb(u8 val, unsigned long port)
-{
-	if (_IO_IS_VALID(port))
-		out_8((u8 __iomem *)(port+pci_io_base), val);
-}
-
-static inline u16 eeh_inw(unsigned long port)
-{
-	u16 val;
-	if (!_IO_IS_VALID(port))
-		return ~0;
-	val = in_le16((u16 __iomem *)(port+pci_io_base));
-	if (EEH_POSSIBLE_ERROR(val, u16))
-		return eeh_check_failure((void __iomem *)(port), val);
-	return val;
-}
-
-static inline void eeh_outw(u16 val, unsigned long port)
-{
-	if (_IO_IS_VALID(port))
-		out_le16((u16 __iomem *)(port+pci_io_base), val);
-}
-
-static inline u32 eeh_inl(unsigned long port)
-{
-	u32 val;
-	if (!_IO_IS_VALID(port))
-		return ~0;
-	val = in_le32((u32 __iomem *)(port+pci_io_base));
-	if (EEH_POSSIBLE_ERROR(val, u32))
-		return eeh_check_failure((void __iomem *)(port), val);
-	return val;
-}
-
-static inline void eeh_outl(u32 val, unsigned long port)
-{
-	if (_IO_IS_VALID(port))
-		out_le32((u32 __iomem *)(port+pci_io_base), val);
-}
-
-/* in-string eeh macros */
-static inline void eeh_insb(unsigned long port, void * buf, int ns)
-{
-	_insb((u8 __iomem *)(port+pci_io_base), buf, ns);
-	if (EEH_POSSIBLE_ERROR((*(((u8*)buf)+ns-1)), u8))
-		eeh_check_failure((void __iomem *)(port), *(u8*)buf);
-}
-
-static inline void eeh_insw_ns(unsigned long port, void * buf, int ns)
-{
-	_insw_ns((u16 __iomem *)(port+pci_io_base), buf, ns);
-	if (EEH_POSSIBLE_ERROR((*(((u16*)buf)+ns-1)), u16))
-		eeh_check_failure((void __iomem *)(port), *(u16*)buf);
-}
-
-static inline void eeh_insl_ns(unsigned long port, void * buf, int nl)
-{
-	_insl_ns((u32 __iomem *)(port+pci_io_base), buf, nl);
-	if (EEH_POSSIBLE_ERROR((*(((u32*)buf)+nl-1)), u32))
-		eeh_check_failure((void __iomem *)(port), *(u32*)buf);
-}
-
-#endif /* _PPC64_EEH_H */
diff --git a/include/asm-ppc64/floppy.h b/include/asm-ppc64/floppy.h
deleted file mode 100644
index 5c497b5..0000000
--- a/include/asm-ppc64/floppy.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Architecture specific parts of the Floppy driver
- *
- * 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) 1995
- */
-#ifndef __ASM_PPC64_FLOPPY_H
-#define __ASM_PPC64_FLOPPY_H
-
-#include <linux/config.h>
-#include <asm/machdep.h>
-
-#define fd_inb(port)			inb_p(port)
-#define fd_outb(value,port)		outb_p(value,port)
-
-#define fd_enable_dma()         enable_dma(FLOPPY_DMA)
-#define fd_disable_dma()        disable_dma(FLOPPY_DMA)
-#define fd_request_dma()        request_dma(FLOPPY_DMA,"floppy")
-#define fd_free_dma()           free_dma(FLOPPY_DMA)
-#define fd_clear_dma_ff()       clear_dma_ff(FLOPPY_DMA)
-#define fd_set_dma_mode(mode)   set_dma_mode(FLOPPY_DMA,mode)
-#define fd_set_dma_count(count) set_dma_count(FLOPPY_DMA,count)
-#define fd_enable_irq()         enable_irq(FLOPPY_IRQ)
-#define fd_disable_irq()        disable_irq(FLOPPY_IRQ)
-#define fd_cacheflush(addr,size) /* nothing */
-#define fd_request_irq()        request_irq(FLOPPY_IRQ, floppy_interrupt, \
-					    SA_INTERRUPT|SA_SAMPLE_RANDOM, \
-				            "floppy", NULL)
-#define fd_free_irq()           free_irq(FLOPPY_IRQ, NULL);
-
-#ifdef CONFIG_PCI
-
-#include <linux/pci.h>
-
-#define fd_dma_setup(addr,size,mode,io) ppc64_fd_dma_setup(addr,size,mode,io)
-
-static __inline__ int 
-ppc64_fd_dma_setup(char *addr, unsigned long size, int mode, int io)
-{
-	static unsigned long prev_size;
-	static dma_addr_t bus_addr = 0;
-	static char *prev_addr;
-	static int prev_dir;
-	int dir;
-
-	dir = (mode == DMA_MODE_READ) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE;
-
-	if (bus_addr 
-	    && (addr != prev_addr || size != prev_size || dir != prev_dir)) {
-		/* different from last time -- unmap prev */
-		pci_unmap_single(NULL, bus_addr, prev_size, prev_dir);
-		bus_addr = 0;
-	}
-
-	if (!bus_addr)	/* need to map it */ {
-		bus_addr = pci_map_single(NULL, addr, size, dir);
-	}
-
-	/* remember this one as prev */
-	prev_addr = addr;
-	prev_size = size;
-	prev_dir = dir;
-
-	fd_clear_dma_ff();
-	fd_cacheflush(addr, size);
-	fd_set_dma_mode(mode);
-	set_dma_addr(FLOPPY_DMA, bus_addr);
-	fd_set_dma_count(size);
-	virtual_dma_port = io;
-	fd_enable_dma();
-
-	return 0;
-}
-
-#endif /* CONFIG_PCI */
-
-__inline__ void virtual_dma_init(void)
-{
-	/* Nothing to do on PowerPC */
-}
-
-static int FDC1 = 0x3f0;
-static int FDC2 = -1;
-
-/*
- * Again, the CMOS information not available
- */
-#define FLOPPY0_TYPE 6
-#define FLOPPY1_TYPE 0
-
-#define N_FDC 2			/* Don't change this! */
-#define N_DRIVE 8
-
-#define FLOPPY_MOTOR_MASK 0xf0
-
-/*
- * The PowerPC has no problems with floppy DMA crossing 64k borders.
- */
-#define CROSS_64KB(a,s)	(0)
-
-#define EXTRA_FLOPPY_PARAMS
-
-#endif /* __ASM_PPC64_FLOPPY_H */
diff --git a/include/asm-ppc64/hvconsole.h b/include/asm-ppc64/hvconsole.h
deleted file mode 100644
index 6da93ce..0000000
--- a/include/asm-ppc64/hvconsole.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * hvconsole.h
- * Copyright (C) 2004 Ryan S Arnold, IBM Corporation
- *
- * LPAR console support.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifndef _PPC64_HVCONSOLE_H
-#define _PPC64_HVCONSOLE_H
-
-/*
- * This is the max number of console adapters that can/will be found as
- * console devices on first stage console init.  Any number beyond this range
- * can't be used as a console device but is still a valid tty device.
- */
-#define MAX_NR_HVC_CONSOLES	16
-
-/* implemented by a low level driver */
-struct hv_ops {
-	int (*get_chars)(uint32_t vtermno, char *buf, int count);
-	int (*put_chars)(uint32_t vtermno, const char *buf, int count);
-};
-extern int hvc_get_chars(uint32_t vtermno, char *buf, int count);
-extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count);
-
-struct hvc_struct;
-
-/* Register a vterm and a slot index for use as a console (console_init) */
-extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops);
-/* register a vterm for hvc tty operation (module_init or hotplug add) */
-extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
-						 struct hv_ops *ops);
-/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
-extern int __devexit hvc_remove(struct hvc_struct *hp);
-#endif /* _PPC64_HVCONSOLE_H */
diff --git a/include/asm-ppc64/hvcserver.h b/include/asm-ppc64/hvcserver.h
deleted file mode 100644
index aecba96..0000000
--- a/include/asm-ppc64/hvcserver.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * hvcserver.h
- * Copyright (C) 2004 Ryan S Arnold, IBM Corporation
- *
- * PPC64 virtual I/O console server support.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#ifndef _PPC64_HVCSERVER_H
-#define _PPC64_HVCSERVER_H
-
-#include <linux/list.h>
-
-/* Converged Location Code length */
-#define HVCS_CLC_LENGTH	79
-
-/**
- * hvcs_partner_info - an element in a list of partner info
- * @node: list_head denoting this partner_info struct's position in the list of
- *	partner info.
- * @unit_address: The partner unit address of this entry.
- * @partition_ID: The partner partition ID of this entry.
- * @location_code: The converged location code of this entry + 1 char for the
- *	null-term.
- *
- * This structure outlines the format that partner info is presented to a caller
- * of the hvcs partner info fetching functions.  These are strung together into
- * a list using linux kernel lists.
- */
-struct hvcs_partner_info {
-	struct list_head node;
-	uint32_t unit_address;
-	uint32_t partition_ID;
-	char location_code[HVCS_CLC_LENGTH + 1]; /* CLC + 1 null-term char */
-};
-
-extern int hvcs_free_partner_info(struct list_head *head);
-extern int hvcs_get_partner_info(uint32_t unit_address,
-		struct list_head *head, unsigned long *pi_buff);
-extern int hvcs_register_connection(uint32_t unit_address,
-		uint32_t p_partition_ID, uint32_t p_unit_address);
-extern int hvcs_free_connection(uint32_t unit_address);
-
-#endif /* _PPC64_HVCSERVER_H */
diff --git a/include/asm-ppc64/nvram.h b/include/asm-ppc64/nvram.h
deleted file mode 100644
index def47d7..0000000
--- a/include/asm-ppc64/nvram.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * PreP compliant NVRAM access
- * This needs to be updated for PPC64
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef _PPC64_NVRAM_H
-#define _PPC64_NVRAM_H
-
-#define NVRW_CNT 0x20
-#define NVRAM_HEADER_LEN 16 /* sizeof(struct nvram_header) */
-#define NVRAM_BLOCK_LEN 16
-#define NVRAM_MAX_REQ (2080/NVRAM_BLOCK_LEN)
-#define NVRAM_MIN_REQ (1056/NVRAM_BLOCK_LEN)
-
-#define NVRAM_AS0  0x74
-#define NVRAM_AS1  0x75
-#define NVRAM_DATA 0x77
-
-
-/* RTC Offsets */
-
-#define MOTO_RTC_SECONDS	0x1FF9
-#define MOTO_RTC_MINUTES	0x1FFA
-#define MOTO_RTC_HOURS		0x1FFB
-#define MOTO_RTC_DAY_OF_WEEK	0x1FFC
-#define MOTO_RTC_DAY_OF_MONTH	0x1FFD
-#define MOTO_RTC_MONTH		0x1FFE
-#define MOTO_RTC_YEAR		0x1FFF
-#define MOTO_RTC_CONTROLA       0x1FF8
-#define MOTO_RTC_CONTROLB       0x1FF9
-
-#define NVRAM_SIG_SP	0x02	/* support processor */
-#define NVRAM_SIG_OF	0x50	/* open firmware config */
-#define NVRAM_SIG_FW	0x51	/* general firmware */
-#define NVRAM_SIG_HW	0x52	/* hardware (VPD) */
-#define NVRAM_SIG_FLIP	0x5a	/* Apple flip/flop header */
-#define NVRAM_SIG_APPL	0x5f	/* Apple "system" (???) */
-#define NVRAM_SIG_SYS	0x70	/* system env vars */
-#define NVRAM_SIG_CFG	0x71	/* config data */
-#define NVRAM_SIG_ELOG	0x72	/* error log */
-#define NVRAM_SIG_VEND	0x7e	/* vendor defined */
-#define NVRAM_SIG_FREE	0x7f	/* Free space */
-#define NVRAM_SIG_OS	0xa0	/* OS defined */
-#define NVRAM_SIG_PANIC	0xa1	/* Apple OSX "panic" */
-
-/* If change this size, then change the size of NVNAME_LEN */
-struct nvram_header {
-	unsigned char signature;
-	unsigned char checksum;
-	unsigned short length;
-	char name[12];
-};
-
-struct nvram_partition {
-	struct list_head partition;
-	struct nvram_header header;
-	unsigned int index;
-};
-
-
-extern int nvram_write_error_log(char * buff, int length, unsigned int err_type);
-extern int nvram_read_error_log(char * buff, int length, unsigned int * err_type);
-extern int nvram_clear_error_log(void);
-extern struct nvram_partition *nvram_find_partition(int sig, const char *name);
-
-extern int pSeries_nvram_init(void);
-extern int pmac_nvram_init(void);
-extern int mmio_nvram_init(void);
-
-/* PowerMac specific nvram stuffs */
-
-enum {
-	pmac_nvram_OF,		/* Open Firmware partition */
-	pmac_nvram_XPRAM,	/* MacOS XPRAM partition */
-	pmac_nvram_NR		/* MacOS Name Registry partition */
-};
-
-/* Return partition offset in nvram */
-extern int	pmac_get_partition(int partition);
-
-/* Direct access to XPRAM on PowerMacs */
-extern u8	pmac_xpram_read(int xpaddr);
-extern void	pmac_xpram_write(int xpaddr, u8 data);
-
-/* Synchronize NVRAM */
-extern int	nvram_sync(void);
-
-/* Some offsets in XPRAM */
-#define PMAC_XPRAM_MACHINE_LOC	0xe4
-#define PMAC_XPRAM_SOUND_VOLUME	0x08
-
-/* Machine location structure in PowerMac XPRAM */
-struct pmac_machine_location {
-	unsigned int	latitude;	/* 2+30 bit Fractional number */
-	unsigned int	longitude;	/* 2+30 bit Fractional number */
-	unsigned int	delta;		/* mix of GMT delta and DLS */
-};
-
-/*
- * /dev/nvram ioctls
- *
- * Note that PMAC_NVRAM_GET_OFFSET is still supported, but is
- * definitely obsolete. Do not use it if you can avoid it
- */
-
-#define OBSOLETE_PMAC_NVRAM_GET_OFFSET \
-				_IOWR('p', 0x40, int)
-
-#define IOC_NVRAM_GET_OFFSET	_IOWR('p', 0x42, int)	/* Get NVRAM partition offset */
-
-#endif /* _PPC64_NVRAM_H */
diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h
deleted file mode 100644
index 3efc328..0000000
--- a/include/asm-ppc64/page.h
+++ /dev/null
@@ -1,328 +0,0 @@
-#ifndef _PPC64_PAGE_H
-#define _PPC64_PAGE_H
-
-/*
- * Copyright (C) 2001 PPC64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/config.h>
-#include <asm/asm-compat.h>
-
-/*
- * We support either 4k or 64k software page size. When using 64k pages
- * however, wether we are really supporting 64k pages in HW or not is
- * irrelevant to those definitions. We always define HW_PAGE_SHIFT to 12
- * as use of 64k pages remains a linux kernel specific, every notion of
- * page number shared with the firmware, TCEs, iommu, etc... still assumes
- * a page size of 4096.
- */
-#ifdef CONFIG_PPC_64K_PAGES
-#define PAGE_SHIFT		16
-#else
-#define PAGE_SHIFT		12
-#endif
-
-#define PAGE_SIZE		(ASM_CONST(1) << PAGE_SHIFT)
-#define PAGE_MASK		(~(PAGE_SIZE-1))
-
-/* HW_PAGE_SHIFT is always 4k pages */
-#define HW_PAGE_SHIFT		12
-#define HW_PAGE_SIZE		(ASM_CONST(1) << HW_PAGE_SHIFT)
-#define HW_PAGE_MASK		(~(HW_PAGE_SIZE-1))
-
-/* PAGE_FACTOR is the number of bits factor between PAGE_SHIFT and
- * HW_PAGE_SHIFT, that is 4k pages
- */
-#define PAGE_FACTOR		(PAGE_SHIFT - HW_PAGE_SHIFT)
-
-/* Segment size */
-#define SID_SHIFT       	28
-#define SID_MASK        	0xfffffffffUL
-#define ESID_MASK		0xfffffffff0000000UL
-#define GET_ESID(x)     	(((x) >> SID_SHIFT) & SID_MASK)
-
-/* Large pages size */
-
-#ifndef __ASSEMBLY__
-extern unsigned int HPAGE_SHIFT;
-#define HPAGE_SIZE		((1UL) << HPAGE_SHIFT)
-#define HPAGE_MASK		(~(HPAGE_SIZE - 1))
-#define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
-#endif /* __ASSEMBLY__ */
-
-#ifdef CONFIG_HUGETLB_PAGE
-
-
-#define HTLB_AREA_SHIFT		40
-#define HTLB_AREA_SIZE		(1UL << HTLB_AREA_SHIFT)
-#define GET_HTLB_AREA(x)	((x) >> HTLB_AREA_SHIFT)
-
-#define LOW_ESID_MASK(addr, len)    (((1U << (GET_ESID(addr+len-1)+1)) \
-	   	                      - (1U << GET_ESID(addr))) & 0xffff)
-#define HTLB_AREA_MASK(addr, len)   (((1U << (GET_HTLB_AREA(addr+len-1)+1)) \
-	   	                      - (1U << GET_HTLB_AREA(addr))) & 0xffff)
-
-#define ARCH_HAS_HUGEPAGE_ONLY_RANGE
-#define ARCH_HAS_PREPARE_HUGEPAGE_RANGE
-#define ARCH_HAS_SETCLEAR_HUGE_PTE
-
-#define touches_hugepage_low_range(mm, addr, len) \
-	(LOW_ESID_MASK((addr), (len)) & (mm)->context.low_htlb_areas)
-#define touches_hugepage_high_range(mm, addr, len) \
-	(HTLB_AREA_MASK((addr), (len)) & (mm)->context.high_htlb_areas)
-
-#define __within_hugepage_low_range(addr, len, segmask) \
-	((LOW_ESID_MASK((addr), (len)) | (segmask)) == (segmask))
-#define within_hugepage_low_range(addr, len) \
-	__within_hugepage_low_range((addr), (len), \
-				    current->mm->context.low_htlb_areas)
-#define __within_hugepage_high_range(addr, len, zonemask) \
-	((HTLB_AREA_MASK((addr), (len)) | (zonemask)) == (zonemask))
-#define within_hugepage_high_range(addr, len) \
-	__within_hugepage_high_range((addr), (len), \
-				    current->mm->context.high_htlb_areas)
-
-#define is_hugepage_only_range(mm, addr, len) \
-	(touches_hugepage_high_range((mm), (addr), (len)) || \
-	  touches_hugepage_low_range((mm), (addr), (len)))
-#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
-
-#define in_hugepage_area(context, addr) \
-	(cpu_has_feature(CPU_FTR_16M_PAGE) && \
-	 ( ((1 << GET_HTLB_AREA(addr)) & (context).high_htlb_areas) || \
-	   ( ((addr) < 0x100000000L) && \
-	     ((1 << GET_ESID(addr)) & (context).low_htlb_areas) ) ) )
-
-#else /* !CONFIG_HUGETLB_PAGE */
-
-#define in_hugepage_area(mm, addr)	0
-
-#endif /* !CONFIG_HUGETLB_PAGE */
-
-/* align addr on a size boundary - adjust address up/down if needed */
-#define _ALIGN_UP(addr,size)	(((addr)+((size)-1))&(~((size)-1)))
-#define _ALIGN_DOWN(addr,size)	((addr)&(~((size)-1)))
-
-/* align addr on a size boundary - adjust address up if needed */
-#define _ALIGN(addr,size)     _ALIGN_UP(addr,size)
-
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr)	_ALIGN(addr, PAGE_SIZE)
-
-#ifdef __KERNEL__
-#ifndef __ASSEMBLY__
-#include <asm/cache.h>
-
-#undef STRICT_MM_TYPECHECKS
-
-#define REGION_SIZE   4UL
-#define REGION_SHIFT  60UL
-#define REGION_MASK   (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT)
-
-static __inline__ void clear_page(void *addr)
-{
-	unsigned long lines, line_size;
-
-	line_size = ppc64_caches.dline_size;
-	lines = ppc64_caches.dlines_per_page;
-
-	__asm__ __volatile__(
-	"mtctr  	%1	# clear_page\n\
-1:      dcbz  	0,%0\n\
-	add	%0,%0,%3\n\
-	bdnz+	1b"
-        : "=r" (addr)
-        : "r" (lines), "0" (addr), "r" (line_size)
-	: "ctr", "memory");
-}
-
-extern void copy_4K_page(void *to, void *from);
-
-#ifdef CONFIG_PPC_64K_PAGES
-static inline void copy_page(void *to, void *from)
-{
-	unsigned int i;
-	for (i=0; i < (1 << (PAGE_SHIFT - 12)); i++) {
-		copy_4K_page(to, from);
-		to += 4096;
-		from += 4096;
-	}
-}
-#else /* CONFIG_PPC_64K_PAGES */
-static inline void copy_page(void *to, void *from)
-{
-	copy_4K_page(to, from);
-}
-#endif /* CONFIG_PPC_64K_PAGES */
-
-struct page;
-extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg);
-extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *p);
-
-#ifdef STRICT_MM_TYPECHECKS
-/*
- * These are used to make use of C type-checking.  
- * Entries in the pte table are 64b, while entries in the pgd & pmd are 32b.
- */
-
-/* PTE level */
-typedef struct { unsigned long pte; } pte_t;
-#define pte_val(x)	((x).pte)
-#define __pte(x)	((pte_t) { (x) })
-
-/* 64k pages additionally define a bigger "real PTE" type that gathers
- * the "second half" part of the PTE for pseudo 64k pages
- */
-#ifdef CONFIG_PPC_64K_PAGES
-typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
-#else
-typedef struct { pte_t pte; } real_pte_t;
-#endif
-
-/* PMD level */
-typedef struct { unsigned long pmd; } pmd_t;
-#define pmd_val(x)	((x).pmd)
-#define __pmd(x)	((pmd_t) { (x) })
-
-/* PUD level exusts only on 4k pages */
-#ifndef CONFIG_PPC_64K_PAGES
-typedef struct { unsigned long pud; } pud_t;
-#define pud_val(x)	((x).pud)
-#define __pud(x)	((pud_t) { (x) })
-#endif
-
-/* PGD level */
-typedef struct { unsigned long pgd; } pgd_t;
-#define pgd_val(x)	((x).pgd)
-#define __pgd(x)	((pgd_t) { (x) })
-
-/* Page protection bits */
-typedef struct { unsigned long pgprot; } pgprot_t;
-#define pgprot_val(x)	((x).pgprot)
-#define __pgprot(x)	((pgprot_t) { (x) })
-
-#else
-
-/*
- * .. while these make it easier on the compiler
- */
-
-typedef unsigned long pte_t;
-#define pte_val(x)	(x)
-#define __pte(x)	(x)
-
-#ifdef CONFIG_PPC_64K_PAGES
-typedef struct { pte_t pte; unsigned long hidx; } real_pte_t;
-#else
-typedef unsigned long real_pte_t;
-#endif
-
-
-typedef unsigned long pmd_t;
-#define pmd_val(x)	(x)
-#define __pmd(x)	(x)
-
-#ifndef CONFIG_PPC_64K_PAGES
-typedef unsigned long pud_t;
-#define pud_val(x)	(x)
-#define __pud(x)	(x)
-#endif
-
-typedef unsigned long pgd_t;
-#define pgd_val(x)	(x)
-#define pgprot_val(x)	(x)
-
-typedef unsigned long pgprot_t;
-#define __pgd(x)	(x)
-#define __pgprot(x)	(x)
-
-#endif
-
-#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
-
-extern int page_is_ram(unsigned long pfn);
-
-extern u64 ppc64_pft_size;		/* Log 2 of page table size */
-
-/* We do define AT_SYSINFO_EHDR but don't use the gate mecanism */
-#define __HAVE_ARCH_GATE_AREA		1
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef MODULE
-#define __page_aligned __attribute__((__aligned__(PAGE_SIZE)))
-#else
-#define __page_aligned \
-	__attribute__((__aligned__(PAGE_SIZE), \
-		__section__(".data.page_aligned")))
-#endif
-
-
-/* This must match the -Ttext linker address            */
-/* Note: tophys & tovirt make assumptions about how     */
-/*       KERNELBASE is defined for performance reasons. */
-/*       When KERNELBASE moves, those macros may have   */
-/*             to change!                               */
-#define PAGE_OFFSET     ASM_CONST(0xC000000000000000)
-#define KERNELBASE      PAGE_OFFSET
-#define VMALLOCBASE     ASM_CONST(0xD000000000000000)
-
-#define VMALLOC_REGION_ID  (VMALLOCBASE >> REGION_SHIFT)
-#define KERNEL_REGION_ID   (KERNELBASE >> REGION_SHIFT)
-#define USER_REGION_ID     (0UL)
-#define REGION_ID(ea)	   (((unsigned long)(ea)) >> REGION_SHIFT)
-
-#define __va(x) ((void *)((unsigned long)(x) + KERNELBASE))
-
-#ifdef CONFIG_FLATMEM
-#define pfn_to_page(pfn)	(mem_map + (pfn))
-#define page_to_pfn(page)	((unsigned long)((page) - mem_map))
-#define pfn_valid(pfn)		((pfn) < max_mapnr)
-#endif
-
-#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-#define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
-
-#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
-
-/*
- * Unfortunately the PLT is in the BSS in the PPC32 ELF ABI,
- * and needs to be executable.  This means the whole heap ends
- * up being executable.
- */
-#define VM_DATA_DEFAULT_FLAGS32	(VM_READ | VM_WRITE | VM_EXEC | \
-				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-#define VM_DATA_DEFAULT_FLAGS64	(VM_READ | VM_WRITE | \
-				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-#define VM_DATA_DEFAULT_FLAGS \
-	(test_thread_flag(TIF_32BIT) ? \
-	 VM_DATA_DEFAULT_FLAGS32 : VM_DATA_DEFAULT_FLAGS64)
-
-/*
- * This is the default if a program doesn't have a PT_GNU_STACK
- * program header entry. The PPC64 ELF ABI has a non executable stack
- * stack by default, so in the absense of a PT_GNU_STACK program header
- * we turn execute permission off.
- */
-#define VM_STACK_DEFAULT_FLAGS32	(VM_READ | VM_WRITE | VM_EXEC | \
-					 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-#define VM_STACK_DEFAULT_FLAGS64	(VM_READ | VM_WRITE | \
-					 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-#define VM_STACK_DEFAULT_FLAGS \
-	(test_thread_flag(TIF_32BIT) ? \
-	 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
-
-#endif /* __KERNEL__ */
-
-#include <asm-generic/page.h>
-
-#endif /* _PPC64_PAGE_H */
diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h
deleted file mode 100644
index ddfe186..0000000
--- a/include/asm-ppc64/prom.h
+++ /dev/null
@@ -1,220 +0,0 @@
-#ifndef _PPC64_PROM_H
-#define _PPC64_PROM_H
-
-/*
- * Definitions for talking to the Open Firmware PROM on
- * Power Macintosh computers.
- *
- * Copyright (C) 1996 Paul Mackerras.
- *
- * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <linux/config.h>
-#include <linux/proc_fs.h>
-#include <asm/atomic.h>
-
-#define PTRRELOC(x)     ((typeof(x))((unsigned long)(x) - offset))
-#define PTRUNRELOC(x)   ((typeof(x))((unsigned long)(x) + offset))
-#define RELOC(x)        (*PTRRELOC(&(x)))
-
-/* Definitions used by the flattened device tree */
-#define OF_DT_HEADER		0xd00dfeed	/* marker */
-#define OF_DT_BEGIN_NODE	0x1		/* Start of node, full name */
-#define OF_DT_END_NODE		0x2		/* End node */
-#define OF_DT_PROP		0x3		/* Property: name off, size,
-						 * content */
-#define OF_DT_NOP		0x4		/* nop */
-#define OF_DT_END		0x9
-
-#define OF_DT_VERSION		0x10
-
-/*
- * This is what gets passed to the kernel by prom_init or kexec
- *
- * The dt struct contains the device tree structure, full pathes and
- * property contents. The dt strings contain a separate block with just
- * the strings for the property names, and is fully page aligned and
- * self contained in a page, so that it can be kept around by the kernel,
- * each property name appears only once in this page (cheap compression)
- *
- * the mem_rsvmap contains a map of reserved ranges of physical memory,
- * passing it here instead of in the device-tree itself greatly simplifies
- * the job of everybody. It's just a list of u64 pairs (base/size) that
- * ends when size is 0
- */
-struct boot_param_header
-{
-	u32	magic;			/* magic word OF_DT_HEADER */
-	u32	totalsize;		/* total size of DT block */
-	u32	off_dt_struct;		/* offset to structure */
-	u32	off_dt_strings;		/* offset to strings */
-	u32	off_mem_rsvmap;		/* offset to memory reserve map */
-	u32	version;		/* format version */
-	u32	last_comp_version;	/* last compatible version */
-	/* version 2 fields below */
-	u32	boot_cpuid_phys;	/* Physical CPU id we're booting on */
-	/* version 3 fields below */
-	u32	dt_strings_size;	/* size of the DT strings block */
-};
-
-
-
-typedef u32 phandle;
-typedef u32 ihandle;
-
-struct address_range {
-	unsigned long space;
-	unsigned long address;
-	unsigned long size;
-};
-
-struct interrupt_info {
-	int	line;
-	int	sense;		/* +ve/-ve logic, edge or level, etc. */
-};
-
-struct pci_address {
-	u32 a_hi;
-	u32 a_mid;
-	u32 a_lo;
-};
-
-struct isa_address {
-	u32 a_hi;
-	u32 a_lo;
-};
-
-struct isa_range {
-	struct isa_address isa_addr;
-	struct pci_address pci_addr;
-	unsigned int size;
-};
-
-struct reg_property {
-	unsigned long address;
-	unsigned long size;
-};
-
-struct reg_property32 {
-	unsigned int address;
-	unsigned int size;
-};
-
-struct reg_property64 {
-	unsigned long address;
-	unsigned long size;
-};
-
-struct property {
-	char	*name;
-	int	length;
-	unsigned char *value;
-	struct property *next;
-};
-
-struct device_node {
-	char	*name;
-	char	*type;
-	phandle	node;
-	phandle linux_phandle;
-	int	n_addrs;
-	struct	address_range *addrs;
-	int	n_intrs;
-	struct	interrupt_info *intrs;
-	char	*full_name;
-
-	struct	property *properties;
-	struct	device_node *parent;
-	struct	device_node *child;
-	struct	device_node *sibling;
-	struct	device_node *next;	/* next device of same type */
-	struct	device_node *allnext;	/* next in list of all nodes */
-	struct  proc_dir_entry *pde;	/* this node's proc directory */
-	struct  kref kref;
-	unsigned long _flags;
-	void	*data;
-#ifdef CONFIG_PPC_ISERIES
-	struct list_head Device_List;
-#endif
-};
-
-extern struct device_node *of_chosen;
-
-/* flag descriptions */
-#define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */
-
-#define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
-#define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
-
-/*
- * Until 32-bit ppc can add proc_dir_entries to its device_node
- * definition, we cannot refer to pde, name_link, and addr_link
- * in arch-independent code.
- */
-#define HAVE_ARCH_DEVTREE_FIXUPS
-
-static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
-{
-	dn->pde = de;
-}
-
-
-/* OBSOLETE: Old stlye node lookup */
-extern struct device_node *find_devices(const char *name);
-extern struct device_node *find_type_devices(const char *type);
-extern struct device_node *find_path_device(const char *path);
-extern struct device_node *find_compatible_devices(const char *type,
-						   const char *compat);
-extern struct device_node *find_all_nodes(void);
-
-/* New style node lookup */
-extern struct device_node *of_find_node_by_name(struct device_node *from,
-	const char *name);
-extern struct device_node *of_find_node_by_type(struct device_node *from,
-	const char *type);
-extern struct device_node *of_find_compatible_node(struct device_node *from,
-	const char *type, const char *compat);
-extern struct device_node *of_find_node_by_path(const char *path);
-extern struct device_node *of_find_node_by_phandle(phandle handle);
-extern struct device_node *of_find_all_nodes(struct device_node *prev);
-extern struct device_node *of_get_parent(const struct device_node *node);
-extern struct device_node *of_get_next_child(const struct device_node *node,
-					     struct device_node *prev);
-extern struct device_node *of_node_get(struct device_node *node);
-extern void of_node_put(struct device_node *node);
-
-/* For scanning the flat device-tree at boot time */
-int __init of_scan_flat_dt(int (*it)(unsigned long node,
-				     const char *uname, int depth,
-				     void *data),
-			   void *data);
-void* __init of_get_flat_dt_prop(unsigned long node, const char *name,
-				 unsigned long *size);
-
-/* For updating the device tree at runtime */
-extern void of_attach_node(struct device_node *);
-extern void of_detach_node(const struct device_node *);
-
-/* Other Prototypes */
-extern unsigned long prom_init(unsigned long, unsigned long, unsigned long,
-	unsigned long, unsigned long);
-extern void finish_device_tree(void);
-extern void unflatten_device_tree(void);
-extern void early_init_devtree(void *);
-extern int device_is_compatible(struct device_node *device, const char *);
-extern int machine_is_compatible(const char *compat);
-extern unsigned char *get_property(struct device_node *node, const char *name,
-				   int *lenp);
-extern void print_properties(struct device_node *node);
-extern int prom_n_addr_cells(struct device_node* np);
-extern int prom_n_size_cells(struct device_node* np);
-extern int prom_n_intr_cells(struct device_node* np);
-extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
-extern int prom_add_property(struct device_node* np, struct property* prop);
-
-#endif /* _PPC64_PROM_H */
diff --git a/include/asm-ppc64/serial.h b/include/asm-ppc64/serial.h
deleted file mode 100644
index d6bcb79..0000000
--- a/include/asm-ppc64/serial.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * include/asm-ppc64/serial.h
- */
-#ifndef _PPC64_SERIAL_H
-#define _PPC64_SERIAL_H
-
-/*
- * This assumes you have a 1.8432 MHz clock for your UART.
- *
- * It'd be nice if someone built a serial card with a 24.576 MHz
- * clock, since the 16550A is capable of handling a top speed of 1.5
- * megabits/second; but this requires the faster clock.
- *
- * 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.
- */
-
-/* Default baud base if not found in device-tree */
-#define BASE_BAUD ( 1843200 / 16 )
-
-#endif /* _PPC64_SERIAL_H */
diff --git a/include/asm-ppc64/system.h b/include/asm-ppc64/system.h
deleted file mode 100644
index bf9a6ab..0000000
--- a/include/asm-ppc64/system.h
+++ /dev/null
@@ -1,310 +0,0 @@
-#ifndef __PPC64_SYSTEM_H
-#define __PPC64_SYSTEM_H
-
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/config.h>
-#include <linux/compiler.h>
-#include <asm/page.h>
-#include <asm/processor.h>
-#include <asm/hw_irq.h>
-#include <asm/synch.h>
-
-/*
- * Memory barrier.
- * The sync instruction guarantees that all memory accesses initiated
- * by this processor have been performed (with respect to all other
- * mechanisms that access memory).  The eieio instruction is a barrier
- * providing an ordering (separately) for (a) cacheable stores and (b)
- * loads and stores to non-cacheable memory (e.g. I/O devices).
- *
- * mb() prevents loads and stores being reordered across this point.
- * rmb() prevents loads being reordered across this point.
- * wmb() prevents stores being reordered across this point.
- * read_barrier_depends() prevents data-dependent loads being reordered
- *	across this point (nop on PPC).
- *
- * We have to use the sync instructions for mb(), since lwsync doesn't
- * order loads with respect to previous stores.  Lwsync is fine for
- * rmb(), though.
- * For wmb(), we use sync since wmb is used in drivers to order
- * stores to system memory with respect to writes to the device.
- * However, smp_wmb() can be a lighter-weight eieio barrier on
- * SMP since it is only used to order updates to system memory.
- */
-#define mb()   __asm__ __volatile__ ("sync" : : : "memory")
-#define rmb()  __asm__ __volatile__ ("lwsync" : : : "memory")
-#define wmb()  __asm__ __volatile__ ("sync" : : : "memory")
-#define read_barrier_depends()  do { } while(0)
-
-#define set_mb(var, value)	do { var = value; smp_mb(); } while (0)
-#define set_wmb(var, value)	do { var = value; smp_wmb(); } while (0)
-
-#ifdef CONFIG_SMP
-#define smp_mb()	mb()
-#define smp_rmb()	rmb()
-#define smp_wmb()	eieio()
-#define smp_read_barrier_depends()  read_barrier_depends()
-#else
-#define smp_mb()	__asm__ __volatile__("": : :"memory")
-#define smp_rmb()	__asm__ __volatile__("": : :"memory")
-#define smp_wmb()	__asm__ __volatile__("": : :"memory")
-#define smp_read_barrier_depends()  do { } while(0)
-#endif /* CONFIG_SMP */
-
-#ifdef __KERNEL__
-struct task_struct;
-struct pt_regs;
-
-#ifdef CONFIG_DEBUGGER
-
-extern int (*__debugger)(struct pt_regs *regs);
-extern int (*__debugger_ipi)(struct pt_regs *regs);
-extern int (*__debugger_bpt)(struct pt_regs *regs);
-extern int (*__debugger_sstep)(struct pt_regs *regs);
-extern int (*__debugger_iabr_match)(struct pt_regs *regs);
-extern int (*__debugger_dabr_match)(struct pt_regs *regs);
-extern int (*__debugger_fault_handler)(struct pt_regs *regs);
-
-#define DEBUGGER_BOILERPLATE(__NAME) \
-static inline int __NAME(struct pt_regs *regs) \
-{ \
-	if (unlikely(__ ## __NAME)) \
-		return __ ## __NAME(regs); \
-	return 0; \
-}
-
-DEBUGGER_BOILERPLATE(debugger)
-DEBUGGER_BOILERPLATE(debugger_ipi)
-DEBUGGER_BOILERPLATE(debugger_bpt)
-DEBUGGER_BOILERPLATE(debugger_sstep)
-DEBUGGER_BOILERPLATE(debugger_iabr_match)
-DEBUGGER_BOILERPLATE(debugger_dabr_match)
-DEBUGGER_BOILERPLATE(debugger_fault_handler)
-
-#ifdef CONFIG_XMON
-extern void xmon_init(int enable);
-#endif
-
-#else
-static inline int debugger(struct pt_regs *regs) { return 0; }
-static inline int debugger_ipi(struct pt_regs *regs) { return 0; }
-static inline int debugger_bpt(struct pt_regs *regs) { return 0; }
-static inline int debugger_sstep(struct pt_regs *regs) { return 0; }
-static inline int debugger_iabr_match(struct pt_regs *regs) { return 0; }
-static inline int debugger_dabr_match(struct pt_regs *regs) { return 0; }
-static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; }
-#endif
-
-extern int set_dabr(unsigned long dabr);
-extern void _exception(int signr, struct pt_regs *regs, int code,
-		       unsigned long addr);
-extern int fix_alignment(struct pt_regs *regs);
-extern void bad_page_fault(struct pt_regs *regs, unsigned long address,
-			   int sig);
-extern void show_regs(struct pt_regs * regs);
-extern void low_hash_fault(struct pt_regs *regs, unsigned long address);
-extern int die(const char *str, struct pt_regs *regs, long err);
-
-extern int _get_PVR(void);
-extern void giveup_fpu(struct task_struct *);
-extern void disable_kernel_fp(void);
-extern void flush_fp_to_thread(struct task_struct *);
-extern void enable_kernel_fp(void);
-extern void giveup_altivec(struct task_struct *);
-extern void disable_kernel_altivec(void);
-extern void enable_kernel_altivec(void);
-extern int emulate_altivec(struct pt_regs *);
-extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
-extern void cvt_df(double *from, float *to, struct thread_struct *thread);
-
-#ifdef CONFIG_ALTIVEC
-extern void flush_altivec_to_thread(struct task_struct *);
-#else
-static inline void flush_altivec_to_thread(struct task_struct *t)
-{
-}
-#endif
-
-static inline void flush_spe_to_thread(struct task_struct *t)
-{
-}
-
-extern int mem_init_done;	/* set on boot once kmalloc can be called */
-extern unsigned long memory_limit;
-
-/* EBCDIC -> ASCII conversion for [0-9A-Z] on iSeries */
-extern unsigned char e2a(unsigned char);
-
-extern struct task_struct *__switch_to(struct task_struct *,
-				       struct task_struct *);
-#define switch_to(prev, next, last)	((last) = __switch_to((prev), (next)))
-
-struct thread_struct;
-extern struct task_struct * _switch(struct thread_struct *prev,
-				    struct thread_struct *next);
-
-extern unsigned long klimit;
-
-extern int powersave_nap;	/* set if nap mode can be used in idle loop */
-
-/*
- * Atomic exchange
- *
- * Changes the memory location '*ptr' to be val and returns
- * the previous value stored there.
- *
- * Inline asm pulled from arch/ppc/kernel/misc.S so ppc64
- * is more like most of the other architectures.
- */
-static __inline__ unsigned long
-__xchg_u32(volatile unsigned int *m, unsigned long val)
-{
-	unsigned long dummy;
-
-	__asm__ __volatile__(
-	EIEIO_ON_SMP
-"1:	lwarx %0,0,%3		# __xchg_u32\n\
-	stwcx. %2,0,%3\n\
-2:	bne- 1b"
-	ISYNC_ON_SMP
- 	: "=&r" (dummy), "=m" (*m)
-	: "r" (val), "r" (m)
-	: "cc", "memory");
-
-	return (dummy);
-}
-
-static __inline__ unsigned long
-__xchg_u64(volatile long *m, unsigned long val)
-{
-	unsigned long dummy;
-
-	__asm__ __volatile__(
-	EIEIO_ON_SMP
-"1:	ldarx %0,0,%3		# __xchg_u64\n\
-	stdcx. %2,0,%3\n\
-2:	bne- 1b"
-	ISYNC_ON_SMP
-	: "=&r" (dummy), "=m" (*m)
-	: "r" (val), "r" (m)
-	: "cc", "memory");
-
-	return (dummy);
-}
-
-/*
- * This function doesn't exist, so you'll get a linker error
- * if something tries to do an invalid xchg().
- */
-extern void __xchg_called_with_bad_pointer(void);
-
-static __inline__ unsigned long
-__xchg(volatile void *ptr, unsigned long x, unsigned int size)
-{
-	switch (size) {
-	case 4:
-		return __xchg_u32(ptr, x);
-	case 8:
-		return __xchg_u64(ptr, x);
-	}
-	__xchg_called_with_bad_pointer();
-	return x;
-}
-
-#define xchg(ptr,x)							     \
-  ({									     \
-     __typeof__(*(ptr)) _x_ = (x);					     \
-     (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
-  })
-
-#define tas(ptr) (xchg((ptr),1))
-
-#define __HAVE_ARCH_CMPXCHG	1
-
-static __inline__ unsigned long
-__cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
-{
-	unsigned int prev;
-
-	__asm__ __volatile__ (
-	EIEIO_ON_SMP
-"1:	lwarx	%0,0,%2		# __cmpxchg_u32\n\
-	cmpw	0,%0,%3\n\
-	bne-	2f\n\
-	stwcx.	%4,0,%2\n\
-	bne-	1b"
-	ISYNC_ON_SMP
-	"\n\
-2:"
-	: "=&r" (prev), "=m" (*p)
-	: "r" (p), "r" (old), "r" (new), "m" (*p)
-	: "cc", "memory");
-
-	return prev;
-}
-
-static __inline__ unsigned long
-__cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new)
-{
-	unsigned long prev;
-
-	__asm__ __volatile__ (
-	EIEIO_ON_SMP
-"1:	ldarx	%0,0,%2		# __cmpxchg_u64\n\
-	cmpd	0,%0,%3\n\
-	bne-	2f\n\
-	stdcx.	%4,0,%2\n\
-	bne-	1b"
-	ISYNC_ON_SMP
-	"\n\
-2:"
-	: "=&r" (prev), "=m" (*p)
-	: "r" (p), "r" (old), "r" (new), "m" (*p)
-	: "cc", "memory");
-
-	return prev;
-}
-
-/* This function doesn't exist, so you'll get a linker error
-   if something tries to do an invalid cmpxchg().  */
-extern void __cmpxchg_called_with_bad_pointer(void);
-
-static __inline__ unsigned long
-__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
-	  unsigned int size)
-{
-	switch (size) {
-	case 4:
-		return __cmpxchg_u32(ptr, old, new);
-	case 8:
-		return __cmpxchg_u64(ptr, old, new);
-	}
-	__cmpxchg_called_with_bad_pointer();
-	return old;
-}
-
-#define cmpxchg(ptr,o,n)\
-	((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
-	(unsigned long)(n),sizeof(*(ptr))))
-
-/*
- * We handle most unaligned accesses in hardware. On the other hand 
- * unaligned DMA can be very expensive on some ppc64 IO chips (it does
- * powers of 2 writes until it reaches sufficient alignment).
- *
- * Based on this we disable the IP header alignment in network drivers.
- */
-#define NET_IP_ALIGN   0
-
-#define arch_align_stack(x) (x)
-
-extern unsigned long reloc_offset(void);
-
-#endif /* __KERNEL__ */
-#endif
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h
index 9d86ba6..b3bd4f6 100644
--- a/include/asm-s390/atomic.h
+++ b/include/asm-s390/atomic.h
@@ -198,6 +198,18 @@ atomic_compare_and_swap(int expected_old
         return retval;
 }
 
+#define atomic_cmpxchg(v, o, n) (atomic_compare_and_swap((o), (n), &((v)->counter)))
+
+#define atomic_add_unless(v, a, u)				\
+({								\
+	int c, old;						\
+	c = atomic_read(v);					\
+	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+		c = old;					\
+	c != (u);						\
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 #define smp_mb__before_atomic_dec()	smp_mb()
 #define smp_mb__after_atomic_dec()	smp_mb()
 #define smp_mb__before_atomic_inc()	smp_mb()
diff --git a/include/asm-sh/atomic.h b/include/asm-sh/atomic.h
index 3c4f805..aabfd33 100644
--- a/include/asm-sh/atomic.h
+++ b/include/asm-sh/atomic.h
@@ -87,6 +87,35 @@ static __inline__ int atomic_sub_return(
 #define atomic_inc(v) atomic_add(1,(v))
 #define atomic_dec(v) atomic_sub(1,(v))
 
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+	int ret;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ret = v->counter;
+	if (likely(ret == old))
+		v->counter = new;
+	local_irq_restore(flags);
+
+	return ret;
+}
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int ret;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ret = v->counter;
+	if (ret != u)
+		v->counter += a;
+	local_irq_restore(flags);
+
+	return ret != u;
+}
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 static __inline__ void atomic_clear_mask(unsigned int mask, atomic_t *v)
 {
 	unsigned long flags;
diff --git a/include/asm-sh64/atomic.h b/include/asm-sh64/atomic.h
index 8c3872d..927a2bc 100644
--- a/include/asm-sh64/atomic.h
+++ b/include/asm-sh64/atomic.h
@@ -99,6 +99,35 @@ static __inline__ int atomic_sub_return(
 #define atomic_inc(v) atomic_add(1,(v))
 #define atomic_dec(v) atomic_sub(1,(v))
 
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+	int ret;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ret = v->counter;
+	if (likely(ret == old))
+		v->counter = new;
+	local_irq_restore(flags);
+
+	return ret;
+}
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int ret;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ret = v->counter;
+	if (ret != u)
+		v->counter += a;
+	local_irq_restore(flags);
+
+	return ret != u;
+}
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 static __inline__ void atomic_clear_mask(unsigned int mask, atomic_t *v)
 {
 	unsigned long flags;
diff --git a/include/asm-sparc/atomic.h b/include/asm-sparc/atomic.h
index 37f6ab6..62bec7a 100644
--- a/include/asm-sparc/atomic.h
+++ b/include/asm-sparc/atomic.h
@@ -19,6 +19,8 @@ typedef struct { volatile int counter; }
 #define ATOMIC_INIT(i)  { (i) }
 
 extern int __atomic_add_return(int, atomic_t *);
+extern int atomic_cmpxchg(atomic_t *, int, int);
+extern int atomic_add_unless(atomic_t *, int, int);
 extern void atomic_set(atomic_t *, int);
 
 #define atomic_read(v)          ((v)->counter)
@@ -48,6 +50,8 @@ extern void atomic_set(atomic_t *, int);
 #define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
 #define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
 
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 /* This is the old 24-bit implementation.  It's still used internally
  * by some sparc-specific code, notably the semaphore implementation.
  */
diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h
index e175afc..8198c3d 100644
--- a/include/asm-sparc64/atomic.h
+++ b/include/asm-sparc64/atomic.h
@@ -70,6 +70,18 @@ extern int atomic64_sub_ret(int, atomic6
 #define atomic_add_negative(i, v) (atomic_add_ret(i, v) < 0)
 #define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0)
 
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
+#define atomic_add_unless(v, a, u)				\
+({								\
+	int c, old;						\
+	c = atomic_read(v);					\
+	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+		c = old;					\
+	c != (u);						\
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 /* Atomic operations are already serializing */
 #ifdef CONFIG_SMP
 #define smp_mb__before_atomic_dec()	membar_storeload_loadload();
diff --git a/include/asm-v850/atomic.h b/include/asm-v850/atomic.h
index 395268a..bede317 100644
--- a/include/asm-v850/atomic.h
+++ b/include/asm-v850/atomic.h
@@ -90,6 +90,36 @@ static __inline__ void atomic_clear_mask
 #define atomic_dec_and_test(v)		(atomic_sub_return (1, (v)) == 0)
 #define atomic_add_negative(i,v)	(atomic_add_return ((i), (v)) < 0)
 
+static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+	int ret;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ret = v->counter;
+	if (likely(ret == old))
+		v->counter = new;
+	local_irq_restore(flags);
+
+	return ret;
+}
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int ret;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ret = v->counter;
+	if (ret != u)
+		v->counter += a;
+	local_irq_restore(flags);
+
+	return ret != u;
+}
+
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 /* Atomic operations are already serializing on ARM */
 #define smp_mb__before_atomic_dec()	barrier()
 #define smp_mb__after_atomic_dec()	barrier()
diff --git a/include/asm-v850/hardirq.h b/include/asm-v850/hardirq.h
index 5dfca80..d98488c 100644
--- a/include/asm-v850/hardirq.h
+++ b/include/asm-v850/hardirq.h
@@ -5,6 +5,8 @@
 #include <linux/threads.h>
 #include <linux/cache.h>
 
+#include <asm/irq.h>
+
 typedef struct {
 	unsigned int __softirq_pending;
 } ____cacheline_aligned irq_cpustat_t;
@@ -22,4 +24,6 @@ typedef struct {
 # error HARDIRQ_BITS is too low!
 #endif
 
+void ack_bad_irq(unsigned int irq);
+
 #endif /* __V850_HARDIRQ_H__ */
diff --git a/include/asm-x86_64/apic.h b/include/asm-x86_64/apic.h
index 6c5d5ca..5647b7d 100644
--- a/include/asm-x86_64/apic.h
+++ b/include/asm-x86_64/apic.h
@@ -111,6 +111,8 @@ extern unsigned int nmi_watchdog;
 
 extern int disable_timer_pin_1;
 
+extern void setup_threshold_lvt(unsigned long lvt_off);
+
 #endif /* CONFIG_X86_LOCAL_APIC */
 
 extern unsigned boot_cpu_id;
diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86_64/atomic.h
index fc4c595..0866ef6 100644
--- a/include/asm-x86_64/atomic.h
+++ b/include/asm-x86_64/atomic.h
@@ -360,6 +360,27 @@ static __inline__ int atomic_sub_return(
 	return atomic_add_return(-i,v);
 }
 
+#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+
+/**
+ * atomic_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+#define atomic_add_unless(v, a, u)				\
+({								\
+	int c, old;						\
+	c = atomic_read(v);					\
+	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+		c = old;					\
+	c != (u);						\
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 #define atomic_inc_return(v)  (atomic_add_return(1,v))
 #define atomic_dec_return(v)  (atomic_sub_return(1,v))
 
diff --git a/include/asm-x86_64/cache.h b/include/asm-x86_64/cache.h
index eda62ba..33e5342 100644
--- a/include/asm-x86_64/cache.h
+++ b/include/asm-x86_64/cache.h
@@ -9,6 +9,6 @@
 /* L1 cache line size */
 #define L1_CACHE_SHIFT	(CONFIG_X86_L1_CACHE_SHIFT)
 #define L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
-#define L1_CACHE_SHIFT_MAX 6	/* largest L1 which this arch supports */
+#define L1_CACHE_SHIFT_MAX 7	/* largest L1 which this arch supports */
 
 #endif
diff --git a/include/asm-x86_64/desc.h b/include/asm-x86_64/desc.h
index 68ac3c6..3376486 100644
--- a/include/asm-x86_64/desc.h
+++ b/include/asm-x86_64/desc.h
@@ -98,16 +98,19 @@ static inline void _set_gate(void *adr, 
 
 static inline void set_intr_gate(int nr, void *func) 
 { 
+	BUG_ON((unsigned)nr > 0xFF);
 	_set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, 0); 
 } 
 
 static inline void set_intr_gate_ist(int nr, void *func, unsigned ist) 
 { 
+	BUG_ON((unsigned)nr > 0xFF);
 	_set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 0, ist); 
 } 
 
 static inline void set_system_gate(int nr, void *func) 
 { 
+	BUG_ON((unsigned)nr > 0xFF);
 	_set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, 0); 
 } 
 
@@ -129,9 +132,16 @@ static inline void set_tssldt_descriptor
 
 static inline void set_tss_desc(unsigned cpu, void *addr)
 { 
-	set_tssldt_descriptor(&cpu_gdt_table[cpu][GDT_ENTRY_TSS], (unsigned long)addr, 
-			      DESC_TSS,
-			      sizeof(struct tss_struct) - 1);
+	/*
+	 * sizeof(unsigned long) coming from an extra "long" at the end
+	 * of the iobitmap. See tss_struct definition in processor.h
+	 *
+	 * -1? seg base+limit should be pointing to the address of the
+	 * last valid byte
+	 */
+	set_tssldt_descriptor(&cpu_gdt_table[cpu][GDT_ENTRY_TSS],
+		(unsigned long)addr, DESC_TSS,
+		IO_BITMAP_OFFSET + IO_BITMAP_BYTES + sizeof(unsigned long) - 1);
 } 
 
 static inline void set_ldt_desc(unsigned cpu, void *addr, int size)
diff --git a/include/asm-x86_64/dma.h b/include/asm-x86_64/dma.h
index 16fa3a0..6f2a817 100644
--- a/include/asm-x86_64/dma.h
+++ b/include/asm-x86_64/dma.h
@@ -72,8 +72,15 @@
 
 #define MAX_DMA_CHANNELS	8
 
-/* The maximum address that we can perform a DMA transfer to on this platform */
-#define MAX_DMA_ADDRESS      (PAGE_OFFSET+0x1000000)
+
+/* 16MB ISA DMA zone */
+#define MAX_DMA_PFN   ((16*1024*1024) >> PAGE_SHIFT)
+
+/* 4GB broken PCI/AGP hardware bus master zone */
+#define MAX_DMA32_PFN ((4UL*1024*1024*1024) >> PAGE_SHIFT)
+
+/* Compat define for old dma zone */
+#define MAX_DMA_ADDRESS ((unsigned long)__va(MAX_DMA_PFN << PAGE_SHIFT))
 
 /* 8237 DMA controllers */
 #define IO_DMA1_BASE	0x00	/* 8 bit slave DMA, channels 0..3 */
diff --git a/include/asm-x86_64/hpet.h b/include/asm-x86_64/hpet.h
index a3877f5..c20c28f 100644
--- a/include/asm-x86_64/hpet.h
+++ b/include/asm-x86_64/hpet.h
@@ -14,18 +14,18 @@
 #define HPET_CFG	0x010
 #define HPET_STATUS	0x020
 #define HPET_COUNTER	0x0f0
-#define HPET_T0_CFG	0x100
-#define HPET_T0_CMP	0x108
-#define HPET_T0_ROUTE	0x110
-#define HPET_T1_CFG	0x120
-#define HPET_T1_CMP	0x128
-#define HPET_T1_ROUTE	0x130
-#define HPET_T2_CFG	0x140
-#define HPET_T2_CMP	0x148
-#define HPET_T2_ROUTE	0x150
+#define HPET_Tn_OFFSET	0x20
+#define HPET_Tn_CFG(n)	 (0x100 + (n) * HPET_Tn_OFFSET)
+#define HPET_Tn_ROUTE(n) (0x104 + (n) * HPET_Tn_OFFSET)
+#define HPET_Tn_CMP(n)	 (0x108 + (n) * HPET_Tn_OFFSET)
+#define HPET_T0_CFG	HPET_Tn_CFG(0)
+#define HPET_T0_CMP	HPET_Tn_CMP(0)
+#define HPET_T1_CFG	HPET_Tn_CFG(1)
+#define HPET_T1_CMP	HPET_Tn_CMP(1)
 
 #define HPET_ID_VENDOR	0xffff0000
 #define HPET_ID_LEGSUP	0x00008000
+#define HPET_ID_64BIT	0x00002000
 #define HPET_ID_NUMBER	0x00001f00
 #define HPET_ID_REV	0x000000ff
 #define	HPET_ID_NUMBER_SHIFT	8
@@ -38,11 +38,18 @@
 #define	HPET_LEGACY_8254	2
 #define	HPET_LEGACY_RTC		8
 
-#define HPET_TN_ENABLE		0x004
-#define HPET_TN_PERIODIC	0x008
-#define HPET_TN_PERIODIC_CAP	0x010
-#define HPET_TN_SETVAL		0x040
-#define HPET_TN_32BIT		0x100
+#define HPET_TN_LEVEL		0x0002
+#define HPET_TN_ENABLE		0x0004
+#define HPET_TN_PERIODIC	0x0008
+#define HPET_TN_PERIODIC_CAP	0x0010
+#define HPET_TN_64BIT_CAP	0x0020
+#define HPET_TN_SETVAL		0x0040
+#define HPET_TN_32BIT		0x0100
+#define HPET_TN_ROUTE		0x3e00
+#define HPET_TN_FSB		0x4000
+#define HPET_TN_FSB_CAP		0x8000
+
+#define HPET_TN_ROUTE_SHIFT	9
 
 extern int is_hpet_enabled(void);
 extern int hpet_rtc_timer_init(void);
diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h
index dc97668..c14a8c7 100644
--- a/include/asm-x86_64/hw_irq.h
+++ b/include/asm-x86_64/hw_irq.h
@@ -55,7 +55,7 @@ struct hw_interrupt_type;
 #define CALL_FUNCTION_VECTOR	0xfc
 #define KDB_VECTOR		0xfb	/* reserved for KDB */
 #define THERMAL_APIC_VECTOR	0xfa
-/* 0xf9 free */
+#define THRESHOLD_APIC_VECTOR   0xf9
 #define INVALIDATE_TLB_VECTOR_END	0xf8
 #define INVALIDATE_TLB_VECTOR_START	0xf0	/* f0-f8 used for TLB flush */
 
diff --git a/include/asm-x86_64/ia32.h b/include/asm-x86_64/ia32.h
index 6efa00f..c7bc9c0 100644
--- a/include/asm-x86_64/ia32.h
+++ b/include/asm-x86_64/ia32.h
@@ -165,6 +165,11 @@ struct siginfo_t;
 int do_get_thread_area(struct thread_struct *t, struct user_desc __user *info);
 int do_set_thread_area(struct thread_struct *t, struct user_desc __user *info);
 int ia32_child_tls(struct task_struct *p, struct pt_regs *childregs);
+
+struct linux_binprm;
+extern int ia32_setup_arg_pages(struct linux_binprm *bprm,
+				unsigned long stack_top, int exec_stack);
+
 #endif
 
 #endif /* !CONFIG_IA32_SUPPORT */
diff --git a/include/asm-x86_64/mce.h b/include/asm-x86_64/mce.h
index 869249d..5d298b7 100644
--- a/include/asm-x86_64/mce.h
+++ b/include/asm-x86_64/mce.h
@@ -67,6 +67,8 @@ struct mce_log { 
 /* Software defined banks */
 #define MCE_EXTENDED_BANK	128
 #define MCE_THERMAL_BANK	MCE_EXTENDED_BANK + 0
+#define MCE_THRESHOLD_BASE      MCE_EXTENDED_BANK + 1 /* MCE_AMD */
+#define MCE_THRESHOLD_DRAM_ECC  MCE_THRESHOLD_BASE + 4
 
 void mce_log(struct mce *m);
 #ifdef CONFIG_X86_MCE_INTEL
@@ -77,4 +79,12 @@ static inline void mce_intel_feature_ini
 }
 #endif
 
+#ifdef CONFIG_X86_MCE_AMD
+void mce_amd_feature_init(struct cpuinfo_x86 *c);
+#else
+static inline void mce_amd_feature_init(struct cpuinfo_x86 *c)
+{
+}
+#endif
+
 #endif
diff --git a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h
index b40c661..69baaa8 100644
--- a/include/asm-x86_64/mmzone.h
+++ b/include/asm-x86_64/mmzone.h
@@ -17,16 +17,15 @@
 /* Simple perfect hash to map physical addresses to node numbers */
 extern int memnode_shift; 
 extern u8  memnodemap[NODEMAPSIZE]; 
-extern int maxnode;
 
 extern struct pglist_data *node_data[];
 
 static inline __attribute__((pure)) int phys_to_nid(unsigned long addr) 
 { 
-	int nid; 
+	unsigned nid; 
 	VIRTUAL_BUG_ON((addr >> memnode_shift) >= NODEMAPSIZE);
 	nid = memnodemap[addr >> memnode_shift]; 
-	VIRTUAL_BUG_ON(nid > maxnode); 
+	VIRTUAL_BUG_ON(nid >= MAX_NUMNODES || !node_data[nid]); 
 	return nid; 
 } 
 
@@ -41,9 +40,7 @@ static inline __attribute__((pure)) int 
 #define pfn_to_nid(pfn) phys_to_nid((unsigned long)(pfn) << PAGE_SHIFT)
 #define kvaddr_to_nid(kaddr)	phys_to_nid(__pa(kaddr))
 
-/* AK: this currently doesn't deal with invalid addresses. We'll see 
-   if the 2.5 kernel doesn't pass them
-   (2.4 used to). */
+/* Requires pfn_valid(pfn) to be true */
 #define pfn_to_page(pfn) ({ \
 	int nid = phys_to_nid(((unsigned long)(pfn)) << PAGE_SHIFT); 	\
 	((pfn) - node_start_pfn(nid)) + NODE_DATA(nid)->node_mem_map;	\
diff --git a/include/asm-x86_64/mpspec.h b/include/asm-x86_64/mpspec.h
index f267e10..6f8a17d 100644
--- a/include/asm-x86_64/mpspec.h
+++ b/include/asm-x86_64/mpspec.h
@@ -16,7 +16,7 @@
 /*
  * A maximum of 255 APICs with the current APIC ID architecture.
  */
-#define MAX_APICS 128
+#define MAX_APICS 255
 
 struct intel_mp_floating
 {
@@ -157,7 +157,8 @@ struct mpc_config_lintsrc
  */
 
 #define MAX_MP_BUSSES 256
-#define MAX_IRQ_SOURCES 256
+/* Each PCI slot may be a combo card with its own bus.  4 IRQ pins per slot. */
+#define MAX_IRQ_SOURCES (MAX_MP_BUSSES * 4)
 enum mp_bustype {
 	MP_BUS_ISA = 1,
 	MP_BUS_EISA,
@@ -172,7 +173,7 @@ extern int smp_found_config;
 extern void find_smp_config (void);
 extern void get_smp_config (void);
 extern int nr_ioapics;
-extern int apic_version [MAX_APICS];
+extern unsigned char apic_version [MAX_APICS];
 extern int mp_irq_entries;
 extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES];
 extern int mpc_default_type;
diff --git a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h
index 5a7fe3c..24dc396 100644
--- a/include/asm-x86_64/msr.h
+++ b/include/asm-x86_64/msr.h
@@ -19,7 +19,7 @@
 			    : "=a" (a__), "=d" (b__) \
 			    : "c" (msr)); \
        val = a__ | (b__<<32); \
-} while(0); 
+} while(0)
 
 #define wrmsr(msr,val1,val2) \
      __asm__ __volatile__("wrmsr" \
diff --git a/include/asm-x86_64/numa.h b/include/asm-x86_64/numa.h
index bcf55c3..d51e56f 100644
--- a/include/asm-x86_64/numa.h
+++ b/include/asm-x86_64/numa.h
@@ -17,6 +17,8 @@ extern void numa_add_cpu(int cpu);
 extern void numa_init_array(void);
 extern int numa_off;
 
+extern void numa_set_node(int cpu, int node);
+
 extern unsigned char apicid_to_node[256];
 
 #define NUMA_NO_NODE 0xff
diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
index e5ab4d2..06e489f 100644
--- a/include/asm-x86_64/page.h
+++ b/include/asm-x86_64/page.h
@@ -11,7 +11,7 @@
 #define PAGE_SIZE	(1UL << PAGE_SHIFT)
 #endif
 #define PAGE_MASK	(~(PAGE_SIZE-1))
-#define PHYSICAL_PAGE_MASK	(~(PAGE_SIZE-1) & (__PHYSICAL_MASK << PAGE_SHIFT))
+#define PHYSICAL_PAGE_MASK	(~(PAGE_SIZE-1) & __PHYSICAL_MASK)
 
 #define THREAD_ORDER 1 
 #ifdef __ASSEMBLY__
diff --git a/include/asm-x86_64/pda.h b/include/asm-x86_64/pda.h
index bbf89aa..8733ccf 100644
--- a/include/asm-x86_64/pda.h
+++ b/include/asm-x86_64/pda.h
@@ -15,6 +15,7 @@ struct x8664_pda {
         int irqcount;		    /* Irq nesting counter. Starts with -1 */  	
 	int cpunumber;		    /* Logical CPU number */
 	char *irqstackptr;	/* top of irqstack */
+	int nodenumber;		    /* number of current node */
 	unsigned int __softirq_pending;
 	unsigned int __nmi_count;	/* number of NMI on this CPUs */
 	struct mm_struct *active_mm;
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
index 7309fff..ecf58c7 100644
--- a/include/asm-x86_64/pgtable.h
+++ b/include/asm-x86_64/pgtable.h
@@ -16,6 +16,7 @@ extern pud_t level3_physmem_pgt[512];
 extern pud_t level3_ident_pgt[512];
 extern pmd_t level2_kernel_pgt[512];
 extern pgd_t init_level4_pgt[];
+extern pgd_t boot_level4_pgt[];
 extern unsigned long __supported_pte_mask;
 
 #define swapper_pg_dir init_level4_pgt
@@ -247,7 +248,7 @@ static inline unsigned long pud_bad(pud_
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))	/* FIXME: is this
 						   right? */
 #define pte_page(x)	pfn_to_page(pte_pfn(x))
-#define pte_pfn(x)  ((pte_val(x) >> PAGE_SHIFT) & __PHYSICAL_MASK)
+#define pte_pfn(x)  ((pte_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT)
 
 static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
 {
@@ -354,7 +355,7 @@ static inline pud_t *__pud_offset_k(pud_
 #define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
 #define	pmd_bad(x)	((pmd_val(x) & (~PTE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE )
 #define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot)))
-#define pmd_pfn(x)  ((pmd_val(x) >> PAGE_SHIFT) & __PHYSICAL_MASK)
+#define pmd_pfn(x)  ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT)
 
 #define pte_to_pgoff(pte) ((pte_val(pte) & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT)
 #define pgoff_to_pte(off) ((pte_t) { ((off) << PAGE_SHIFT) | _PAGE_FILE })
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
index 03837d3..4861246 100644
--- a/include/asm-x86_64/processor.h
+++ b/include/asm-x86_64/processor.h
@@ -61,10 +61,12 @@ struct cpuinfo_x86 {
 	int	x86_cache_alignment;
 	int	x86_tlbsize;	/* number of 4K pages in DTLB/ITLB combined(in pages)*/
         __u8    x86_virt_bits, x86_phys_bits;
-	__u8	x86_num_cores;
+	__u8	x86_max_cores;	/* cpuid returned max cores value */
         __u32   x86_power; 	
 	__u32   extended_cpuid_level;	/* Max extended CPUID function supported */
 	unsigned long loops_per_jiffy;
+	__u8	apicid;
+	__u8	booted_cores;	/* number of cores as seen by OS */
 } ____cacheline_aligned;
 
 #define X86_VENDOR_INTEL 0
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index dbb37b0..3450108 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -11,6 +11,8 @@ struct pt_regs;
 extern void start_kernel(void);
 extern void pda_init(int); 
 
+extern void zap_low_mappings(int cpu);
+
 extern void early_idt_handler(void);
 
 extern void mcheck_init(struct cpuinfo_x86 *c);
@@ -22,6 +24,8 @@ extern void mtrr_bp_init(void);
 #define mtrr_bp_init() do {} while (0)
 #endif
 extern void init_memory_mapping(unsigned long start, unsigned long end);
+extern void size_zones(unsigned long *z, unsigned long *h,
+			unsigned long start_pfn, unsigned long end_pfn);
 
 extern void system_call(void); 
 extern int kernel_syscall(void);
diff --git a/include/asm-x86_64/rwsem.h b/include/asm-x86_64/rwsem.h
deleted file mode 100644
index 46077e9..0000000
--- a/include/asm-x86_64/rwsem.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/* rwsem.h: R/W semaphores implemented using XADD/CMPXCHG for x86_64+
- *
- * Written by David Howells (dhowells@redhat.com).
- * Ported by Andi Kleen <ak@suse.de> to x86-64.
- *
- * Derived from asm-i386/semaphore.h and asm-i386/rwsem.h
- *
- *
- * The MSW of the count is the negated number of active writers and waiting
- * lockers, and the LSW is the total number of active locks
- *
- * The lock count is initialized to 0 (no active and no waiting lockers).
- *
- * When a writer subtracts WRITE_BIAS, it'll get 0xffff0001 for the case of an
- * uncontended lock. This can be determined because XADD returns the old value.
- * Readers increment by 1 and see a positive value when uncontended, negative
- * if there are writers (and maybe) readers waiting (in which case it goes to
- * sleep).
- *
- * The value of WAITING_BIAS supports up to 32766 waiting processes. This can
- * be extended to 65534 by manually checking the whole MSW rather than relying
- * on the S flag.
- *
- * The value of ACTIVE_BIAS supports up to 65535 active processes.
- *
- * This should be totally fair - if anything is waiting, a process that wants a
- * lock will go to the back of the queue. When the currently active lock is
- * released, if there's a writer at the front of the queue, then that and only
- * that will be woken up; if there's a bunch of consecutive readers at the
- * front, then they'll all be woken up, but no other readers will be.
- */
-
-#ifndef _X8664_RWSEM_H
-#define _X8664_RWSEM_H
-
-#ifndef _LINUX_RWSEM_H
-#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
-#endif
-
-#ifdef __KERNEL__
-
-#include <linux/list.h>
-#include <linux/spinlock.h>
-
-struct rwsem_waiter;
-
-extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
-extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
-extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *);
-extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
-
-/*
- * the semaphore definition
- */
-struct rw_semaphore {
-	signed int		count;
-#define RWSEM_UNLOCKED_VALUE		0x00000000
-#define RWSEM_ACTIVE_BIAS		0x00000001
-#define RWSEM_ACTIVE_MASK		0x0000ffff
-#define RWSEM_WAITING_BIAS		(-0x00010000)
-#define RWSEM_ACTIVE_READ_BIAS		RWSEM_ACTIVE_BIAS
-#define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
-	spinlock_t		wait_lock;
-	struct list_head	wait_list;
-#if RWSEM_DEBUG
-	int			debug;
-#endif
-};
-
-/*
- * initialisation
- */
-#if RWSEM_DEBUG
-#define __RWSEM_DEBUG_INIT      , 0
-#else
-#define __RWSEM_DEBUG_INIT	/* */
-#endif
-
-#define __RWSEM_INITIALIZER(name) \
-{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) \
-	__RWSEM_DEBUG_INIT }
-
-#define DECLARE_RWSEM(name) \
-	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
-
-static inline void init_rwsem(struct rw_semaphore *sem)
-{
-	sem->count = RWSEM_UNLOCKED_VALUE;
-	spin_lock_init(&sem->wait_lock);
-	INIT_LIST_HEAD(&sem->wait_list);
-#if RWSEM_DEBUG
-	sem->debug = 0;
-#endif
-}
-
-/*
- * lock for reading
- */
-static inline void __down_read(struct rw_semaphore *sem)
-{
-	__asm__ __volatile__(
-		"# beginning down_read\n\t"
-LOCK_PREFIX	"  incl      (%%rdi)\n\t" /* adds 0x00000001, returns the old value */
-		"  js        2f\n\t" /* jump if we weren't granted the lock */
-		"1:\n\t"
-		LOCK_SECTION_START("") \
-		"2:\n\t"
-		"  call      rwsem_down_read_failed_thunk\n\t"
-		"  jmp       1b\n"
-		LOCK_SECTION_END \
-		"# ending down_read\n\t"
-		: "+m"(sem->count)
-		: "D"(sem)
-		: "memory", "cc");
-}
-
-
-/*
- * trylock for reading -- returns 1 if successful, 0 if contention
- */
-static inline int __down_read_trylock(struct rw_semaphore *sem)
-{
-	__s32 result, tmp;
-	__asm__ __volatile__(
-		"# beginning __down_read_trylock\n\t"
-		"  movl      %0,%1\n\t"
-		"1:\n\t"
-		"  movl	     %1,%2\n\t"
-		"  addl      %3,%2\n\t"
-		"  jle	     2f\n\t"
-LOCK_PREFIX	"  cmpxchgl  %2,%0\n\t"
-		"  jnz	     1b\n\t"
-		"2:\n\t"
-		"# ending __down_read_trylock\n\t"
-		: "+m"(sem->count), "=&a"(result), "=&r"(tmp)
-		: "i"(RWSEM_ACTIVE_READ_BIAS)
-		: "memory", "cc");
-	return result>=0 ? 1 : 0;
-}
-
-
-/*
- * lock for writing
- */
-static inline void __down_write(struct rw_semaphore *sem)
-{
-	int tmp;
-
-	tmp = RWSEM_ACTIVE_WRITE_BIAS;
-	__asm__ __volatile__(
-		"# beginning down_write\n\t"
-LOCK_PREFIX	"  xaddl      %0,(%%rdi)\n\t" /* subtract 0x0000ffff, returns the old value */
-		"  testl     %0,%0\n\t" /* was the count 0 before? */
-		"  jnz       2f\n\t" /* jump if we weren't granted the lock */
-		"1:\n\t"
-		LOCK_SECTION_START("")
-		"2:\n\t"
-		"  call      rwsem_down_write_failed_thunk\n\t"
-		"  jmp       1b\n"
-		LOCK_SECTION_END
-		"# ending down_write"
-		: "=&r" (tmp) 
-		: "0"(tmp), "D"(sem)
-		: "memory", "cc");
-}
-
-/*
- * trylock for writing -- returns 1 if successful, 0 if contention
- */
-static inline int __down_write_trylock(struct rw_semaphore *sem)
-{
-	signed long ret = cmpxchg(&sem->count,
-				  RWSEM_UNLOCKED_VALUE, 
-				  RWSEM_ACTIVE_WRITE_BIAS);
-	if (ret == RWSEM_UNLOCKED_VALUE)
-		return 1;
-	return 0;
-}
-
-/*
- * unlock after reading
- */
-static inline void __up_read(struct rw_semaphore *sem)
-{
-	__s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
-	__asm__ __volatile__(
-		"# beginning __up_read\n\t"
-LOCK_PREFIX	"  xaddl      %[tmp],(%%rdi)\n\t" /* subtracts 1, returns the old value */
-		"  js        2f\n\t" /* jump if the lock is being waited upon */
-		"1:\n\t"
-		LOCK_SECTION_START("")
-		"2:\n\t"
-		"  decw      %w[tmp]\n\t" /* do nothing if still outstanding active readers */
-		"  jnz       1b\n\t"
-		"  call      rwsem_wake_thunk\n\t"
-		"  jmp       1b\n"
-		LOCK_SECTION_END
-		"# ending __up_read\n"
-		: "+m"(sem->count), [tmp] "+r" (tmp)
-		: "D"(sem)
-		: "memory", "cc");
-}
-
-/*
- * unlock after writing
- */
-static inline void __up_write(struct rw_semaphore *sem)
-{
-	unsigned tmp; 
-	__asm__ __volatile__(
-		"# beginning __up_write\n\t"
-		"  movl     %[bias],%[tmp]\n\t"
-LOCK_PREFIX	"  xaddl     %[tmp],(%%rdi)\n\t" /* tries to transition 0xffff0001 -> 0x00000000 */
-		"  jnz       2f\n\t" /* jump if the lock is being waited upon */
-		"1:\n\t"
-		LOCK_SECTION_START("")
-		"2:\n\t"
-		"  decw      %w[tmp]\n\t" /* did the active count reduce to 0? */
-		"  jnz       1b\n\t" /* jump back if not */
-		"  call      rwsem_wake_thunk\n\t"
-		"  jmp       1b\n"
-		LOCK_SECTION_END
-		"# ending __up_write\n"
-		: "+m"(sem->count), [tmp] "=r" (tmp)
-		: "D"(sem), [bias] "i"(-RWSEM_ACTIVE_WRITE_BIAS)
-		: "memory", "cc");
-}
-
-/*
- * downgrade write lock to read lock
- */
-static inline void __downgrade_write(struct rw_semaphore *sem)
-{
-	__asm__ __volatile__(
-		"# beginning __downgrade_write\n\t"
-LOCK_PREFIX	"  addl      %[bias],(%%rdi)\n\t" /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
-		"  js        2f\n\t" /* jump if the lock is being waited upon */
-		"1:\n\t"
-		LOCK_SECTION_START("")
-		"2:\n\t"
-		"  call	     rwsem_downgrade_thunk\n"
-		"  jmp       1b\n"
-		LOCK_SECTION_END
-		"# ending __downgrade_write\n"
-		: "=m"(sem->count)
-		: "D"(sem), [bias] "i"(-RWSEM_WAITING_BIAS), "m"(sem->count)
-		: "memory", "cc");
-}
-
-/*
- * implement atomic add functionality
- */
-static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
-{
-	__asm__ __volatile__(
-LOCK_PREFIX	"addl %1,%0"
-		:"=m"(sem->count)
-		:"ir"(delta), "m"(sem->count));
-}
-
-/*
- * implement exchange and add functionality
- */
-static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
-{
-	int tmp = delta;
-
-	__asm__ __volatile__(
-LOCK_PREFIX	"xaddl %0,(%2)"
-		: "=r"(tmp), "=m"(sem->count)
-		: "r"(sem), "m"(sem->count), "0" (tmp)
-		: "memory");
-
-	return tmp+delta;
-}
-
-static inline int rwsem_is_locked(struct rw_semaphore *sem)
-{
-	return (sem->count != 0);
-}
-
-#endif /* __KERNEL__ */
-#endif /* _X8664_RWSEM_H */
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
index b9fb217..d030409 100644
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -47,7 +47,6 @@ extern void lock_ipi_call_lock(void);
 extern void unlock_ipi_call_lock(void);
 extern int smp_num_siblings;
 extern void smp_send_reschedule(int cpu);
-extern void zap_low_mappings(void);
 void smp_stop_cpu(void);
 extern int smp_call_function_single(int cpuid, void (*func) (void *info),
 				void *info, int retry, int wait);
@@ -82,6 +81,8 @@ extern int safe_smp_processor_id(void);
 extern int __cpu_disable(void);
 extern void __cpu_die(unsigned int cpu);
 extern void prefill_possible_map(void);
+extern unsigned num_processors;
+extern unsigned disabled_cpus;
 
 #endif /* !ASSEMBLY */
 
diff --git a/include/asm-x86_64/spinlock.h b/include/asm-x86_64/spinlock.h
index 6963683..fe484a6 100644
--- a/include/asm-x86_64/spinlock.h
+++ b/include/asm-x86_64/spinlock.h
@@ -18,22 +18,22 @@
  */
 
 #define __raw_spin_is_locked(x) \
-		(*(volatile signed char *)(&(x)->slock) <= 0)
+		(*(volatile signed int *)(&(x)->slock) <= 0)
 
 #define __raw_spin_lock_string \
 	"\n1:\t" \
-	"lock ; decb %0\n\t" \
+	"lock ; decl %0\n\t" \
 	"js 2f\n" \
 	LOCK_SECTION_START("") \
 	"2:\t" \
 	"rep;nop\n\t" \
-	"cmpb $0,%0\n\t" \
+	"cmpl $0,%0\n\t" \
 	"jle 2b\n\t" \
 	"jmp 1b\n" \
 	LOCK_SECTION_END
 
 #define __raw_spin_unlock_string \
-	"movb $1,%0" \
+	"movl $1,%0" \
 		:"=m" (lock->slock) : : "memory"
 
 static inline void __raw_spin_lock(raw_spinlock_t *lock)
@@ -47,10 +47,10 @@ static inline void __raw_spin_lock(raw_s
 
 static inline int __raw_spin_trylock(raw_spinlock_t *lock)
 {
-	char oldval;
+	int oldval;
 
 	__asm__ __volatile__(
-		"xchgb %b0,%1"
+		"xchgl %0,%1"
 		:"=q" (oldval), "=m" (lock->slock)
 		:"0" (0) : "memory");
 
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h
index 1c603cd..d39ebd5 100644
--- a/include/asm-x86_64/topology.h
+++ b/include/asm-x86_64/topology.h
@@ -28,6 +28,8 @@ extern int __node_distance(int, int);
 #define pcibus_to_node(bus)		((long)(bus->sysdata))	
 #define pcibus_to_cpumask(bus)		node_to_cpumask(pcibus_to_node(bus));
 
+#define numa_node_id()			read_pda(nodenumber)
+
 /* sched_domains SD_NODE_INIT for x86_64 machines */
 #define SD_NODE_INIT (struct sched_domain) {		\
 	.span			= CPU_MASK_NONE,	\
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index 3c494b6..2c42150 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -462,7 +462,7 @@ __SYSCALL(__NR_fremovexattr, sys_fremove
 #define __NR_tkill	200
 __SYSCALL(__NR_tkill, sys_tkill) 
 #define __NR_time      201
-__SYSCALL(__NR_time, sys_time64)
+__SYSCALL(__NR_time, sys_time)
 #define __NR_futex     202
 __SYSCALL(__NR_futex, sys_futex)
 #define __NR_sched_setaffinity    203
@@ -608,6 +608,7 @@ do { \
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_COMPAT_SYS_TIME
 #endif
 
diff --git a/include/asm-xtensa/atomic.h b/include/asm-xtensa/atomic.h
index 12b5732..3670cc7 100644
--- a/include/asm-xtensa/atomic.h
+++ b/include/asm-xtensa/atomic.h
@@ -223,6 +223,26 @@ static inline int atomic_sub_return(int 
  */
 #define atomic_add_negative(i,v) (atomic_add_return((i),(v)) < 0)
 
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
+/**
+ * atomic_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+#define atomic_add_unless(v, a, u)				\
+({								\
+	int c, old;						\
+	c = atomic_read(v);					\
+	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+		c = old;					\
+	c != (u);						\
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 
 static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
 {
diff --git a/include/linux/acct.h b/include/linux/acct.h
index 93c5b3c..9a66401 100644
--- a/include/linux/acct.h
+++ b/include/linux/acct.h
@@ -16,6 +16,8 @@
 #define _LINUX_ACCT_H
 
 #include <linux/types.h>
+#include <linux/jiffies.h>
+
 #include <asm/param.h>
 #include <asm/byteorder.h>
 
diff --git a/include/linux/aio.h b/include/linux/aio.h
index 403d71d..49fd376 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -124,7 +124,7 @@ struct kiocb {
 		(x)->ki_users = 1;			\
 		(x)->ki_key = KIOCB_SYNC_KEY;		\
 		(x)->ki_filp = (filp);			\
-		(x)->ki_ctx = &tsk->active_mm->default_kioctx;	\
+		(x)->ki_ctx = NULL;			\
 		(x)->ki_cancel = NULL;			\
 		(x)->ki_dtor = NULL;			\
 		(x)->ki_obj.tsk = tsk;			\
@@ -210,8 +210,15 @@ struct kioctx *lookup_ioctx(unsigned lon
 int FASTCALL(io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
 				  struct iocb *iocb));
 
-#define get_ioctx(kioctx)	do { if (unlikely(atomic_read(&(kioctx)->users) <= 0)) BUG(); atomic_inc(&(kioctx)->users); } while (0)
-#define put_ioctx(kioctx)	do { if (unlikely(atomic_dec_and_test(&(kioctx)->users))) __put_ioctx(kioctx); else if (unlikely(atomic_read(&(kioctx)->users) < 0)) BUG(); } while (0)
+#define get_ioctx(kioctx) do {						\
+	BUG_ON(unlikely(atomic_read(&(kioctx)->users) <= 0));		\
+	atomic_inc(&(kioctx)->users);					\
+} while (0)
+#define put_ioctx(kioctx) do {						\
+	BUG_ON(unlikely(atomic_read(&(kioctx)->users) <= 0));		\
+	if (unlikely(atomic_dec_and_test(&(kioctx)->users))) 		\
+		__put_ioctx(kioctx);					\
+} while (0)
 
 #define in_aio() !is_sync_wait(current->io_wait)
 /* may be used for debugging */
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index cb3c3ef..38c2fb7 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -84,6 +84,16 @@ static __inline__ int get_bitmask_order(
 	return order;	/* We could be slightly more clever with -1 here... */
 }
 
+static __inline__ int get_count_order(unsigned int count)
+{
+	int order;
+	
+	order = fls(count) - 1;
+	if (count & (count - 1))
+		order++;
+	return order;
+}
+
 /*
  * hweightN: returns the hamming weight (i.e. the number
  * of bits set) of a N-bit word
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 025a7f0..a33a31e 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -406,6 +406,7 @@ struct request_queue
 
 	atomic_t		refcnt;
 
+	unsigned int		nr_sorted;
 	unsigned int		in_flight;
 
 	/*
@@ -631,6 +632,7 @@ static inline void elv_dispatch_add_tail
 {
 	if (q->last_merge == rq)
 		q->last_merge = NULL;
+	q->nr_sorted--;
 
 	q->end_sector = rq_end_sector(rq);
 	q->boundary_rq = rq;
diff --git a/include/linux/cm4000_cs.h b/include/linux/cm4000_cs.h
new file mode 100644
index 0000000..605ebe2
--- /dev/null
+++ b/include/linux/cm4000_cs.h
@@ -0,0 +1,66 @@
+#ifndef	_CM4000_H_
+#define	_CM4000_H_
+
+#define	MAX_ATR			33
+
+#define	CM4000_MAX_DEV		4
+
+/* those two structures are passed via ioctl() from/to userspace.  They are
+ * used by existing userspace programs, so I kepth the awkward "bIFSD" naming
+ * not to break compilation of userspace apps. -HW */
+
+typedef struct atreq {
+	int32_t atr_len;
+	unsigned char atr[64];
+	int32_t power_act;
+	unsigned char bIFSD;
+	unsigned char bIFSC;
+} atreq_t;
+
+
+/* what is particularly stupid in the original driver is the arch-dependant
+ * member sizes. This leads to CONFIG_COMPAT breakage, since 32bit userspace
+ * will lay out the structure members differently than the 64bit kernel.
+ *
+ * I've changed "ptsreq.protocol" from "unsigned long" to "u_int32_t".
+ * On 32bit this will make no difference.  With 64bit kernels, it will make
+ * 32bit apps work, too.
+ */
+
+typedef struct ptsreq {
+	u_int32_t protocol; /*T=0: 2^0, T=1:  2^1*/
+ 	unsigned char flags;
+ 	unsigned char pts1;
+ 	unsigned char pts2;
+	unsigned char pts3;
+} ptsreq_t;
+
+#define	CM_IOC_MAGIC		'c'
+#define	CM_IOC_MAXNR	        255
+
+#define	CM_IOCGSTATUS		_IOR (CM_IOC_MAGIC, 0, unsigned char *)
+#define	CM_IOCGATR		_IOWR(CM_IOC_MAGIC, 1, atreq_t *)
+#define	CM_IOCSPTS		_IOW (CM_IOC_MAGIC, 2, ptsreq_t *)
+#define	CM_IOCSRDR		_IO  (CM_IOC_MAGIC, 3)
+#define CM_IOCARDOFF            _IO  (CM_IOC_MAGIC, 4)
+
+#define CM_IOSDBGLVL            _IOW(CM_IOC_MAGIC, 250, int*)
+
+/* card and device states */
+#define	CM_CARD_INSERTED		0x01
+#define	CM_CARD_POWERED			0x02
+#define	CM_ATR_PRESENT			0x04
+#define	CM_ATR_VALID	 		0x08
+#define	CM_STATE_VALID			0x0f
+/* extra info only from CM4000 */
+#define	CM_NO_READER			0x10
+#define	CM_BAD_CARD			0x20
+
+
+#ifdef __KERNEL__
+
+#define	DEVICE_NAME		"cmm"
+#define	MODULE_NAME		"cm4000_cs"
+
+#endif	/* __KERNEL__ */
+#endif	/* _CM4000_H_ */
diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h
index 2209ad3..174f337 100644
--- a/include/linux/compat_ioctl.h
+++ b/include/linux/compat_ioctl.h
@@ -259,6 +259,14 @@ COMPATIBLE_IOCTL(RTC_RD_TIME)
 COMPATIBLE_IOCTL(RTC_SET_TIME)
 COMPATIBLE_IOCTL(RTC_WKALM_SET)
 COMPATIBLE_IOCTL(RTC_WKALM_RD)
+/*
+ * These two are only for the sbus rtc driver, but
+ * hwclock tries them on every rtc device first when
+ * running on sparc.  On other architectures the entries
+ * are useless but harmless.
+ */
+COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
+COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
 /* Little m */
 COMPATIBLE_IOCTL(MTIOCTOP)
 /* Socket level stuff */
diff --git a/include/linux/file.h b/include/linux/file.h
index d3b1a15..418b610 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -33,13 +33,13 @@ struct fdtable {
  * Open file table structure
  */
 struct files_struct {
-        atomic_t count;
-        spinlock_t file_lock;     /* Protects all the below members.  Nests inside tsk->alloc_lock */
+	atomic_t count;
 	struct fdtable *fdt;
 	struct fdtable fdtab;
-        fd_set close_on_exec_init;
-        fd_set open_fds_init;
-        struct file * fd_array[NR_OPEN_DEFAULT];
+	fd_set close_on_exec_init;
+	fd_set open_fds_init;
+	struct file * fd_array[NR_OPEN_DEFAULT];
+	spinlock_t file_lock;     /* Protects concurrent writers.  Nests inside tsk->alloc_lock */
 };
 
 #define files_fdtable(files) (rcu_dereference((files)->fdt))
diff --git a/include/linux/font.h b/include/linux/font.h
index 8aac48c..53b129f 100644
--- a/include/linux/font.h
+++ b/include/linux/font.h
@@ -31,7 +31,6 @@ struct font_desc {
 #define SUN12x22_IDX	7
 #define ACORN8x8_IDX	8
 #define	MINI4x6_IDX	9
-#define	RL_IDX	10
 
 extern const struct font_desc	font_vga_8x8,
 			font_vga_8x16,
@@ -42,7 +41,6 @@ extern const struct font_desc	font_vga_8
 			font_sun_8x16,
 			font_sun_12x22,
 			font_acorn_8x8,
-			font_rl,
 			font_mini_4x6;
 
 /* Find a font with a specific name */
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 114d5d5..934aa9b 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -4,7 +4,7 @@
  * Definitions for any platform device related flags or structures for
  * Freescale processor devices
  *
- * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
  *
  * Copyright 2004 Freescale Semiconductor, Inc
  *
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 8eeaa53..eef5ccd 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -78,7 +78,7 @@ struct hd_struct {
 	sector_t start_sect;
 	sector_t nr_sects;
 	struct kobject kobj;
-	unsigned ios[2], sectors[2];
+	unsigned ios[2], sectors[2];	/* READs and WRITEs */
 	int policy, partno;
 };
 
@@ -89,7 +89,7 @@ struct hd_struct {
 #define GENHD_FL_SUPPRESS_PARTITION_INFO	32
 
 struct disk_stats {
-	unsigned sectors[2];
+	unsigned sectors[2];		/* READs and WRITEs */
 	unsigned ios[2];
 	unsigned merges[2];
 	unsigned ticks[2];
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index c377943..313dfe9 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -14,6 +14,13 @@ struct vm_area_struct;
 /* Zone modifiers in GFP_ZONEMASK (see linux/mmzone.h - low two bits) */
 #define __GFP_DMA	((__force gfp_t)0x01u)
 #define __GFP_HIGHMEM	((__force gfp_t)0x02u)
+#ifdef CONFIG_DMA_IS_DMA32
+#define __GFP_DMA32	((__force gfp_t)0x01)	/* ZONE_DMA is ZONE_DMA32 */
+#elif BITS_PER_LONG < 64
+#define __GFP_DMA32	((__force gfp_t)0x00)	/* ZONE_NORMAL is ZONE_DMA32 */
+#else
+#define __GFP_DMA32	((__force gfp_t)0x04)	/* Has own ZONE_DMA32 */
+#endif
 
 /*
  * Action modifiers - doesn't change the zoning
@@ -39,8 +46,7 @@ struct vm_area_struct;
 #define __GFP_COMP	((__force gfp_t)0x4000u)/* Add compound page metadata */
 #define __GFP_ZERO	((__force gfp_t)0x8000u)/* Return zeroed page on success */
 #define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) /* Don't use emergency reserves */
-#define __GFP_NORECLAIM  ((__force gfp_t)0x20000u) /* No realy zone reclaim during allocation */
-#define __GFP_HARDWALL   ((__force gfp_t)0x40000u) /* Enforce hardwall cpuset memory allocs */
+#define __GFP_HARDWALL   ((__force gfp_t)0x20000u) /* Enforce hardwall cpuset memory allocs */
 
 #define __GFP_BITS_SHIFT 20	/* Room for 20 __GFP_FOO bits */
 #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
@@ -49,7 +55,7 @@ struct vm_area_struct;
 #define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \
 			__GFP_COLD|__GFP_NOWARN|__GFP_REPEAT| \
 			__GFP_NOFAIL|__GFP_NORETRY|__GFP_NO_GROW|__GFP_COMP| \
-			__GFP_NOMEMALLOC|__GFP_NORECLAIM|__GFP_HARDWALL)
+			__GFP_NOMEMALLOC|__GFP_HARDWALL)
 
 #define GFP_ATOMIC	(__GFP_HIGH)
 #define GFP_NOIO	(__GFP_WAIT)
@@ -64,6 +70,10 @@ struct vm_area_struct;
 
 #define GFP_DMA		__GFP_DMA
 
+/* 4GB DMA on some platforms */
+#define GFP_DMA32	__GFP_DMA32
+
+
 #define gfp_zone(mask) ((__force int)((mask) & (__force gfp_t)GFP_ZONEMASK))
 
 /*
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 5912874..71d2b8a 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -90,6 +90,8 @@ extern void synchronize_irq(unsigned int
 #define nmi_enter()		irq_enter()
 #define nmi_exit()		sub_preempt_count(HARDIRQ_OFFSET)
 
+struct task_struct;
+
 #ifndef CONFIG_VIRT_CPU_ACCOUNTING
 static inline void account_user_vtime(struct task_struct *tsk)
 {
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 0cea162..1056717 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -102,8 +102,8 @@ static inline unsigned long hugetlb_tota
 #define hugetlb_fault(mm, vma, addr, write)	({ BUG(); 0; })
 
 #ifndef HPAGE_MASK
-#define HPAGE_MASK	0		/* Keep the compiler happy */
-#define HPAGE_SIZE	0
+#define HPAGE_MASK	PAGE_MASK		/* Keep the compiler happy */
+#define HPAGE_SIZE	PAGE_SIZE
 #endif
 
 #endif /* !CONFIG_HUGETLB_PAGE */
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 74abaec..1543daa 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -107,6 +107,7 @@
 #define I2C_DRIVERID_CX25840	71	/* cx2584x video encoder	*/
 #define I2C_DRIVERID_SAA7127	72	/* saa7124 video encoder	*/
 #define I2C_DRIVERID_SAA711X	73	/* saa711x video encoders	*/
+#define I2C_DRIVERID_AKITAIOEXP	74	/* IO Expander on Sharp SL-C1000 */
 
 #define I2C_DRIVERID_EXP0	0xF0	/* experimental use id's	*/
 #define I2C_DRIVERID_EXP1	0xF1
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 68ab5f2..dcfd2ec 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -51,7 +51,6 @@
 	.page_table_lock =  SPIN_LOCK_UNLOCKED, 		\
 	.mmlist		= LIST_HEAD_INIT(name.mmlist),		\
 	.cpu_vm_mask	= CPU_MASK_ALL,				\
-	.default_kioctx = INIT_KIOCTX(name.default_kioctx, name),	\
 }
 
 #define INIT_SIGNALS(sig) {	\
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 0a90205..41f150a 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -9,6 +9,7 @@
 #include <linux/preempt.h>
 #include <linux/cpumask.h>
 #include <linux/hardirq.h>
+#include <linux/sched.h>
 #include <asm/atomic.h>
 #include <asm/ptrace.h>
 #include <asm/system.h>
diff --git a/include/linux/libata.h b/include/linux/libata.h
index ad59961..f2dbb68 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -59,6 +59,8 @@
 #define VPRINTK(fmt, args...)
 #endif	/* ATA_DEBUG */
 
+#define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
+
 #ifdef ATA_NDEBUG
 #define assert(expr)
 #else
@@ -119,6 +121,7 @@ enum {
 	ATA_FLAG_PIO_DMA	= (1 << 8), /* PIO cmds via DMA */
 	ATA_FLAG_NOINTR		= (1 << 9), /* FIXME: Remove this once
 					     * proper HSM is in place. */
+	ATA_FLAG_DEBUGMSG	= (1 << 10),
 
 	ATA_QCFLAG_ACTIVE	= (1 << 1), /* cmd not yet ack'd to scsi lyer */
 	ATA_QCFLAG_SG		= (1 << 3), /* have s/g table? */
@@ -659,6 +662,17 @@ static inline void ata_tf_init(struct at
 		tf->device = ATA_DEVICE_OBS | ATA_DEV1;
 }
 
+static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
+{
+	qc->__sg = NULL;
+	qc->flags = 0;
+	qc->cursect = qc->cursg = qc->cursg_ofs = 0;
+	qc->nsect = 0;
+	qc->nbytes = qc->curbytes = 0;
+
+	ata_tf_init(qc->ap, &qc->tf, qc->dev->devno);
+}
+
 
 /**
  *	ata_irq_on - Enable interrupts on a port.
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7b115fe..1013a42 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -206,12 +206,6 @@ struct vm_operations_struct {
 struct mmu_gather;
 struct inode;
 
-#ifdef ARCH_HAS_ATOMIC_UNSIGNED
-typedef unsigned page_flags_t;
-#else
-typedef unsigned long page_flags_t;
-#endif
-
 /*
  * Each physical page in the system has a struct page associated with
  * it to keep track of whatever it is we are using the page for at the
@@ -219,7 +213,7 @@ typedef unsigned long page_flags_t;
  * a page.
  */
 struct page {
-	page_flags_t flags;		/* Atomic flags, some possibly
+	unsigned long flags;		/* Atomic flags, some possibly
 					 * updated asynchronously */
 	atomic_t _count;		/* Usage count, see below. */
 	atomic_t _mapcount;		/* Count of ptes mapped in mms,
@@ -435,7 +429,7 @@ static inline void put_page(struct page 
 #endif
 
 /* Page flags: | [SECTION] | [NODE] | ZONE | ... | FLAGS | */
-#define SECTIONS_PGOFF		((sizeof(page_flags_t)*8) - SECTIONS_WIDTH)
+#define SECTIONS_PGOFF		((sizeof(unsigned long)*8) - SECTIONS_WIDTH)
 #define NODES_PGOFF		(SECTIONS_PGOFF - NODES_WIDTH)
 #define ZONES_PGOFF		(NODES_PGOFF - ZONES_WIDTH)
 
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index f5fa308..2c8edad 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -71,10 +71,11 @@ struct per_cpu_pageset {
 #endif
 
 #define ZONE_DMA		0
-#define ZONE_NORMAL		1
-#define ZONE_HIGHMEM		2
+#define ZONE_DMA32		1
+#define ZONE_NORMAL		2
+#define ZONE_HIGHMEM		3
 
-#define MAX_NR_ZONES		3	/* Sync this with ZONES_SHIFT */
+#define MAX_NR_ZONES		4	/* Sync this with ZONES_SHIFT */
 #define ZONES_SHIFT		2	/* ceil(log2(MAX_NR_ZONES)) */
 
 
@@ -108,9 +109,10 @@ struct per_cpu_pageset {
 
 /*
  * On machines where it is needed (eg PCs) we divide physical memory
- * into multiple physical zones. On a PC we have 3 zones:
+ * into multiple physical zones. On a PC we have 4 zones:
  *
  * ZONE_DMA	  < 16 MB	ISA DMA capable memory
+ * ZONE_DMA32	     0 MB 	Empty
  * ZONE_NORMAL	16-896 MB	direct mapped by the kernel
  * ZONE_HIGHMEM	 > 896 MB	only page cache and user processes
  */
@@ -329,7 +331,7 @@ void get_zone_counts(unsigned long *acti
 void build_all_zonelists(void);
 void wakeup_kswapd(struct zone *zone, int order);
 int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
-		int alloc_type, int can_try_harder, gfp_t gfp_high);
+		int classzone_idx, int alloc_flags);
 
 #ifdef CONFIG_HAVE_MEMORY_PRESENT
 void memory_present(int nid, unsigned long start, unsigned long end);
@@ -433,7 +435,9 @@ int lowmem_reserve_ratio_sysctl_handler(
 
 #include <linux/topology.h>
 /* Returns the number of the current Node. */
+#ifndef numa_node_id
 #define numa_node_id()		(cpu_to_node(raw_smp_processor_id()))
+#endif
 
 #ifndef CONFIG_NEED_MULTIPLE_NODES
 
@@ -453,12 +457,12 @@ extern struct pglist_data contig_page_da
 #include <asm/sparsemem.h>
 #endif
 
-#if BITS_PER_LONG == 32 || defined(ARCH_HAS_ATOMIC_UNSIGNED)
+#if BITS_PER_LONG == 32
 /*
- * with 32 bit page->flags field, we reserve 8 bits for node/zone info.
- * there are 3 zones (2 bits) and this leaves 8-2=6 bits for nodes.
+ * with 32 bit page->flags field, we reserve 9 bits for node/zone info.
+ * there are 4 zones (3 bits) and this leaves 9-3=6 bits for nodes.
  */
-#define FLAGS_RESERVED		8
+#define FLAGS_RESERVED		9
 
 #elif BITS_PER_LONG == 64
 /*
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 72975fa..934a247 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -112,7 +112,6 @@ struct nfnl_callback
 {
 	int (*call)(struct sock *nl, struct sk_buff *skb, 
 		struct nlmsghdr *nlh, struct nfattr *cda[], int *errp);
-	kernel_cap_t cap_required; /* capabilities required for this msg */
 	u_int16_t attr_count;	/* number of nfattr's */
 };
 
@@ -154,11 +153,14 @@ extern void nfattr_parse(struct nfattr *
 
 #define nfattr_bad_size(tb, max, cta_min)				\
 ({	int __i, __res = 0;						\
- 	for (__i=0; __i<max; __i++) 					\
+ 	for (__i=0; __i<max; __i++) {					\
+ 		if (!cta_min[__i])					\
+ 			continue;					\
  		if (tb[__i] && NFA_PAYLOAD(tb[__i]) < cta_min[__i]){	\
  			__res = 1;					\
  			break;						\
  		}							\
+ 	}								\
  	__res;								\
 })
 
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index ba6c310..ee700c6 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -53,12 +53,12 @@ void release_pages(struct page **pages, 
 
 static inline struct page *page_cache_alloc(struct address_space *x)
 {
-	return alloc_pages(mapping_gfp_mask(x)|__GFP_NORECLAIM, 0);
+	return alloc_pages(mapping_gfp_mask(x), 0);
 }
 
 static inline struct page *page_cache_alloc_cold(struct address_space *x)
 {
-	return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD|__GFP_NORECLAIM, 0);
+	return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0);
 }
 
 typedef int filler_t(void *, struct page *);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index d00f8ba..d4c1c8f 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -805,6 +805,10 @@
 #define PCI_DEVICE_ID_APPLE_SH_SUNGEM   0x0051
 #define PCI_DEVICE_ID_APPLE_U3L_AGP	0x0058
 #define PCI_DEVICE_ID_APPLE_U3H_AGP	0x0059
+#define PCI_DEVICE_ID_APPLE_IPID2_AGP	0x0066
+#define PCI_DEVICE_ID_APPLE_IPID2_ATA	0x0069
+#define PCI_DEVICE_ID_APPLE_IPID2_FW	0x006a
+#define PCI_DEVICE_ID_APPLE_IPID2_GMAC	0x006b
 #define PCI_DEVICE_ID_APPLE_TIGON3	0x1645
 
 #define PCI_VENDOR_ID_YAMAHA		0x1073
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index 5451eb1..fb8d2d2 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -38,7 +38,7 @@ extern void free_percpu(const void *);
 
 #else /* CONFIG_SMP */
 
-#define per_cpu_ptr(ptr, cpu) (ptr)
+#define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); })
 
 static inline void *__alloc_percpu(size_t size, size_t align)
 {
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 1514098..5be87ba 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -94,55 +94,6 @@ struct pm_dev
 	struct list_head entry;
 };
 
-#ifdef CONFIG_PM
-
-extern int pm_active;
-
-#define PM_IS_ACTIVE() (pm_active != 0)
-
-/*
- * Register a device with power management
- */
-struct pm_dev __deprecated *
-pm_register(pm_dev_t type, unsigned long id, pm_callback callback);
-
-/*
- * Unregister a device with power management
- */
-void __deprecated pm_unregister(struct pm_dev *dev);
-
-/*
- * Unregister all devices with matching callback
- */
-void __deprecated pm_unregister_all(pm_callback callback);
-
-/*
- * Send a request to all devices
- */
-int __deprecated pm_send_all(pm_request_t rqst, void *data);
-
-#else /* CONFIG_PM */
-
-#define PM_IS_ACTIVE() 0
-
-static inline struct pm_dev *pm_register(pm_dev_t type,
-					 unsigned long id,
-					 pm_callback callback)
-{
-	return NULL;
-}
-
-static inline void pm_unregister(struct pm_dev *dev) {}
-
-static inline void pm_unregister_all(pm_callback callback) {}
-
-static inline int pm_send_all(pm_request_t rqst, void *data)
-{
-	return 0;
-}
-
-#endif /* CONFIG_PM */
-
 /* Functions above this comment are list-based old-style power
  * managment. Please avoid using them.  */
 
diff --git a/include/linux/pm_legacy.h b/include/linux/pm_legacy.h
new file mode 100644
index 0000000..1252b45
--- /dev/null
+++ b/include/linux/pm_legacy.h
@@ -0,0 +1,56 @@
+#ifndef __LINUX_PM_LEGACY_H__
+#define __LINUX_PM_LEGACY_H__
+
+#include <linux/config.h>
+
+#ifdef CONFIG_PM_LEGACY
+
+extern int pm_active;
+
+#define PM_IS_ACTIVE() (pm_active != 0)
+
+/*
+ * Register a device with power management
+ */
+struct pm_dev __deprecated *
+pm_register(pm_dev_t type, unsigned long id, pm_callback callback);
+
+/*
+ * Unregister a device with power management
+ */
+void __deprecated pm_unregister(struct pm_dev *dev);
+
+/*
+ * Unregister all devices with matching callback
+ */
+void __deprecated pm_unregister_all(pm_callback callback);
+
+/*
+ * Send a request to all devices
+ */
+int __deprecated pm_send_all(pm_request_t rqst, void *data);
+
+#else /* CONFIG_PM_LEGACY */
+
+#define PM_IS_ACTIVE() 0
+
+static inline struct pm_dev *pm_register(pm_dev_t type,
+					 unsigned long id,
+					 pm_callback callback)
+{
+	return NULL;
+}
+
+static inline void pm_unregister(struct pm_dev *dev) {}
+
+static inline void pm_unregister_all(pm_callback callback) {}
+
+static inline int pm_send_all(pm_request_t rqst, void *data)
+{
+	return 0;
+}
+
+#endif /* CONFIG_PM_LEGACY */
+
+#endif /* __LINUX_PM_LEGACY_H__ */
+
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index dd98c54..d9a2f52 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -7,6 +7,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/thread_info.h>
 #include <linux/linkage.h>
 
 #ifdef CONFIG_DEBUG_PREEMPT
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2bbf968..2038bd2 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -357,7 +357,6 @@ struct mm_struct {
 	/* aio bits */
 	rwlock_t		ioctx_list_lock;
 	struct kioctx		*ioctx_list;
-	struct kioctx		default_kioctx;
 };
 
 struct sighand_struct {
@@ -1233,32 +1232,49 @@ static inline void task_unlock(struct ta
 	spin_unlock(&p->alloc_lock);
 }
 
+#ifndef __HAVE_THREAD_FUNCTIONS
+
+#define task_thread_info(task) (task)->thread_info
+
+static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
+{
+	*task_thread_info(p) = *task_thread_info(org);
+	task_thread_info(p)->task = p;
+}
+
+static inline unsigned long *end_of_stack(struct task_struct *p)
+{
+	return (unsigned long *)(p->thread_info + 1);
+}
+
+#endif
+
 /* set thread flags in other task's structures
  * - see asm/thread_info.h for TIF_xxxx flags available
  */
 static inline void set_tsk_thread_flag(struct task_struct *tsk, int flag)
 {
-	set_ti_thread_flag(tsk->thread_info,flag);
+	set_ti_thread_flag(task_thread_info(tsk), flag);
 }
 
 static inline void clear_tsk_thread_flag(struct task_struct *tsk, int flag)
 {
-	clear_ti_thread_flag(tsk->thread_info,flag);
+	clear_ti_thread_flag(task_thread_info(tsk), flag);
 }
 
 static inline int test_and_set_tsk_thread_flag(struct task_struct *tsk, int flag)
 {
-	return test_and_set_ti_thread_flag(tsk->thread_info,flag);
+	return test_and_set_ti_thread_flag(task_thread_info(tsk), flag);
 }
 
 static inline int test_and_clear_tsk_thread_flag(struct task_struct *tsk, int flag)
 {
-	return test_and_clear_ti_thread_flag(tsk->thread_info,flag);
+	return test_and_clear_ti_thread_flag(task_thread_info(tsk), flag);
 }
 
 static inline int test_tsk_thread_flag(struct task_struct *tsk, int flag)
 {
-	return test_ti_thread_flag(tsk->thread_info,flag);
+	return test_ti_thread_flag(task_thread_info(tsk), flag);
 }
 
 static inline void set_tsk_need_resched(struct task_struct *tsk)
@@ -1329,12 +1345,12 @@ extern void signal_wake_up(struct task_s
 
 static inline unsigned int task_cpu(const struct task_struct *p)
 {
-	return p->thread_info->cpu;
+	return task_thread_info(p)->cpu;
 }
 
 static inline void set_task_cpu(struct task_struct *p, unsigned int cpu)
 {
-	p->thread_info->cpu = cpu;
+	task_thread_info(p)->cpu = cpu;
 }
 
 #else
diff --git a/include/linux/smp_lock.h b/include/linux/smp_lock.h
index b63ce70..fa1ff3b 100644
--- a/include/linux/smp_lock.h
+++ b/include/linux/smp_lock.h
@@ -2,11 +2,10 @@
 #define __LINUX_SMPLOCK_H
 
 #include <linux/config.h>
+#ifdef CONFIG_LOCK_KERNEL
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 
-#ifdef CONFIG_LOCK_KERNEL
-
 #define kernel_locked()		(current->lock_depth >= 0)
 
 extern int __lockfunc __reacquire_kernel_lock(void);
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 64f203c..6bc03c9 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -20,7 +20,6 @@
 
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/list.h>
 #include <linux/compiler.h>
 
 struct file;
@@ -859,6 +858,7 @@ enum
 };
 
 #ifdef __KERNEL__
+#include <linux/list.h>
 
 extern void sysctl_init(void);
 
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index d252f45..1c4eb41 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -27,31 +27,6 @@ extern long do_no_restart_syscall(struct
  * - pass TIF_xxxx constants to these functions
  */
 
-static inline void set_thread_flag(int flag)
-{
-	set_bit(flag,&current_thread_info()->flags);
-}
-
-static inline void clear_thread_flag(int flag)
-{
-	clear_bit(flag,&current_thread_info()->flags);
-}
-
-static inline int test_and_set_thread_flag(int flag)
-{
-	return test_and_set_bit(flag,&current_thread_info()->flags);
-}
-
-static inline int test_and_clear_thread_flag(int flag)
-{
-	return test_and_clear_bit(flag,&current_thread_info()->flags);
-}
-
-static inline int test_thread_flag(int flag)
-{
-	return test_bit(flag,&current_thread_info()->flags);
-}
-
 static inline void set_ti_thread_flag(struct thread_info *ti, int flag)
 {
 	set_bit(flag,&ti->flags);
@@ -77,15 +52,19 @@ static inline int test_ti_thread_flag(st
 	return test_bit(flag,&ti->flags);
 }
 
-static inline void set_need_resched(void)
-{
-	set_thread_flag(TIF_NEED_RESCHED);
-}
+#define set_thread_flag(flag) \
+	set_ti_thread_flag(current_thread_info(), flag)
+#define clear_thread_flag(flag) \
+	clear_ti_thread_flag(current_thread_info(), flag)
+#define test_and_set_thread_flag(flag) \
+	test_and_set_ti_thread_flag(current_thread_info(), flag)
+#define test_and_clear_thread_flag(flag) \
+	test_and_clear_ti_thread_flag(current_thread_info(), flag)
+#define test_thread_flag(flag) \
+	test_ti_thread_flag(current_thread_info(), flag)
 
-static inline void clear_need_resched(void)
-{
-	clear_thread_flag(TIF_NEED_RESCHED);
-}
+#define set_need_resched()	set_thread_flag(TIF_NEED_RESCHED)
+#define clear_need_resched()	clear_thread_flag(TIF_NEED_RESCHED)
 
 #endif
 
diff --git a/include/linux/time.h b/include/linux/time.h
index 8e83f4e..bfbe92d 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -101,7 +101,7 @@ extern struct timespec timespec_trunc(st
 static inline void
 set_normalized_timespec (struct timespec *ts, time_t sec, long nsec)
 {
-	while (nsec > NSEC_PER_SEC) {
+	while (nsec >= NSEC_PER_SEC) {
 		nsec -= NSEC_PER_SEC;
 		++sec;
 	}
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 748d043..856d232 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -819,7 +819,7 @@ typedef void (*usb_complete_t)(struct ur
  */
 struct urb
 {
-	/* private, usb core and host controller only fields in the urb */
+	/* private: usb core and host controller only fields in the urb */
 	struct kref kref;		/* reference count of the URB */
 	spinlock_t lock;		/* lock for the URB */
 	void *hcpriv;			/* private data for host controller */
@@ -827,7 +827,7 @@ struct urb
 	atomic_t use_count;		/* concurrent submissions counter */
 	u8 reject;			/* submissions will fail */
 
-	/* public, documented fields in the urb that can be used by drivers */
+	/* public: documented fields in the urb that can be used by drivers */
 	struct list_head urb_list;	/* list head for use by the urb's
 					 * current owner */
 	struct usb_device *dev; 	/* (in) pointer to associated device */
@@ -1045,7 +1045,7 @@ struct usb_sg_request {
 	size_t			bytes;
 
 	/* 
-	 * members below are private to usbcore,
+	 * members below are private: to usbcore,
 	 * and are not provided for driver access!
 	 */
 	spinlock_t		lock;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index a114fff..1cded68 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -636,6 +636,7 @@ typedef __u64 v4l2_std_id;
 #define V4L2_STD_SECAM_K        ((v4l2_std_id)0x00100000)
 #define V4L2_STD_SECAM_K1       ((v4l2_std_id)0x00200000)
 #define V4L2_STD_SECAM_L        ((v4l2_std_id)0x00400000)
+#define V4L2_STD_SECAM_LC       ((v4l2_std_id)0x00800000)
 
 /* ATSC/HDTV */
 #define V4L2_STD_ATSC_8_VSB     ((v4l2_std_id)0x01000000)
diff --git a/include/media/ir-common.h b/include/media/ir-common.h
index 0f1ba95..ad3e9bb 100644
--- a/include/media/ir-common.h
+++ b/include/media/ir-common.h
@@ -49,6 +49,7 @@ struct ir_input_state {
 
 extern IR_KEYTAB_TYPE ir_codes_rc5_tv[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_empty[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE];
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
index 00fa57e..730f21e 100644
--- a/include/media/ir-kbd-i2c.h
+++ b/include/media/ir-kbd-i2c.h
@@ -19,4 +19,6 @@ struct IR_i2c {
 	char                   phys[32];
 	int                    (*get_key)(struct IR_i2c*, u32*, u32*);
 };
+
+int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw);
 #endif
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 9184e53..faa0f8e 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -113,6 +113,7 @@
 #define TUNER_PHILIPS_TD1316		67
 
 #define TUNER_PHILIPS_TUV1236D		68	/* ATI HDTV Wonder */
+#define TUNER_TNF_5335MF                69	/* Sabrent Bt848   */
 
 #define NOTUNER 0
 #define PAL     1	/* PAL_BG */
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
new file mode 100644
index 0000000..d3fd481
--- /dev/null
+++ b/include/media/v4l2-common.h
@@ -0,0 +1,110 @@
+/*
+    v4l2 common internal API header
+
+    This header contains internal shared ioctl definitions for use by the
+    internal low-level v4l2 drivers.
+    Each ioctl begins with VIDIOC_INT_ to clearly mark that it is an internal
+    define,
+
+    Copyright (C) 2005  Hans Verkuil <hverkuil@xs4all.nl>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef V4L2_COMMON_H_
+#define V4L2_COMMON_H_
+
+/* VIDIOC_INT_AUDIO_CLOCK_FREQ */
+enum v4l2_audio_clock_freq {
+	V4L2_AUDCLK_32_KHZ  = 32000,
+	V4L2_AUDCLK_441_KHZ = 44100,
+	V4L2_AUDCLK_48_KHZ  = 48000,
+};
+
+/* VIDIOC_INT_G_REGISTER and VIDIOC_INT_S_REGISTER */
+struct v4l2_register {
+	u32 i2c_id; 		/* I2C driver ID of the I2C chip. 0 for the I2C adapter. */
+	unsigned long reg;
+	u32 val;
+};
+
+/* VIDIOC_INT_DECODE_VBI_LINE */
+struct v4l2_decode_vbi_line {
+	u32 is_second_field;	/* Set to 0 for the first (odd) field,
+				   set to 1 for the second (even) field. */
+	u8 *p; 			/* Pointer to the sliced VBI data from the decoder.
+				   On exit points to the start of the payload. */
+	u32 line;		/* Line number of the sliced VBI data (1-23) */
+	u32 type;		/* VBI service type (V4L2_SLICED_*). 0 if no service found */
+};
+
+/* VIDIOC_INT_G_CHIP_IDENT: identifies the actual chip installed on the board */
+enum v4l2_chip_ident {
+	/* general idents: reserved range 0-49 */
+	V4L2_IDENT_UNKNOWN = 0,
+
+	/* module saa7115: reserved range 100-149 */
+	V4L2_IDENT_SAA7114 = 104,
+	V4L2_IDENT_SAA7115 = 105,
+
+	/* module saa7127: reserved range 150-199 */
+	V4L2_IDENT_SAA7127 = 157,
+	V4L2_IDENT_SAA7129 = 159,
+
+	/* module cx25840: reserved range 200-249 */
+	V4L2_IDENT_CX25840 = 240,
+	V4L2_IDENT_CX25841 = 241,
+	V4L2_IDENT_CX25842 = 242,
+	V4L2_IDENT_CX25843 = 243,
+};
+
+/* only implemented if CONFIG_VIDEO_ADV_DEBUG is defined */
+#define	VIDIOC_INT_S_REGISTER 		_IOR ('d', 100, struct v4l2_register)
+#define	VIDIOC_INT_G_REGISTER 		_IOWR('d', 101, struct v4l2_register)
+
+/* Reset the I2C chip */
+#define VIDIOC_INT_RESET            	_IO  ('d', 102)
+
+/* Set the frequency of the audio clock output.
+   Used to slave an audio processor to the video decoder, ensuring that audio
+   and video remain synchronized. */
+#define VIDIOC_INT_AUDIO_CLOCK_FREQ 	_IOR ('d', 103, enum v4l2_audio_clock_freq)
+
+/* Video decoders that support sliced VBI need to implement this ioctl.
+   Field p of the v4l2_sliced_vbi_line struct is set to the start of the VBI
+   data that was generated by the decoder. The driver then parses the sliced
+   VBI data and sets the other fields in the struct accordingly. The pointer p
+   is updated to point to the start of the payload which can be copied
+   verbatim into the data field of the v4l2_sliced_vbi_data struct. If no
+   valid VBI data was found, then the type field is set to 0 on return. */
+#define VIDIOC_INT_DECODE_VBI_LINE  	_IOWR('d', 104, struct v4l2_decode_vbi_line)
+
+/* Used to generate VBI signals on a video signal. v4l2_sliced_vbi_data is
+   filled with the data packets that should be output. Note that if you set
+   the line field to 0, then that VBI signal is disabled. */
+#define VIDIOC_INT_S_VBI_DATA 		_IOW ('d', 105, struct v4l2_sliced_vbi_data)
+
+/* Used to obtain the sliced VBI packet from a readback register. Not all
+   video decoders support this. If no data is available because the readback
+   register contains invalid or erroneous data -EIO is returned. Note that
+   you must fill in the 'id' member and the 'field' member (to determine
+   whether CC data from the first or second field should be obtained). */
+#define VIDIOC_INT_G_VBI_DATA 		_IOWR('d', 106, struct v4l2_sliced_vbi_data *)
+
+/* Returns the chip identifier or V4L2_IDENT_UNKNOWN if no identification can
+   be made. */
+#define VIDIOC_INT_G_CHIP_IDENT		_IOR ('d', 107, enum v4l2_chip_ident *)
+
+#endif /* V4L2_COMMON_H_ */
diff --git a/include/net/llc_pdu.h b/include/net/llc_pdu.h
index c7a9594..8f63065 100644
--- a/include/net/llc_pdu.h
+++ b/include/net/llc_pdu.h
@@ -357,7 +357,7 @@ static inline void llc_pdu_init_as_test_
 
 /* LLC Type 1 XID command/response information fields format */
 struct llc_xid_info {
-	u8 fmt_id;	/* always 0x18 for LLC */
+	u8 fmt_id;	/* always 0x81 for LLC */
 	u8 type;	/* different if NULL/non-NULL LSAP */
 	u8 rw;		/* sender receive window */
 };
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 0f98480..d78025f 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -552,8 +552,8 @@ extern u32	__tcp_select_window(struct so
 
 /* TCP timestamps are only 32-bits, this causes a slight
  * complication on 64-bit systems since we store a snapshot
- * of jiffies in the buffer control blocks below.  We decidedly
- * only use of the low 32-bits of jiffies and hide the ugly
+ * of jiffies in the buffer control blocks below.  We decided
+ * to use only the low 32-bits of jiffies and hide the ugly
  * casts with the following macro.
  */
 #define tcp_time_stamp		((__u32)(jiffies))
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 5a737ed..7430640 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -1809,11 +1809,12 @@ int cpuset_zone_allowed(struct zone *z, 
 	if (gfp_mask & __GFP_HARDWALL)	/* If hardwall request, stop here */
 		return 0;
 
+	if (current->flags & PF_EXITING) /* Let dying task have memory */
+		return 1;
+
 	/* Not hardwall and node outside mems_allowed: scan up cpusets */
 	down(&callback_sem);
 
-	if (current->flags & PF_EXITING) /* Let dying task have memory */
-		return 1;
 	task_lock(current);
 	cs = nearest_exclusive_ancestor(current->cpuset);
 	task_unlock(current);
diff --git a/kernel/exit.c b/kernel/exit.c
index 452a1d1..ee51568 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -859,7 +859,7 @@ fastcall NORET_TYPE void do_exit(long co
 	if (group_dead && tsk->signal->leader)
 		disassociate_ctty(1);
 
-	module_put(tsk->thread_info->exec_domain->module);
+	module_put(task_thread_info(tsk)->exec_domain->module);
 	if (tsk->binfmt)
 		module_put(tsk->binfmt->module);
 
diff --git a/kernel/fork.c b/kernel/fork.c
index 158710d..e0d0b77 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -171,10 +171,9 @@ static struct task_struct *dup_task_stru
 		return NULL;
 	}
 
-	*ti = *orig->thread_info;
 	*tsk = *orig;
 	tsk->thread_info = ti;
-	ti->task = tsk;
+	setup_thread_stack(tsk, orig);
 
 	/* One for us, one for whoever does the "release_task()" (usually parent) */
 	atomic_set(&tsk->usage,2);
@@ -324,7 +323,6 @@ static struct mm_struct * mm_init(struct
 	spin_lock_init(&mm->page_table_lock);
 	rwlock_init(&mm->ioctx_list_lock);
 	mm->ioctx_list = NULL;
-	mm->default_kioctx = (struct kioctx)INIT_KIOCTX(mm->default_kioctx, *mm);
 	mm->free_area_cache = TASK_UNMAPPED_BASE;
 	mm->cached_hole_size = ~0UL;
 
@@ -919,7 +917,7 @@ static task_t *copy_process(unsigned lon
 	if (nr_threads >= max_threads)
 		goto bad_fork_cleanup_count;
 
-	if (!try_module_get(p->thread_info->exec_domain->module))
+	if (!try_module_get(task_thread_info(p)->exec_domain->module))
 		goto bad_fork_cleanup_count;
 
 	if (p->binfmt && !try_module_get(p->binfmt->module))
@@ -1180,7 +1178,7 @@ bad_fork_cleanup:
 	if (p->binfmt)
 		module_put(p->binfmt->module);
 bad_fork_cleanup_put_domain:
-	module_put(p->thread_info->exec_domain->module);
+	module_put(task_thread_info(p)->exec_domain->module);
 bad_fork_cleanup_count:
 	put_group_info(p->group_info);
 	atomic_dec(&p->user->processes);
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index ea55c7a..5870efb 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -270,7 +270,7 @@ static void tstojiffie(struct timespec *
 	long sec = tp->tv_sec;
 	long nsec = tp->tv_nsec + res - 1;
 
-	if (nsec > NSEC_PER_SEC) {
+	if (nsec >= NSEC_PER_SEC) {
 		sec++;
 		nsec -= NSEC_PER_SEC;
 	}
@@ -1209,13 +1209,9 @@ static int do_posix_clock_monotonic_get(
 
 	do_posix_clock_monotonic_gettime_parts(tp, &wall_to_mono);
 
-	tp->tv_sec += wall_to_mono.tv_sec;
-	tp->tv_nsec += wall_to_mono.tv_nsec;
+	set_normalized_timespec(tp, tp->tv_sec + wall_to_mono.tv_sec,
+				tp->tv_nsec + wall_to_mono.tv_nsec);
 
-	if ((tp->tv_nsec - NSEC_PER_SEC) > 0) {
-		tp->tv_nsec -= NSEC_PER_SEC;
-		tp->tv_sec++;
-	}
 	return 0;
 }
 
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 46a5e5a..5ec248c 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -19,6 +19,15 @@ config PM
 	  will issue the hlt instruction if nothing is to be done, thereby
 	  sending the processor to sleep and saving power.
 
+config PM_LEGACY
+	bool "Legacy Power Management API"
+	depends on PM
+	default y
+	---help---
+	   Support for pm_register() and friends.
+
+	   If unsure, say Y.
+
 config PM_DEBUG
 	bool "Power Management Debug Support"
 	depends on PM
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
index c71eb45..04be7d0 100644
--- a/kernel/power/Makefile
+++ b/kernel/power/Makefile
@@ -3,7 +3,8 @@ ifeq ($(CONFIG_PM_DEBUG),y)
 EXTRA_CFLAGS	+=	-DDEBUG
 endif
 
-obj-y				:= main.o process.o console.o pm.o
+obj-y				:= main.o process.o console.o
+obj-$(CONFIG_PM_LEGACY)		+= pm.o
 obj-$(CONFIG_SOFTWARE_SUSPEND)	+= swsusp.o disk.o snapshot.o
 
 obj-$(CONFIG_SUSPEND_SMP)	+= smp.o
diff --git a/kernel/power/pm.c b/kernel/power/pm.c
index 1591493..33c508e 100644
--- a/kernel/power/pm.c
+++ b/kernel/power/pm.c
@@ -23,6 +23,7 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/interrupt.h>
 
 int pm_active;
diff --git a/kernel/printk.c b/kernel/printk.c
index e9be027..ac8a08f 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -491,7 +491,10 @@ __attribute__((weak)) unsigned long long
 	return sched_clock();
 }
 
-/*
+/**
+ * printk - print a kernel message
+ * @fmt: format string
+ *
  * This is printk.  It can be called from any context.  We want it to work.
  *
  * We try to grab the console_sem.  If we succeed, it's easy - we log the output and
@@ -503,6 +506,9 @@ __attribute__((weak)) unsigned long long
  * One effect of this deferred printing is that code which calls printk() and
  * then changes console_loglevel may break. This is because console_loglevel
  * is inspected when the actual printing occurs.
+ *
+ * See also:
+ * printf(3)
  */
 
 asmlinkage int printk(const char *fmt, ...)
@@ -655,6 +661,9 @@ static void call_console_drivers(unsigne
 
 /**
  * add_preferred_console - add a device to the list of preferred consoles.
+ * @name: device name
+ * @idx: device index
+ * @options: options for this console
  *
  * The last preferred console added will be used for kernel messages
  * and stdin/out/err for init.  Normally this is used by console_setup
@@ -764,7 +773,8 @@ void release_console_sem(void)
 }
 EXPORT_SYMBOL(release_console_sem);
 
-/** console_conditional_schedule - yield the CPU if required
+/**
+ * console_conditional_schedule - yield the CPU if required
  *
  * If the console code is currently allowed to sleep, and
  * if this CPU should yield the CPU to another task, do
@@ -976,6 +986,8 @@ EXPORT_SYMBOL(unregister_console);
 
 /**
  * tty_write_message - write a message to a certain tty, not just the console.
+ * @tty: the destination tty_struct
+ * @msg: the message to write
  *
  * This is used for messages that need to be redirected to a specific tty.
  * We don't put it into the syslog queue right now maybe in the future if
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index b88d418..17ee7e5 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -470,7 +470,7 @@ asmlinkage long sys_ptrace(long request,
 
 	if (request == PTRACE_ATTACH) {
 		ret = ptrace_attach(child);
-		goto out;
+		goto out_put_task_struct;
 	}
 
 	ret = ptrace_check_attach(child, request == PTRACE_KILL);
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 9b58f1e..eb6719c 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -195,6 +195,8 @@ rcu_torture_writer(void *arg)
 	static DEFINE_RCU_RANDOM(rand);
 
 	VERBOSE_PRINTK_STRING("rcu_torture_writer task started");
+	set_user_nice(current, 19);
+
 	do {
 		schedule_timeout_uninterruptible(1);
 		if (rcu_batches_completed() == oldbatch)
@@ -238,6 +240,8 @@ rcu_torture_reader(void *arg)
 	int pipe_count;
 
 	VERBOSE_PRINTK_STRING("rcu_torture_reader task started");
+	set_user_nice(current, 19);
+
 	do {
 		rcu_read_lock();
 		completed = rcu_batches_completed();
diff --git a/kernel/sched.c b/kernel/sched.c
index b650667..6f46c94 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1437,7 +1437,7 @@ void fastcall sched_fork(task_t *p, int 
 #endif
 #ifdef CONFIG_PREEMPT
 	/* Want to start with kernel preemption disabled. */
-	p->thread_info->preempt_count = 1;
+	task_thread_info(p)->preempt_count = 1;
 #endif
 	/*
 	 * Share the timeslice between parent and child, thus the
@@ -4327,10 +4327,10 @@ static void show_task(task_t *p)
 #endif
 #ifdef CONFIG_DEBUG_STACK_USAGE
 	{
-		unsigned long *n = (unsigned long *) (p->thread_info+1);
+		unsigned long *n = end_of_stack(p);
 		while (!*n)
 			n++;
-		free = (unsigned long) n - (unsigned long)(p->thread_info+1);
+		free = (unsigned long)n - (unsigned long)end_of_stack(p);
 	}
 #endif
 	printk("%5lu %5d %6d ", free, p->pid, p->parent->pid);
@@ -4410,9 +4410,9 @@ void __devinit init_idle(task_t *idle, i
 
 	/* Set the preempt count _outside_ the spinlocks! */
 #if defined(CONFIG_PREEMPT) && !defined(CONFIG_PREEMPT_BKL)
-	idle->thread_info->preempt_count = (idle->lock_depth >= 0);
+	task_thread_info(idle)->preempt_count = (idle->lock_depth >= 0);
 #else
-	idle->thread_info->preempt_count = 0;
+	task_thread_info(idle)->preempt_count = 0;
 #endif
 }
 
diff --git a/kernel/signal.c b/kernel/signal.c
index 80789a5..d7611f1 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -513,16 +513,7 @@ static int __dequeue_signal(struct sigpe
 {
 	int sig = 0;
 
-	/* SIGKILL must have priority, otherwise it is quite easy
-	 * to create an unkillable process, sending sig < SIGKILL
-	 * to self */
-	if (unlikely(sigismember(&pending->signal, SIGKILL))) {
-		if (!sigismember(mask, SIGKILL))
-			sig = SIGKILL;
-	}
-
-	if (likely(!sig))
-		sig = next_signal(pending, mask);
+	sig = next_signal(pending, mask);
 	if (sig) {
 		if (current->notifier) {
 			if (sigismember(current->notifier_mask, sig)) {
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c
index 84a9d18..b3d4dc8 100644
--- a/kernel/stop_machine.c
+++ b/kernel/stop_machine.c
@@ -119,13 +119,12 @@ static int stop_machine(void)
 		return ret;
 	}
 
-	/* Don't schedule us away at this point, please. */
-	local_irq_disable();
-
 	/* Now they are all started, make them hold the CPUs, ready. */
+	preempt_disable();
 	stopmachine_set_state(STOPMACHINE_PREPARE);
 
 	/* Make them disable irqs. */
+	local_irq_disable();
 	stopmachine_set_state(STOPMACHINE_DISABLE_IRQ);
 
 	return 0;
@@ -135,6 +134,7 @@ static void restart_machine(void)
 {
 	stopmachine_set_state(STOPMACHINE_EXIT);
 	local_irq_enable();
+	preempt_enable_no_resched();
 }
 
 struct stop_machine_data
diff --git a/mm/filemap.c b/mm/filemap.c
index 5d6e4c2..33a28bf 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -134,7 +134,7 @@ static int sync_page(void *word)
 	struct address_space *mapping;
 	struct page *page;
 
-	page = container_of((page_flags_t *)word, struct page, flags);
+	page = container_of((unsigned long *)word, struct page, flags);
 
 	/*
 	 * page_mapping() is being called without PG_locked held.
diff --git a/mm/memory.c b/mm/memory.c
index 0f60baf..2998cfc 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -549,10 +549,10 @@ int copy_page_range(struct mm_struct *ds
 	return 0;
 }
 
-static void zap_pte_range(struct mmu_gather *tlb,
+static unsigned long zap_pte_range(struct mmu_gather *tlb,
 				struct vm_area_struct *vma, pmd_t *pmd,
 				unsigned long addr, unsigned long end,
-				struct zap_details *details)
+				long *zap_work, struct zap_details *details)
 {
 	struct mm_struct *mm = tlb->mm;
 	pte_t *pte;
@@ -563,10 +563,15 @@ static void zap_pte_range(struct mmu_gat
 	pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
 	do {
 		pte_t ptent = *pte;
-		if (pte_none(ptent))
+		if (pte_none(ptent)) {
+			(*zap_work)--;
 			continue;
+		}
 		if (pte_present(ptent)) {
 			struct page *page = NULL;
+
+			(*zap_work) -= PAGE_SIZE;
+
 			if (!(vma->vm_flags & VM_RESERVED)) {
 				unsigned long pfn = pte_pfn(ptent);
 				if (unlikely(!pfn_valid(pfn)))
@@ -624,16 +629,18 @@ static void zap_pte_range(struct mmu_gat
 		if (!pte_file(ptent))
 			free_swap_and_cache(pte_to_swp_entry(ptent));
 		pte_clear_full(mm, addr, pte, tlb->fullmm);
-	} while (pte++, addr += PAGE_SIZE, addr != end);
+	} while (pte++, addr += PAGE_SIZE, (addr != end && *zap_work > 0));
 
 	add_mm_rss(mm, file_rss, anon_rss);
 	pte_unmap_unlock(pte - 1, ptl);
+
+	return addr;
 }
 
-static inline void zap_pmd_range(struct mmu_gather *tlb,
+static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
 				struct vm_area_struct *vma, pud_t *pud,
 				unsigned long addr, unsigned long end,
-				struct zap_details *details)
+				long *zap_work, struct zap_details *details)
 {
 	pmd_t *pmd;
 	unsigned long next;
@@ -641,16 +648,21 @@ static inline void zap_pmd_range(struct 
 	pmd = pmd_offset(pud, addr);
 	do {
 		next = pmd_addr_end(addr, end);
-		if (pmd_none_or_clear_bad(pmd))
+		if (pmd_none_or_clear_bad(pmd)) {
+			(*zap_work)--;
 			continue;
-		zap_pte_range(tlb, vma, pmd, addr, next, details);
-	} while (pmd++, addr = next, addr != end);
+		}
+		next = zap_pte_range(tlb, vma, pmd, addr, next,
+						zap_work, details);
+	} while (pmd++, addr = next, (addr != end && *zap_work > 0));
+
+	return addr;
 }
 
-static inline void zap_pud_range(struct mmu_gather *tlb,
+static inline unsigned long zap_pud_range(struct mmu_gather *tlb,
 				struct vm_area_struct *vma, pgd_t *pgd,
 				unsigned long addr, unsigned long end,
-				struct zap_details *details)
+				long *zap_work, struct zap_details *details)
 {
 	pud_t *pud;
 	unsigned long next;
@@ -658,15 +670,21 @@ static inline void zap_pud_range(struct 
 	pud = pud_offset(pgd, addr);
 	do {
 		next = pud_addr_end(addr, end);
-		if (pud_none_or_clear_bad(pud))
+		if (pud_none_or_clear_bad(pud)) {
+			(*zap_work)--;
 			continue;
-		zap_pmd_range(tlb, vma, pud, addr, next, details);
-	} while (pud++, addr = next, addr != end);
+		}
+		next = zap_pmd_range(tlb, vma, pud, addr, next,
+						zap_work, details);
+	} while (pud++, addr = next, (addr != end && *zap_work > 0));
+
+	return addr;
 }
 
-static void unmap_page_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
+static unsigned long unmap_page_range(struct mmu_gather *tlb,
+				struct vm_area_struct *vma,
 				unsigned long addr, unsigned long end,
-				struct zap_details *details)
+				long *zap_work, struct zap_details *details)
 {
 	pgd_t *pgd;
 	unsigned long next;
@@ -679,11 +697,16 @@ static void unmap_page_range(struct mmu_
 	pgd = pgd_offset(vma->vm_mm, addr);
 	do {
 		next = pgd_addr_end(addr, end);
-		if (pgd_none_or_clear_bad(pgd))
+		if (pgd_none_or_clear_bad(pgd)) {
+			(*zap_work)--;
 			continue;
-		zap_pud_range(tlb, vma, pgd, addr, next, details);
-	} while (pgd++, addr = next, addr != end);
+		}
+		next = zap_pud_range(tlb, vma, pgd, addr, next,
+						zap_work, details);
+	} while (pgd++, addr = next, (addr != end && *zap_work > 0));
 	tlb_end_vma(tlb, vma);
+
+	return addr;
 }
 
 #ifdef CONFIG_PREEMPT
@@ -724,7 +747,7 @@ unsigned long unmap_vmas(struct mmu_gath
 		unsigned long end_addr, unsigned long *nr_accounted,
 		struct zap_details *details)
 {
-	unsigned long zap_bytes = ZAP_BLOCK_SIZE;
+	long zap_work = ZAP_BLOCK_SIZE;
 	unsigned long tlb_start = 0;	/* For tlb_finish_mmu */
 	int tlb_start_valid = 0;
 	unsigned long start = start_addr;
@@ -745,27 +768,25 @@ unsigned long unmap_vmas(struct mmu_gath
 			*nr_accounted += (end - start) >> PAGE_SHIFT;
 
 		while (start != end) {
-			unsigned long block;
-
 			if (!tlb_start_valid) {
 				tlb_start = start;
 				tlb_start_valid = 1;
 			}
 
-			if (is_vm_hugetlb_page(vma)) {
-				block = end - start;
+			if (unlikely(is_vm_hugetlb_page(vma))) {
 				unmap_hugepage_range(vma, start, end);
-			} else {
-				block = min(zap_bytes, end - start);
-				unmap_page_range(*tlbp, vma, start,
-						start + block, details);
+				zap_work -= (end - start) /
+						(HPAGE_SIZE / PAGE_SIZE);
+				start = end;
+			} else
+				start = unmap_page_range(*tlbp, vma,
+						start, end, &zap_work, details);
+
+			if (zap_work > 0) {
+				BUG_ON(start != end);
+				break;
 			}
 
-			start += block;
-			zap_bytes -= block;
-			if ((long)zap_bytes > 0)
-				continue;
-
 			tlb_finish_mmu(*tlbp, tlb_start, start);
 
 			if (need_resched() ||
@@ -779,7 +800,7 @@ unsigned long unmap_vmas(struct mmu_gath
 
 			*tlbp = tlb_gather_mmu(vma->vm_mm, fullmm);
 			tlb_start_valid = 0;
-			zap_bytes = ZAP_BLOCK_SIZE;
+			zap_work = ZAP_BLOCK_SIZE;
 		}
 	}
 out:
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 987225b..104e69c 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -60,8 +60,11 @@ long nr_swap_pages;
  *	NORMAL allocation will leave 784M/256 of ram reserved in the ZONE_DMA
  *	HIGHMEM allocation will leave 224M/32 of ram reserved in ZONE_NORMAL
  *	HIGHMEM allocation will (224M+784M)/256 of ram reserved in ZONE_DMA
+ *
+ * TBD: should special case ZONE_DMA32 machines here - in those we normally
+ * don't need any ZONE_NORMAL reservation
  */
-int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1] = { 256, 32 };
+int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1] = { 256, 256, 32 };
 
 EXPORT_SYMBOL(totalram_pages);
 
@@ -72,7 +75,7 @@ EXPORT_SYMBOL(totalram_pages);
 struct zone *zone_table[1 << ZONETABLE_SHIFT] __read_mostly;
 EXPORT_SYMBOL(zone_table);
 
-static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
+static char *zone_names[MAX_NR_ZONES] = { "DMA", "DMA32", "Normal", "HighMem" };
 int min_free_kbytes = 1024;
 
 unsigned long __initdata nr_kernel_pages;
@@ -124,7 +127,7 @@ static void bad_page(const char *functio
 	printk(KERN_EMERG "Bad page state at %s (in process '%s', page %p)\n",
 		function, current->comm, page);
 	printk(KERN_EMERG "flags:0x%0*lx mapping:%p mapcount:%d count:%d\n",
-		(int)(2*sizeof(page_flags_t)), (unsigned long)page->flags,
+		(int)(2*sizeof(unsigned long)), (unsigned long)page->flags,
 		page->mapping, page_mapcount(page), page_count(page));
 	printk(KERN_EMERG "Backtrace:\n");
 	dump_stack();
@@ -732,9 +735,7 @@ buffered_rmqueue(struct zone *zone, int 
 		}
 		local_irq_restore(flags);
 		put_cpu();
-	}
-
-	if (page == NULL) {
+	} else {
 		spin_lock_irqsave(&zone->lock, flags);
 		page = __rmqueue(zone, order);
 		spin_unlock_irqrestore(&zone->lock, flags);
@@ -754,20 +755,25 @@ buffered_rmqueue(struct zone *zone, int 
 	return page;
 }
 
+#define ALLOC_NO_WATERMARKS	0x01 /* don't check watermarks at all */
+#define ALLOC_HARDER		0x02 /* try to alloc harder */
+#define ALLOC_HIGH		0x04 /* __GFP_HIGH set */
+#define ALLOC_CPUSET		0x08 /* check for correct cpuset */
+
 /*
  * Return 1 if free pages are above 'mark'. This takes into account the order
  * of the allocation.
  */
 int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
-		      int classzone_idx, int can_try_harder, gfp_t gfp_high)
+		      int classzone_idx, int alloc_flags)
 {
 	/* free_pages my go negative - that's OK */
 	long min = mark, free_pages = z->free_pages - (1 << order) + 1;
 	int o;
 
-	if (gfp_high)
+	if (alloc_flags & ALLOC_HIGH)
 		min -= min / 2;
-	if (can_try_harder)
+	if (alloc_flags & ALLOC_HARDER)
 		min -= min / 4;
 
 	if (free_pages <= min + z->lowmem_reserve[classzone_idx])
@@ -785,14 +791,40 @@ int zone_watermark_ok(struct zone *z, in
 	return 1;
 }
 
-static inline int
-should_reclaim_zone(struct zone *z, gfp_t gfp_mask)
+/*
+ * get_page_from_freeliest goes through the zonelist trying to allocate
+ * a page.
+ */
+static struct page *
+get_page_from_freelist(gfp_t gfp_mask, unsigned int order,
+		struct zonelist *zonelist, int alloc_flags)
 {
-	if (!z->reclaim_pages)
-		return 0;
-	if (gfp_mask & __GFP_NORECLAIM)
-		return 0;
-	return 1;
+	struct zone **z = zonelist->zones;
+	struct page *page = NULL;
+	int classzone_idx = zone_idx(*z);
+
+	/*
+	 * Go through the zonelist once, looking for a zone with enough free.
+	 * See also cpuset_zone_allowed() comment in kernel/cpuset.c.
+	 */
+	do {
+		if ((alloc_flags & ALLOC_CPUSET) &&
+				!cpuset_zone_allowed(*z, gfp_mask))
+			continue;
+
+		if (!(alloc_flags & ALLOC_NO_WATERMARKS)) {
+			if (!zone_watermark_ok(*z, order, (*z)->pages_low,
+				    classzone_idx, alloc_flags))
+				continue;
+		}
+
+		page = buffered_rmqueue(*z, order, gfp_mask);
+		if (page) {
+			zone_statistics(zonelist, *z);
+			break;
+		}
+	} while (*(++z) != NULL);
+	return page;
 }
 
 /*
@@ -803,105 +835,75 @@ __alloc_pages(gfp_t gfp_mask, unsigned i
 		struct zonelist *zonelist)
 {
 	const gfp_t wait = gfp_mask & __GFP_WAIT;
-	struct zone **zones, *z;
+	struct zone **z;
 	struct page *page;
 	struct reclaim_state reclaim_state;
 	struct task_struct *p = current;
-	int i;
-	int classzone_idx;
 	int do_retry;
-	int can_try_harder;
+	int alloc_flags;
 	int did_some_progress;
 
 	might_sleep_if(wait);
 
-	/*
-	 * The caller may dip into page reserves a bit more if the caller
-	 * cannot run direct reclaim, or is the caller has realtime scheduling
-	 * policy
-	 */
-	can_try_harder = (unlikely(rt_task(p)) && !in_interrupt()) || !wait;
-
-	zones = zonelist->zones;  /* the list of zones suitable for gfp_mask */
+	z = zonelist->zones;  /* the list of zones suitable for gfp_mask */
 
-	if (unlikely(zones[0] == NULL)) {
+	if (unlikely(*z == NULL)) {
 		/* Should this ever happen?? */
 		return NULL;
 	}
+restart:
+	page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order,
+				zonelist, ALLOC_CPUSET);
+	if (page)
+		goto got_pg;
 
-	classzone_idx = zone_idx(zones[0]);
+	do
+		wakeup_kswapd(*z, order);
+	while (*(++z));
 
-restart:
 	/*
-	 * Go through the zonelist once, looking for a zone with enough free.
-	 * See also cpuset_zone_allowed() comment in kernel/cpuset.c.
+	 * OK, we're below the kswapd watermark and have kicked background
+	 * reclaim. Now things get more complex, so set up alloc_flags according
+	 * to how we want to proceed.
+	 *
+	 * The caller may dip into page reserves a bit more if the caller
+	 * cannot run direct reclaim, or if the caller has realtime scheduling
+	 * policy.
 	 */
-	for (i = 0; (z = zones[i]) != NULL; i++) {
-		int do_reclaim = should_reclaim_zone(z, gfp_mask);
-
-		if (!cpuset_zone_allowed(z, __GFP_HARDWALL))
-			continue;
-
-		/*
-		 * If the zone is to attempt early page reclaim then this loop
-		 * will try to reclaim pages and check the watermark a second
-		 * time before giving up and falling back to the next zone.
-		 */
-zone_reclaim_retry:
-		if (!zone_watermark_ok(z, order, z->pages_low,
-				       classzone_idx, 0, 0)) {
-			if (!do_reclaim)
-				continue;
-			else {
-				zone_reclaim(z, gfp_mask, order);
-				/* Only try reclaim once */
-				do_reclaim = 0;
-				goto zone_reclaim_retry;
-			}
-		}
-
-		page = buffered_rmqueue(z, order, gfp_mask);
-		if (page)
-			goto got_pg;
-	}
-
-	for (i = 0; (z = zones[i]) != NULL; i++)
-		wakeup_kswapd(z, order);
+	alloc_flags = 0;
+	if ((unlikely(rt_task(p)) && !in_interrupt()) || !wait)
+		alloc_flags |= ALLOC_HARDER;
+	if (gfp_mask & __GFP_HIGH)
+		alloc_flags |= ALLOC_HIGH;
+	if (wait)
+		alloc_flags |= ALLOC_CPUSET;
 
 	/*
 	 * Go through the zonelist again. Let __GFP_HIGH and allocations
-	 * coming from realtime tasks to go deeper into reserves
+	 * coming from realtime tasks go deeper into reserves.
 	 *
 	 * This is the last chance, in general, before the goto nopage.
 	 * Ignore cpuset if GFP_ATOMIC (!wait) rather than fail alloc.
 	 * See also cpuset_zone_allowed() comment in kernel/cpuset.c.
 	 */
-	for (i = 0; (z = zones[i]) != NULL; i++) {
-		if (!zone_watermark_ok(z, order, z->pages_min,
-				       classzone_idx, can_try_harder,
-				       gfp_mask & __GFP_HIGH))
-			continue;
-
-		if (wait && !cpuset_zone_allowed(z, gfp_mask))
-			continue;
-
-		page = buffered_rmqueue(z, order, gfp_mask);
-		if (page)
-			goto got_pg;
-	}
+	page = get_page_from_freelist(gfp_mask, order, zonelist, alloc_flags);
+	if (page)
+		goto got_pg;
 
 	/* This allocation should allow future memory freeing. */
 
 	if (((p->flags & PF_MEMALLOC) || unlikely(test_thread_flag(TIF_MEMDIE)))
 			&& !in_interrupt()) {
 		if (!(gfp_mask & __GFP_NOMEMALLOC)) {
+nofail_alloc:
 			/* go through the zonelist yet again, ignoring mins */
-			for (i = 0; (z = zones[i]) != NULL; i++) {
-				if (!cpuset_zone_allowed(z, gfp_mask))
-					continue;
-				page = buffered_rmqueue(z, order, gfp_mask);
-				if (page)
-					goto got_pg;
+			page = get_page_from_freelist(gfp_mask, order,
+				zonelist, ALLOC_NO_WATERMARKS|ALLOC_CPUSET);
+			if (page)
+				goto got_pg;
+			if (gfp_mask & __GFP_NOFAIL) {
+				blk_congestion_wait(WRITE, HZ/50);
+				goto nofail_alloc;
 			}
 		}
 		goto nopage;
@@ -919,7 +921,7 @@ rebalance:
 	reclaim_state.reclaimed_slab = 0;
 	p->reclaim_state = &reclaim_state;
 
-	did_some_progress = try_to_free_pages(zones, gfp_mask);
+	did_some_progress = try_to_free_pages(zonelist->zones, gfp_mask);
 
 	p->reclaim_state = NULL;
 	p->flags &= ~PF_MEMALLOC;
@@ -927,19 +929,10 @@ rebalance:
 	cond_resched();
 
 	if (likely(did_some_progress)) {
-		for (i = 0; (z = zones[i]) != NULL; i++) {
-			if (!zone_watermark_ok(z, order, z->pages_min,
-					       classzone_idx, can_try_harder,
-					       gfp_mask & __GFP_HIGH))
-				continue;
-
-			if (!cpuset_zone_allowed(z, gfp_mask))
-				continue;
-
-			page = buffered_rmqueue(z, order, gfp_mask);
-			if (page)
-				goto got_pg;
-		}
+		page = get_page_from_freelist(gfp_mask, order,
+						zonelist, alloc_flags);
+		if (page)
+			goto got_pg;
 	} else if ((gfp_mask & __GFP_FS) && !(gfp_mask & __GFP_NORETRY)) {
 		/*
 		 * Go through the zonelist yet one more time, keep
@@ -947,18 +940,10 @@ rebalance:
 		 * a parallel oom killing, we must fail if we're still
 		 * under heavy pressure.
 		 */
-		for (i = 0; (z = zones[i]) != NULL; i++) {
-			if (!zone_watermark_ok(z, order, z->pages_high,
-					       classzone_idx, 0, 0))
-				continue;
-
-			if (!cpuset_zone_allowed(z, __GFP_HARDWALL))
-				continue;
-
-			page = buffered_rmqueue(z, order, gfp_mask);
-			if (page)
-				goto got_pg;
-		}
+		page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order,
+						zonelist, ALLOC_CPUSET);
+		if (page)
+			goto got_pg;
 
 		out_of_memory(gfp_mask, order);
 		goto restart;
@@ -991,9 +976,7 @@ nopage:
 		dump_stack();
 		show_mem();
 	}
-	return NULL;
 got_pg:
-	zone_statistics(zonelist, z);
 	return page;
 }
 
@@ -1441,6 +1424,10 @@ static int __init build_zonelists_node(p
 		zone = pgdat->node_zones + ZONE_NORMAL;
 		if (zone->present_pages)
 			zonelist->zones[j++] = zone;
+	case ZONE_DMA32:
+		zone = pgdat->node_zones + ZONE_DMA32;
+		if (zone->present_pages)
+			zonelist->zones[j++] = zone;
 	case ZONE_DMA:
 		zone = pgdat->node_zones + ZONE_DMA;
 		if (zone->present_pages)
@@ -1455,6 +1442,8 @@ static inline int highest_zone(int zone_
 	int res = ZONE_NORMAL;
 	if (zone_bits & (__force int)__GFP_HIGHMEM)
 		res = ZONE_HIGHMEM;
+	if (zone_bits & (__force int)__GFP_DMA32)
+		res = ZONE_DMA32;
 	if (zone_bits & (__force int)__GFP_DMA)
 		res = ZONE_DMA;
 	return res;
@@ -1866,11 +1855,10 @@ static int __devinit pageset_cpuup_callb
 			if (process_zones(cpu))
 				ret = NOTIFY_BAD;
 			break;
-#ifdef CONFIG_HOTPLUG_CPU
+		case CPU_UP_CANCELED:
 		case CPU_DEAD:
 			free_zone_pagesets(cpu);
 			break;
-#endif
 		default:
 			break;
 	}
@@ -1975,7 +1963,7 @@ static void __init free_area_init_core(s
 		if (zholes_size)
 			realsize -= zholes_size[j];
 
-		if (j == ZONE_DMA || j == ZONE_NORMAL)
+		if (j < ZONE_HIGHMEM)
 			nr_kernel_pages += realsize;
 		nr_all_pages += realsize;
 
@@ -2417,13 +2405,18 @@ void setup_per_zone_pages_min(void)
 	}
 
 	for_each_zone(zone) {
+		unsigned long tmp;
 		spin_lock_irqsave(&zone->lru_lock, flags);
+		tmp = (pages_min * zone->present_pages) / lowmem_pages;
 		if (is_highmem(zone)) {
 			/*
-			 * Often, highmem doesn't need to reserve any pages.
-			 * But the pages_min/low/high values are also used for
-			 * batching up page reclaim activity so we need a
-			 * decent value here.
+			 * __GFP_HIGH and PF_MEMALLOC allocations usually don't
+			 * need highmem pages, so cap pages_min to a small
+			 * value here.
+			 *
+			 * The (pages_high-pages_low) and (pages_low-pages_min)
+			 * deltas controls asynch page reclaim, and so should
+			 * not be capped for highmem.
 			 */
 			int min_pages;
 
@@ -2434,19 +2427,15 @@ void setup_per_zone_pages_min(void)
 				min_pages = 128;
 			zone->pages_min = min_pages;
 		} else {
-			/* if it's a lowmem zone, reserve a number of pages
+			/*
+			 * If it's a lowmem zone, reserve a number of pages
 			 * proportionate to the zone's size.
 			 */
-			zone->pages_min = (pages_min * zone->present_pages) /
-			                   lowmem_pages;
+			zone->pages_min = tmp;
 		}
 
-		/*
-		 * When interpreting these watermarks, just keep in mind that:
-		 * zone->pages_min == (zone->pages_min * 4) / 4;
-		 */
-		zone->pages_low   = (zone->pages_min * 5) / 4;
-		zone->pages_high  = (zone->pages_min * 6) / 4;
+		zone->pages_low   = zone->pages_min + tmp / 4;
+		zone->pages_high  = zone->pages_min + tmp / 2;
 		spin_unlock_irqrestore(&zone->lru_lock, flags);
 	}
 }
diff --git a/mm/slab.c b/mm/slab.c
index 8a73dcf..e5ec26e 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -565,14 +565,29 @@ static void **dbg_userword(kmem_cache_t 
 #define	BREAK_GFP_ORDER_LO	0
 static int slab_break_gfp_order = BREAK_GFP_ORDER_LO;
 
-/* Macros for storing/retrieving the cachep and or slab from the
+/* Functions for storing/retrieving the cachep and or slab from the
  * global 'mem_map'. These are used to find the slab an obj belongs to.
  * With kfree(), these are used to find the cache which an obj belongs to.
  */
-#define	SET_PAGE_CACHE(pg,x)  ((pg)->lru.next = (struct list_head *)(x))
-#define	GET_PAGE_CACHE(pg)    ((kmem_cache_t *)(pg)->lru.next)
-#define	SET_PAGE_SLAB(pg,x)   ((pg)->lru.prev = (struct list_head *)(x))
-#define	GET_PAGE_SLAB(pg)     ((struct slab *)(pg)->lru.prev)
+static inline void page_set_cache(struct page *page, struct kmem_cache *cache)
+{
+	page->lru.next = (struct list_head *)cache;
+}
+
+static inline struct kmem_cache *page_get_cache(struct page *page)
+{
+	return (struct kmem_cache *)page->lru.next;
+}
+
+static inline void page_set_slab(struct page *page, struct slab *slab)
+{
+	page->lru.prev = (struct list_head *)slab;
+}
+
+static inline struct slab *page_get_slab(struct page *page)
+{
+	return (struct slab *)page->lru.prev;
+}
 
 /* These are the default caches for kmalloc. Custom caches can have other sizes. */
 struct cache_sizes malloc_sizes[] = {
@@ -1190,11 +1205,7 @@ static void *kmem_getpages(kmem_cache_t 
 	int i;
 
 	flags |= cachep->gfpflags;
-	if (likely(nodeid == -1)) {
-		page = alloc_pages(flags, cachep->gfporder);
-	} else {
-		page = alloc_pages_node(nodeid, flags, cachep->gfporder);
-	}
+	page = alloc_pages_node(nodeid, flags, cachep->gfporder);
 	if (!page)
 		return NULL;
 	addr = page_address(page);
@@ -1368,7 +1379,7 @@ static void check_poison_obj(kmem_cache_
 		/* Print some data about the neighboring objects, if they
 		 * exist:
 		 */
-		struct slab *slabp = GET_PAGE_SLAB(virt_to_page(objp));
+		struct slab *slabp = page_get_slab(virt_to_page(objp));
 		int objnr;
 
 		objnr = (objp-slabp->s_mem)/cachep->objsize;
@@ -2138,8 +2149,8 @@ static void set_slab_attr(kmem_cache_t *
 	i = 1 << cachep->gfporder;
 	page = virt_to_page(objp);
 	do {
-		SET_PAGE_CACHE(page, cachep);
-		SET_PAGE_SLAB(page, slabp);
+		page_set_cache(page, cachep);
+		page_set_slab(page, slabp);
 		page++;
 	} while (--i);
 }
@@ -2269,14 +2280,14 @@ static void *cache_free_debugcheck(kmem_
 	kfree_debugcheck(objp);
 	page = virt_to_page(objp);
 
-	if (GET_PAGE_CACHE(page) != cachep) {
+	if (page_get_cache(page) != cachep) {
 		printk(KERN_ERR "mismatch in kmem_cache_free: expected cache %p, got %p\n",
-				GET_PAGE_CACHE(page),cachep);
+				page_get_cache(page),cachep);
 		printk(KERN_ERR "%p is %s.\n", cachep, cachep->name);
-		printk(KERN_ERR "%p is %s.\n", GET_PAGE_CACHE(page), GET_PAGE_CACHE(page)->name);
+		printk(KERN_ERR "%p is %s.\n", page_get_cache(page), page_get_cache(page)->name);
 		WARN_ON(1);
 	}
-	slabp = GET_PAGE_SLAB(page);
+	slabp = page_get_slab(page);
 
 	if (cachep->flags & SLAB_RED_ZONE) {
 		if (*dbg_redzone1(cachep, objp) != RED_ACTIVE || *dbg_redzone2(cachep, objp) != RED_ACTIVE) {
@@ -2628,7 +2639,7 @@ static void free_block(kmem_cache_t *cac
 		struct slab *slabp;
 		unsigned int objnr;
 
-		slabp = GET_PAGE_SLAB(virt_to_page(objp));
+		slabp = page_get_slab(virt_to_page(objp));
 		l3 = cachep->nodelists[node];
 		list_del(&slabp->list);
 		objnr = (objp - slabp->s_mem) / cachep->objsize;
@@ -2744,7 +2755,7 @@ static inline void __cache_free(kmem_cac
 #ifdef CONFIG_NUMA
 	{
 		struct slab *slabp;
-		slabp = GET_PAGE_SLAB(virt_to_page(objp));
+		slabp = page_get_slab(virt_to_page(objp));
 		if (unlikely(slabp->nodeid != numa_node_id())) {
 			struct array_cache *alien = NULL;
 			int nodeid = slabp->nodeid;
@@ -2830,7 +2841,7 @@ int fastcall kmem_ptr_validate(kmem_cach
 	page = virt_to_page(ptr);
 	if (unlikely(!PageSlab(page)))
 		goto out;
-	if (unlikely(GET_PAGE_CACHE(page) != cachep))
+	if (unlikely(page_get_cache(page) != cachep))
 		goto out;
 	return 1;
 out:
@@ -3026,7 +3037,7 @@ void kfree(const void *objp)
 		return;
 	local_irq_save(flags);
 	kfree_debugcheck(objp);
-	c = GET_PAGE_CACHE(virt_to_page(objp));
+	c = page_get_cache(virt_to_page(objp));
 	__cache_free(c, (void*)objp);
 	local_irq_restore(flags);
 }
@@ -3596,7 +3607,7 @@ unsigned int ksize(const void *objp)
 	if (unlikely(objp == NULL))
 		return 0;
 
-	return obj_reallen(GET_PAGE_CACHE(virt_to_page(objp)));
+	return obj_reallen(page_get_cache(virt_to_page(objp)));
 }
 
 
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 135bf8c..2813054 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1074,7 +1074,7 @@ loop_again:
 					continue;
 
 				if (!zone_watermark_ok(zone, order,
-						zone->pages_high, 0, 0, 0)) {
+						zone->pages_high, 0, 0)) {
 					end_zone = i;
 					goto scan;
 				}
@@ -1111,7 +1111,7 @@ scan:
 
 			if (nr_pages == 0) {	/* Not software suspend */
 				if (!zone_watermark_ok(zone, order,
-						zone->pages_high, end_zone, 0, 0))
+						zone->pages_high, end_zone, 0))
 					all_zones_ok = 0;
 			}
 			zone->temp_priority = priority;
@@ -1259,7 +1259,7 @@ void wakeup_kswapd(struct zone *zone, in
 		return;
 
 	pgdat = zone->zone_pgdat;
-	if (zone_watermark_ok(zone, order, zone->pages_low, 0, 0, 0))
+	if (zone_watermark_ok(zone, order, zone->pages_low, 0, 0))
 		return;
 	if (pgdat->kswapd_max_order < order)
 		pgdat->kswapd_max_order = order;
diff --git a/net/Makefile b/net/Makefile
index 4aa2f46..f5141b9 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -15,8 +15,8 @@ obj-$(CONFIG_NET)		+= $(tmp-y)
 # LLC has to be linked before the files in net/802/
 obj-$(CONFIG_LLC)		+= llc/
 obj-$(CONFIG_NET)		+= ethernet/ 802/ sched/ netlink/
-obj-$(CONFIG_INET)		+= ipv4/
 obj-$(CONFIG_NETFILTER)		+= netfilter/
+obj-$(CONFIG_INET)		+= ipv4/
 obj-$(CONFIG_XFRM)		+= xfrm/
 obj-$(CONFIG_UNIX)		+= unix/
 ifneq ($(CONFIG_IPV6),)
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index d2a4fec..de9f446 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -467,7 +467,7 @@ out:	
 }
 #endif
 
-static const int cta_min_ip[CTA_IP_MAX] = {
+static const size_t cta_min_ip[CTA_IP_MAX] = {
 	[CTA_IP_V4_SRC-1]	= sizeof(u_int32_t),
 	[CTA_IP_V4_DST-1]	= sizeof(u_int32_t),
 };
@@ -497,7 +497,7 @@ ctnetlink_parse_tuple_ip(struct nfattr *
 	return 0;
 }
 
-static const int cta_min_proto[CTA_PROTO_MAX] = {
+static const size_t cta_min_proto[CTA_PROTO_MAX] = {
 	[CTA_PROTO_NUM-1]	= sizeof(u_int16_t),
 	[CTA_PROTO_SRC_PORT-1]	= sizeof(u_int16_t),
 	[CTA_PROTO_DST_PORT-1]	= sizeof(u_int16_t),
@@ -576,7 +576,7 @@ ctnetlink_parse_tuple(struct nfattr *cda
 }
 
 #ifdef CONFIG_IP_NF_NAT_NEEDED
-static const int cta_min_protonat[CTA_PROTONAT_MAX] = {
+static const size_t cta_min_protonat[CTA_PROTONAT_MAX] = {
 	[CTA_PROTONAT_PORT_MIN-1]	= sizeof(u_int16_t),
 	[CTA_PROTONAT_PORT_MAX-1]	= sizeof(u_int16_t),
 };
@@ -614,6 +614,11 @@ static int ctnetlink_parse_nat_proto(str
 	return 0;
 }
 
+static const size_t cta_min_nat[CTA_NAT_MAX] = {
+	[CTA_NAT_MINIP-1]       = sizeof(u_int32_t),
+	[CTA_NAT_MAXIP-1]       = sizeof(u_int32_t),
+};
+
 static inline int
 ctnetlink_parse_nat(struct nfattr *cda[],
 		    const struct ip_conntrack *ct, struct ip_nat_range *range)
@@ -627,6 +632,9 @@ ctnetlink_parse_nat(struct nfattr *cda[]
 	
 	nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]);
 
+	if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat))
+		return -EINVAL;
+
 	if (tb[CTA_NAT_MINIP-1])
 		range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
 
@@ -667,6 +675,14 @@ ctnetlink_parse_help(struct nfattr *attr
 	return 0;
 }
 
+static const size_t cta_min[CTA_MAX] = {
+	[CTA_STATUS-1] 		= sizeof(u_int32_t),
+	[CTA_TIMEOUT-1] 	= sizeof(u_int32_t),
+	[CTA_MARK-1]		= sizeof(u_int32_t),
+	[CTA_USE-1]		= sizeof(u_int32_t),
+	[CTA_ID-1]		= sizeof(u_int32_t)
+};
+
 static int
 ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, 
 			struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
@@ -678,6 +694,9 @@ ctnetlink_del_conntrack(struct sock *ctn
 
 	DEBUGP("entered %s\n", __FUNCTION__);
 
+	if (nfattr_bad_size(cda, CTA_MAX, cta_min))
+		return -EINVAL;
+
 	if (cda[CTA_TUPLE_ORIG-1])
 		err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG);
 	else if (cda[CTA_TUPLE_REPLY-1])
@@ -760,6 +779,9 @@ ctnetlink_get_conntrack(struct sock *ctn
 		return 0;
 	}
 
+	if (nfattr_bad_size(cda, CTA_MAX, cta_min))
+		return -EINVAL;
+
 	if (cda[CTA_TUPLE_ORIG-1])
 		err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG);
 	else if (cda[CTA_TUPLE_REPLY-1])
@@ -1047,6 +1069,9 @@ ctnetlink_new_conntrack(struct sock *ctn
 
 	DEBUGP("entered %s\n", __FUNCTION__);
 
+	if (nfattr_bad_size(cda, CTA_MAX, cta_min))
+		return -EINVAL;
+
 	if (cda[CTA_TUPLE_ORIG-1]) {
 		err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG);
 		if (err < 0)
@@ -1252,6 +1277,11 @@ out:	
 	return skb->len;
 }
 
+static const size_t cta_min_exp[CTA_EXPECT_MAX] = {
+	[CTA_EXPECT_TIMEOUT-1]          = sizeof(u_int32_t),
+	[CTA_EXPECT_ID-1]               = sizeof(u_int32_t)
+};
+
 static int
 ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, 
 		     struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
@@ -1263,6 +1293,9 @@ ctnetlink_get_expect(struct sock *ctnl, 
 
 	DEBUGP("entered %s\n", __FUNCTION__);
 
+	if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
+		return -EINVAL;
+
 	if (nlh->nlmsg_flags & NLM_F_DUMP) {
 		struct nfgenmsg *msg = NLMSG_DATA(nlh);
 		u32 rlen;
@@ -1333,6 +1366,9 @@ ctnetlink_del_expect(struct sock *ctnl, 
 	struct ip_conntrack_helper *h;
 	int err;
 
+	if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
+		return -EINVAL;
+
 	if (cda[CTA_EXPECT_TUPLE-1]) {
 		/* delete a single expect by tuple */
 		err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE);
@@ -1462,6 +1498,9 @@ ctnetlink_new_expect(struct sock *ctnl, 
 
 	DEBUGP("entered %s\n", __FUNCTION__);	
 
+	if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
+		return -EINVAL;
+
 	if (!cda[CTA_EXPECT_TUPLE-1]
 	    || !cda[CTA_EXPECT_MASK-1]
 	    || !cda[CTA_EXPECT_MASTER-1])
@@ -1504,29 +1543,22 @@ static struct notifier_block ctnl_notifi
 
 static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
 	[IPCTNL_MSG_CT_NEW]		= { .call = ctnetlink_new_conntrack,
-					    .attr_count = CTA_MAX,
-					    .cap_required = CAP_NET_ADMIN },
+					    .attr_count = CTA_MAX, },
 	[IPCTNL_MSG_CT_GET] 		= { .call = ctnetlink_get_conntrack,
-					    .attr_count = CTA_MAX,
-					    .cap_required = CAP_NET_ADMIN },
+					    .attr_count = CTA_MAX, },
 	[IPCTNL_MSG_CT_DELETE]  	= { .call = ctnetlink_del_conntrack,
-					    .attr_count = CTA_MAX,
-					    .cap_required = CAP_NET_ADMIN },
+					    .attr_count = CTA_MAX, },
 	[IPCTNL_MSG_CT_GET_CTRZERO] 	= { .call = ctnetlink_get_conntrack,
-					    .attr_count = CTA_MAX,
-					    .cap_required = CAP_NET_ADMIN },
+					    .attr_count = CTA_MAX, },
 };
 
 static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = {
 	[IPCTNL_MSG_EXP_GET]		= { .call = ctnetlink_get_expect,
-					    .attr_count = CTA_EXPECT_MAX,
-					    .cap_required = CAP_NET_ADMIN },
+					    .attr_count = CTA_EXPECT_MAX, },
 	[IPCTNL_MSG_EXP_NEW]		= { .call = ctnetlink_new_expect,
-					    .attr_count = CTA_EXPECT_MAX,
-					    .cap_required = CAP_NET_ADMIN },
+					    .attr_count = CTA_EXPECT_MAX, },
 	[IPCTNL_MSG_EXP_DELETE]		= { .call = ctnetlink_del_expect,
-					    .attr_count = CTA_EXPECT_MAX,
-					    .cap_required = CAP_NET_ADMIN },
+					    .attr_count = CTA_EXPECT_MAX, },
 };
 
 static struct nfnetlink_subsystem ctnl_subsys = {
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index 468c600..ee3b7d6 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -357,6 +357,10 @@ nfattr_failure:
 	return -1;
 }
 
+static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX] = {
+	[CTA_PROTOINFO_TCP_STATE-1]	= sizeof(u_int8_t),
+};
+
 static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
 {
 	struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
@@ -369,6 +373,9 @@ static int nfattr_to_tcp(struct nfattr *
 
         nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr);
 
+	if (nfattr_bad_size(tb, CTA_PROTOINFO_TCP_MAX, cta_min_tcp))
+		return -EINVAL;
+
 	if (!tb[CTA_PROTOINFO_TCP_STATE-1])
 		return -EINVAL;
 
@@ -814,6 +821,7 @@ static u8 tcp_valid_flags[(TH_FIN|TH_SYN
 {
 	[TH_SYN]			= 1,
 	[TH_SYN|TH_ACK]			= 1,
+	[TH_SYN|TH_PUSH]		= 1,
 	[TH_SYN|TH_ACK|TH_PUSH]		= 1,
 	[TH_RST]			= 1,
 	[TH_RST|TH_ACK]			= 1,
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 40a26b7..bf2e230 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -367,7 +367,7 @@ static void tcp_rcv_rtt_update(struct tc
 		 * are stalled on filesystem I/O.
 		 *
 		 * Also, since we are only going for a minimum in the
-		 * non-timestamp case, we do not smoother things out
+		 * non-timestamp case, we do not smooth things out
 		 * else with timestamps disabled convergence takes too
 		 * long.
 		 */
@@ -546,7 +546,7 @@ static void tcp_rtt_estimator(struct soc
 	 *
 	 * Funny. This algorithm seems to be very broken.
 	 * These formulae increase RTO, when it should be decreased, increase
-	 * too slowly, when it should be increased fastly, decrease too fastly
+	 * too slowly, when it should be increased quickly, decrease too quickly
 	 * etc. I guess in BSD RTO takes ONE value, so that it is absolutely
 	 * does not matter how to _calculate_ it. Seems, it was trap
 	 * that VJ failed to avoid. 8)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index ddcf775..56a09a4 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1045,9 +1045,10 @@ int ipv6_dev_get_saddr(struct net_device
 			}
 #endif
 			/* Rule 8: Use longest matching prefix */
-			if (hiscore.rule < 8)
+			if (hiscore.rule < 8) {
 				hiscore.matchlen = ipv6_addr_diff(&ifa_result->addr, daddr);
-			score.rule++;
+				hiscore.rule++;
+			}
 			score.matchlen = ipv6_addr_diff(&ifa->addr, daddr);
 			if (score.matchlen > hiscore.matchlen) {
 				score.rule = 8;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 003fd99..25757ad 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -287,7 +287,7 @@ int ipv6_setsockopt(struct sock *sk, int
 	{
 		struct ipv6_txoptions *opt;
 		if (optlen == 0)
-			optval = 0;
+			optval = NULL;
 
 		/* hop-by-hop / destination options are privileged option */
 		retv = -EPERM;
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 971ba60..060d612 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -5,10 +5,20 @@
 menu "IPv6: Netfilter Configuration (EXPERIMENTAL)"
 	depends on INET && IPV6 && NETFILTER && EXPERIMENTAL
 
-#tristate 'Connection tracking (required for masq/NAT)' CONFIG_IP6_NF_CONNTRACK
-#if [ "$CONFIG_IP6_NF_CONNTRACK" != "n" ]; then
-#  dep_tristate '  FTP protocol support' CONFIG_IP6_NF_FTP $CONFIG_IP6_NF_CONNTRACK
-#fi
+config NF_CONNTRACK_IPV6
+	tristate "IPv6 support for new connection tracking (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && NF_CONNTRACK
+	---help---
+	  Connection tracking keeps a record of what packets have passed
+	  through your machine, in order to figure out how they are related
+	  into connections.
+
+	  This is IPv6 support on Layer 3 independent connection tracking.
+	  Layer 3 independent connection tracking is experimental scheme
+	  which generalize ip_conntrack to support other layer 3 protocols.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config IP6_NF_QUEUE
 	tristate "IP6 Userspace queueing via NETLINK (OBSOLETE)"
 	---help---
@@ -114,7 +124,6 @@ config IP6_NF_MATCH_OWNER
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
-#  dep_tristate '  MAC address match support' CONFIG_IP6_NF_MATCH_MAC $CONFIG_IP6_NF_IPTABLES
 config IP6_NF_MATCH_MARK
 	tristate "netfilter MARK match support"
 	depends on IP6_NF_IPTABLES
@@ -170,15 +179,6 @@ config IP6_NF_MATCH_PHYSDEV
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
-#  dep_tristate '  Multiple port match support' CONFIG_IP6_NF_MATCH_MULTIPORT $CONFIG_IP6_NF_IPTABLES
-#  dep_tristate '  TOS match support' CONFIG_IP6_NF_MATCH_TOS $CONFIG_IP6_NF_IPTABLES
-#  if [ "$CONFIG_IP6_NF_CONNTRACK" != "n" ]; then
-#    dep_tristate '  Connection state match support' CONFIG_IP6_NF_MATCH_STATE $CONFIG_IP6_NF_CONNTRACK $CONFIG_IP6_NF_IPTABLES 
-#  fi
-#  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-#    dep_tristate '  Unclean match support (EXPERIMENTAL)' CONFIG_IP6_NF_MATCH_UNCLEAN $CONFIG_IP6_NF_IPTABLES
-#    dep_tristate '  Owner match support (EXPERIMENTAL)' CONFIG_IP6_NF_MATCH_OWNER $CONFIG_IP6_NF_IPTABLES
-#  fi
 # The targets
 config IP6_NF_FILTER
 	tristate "Packet filtering"
@@ -220,12 +220,6 @@ config IP6_NF_TARGET_NFQUEUE
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
-#  if [ "$CONFIG_IP6_NF_FILTER" != "n" ]; then
-#    dep_tristate '    REJECT target support' CONFIG_IP6_NF_TARGET_REJECT $CONFIG_IP6_NF_FILTER
-#    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-#      dep_tristate '    MIRROR target support (EXPERIMENTAL)' CONFIG_IP6_NF_TARGET_MIRROR $CONFIG_IP6_NF_FILTER
-#    fi
-#  fi
 config IP6_NF_MANGLE
 	tristate "Packet mangling"
 	depends on IP6_NF_IPTABLES
@@ -236,7 +230,6 @@ config IP6_NF_MANGLE
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
-#    dep_tristate '    TOS target support' CONFIG_IP6_NF_TARGET_TOS $CONFIG_IP_NF_MANGLE
 config IP6_NF_TARGET_MARK
 	tristate "MARK target support"
 	depends on IP6_NF_MANGLE
@@ -266,7 +259,6 @@ config IP6_NF_TARGET_HL
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
-#dep_tristate '  LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES
 config IP6_NF_RAW
 	tristate  'raw table support (required for TRACE)'
 	depends on IP6_NF_IPTABLES
@@ -278,19 +270,5 @@ config IP6_NF_RAW
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
-config NF_CONNTRACK_IPV6
-	tristate "IPv6 support for new connection tracking (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && NF_CONNTRACK
-	---help---
-	  Connection tracking keeps a record of what packets have passed
-	  through your machine, in order to figure out how they are related
-	  into connections.
-
-	  This is IPv6 support on Layer 3 independent connection tracking.
-	  Layer 3 independent connection tracking is experimental scheme
-	  which generalize ip_conntrack to support other layer 3 protocols.
-
-	  To compile it as a module, choose M here.  If unsure, say N.
-
 endmenu
 
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index e2c90b3..753a3ae 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -339,8 +339,8 @@ extern unsigned long nf_ct_icmpv6_timeou
 
 /* From nf_conntrack_frag6.c */
 extern unsigned long nf_ct_frag6_timeout;
-extern unsigned long nf_ct_frag6_low_thresh;
-extern unsigned long nf_ct_frag6_high_thresh;
+extern unsigned int nf_ct_frag6_low_thresh;
+extern unsigned int nf_ct_frag6_high_thresh;
 
 static struct ctl_table_header *nf_ct_ipv6_sysctl_header;
 
@@ -367,7 +367,7 @@ static ctl_table nf_ct_sysctl_table[] = 
 		.data		= &nf_ct_frag6_low_thresh,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec_jiffies,
+		.proc_handler	= &proc_dointvec,
 	},
 	{
 		.ctl_name	= NET_NF_CONNTRACK_FRAG6_HIGH_THRESH,
@@ -375,7 +375,7 @@ static ctl_table nf_ct_sysctl_table[] = 
 		.data		= &nf_ct_frag6_high_thresh,
 		.maxlen		= sizeof(unsigned int),
 		.mode		= 0644,
-		.proc_handler	= &proc_dointvec_jiffies,
+		.proc_handler	= &proc_dointvec,
 	},
         { .ctl_name = 0 }
 };
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 7640b9b..c2c52af 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -55,9 +55,9 @@
 #define NF_CT_FRAG6_LOW_THRESH 196608  /* == 192*1024 */
 #define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT
 
-int nf_ct_frag6_high_thresh = 256*1024;
-int nf_ct_frag6_low_thresh = 192*1024;
-int nf_ct_frag6_timeout = IPV6_FRAG_TIMEOUT;
+unsigned int nf_ct_frag6_high_thresh = 256*1024;
+unsigned int nf_ct_frag6_low_thresh = 192*1024;
+unsigned long nf_ct_frag6_timeout = IPV6_FRAG_TIMEOUT;
 
 struct nf_ct_frag6_skb_cb
 {
@@ -190,8 +190,10 @@ static void nf_ct_frag6_secret_rebuild(u
 atomic_t nf_ct_frag6_mem = ATOMIC_INIT(0);
 
 /* Memory Tracking Functions. */
-static inline void frag_kfree_skb(struct sk_buff *skb)
+static inline void frag_kfree_skb(struct sk_buff *skb, unsigned int *work)
 {
+	if (work)
+		*work -= skb->truesize;
 	atomic_sub(skb->truesize, &nf_ct_frag6_mem);
 	if (NFCT_FRAG6_CB(skb)->orig)
 		kfree_skb(NFCT_FRAG6_CB(skb)->orig);
@@ -199,8 +201,11 @@ static inline void frag_kfree_skb(struct
 	kfree_skb(skb);
 }
 
-static inline void frag_free_queue(struct nf_ct_frag6_queue *fq)
+static inline void frag_free_queue(struct nf_ct_frag6_queue *fq,
+				   unsigned int *work)
 {
+	if (work)
+		*work -= sizeof(struct nf_ct_frag6_queue);
 	atomic_sub(sizeof(struct nf_ct_frag6_queue), &nf_ct_frag6_mem);
 	kfree(fq);
 }
@@ -218,7 +223,8 @@ static inline struct nf_ct_frag6_queue *
 /* Destruction primitives. */
 
 /* Complete destruction of fq. */
-static void nf_ct_frag6_destroy(struct nf_ct_frag6_queue *fq)
+static void nf_ct_frag6_destroy(struct nf_ct_frag6_queue *fq,
+				unsigned int *work)
 {
 	struct sk_buff *fp;
 
@@ -230,17 +236,17 @@ static void nf_ct_frag6_destroy(struct n
 	while (fp) {
 		struct sk_buff *xp = fp->next;
 
-		frag_kfree_skb(fp);
+		frag_kfree_skb(fp, work);
 		fp = xp;
 	}
 
-	frag_free_queue(fq);
+	frag_free_queue(fq, work);
 }
 
-static __inline__ void fq_put(struct nf_ct_frag6_queue *fq)
+static __inline__ void fq_put(struct nf_ct_frag6_queue *fq, unsigned int *work)
 {
 	if (atomic_dec_and_test(&fq->refcnt))
-		nf_ct_frag6_destroy(fq);
+		nf_ct_frag6_destroy(fq, work);
 }
 
 /* Kill fq entry. It is not destroyed immediately,
@@ -262,16 +268,21 @@ static void nf_ct_frag6_evictor(void)
 {
 	struct nf_ct_frag6_queue *fq;
 	struct list_head *tmp;
+	unsigned int work;
 
-	for (;;) {
-		if (atomic_read(&nf_ct_frag6_mem) <= nf_ct_frag6_low_thresh)
-			return;
+	work = atomic_read(&nf_ct_frag6_mem);
+	if (work <= nf_ct_frag6_low_thresh)
+		return;
+
+	work -= nf_ct_frag6_low_thresh;
+	while (work > 0) {
 		read_lock(&nf_ct_frag6_lock);
 		if (list_empty(&nf_ct_frag6_lru_list)) {
 			read_unlock(&nf_ct_frag6_lock);
 			return;
 		}
 		tmp = nf_ct_frag6_lru_list.next;
+		BUG_ON(tmp == NULL);
 		fq = list_entry(tmp, struct nf_ct_frag6_queue, lru_list);
 		atomic_inc(&fq->refcnt);
 		read_unlock(&nf_ct_frag6_lock);
@@ -281,7 +292,7 @@ static void nf_ct_frag6_evictor(void)
 			fq_kill(fq);
 		spin_unlock(&fq->lock);
 
-		fq_put(fq);
+		fq_put(fq, &work);
 	}
 }
 
@@ -298,7 +309,7 @@ static void nf_ct_frag6_expire(unsigned 
 
 out:
 	spin_unlock(&fq->lock);
-	fq_put(fq);
+	fq_put(fq, NULL);
 }
 
 /* Creation primitives. */
@@ -318,7 +329,7 @@ static struct nf_ct_frag6_queue *nf_ct_f
 			atomic_inc(&fq->refcnt);
 			write_unlock(&nf_ct_frag6_lock);
 			fq_in->last_in |= COMPLETE;
-			fq_put(fq_in);
+			fq_put(fq_in, NULL);
 			return fq;
 		}
 	}
@@ -535,7 +546,7 @@ static int nf_ct_frag6_queue(struct nf_c
 				fq->fragments = next;
 
 			fq->meat -= free_it->len;
-			frag_kfree_skb(free_it);
+			frag_kfree_skb(free_it, NULL);
 		}
 	}
 
@@ -811,7 +822,7 @@ struct sk_buff *nf_ct_frag6_gather(struc
 	if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) {
 		spin_unlock(&fq->lock);
 		DEBUGP("Can't insert skb to queue\n");
-		fq_put(fq);
+		fq_put(fq, NULL);
 		goto ret_orig;
 	}
 
@@ -822,7 +833,7 @@ struct sk_buff *nf_ct_frag6_gather(struc
 	}
 	spin_unlock(&fq->lock);
 
-	fq_put(fq);
+	fq_put(fq, NULL);
 	return ret_skb;
 
 ret_orig:
@@ -881,5 +892,6 @@ int nf_ct_frag6_init(void)
 void nf_ct_frag6_cleanup(void)
 {
 	del_timer(&nf_ct_frag6_secret_timer);
+	nf_ct_frag6_low_thresh = 0;
 	nf_ct_frag6_evictor();
 }
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index f7f42c3..9a71a8d 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1701,10 +1701,8 @@ static void fib6_dump_end(struct netlink
 		fib6_walker_unlink(w);
 		kfree(w);
 	}
-	if (cb->args[1]) {
-		cb->done = (void*)cb->args[1];
-		cb->args[1] = 0;
-	}
+	cb->done = (void*)cb->args[1];
+	cb->args[1] = 0;
 }
 
 static int fib6_dump_done(struct netlink_callback *cb)
@@ -1734,7 +1732,7 @@ int inet6_dump_fib(struct sk_buff *skb, 
 		/*
 		 * 2. allocate and initialize walker.
 		 */
-		w = kmalloc(sizeof(*w), GFP_ATOMIC);
+		w = kmalloc(sizeof(*w), GFP_KERNEL);
 		if (w == NULL)
 			return -ENOMEM;
 		RT6_TRACE("dump<%p", w);
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 59d02cb..c3f0b07 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -116,7 +116,9 @@ static int llc_ui_send_data(struct sock*
 	struct llc_sock* llc = llc_sk(sk);
 	int rc = 0;
 
-	if (unlikely(llc_data_accept_state(llc->state) || llc->p_flag)) {
+	if (unlikely(llc_data_accept_state(llc->state) || 
+		     llc->remote_busy_flag ||
+		     llc->p_flag)) {
 		long timeout = sock_sndtimeo(sk, noblock);
 
 		rc = llc_ui_wait_for_busy_core(sk, timeout);
@@ -542,6 +544,7 @@ static int llc_ui_wait_for_busy_core(str
 		if (sk_wait_event(sk, &timeout,
 				  (sk->sk_shutdown & RCV_SHUTDOWN) ||
 				  (!llc_data_accept_state(llc->state) &&
+				   !llc->remote_busy_flag &&
 				   !llc->p_flag)))
 			break;
 		rc = -ERESTARTSYS;
diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
index b0bcfb1..91fb6bc 100644
--- a/net/llc/llc_c_ac.c
+++ b/net/llc/llc_c_ac.c
@@ -866,7 +866,8 @@ int llc_conn_ac_send_ack_if_needed(struc
 		llc->ack_must_be_send = 1;
 		llc->ack_pf = pf_bit & 1;
 	}
-	if (((llc->vR - llc->first_pdu_Ns + 129) % 128) >= llc->npta) {
+	if (((llc->vR - llc->first_pdu_Ns + 1 + LLC_2_SEQ_NBR_MODULO)
+			% LLC_2_SEQ_NBR_MODULO) >= llc->npta) {
 		llc_conn_ac_send_rr_rsp_f_set_ackpf(sk, skb);
 		llc->ack_must_be_send	= 0;
 		llc->ack_pf		= 0;
@@ -994,8 +995,8 @@ static int llc_conn_ac_inc_npta_value(st
 		llc->dec_step = 0;
 		llc->dec_cntr = llc->inc_cntr = 2;
 		++llc->npta;
-		if (llc->npta > 127)
-			llc->npta = 127 ;
+		if (llc->npta > ~LLC_2_SEQ_NBR_MODULO)
+			llc->npta = ~LLC_2_SEQ_NBR_MODULO ;
 	} else
 		--llc->inc_cntr;
 	return 0;
@@ -1065,9 +1066,10 @@ int llc_conn_ac_dec_tx_win_size(struct s
 	struct llc_sock *llc = llc_sk(sk);
 	u8 unacked_pdu = skb_queue_len(&llc->pdu_unack_q);
 
-	llc->k -= unacked_pdu;
-	if (llc->k < 2)
-		llc->k = 2;
+	if (llc->k - unacked_pdu < 1)
+		llc->k = 1;
+	else
+		llc->k -= unacked_pdu;
 	return 0;
 }
 
@@ -1084,8 +1086,8 @@ int llc_conn_ac_inc_tx_win_size(struct s
 	struct llc_sock *llc = llc_sk(sk);
 
 	llc->k += 1;
-	if (llc->k > 128)
-		llc->k = 128 ;
+	if (llc->k > ~LLC_2_SEQ_NBR_MODULO)
+		llc->k = ~LLC_2_SEQ_NBR_MODULO ;
 	return 0;
 }
 
@@ -1309,7 +1311,7 @@ int llc_conn_ac_set_vs_nr(struct sock *s
 
 static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb)
 {
-	llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % 128;
+	llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % LLC_2_SEQ_NBR_MODULO;
 	return 0;
 }
 
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 9a67c79..ea094b2 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1395,6 +1395,13 @@ void nf_conntrack_cleanup(void)
 	kmem_cache_destroy(nf_conntrack_expect_cachep);
 	free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc,
 			    nf_conntrack_htable_size);
+
+	/* free l3proto protocol tables */
+	for (i = 0; i < PF_MAX; i++)
+		if (nf_ct_protos[i]) {
+			kfree(nf_ct_protos[i]);
+			nf_ct_protos[i] = NULL;
+		}
 }
 
 static struct list_head *alloc_hashtable(int size, int *vmalloced)
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 83d90dd..5a6fcf3 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -779,6 +779,7 @@ static u8 tcp_valid_flags[(TH_FIN|TH_SYN
 {
 	[TH_SYN]			= 1,
 	[TH_SYN|TH_ACK]			= 1,
+	[TH_SYN|TH_PUSH]		= 1,
 	[TH_SYN|TH_ACK|TH_PUSH]		= 1,
 	[TH_RST]			= 1,
 	[TH_RST|TH_ACK]			= 1,
@@ -969,6 +970,12 @@ static int tcp_packet(struct nf_conn *co
 		    		conntrack->timeout.function((unsigned long)
 		    					    conntrack);
 		    	return -NF_REPEAT;
+		} else {
+			write_unlock_bh(&tcp_lock);
+			if (LOG_INVALID(IPPROTO_TCP))
+				nf_log_packet(pf, 0, skb, NULL, NULL,
+					      NULL, "nf_ct_tcp: invalid SYN");
+			return -NF_ACCEPT;
 		}
 	case TCP_CONNTRACK_CLOSE:
 		if (index == TCP_RST_SET
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 45224db..5af381f 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -694,7 +694,7 @@ static int init_or_cleanup(int init)
  cleanup_proc_stat:
 #endif
 #ifdef CONFIG_PROC_FS
-	proc_net_remove("nf_conntrack_stat");
+	remove_proc_entry("nf_conntrack", proc_net_stat);
  cleanup_proc_exp:
 	proc_net_remove("nf_conntrack_expect");
  cleanup_proc:
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 83f4c53..a60c59b 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -223,6 +223,12 @@ static inline int nfnetlink_rcv_msg(stru
 		 NFNL_SUBSYS_ID(nlh->nlmsg_type),
 		 NFNL_MSG_TYPE(nlh->nlmsg_type));
 
+	if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
+		DEBUGP("missing CAP_NET_ADMIN\n");
+		*errp = -EPERM;
+		return -1;
+	}
+
 	/* Only requests are handled by kernel now. */
 	if (!(nlh->nlmsg_flags & NLM_F_REQUEST)) {
 		DEBUGP("received non-request message\n");
@@ -240,15 +246,12 @@ static inline int nfnetlink_rcv_msg(stru
 	ss = nfnetlink_get_subsys(type);
 	if (!ss) {
 #ifdef CONFIG_KMOD
-		if (cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) {
-			/* don't call nfnl_shunlock, since it would reenter
-			 * with further packet processing */
-			up(&nfnl_sem);
-			request_module("nfnetlink-subsys-%d",
-					NFNL_SUBSYS_ID(type));
-			nfnl_shlock();
-			ss = nfnetlink_get_subsys(type);
-		}
+		/* don't call nfnl_shunlock, since it would reenter
+		 * with further packet processing */
+		up(&nfnl_sem);
+		request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
+		nfnl_shlock();
+		ss = nfnetlink_get_subsys(type);
 		if (!ss)
 #endif
 			goto err_inval;
@@ -260,13 +263,6 @@ static inline int nfnetlink_rcv_msg(stru
 		goto err_inval;
 	}
 
-	if (nc->cap_required && 
-	    !cap_raised(NETLINK_CB(skb).eff_cap, nc->cap_required)) {
-		DEBUGP("permission denied for type %d\n", type);
-		*errp = -EPERM;
-		return -1;
-	}
-
 	{
 		u_int16_t attr_count = 
 			ss->cb[NFNL_MSG_TYPE(nlh->nlmsg_type)].attr_count;
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index d194676..cba6372 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -862,11 +862,9 @@ out_put:
 
 static struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = {
 	[NFULNL_MSG_PACKET]	= { .call = nfulnl_recv_unsupp,
-				    .attr_count = NFULA_MAX,
-				    .cap_required = CAP_NET_ADMIN, },
+				    .attr_count = NFULA_MAX, },
 	[NFULNL_MSG_CONFIG]	= { .call = nfulnl_recv_config,
-				    .attr_count = NFULA_CFG_MAX,
-				    .cap_required = CAP_NET_ADMIN },
+				    .attr_count = NFULA_CFG_MAX, },
 };
 
 static struct nfnetlink_subsystem nfulnl_subsys = {
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index f065a6c..f28460b 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -931,14 +931,11 @@ out_put:
 
 static struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = {
 	[NFQNL_MSG_PACKET]	= { .call = nfqnl_recv_unsupp,
-				    .attr_count = NFQA_MAX,
-				    .cap_required = CAP_NET_ADMIN },
+				    .attr_count = NFQA_MAX, },
 	[NFQNL_MSG_VERDICT]	= { .call = nfqnl_recv_verdict,
-				    .attr_count = NFQA_MAX,
-				    .cap_required = CAP_NET_ADMIN },
+				    .attr_count = NFQA_MAX, },
 	[NFQNL_MSG_CONFIG]	= { .call = nfqnl_recv_config,
-				    .attr_count = NFQA_CFG_MAX,
-				    .cap_required = CAP_NET_ADMIN },
+				    .attr_count = NFQA_CFG_MAX, },
 };
 
 static struct nfnetlink_subsystem nfqnl_subsys = {
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index e50e7cf..c6a5191 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1178,6 +1178,7 @@ svc_recv(struct svc_serv *serv, struct s
 	arg->tail[0].iov_len = 0;
 
 	try_to_freeze();
+	cond_resched();
 	if (signalled())
 		return -EINTR;
 
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 8aaf74e..2f45fd2 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -117,6 +117,8 @@ use strict;
 # struct my_struct {
 #     int a;
 #     int b;
+# /* private: */
+#     int c;
 # };
 #
 # All descriptions can be multiline, except the short function description.
@@ -1304,6 +1306,12 @@ sub dump_struct($$) {
 	# ignore embedded structs or unions
 	$members =~ s/{.*?}//g;
 
+	# ignore members marked private:
+	$members =~ s/\/\*.*?private:.*?public:.*?\*\///gos;
+	$members =~ s/\/\*.*?private:.*//gos;
+	# strip comments:
+	$members =~ s/\/\*.*?\*\///gos;
+
 	create_parameterlist($members, ';', $file);
 
 	output_declaration($declaration_name,
@@ -1329,6 +1337,7 @@ sub dump_enum($$) {
     my $x = shift;
     my $file = shift;
 
+    $x =~ s@/\*.*?\*/@@gos;	# strip comments.
     if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
         $declaration_name = $1;
         my $members = $2;
@@ -1365,6 +1374,7 @@ sub dump_typedef($$) {
     my $x = shift;
     my $file = shift;
 
+    $x =~ s@/\*.*?\*/@@gos;	# strip comments.
     while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) {
         $x =~ s/\(*.\)\s*;$/;/;
 	$x =~ s/\[*.\]\s*;$/;/;
@@ -1420,7 +1430,7 @@ sub create_parameterlist($$$) {
 	    $type = $arg;
 	    $type =~ s/([^\(]+\(\*)$param/$1/;
 	    push_parameter($param, $type, $file);
-	} else {
+	} elsif ($arg) {
 	    $arg =~ s/\s*:\s*/:/g;
 	    $arg =~ s/\s*\[/\[/g;
 
@@ -1628,7 +1638,6 @@ sub process_state3_type($$) { 
     my $x = shift;
     my $file = shift;
 
-    $x =~ s@/\*.*?\*/@@gos;	# strip comments.
     $x =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
     $x =~ s@^\s+@@gos; # strip leading spaces
     $x =~ s@\s+$@@gos; # strip trailing spaces
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c
index 7c835ab..3f30c57 100644
--- a/sound/oss/ad1848.c
+++ b/sound/oss/ad1848.c
@@ -47,6 +47,7 @@
 #include <linux/module.h>
 #include <linux/stddef.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/isapnp.h>
 #include <linux/pnp.h>
 #include <linux/spinlock.h>
diff --git a/sound/oss/cs4281/cs4281m.c b/sound/oss/cs4281/cs4281m.c
index d0d3963..adc6896 100644
--- a/sound/oss/cs4281/cs4281m.c
+++ b/sound/oss/cs4281/cs4281m.c
@@ -298,6 +298,7 @@ struct cs4281_state {
 	struct cs4281_pipeline pl[CS4281_NUMBER_OF_PIPELINES];
 };
 
+#include <linux/pm_legacy.h>
 #include "cs4281pm-24.c"
 
 #if CSDEBUG
diff --git a/sound/oss/maestro.c b/sound/oss/maestro.c
index 3dce504..3abd354 100644
--- a/sound/oss/maestro.c
+++ b/sound/oss/maestro.c
@@ -231,6 +231,7 @@
 #include <asm/uaccess.h>
 
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 static int maestro_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *d);
 
 #include "maestro.h"
diff --git a/sound/oss/nm256_audio.c b/sound/oss/nm256_audio.c
index 6697006..0ce2c40 100644
--- a/sound/oss/nm256_audio.c
+++ b/sound/oss/nm256_audio.c
@@ -25,6 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include "sound_config.h"
diff --git a/sound/oss/opl3sa2.c b/sound/oss/opl3sa2.c
index 2efbd86..cd41d0e 100644
--- a/sound/oss/opl3sa2.c
+++ b/sound/oss/opl3sa2.c
@@ -70,6 +70,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
+#include <linux/pm_legacy.h>
 #include "sound_config.h"
 
 #include "ad1848.h"
@@ -138,7 +139,7 @@ typedef struct {
 	struct pnp_dev* pdev;
 	int activated;			/* Whether said devices have been activated */
 #endif
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
 	unsigned int	in_suspend;
 	struct pm_dev	*pmdev;
 #endif
@@ -341,7 +342,7 @@ static void opl3sa2_mixer_reset(opl3sa2_
 }
 
 /* Currently only used for power management */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
 static void opl3sa2_mixer_restore(opl3sa2_state_t* devc)
 {
 	if (devc) {
@@ -354,7 +355,7 @@ static void opl3sa2_mixer_restore(opl3sa
 		}
 	}
 }
-#endif
+#endif /* CONFIG_PM_LEGACY */
 
 static inline void arg_to_vol_mono(unsigned int vol, int* value)
 {
@@ -831,7 +832,8 @@ static struct pnp_driver opl3sa2_driver 
 
 /* End of component functions */
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
+
 static DEFINE_SPINLOCK(opl3sa2_lock);
 
 /* Power Management support functions */
@@ -906,7 +908,7 @@ static int opl3sa2_pm_callback(struct pm
 	}
 	return 0;
 }
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_LEGACY */
 
 /*
  * Install OPL3-SA2 based card(s).
@@ -1019,12 +1021,12 @@ static int __init init_opl3sa2(void)
 
 		/* ewww =) */
 		opl3sa2_state[card].card = card;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
 		/* register our power management capabilities */
 		opl3sa2_state[card].pmdev = pm_register(PM_ISA_DEV, card, opl3sa2_pm_callback);
 		if (opl3sa2_state[card].pmdev)
 			opl3sa2_state[card].pmdev->data = &opl3sa2_state[card];
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_LEGACY */
 
 		/*
 		 * Set the Yamaha 3D enhancement mode (aka Ymersion) if asked to and
@@ -1081,7 +1083,7 @@ static void __exit cleanup_opl3sa2(void)
 	int card;
 
 	for(card = 0; card < opl3sa2_cards_num; card++) {
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_LEGACY
 		if (opl3sa2_state[card].pmdev)
 			pm_unregister(opl3sa2_state[card].pmdev);
 #endif
