From 4fb416f4abe28a060a5a5b6aba60af0924e0f27c Mon Sep 17 00:00:00 2001
From: Andi Kleen <ak@suse.de>
Date: Sun, 15 Jun 2003 20:10:50 -0700
Subject: [PATCH] [PATCH] x86-64 merge

Lots of small fixes and I merged the PCI subsystem with i386 again
because it was mostly identical. This makes the patch quite big,
but it only removes files.

 - Merge PCI subsystem with i386.

   This changes the initialization order of PCI and IOMMU slightly.  It
   didn't see any problems yet, but it could cause some in theory.  It
   re-adds some code that used to be removed, but it's only small stuff
   and it should hopefully cause less mainteance overhead longer term.

 - Fix warnings
 - Merge cpuid.c with i386.c
 - Sync msr.c with i386
 - Consolidate externs in asm/proto.h
 - sysfs/sysdev fixes for apic/nmi (Bryan O'Sullivan)
 - Fix /proc/kcore access
 - Add real kern_addr_valid (used for above).
 - Support consistent dma_mask in IOMMU
 - Fix double print of AMD for CPU model.
 - Remove unused wakeup.S file.
 - Remove obsolete CONFIG_SIMNOW ifdef.
 - Support ptrace access for 32bit vsyscalls.
 - Fix warnings in 32bit boot code compilation.
---
 arch/x86_64/Makefile           |   1 -
 arch/x86_64/ia32/vsyscall.S    |   2 +-
 arch/x86_64/kernel/Makefile    |   4 +-
 arch/x86_64/kernel/aperture.c  |   2 -
 arch/x86_64/kernel/apic.c      |  34 +-
 arch/x86_64/kernel/bluesmoke.c |   3 +-
 arch/x86_64/kernel/cpuid.c     | 178 ---------
 arch/x86_64/kernel/ldt.c       |   3 +-
 arch/x86_64/kernel/msr.c       |  24 +-
 arch/x86_64/kernel/nmi.c       |  44 +--
 arch/x86_64/kernel/pci-gart.c  |  34 +-
 arch/x86_64/kernel/pci-nommu.c |   3 +-
 arch/x86_64/kernel/process.c   |   2 -
 arch/x86_64/kernel/setup.c     |   2 +-
 arch/x86_64/kernel/signal.c    |   2 -
 arch/x86_64/kernel/smpboot.c   |  12 +-
 arch/x86_64/kernel/time.c      |   4 +-
 arch/x86_64/kernel/traps.c     |   9 +-
 arch/x86_64/kernel/wakeup.S    | 306 ----------------
 arch/x86_64/lib/delay.c        |   2 -
 arch/x86_64/mm/init.c          |  43 ++-
 arch/x86_64/pci/Makefile       |  23 +-
 arch/x86_64/pci/acpi.c         |  27 --
 arch/x86_64/pci/changelog      |   1 -
 arch/x86_64/pci/common.c       | 212 -----------
 arch/x86_64/pci/direct.c       | 281 ---------------
 arch/x86_64/pci/fixup.c        |  48 ---
 arch/x86_64/pci/irq.c          | 639 ---------------------------------
 arch/x86_64/pci/legacy.c       |  68 ----
 arch/x86_64/pci/pci.h          |  75 ----
 arch/x86_64/pci/x86-64.c       | 299 ---------------
 include/asm-x86_64/fixmap.h    |   5 +
 include/asm-x86_64/io.h        |   2 +-
 include/asm-x86_64/mmzone.h    |  14 -
 include/asm-x86_64/page.h      |   2 +
 include/asm-x86_64/pci.h       |   1 -
 include/asm-x86_64/pgtable.h   |  11 +-
 include/asm-x86_64/proto.h     |  22 +-
 38 files changed, 178 insertions(+), 2266 deletions(-)
 delete mode 100644 arch/x86_64/kernel/cpuid.c
 delete mode 100644 arch/x86_64/kernel/wakeup.S
 delete mode 100644 arch/x86_64/pci/acpi.c
 delete mode 100644 arch/x86_64/pci/changelog
 delete mode 100644 arch/x86_64/pci/common.c
 delete mode 100644 arch/x86_64/pci/direct.c
 delete mode 100644 arch/x86_64/pci/fixup.c
 delete mode 100644 arch/x86_64/pci/irq.c
 delete mode 100644 arch/x86_64/pci/legacy.c
 delete mode 100644 arch/x86_64/pci/pci.h
 delete mode 100644 arch/x86_64/pci/x86-64.c

diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 1faa3f4937ab..35447c84d97c 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -42,7 +42,6 @@ CFLAGS += -mno-red-zone
 CFLAGS += -mcmodel=kernel
 CFLAGS += -pipe
 # this makes reading assembly source easier, but produces worse code
-# disable for production kernel
 CFLAGS += -fno-reorder-blocks	
 # should lower this a lot and see how much .text is saves	
 CFLAGS += -finline-limit=2000
diff --git a/arch/x86_64/ia32/vsyscall.S b/arch/x86_64/ia32/vsyscall.S
index c7af4f64d9e8..1cde011239ce 100644
--- a/arch/x86_64/ia32/vsyscall.S
+++ b/arch/x86_64/ia32/vsyscall.S
@@ -35,7 +35,7 @@ __kernel_sigreturn:
 
 	.section .text.rtsigreturn,"ax"
 	.balign 32
-	.globl __kernel_rt_sigreturn,"ax"
+	.globl __kernel_rt_sigreturn
 	.type __kernel_rt_sigreturn,@function
 __kernel_rt_sigreturn:
 .LSTART_rt_sigreturn:
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index 765fa7d91c80..128cd3867de8 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -24,6 +24,8 @@ obj-$(CONFIG_MODULES) += module.o
 
 $(obj)/bootflag.c: 
 	@ln -sf ../../i386/kernel/bootflag.c $(obj)/bootflag.c
+$(obj)/cpuid.c: 
+	@ln -sf ../../i386/kernel/cpuid.c $(obj)/cpuid.c
 
-clean-files += bootflag.c
+clean-files += bootflag.c cpuid.c
 
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
index 871394fa7547..aedd584b7ae0 100644
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -25,8 +25,6 @@
 int fallback_aper_order __initdata = 1; /* 64MB */
 int fallback_aper_force __initdata = 0; 
 
-extern int no_iommu, force_mmu;
-
 /* This code runs before the PCI subsystem is initialized, so just 
    access the northbridge directly. */
 
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 1addbb749ec2..f4e2169b1508 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -25,6 +25,7 @@
 #include <linux/interrupt.h>
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
+#include <linux/sysdev.h>
 
 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -464,13 +465,11 @@ static struct {
 	unsigned int apic_thmr;
 } apic_pm_state;
 
-static int lapic_suspend(struct device *dev, u32 state, u32 level)
+static int lapic_suspend(struct sys_device *dev, u32 state)
 {
 	unsigned int l, h;
 	unsigned long flags;
 
-	if (level != SUSPEND_POWER_DOWN)
-		return 0;
 	if (!apic_pm_state.active)
 		return 0;
 
@@ -497,13 +496,11 @@ static int lapic_suspend(struct device *dev, u32 state, u32 level)
 	return 0;
 }
 
-static int lapic_resume(struct device *dev, u32 level)
+static int lapic_resume(struct sys_device *dev)
 {
 	unsigned int l, h;
 	unsigned long flags;
 
-	if (level != RESUME_POWER_ON)
-		return 0;
 	if (!apic_pm_state.active)
 		return 0;
 
@@ -537,38 +534,35 @@ static int lapic_resume(struct device *dev, u32 level)
 	return 0;
 }
 
-static struct device_driver lapic_driver = {
-	.name		= "lapic",
-	.bus		= &system_bus_type,
+static struct sysdev_class lapic_sysclass = {
+	set_kset_name("lapic"),
 	.resume		= lapic_resume,
 	.suspend	= lapic_suspend,
 };
 
 /* not static, needed by child devices */
-struct sys_device device_lapic = {
-	.name		= "lapic",
+static struct sys_device device_lapic = {
 	.id		= 0,
-	.dev		= {
-		.name	= "lapic",
-		.driver	= &lapic_driver,
-	},
+	.cls		= &lapic_sysclass,
 };
-EXPORT_SYMBOL(device_lapic);
 
 static void __init apic_pm_activate(void)
 {
 	apic_pm_state.active = 1;
 }
 
-static int __init init_lapic_devicefs(void)
+static int __init init_lapic_sysfs(void)
 {
+	int error;
 	if (!cpu_has_apic)
 		return 0;
 	/* XXX: remove suspend/resume procs if !apic_pm_state.active? */
-	driver_register(&lapic_driver);
-	return sys_device_register(&device_lapic);
+	error = sysdev_class_register(&lapic_sysclass);
+	if (!error)
+		error = sys_device_register(&device_lapic);
+	return error;
 }
-device_initcall(init_lapic_devicefs);
+device_initcall(init_lapic_sysfs);
 
 #else	/* CONFIG_PM */
 
diff --git a/arch/x86_64/kernel/bluesmoke.c b/arch/x86_64/kernel/bluesmoke.c
index 392b8bab96ee..bd71684c0e6e 100644
--- a/arch/x86_64/kernel/bluesmoke.c
+++ b/arch/x86_64/kernel/bluesmoke.c
@@ -303,7 +303,7 @@ static void k8_machine_check(struct pt_regs * regs, long error_code)
 	wrmsrl(MSR_IA32_MCG_STATUS, 0);
        
 	if (regs && (status & (1<<1)))
-		printk(KERN_EMERG "MCE at EIP %lx ESP %lx\n", regs->rip, regs->rsp); 
+		printk(KERN_EMERG "MCE at RIP %lx RSP %lx\n", regs->rip, regs->rsp); 
 
  others:
 	generic_machine_check(regs, error_code); 
@@ -352,7 +352,6 @@ static void __init k8_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u64 cap;
 	int i;
-	struct pci_dev *nb; 
 
 	if (!test_bit(X86_FEATURE_MCE, &c->x86_capability) || 
 	    !test_bit(X86_FEATURE_MCA, &c->x86_capability))
diff --git a/arch/x86_64/kernel/cpuid.c b/arch/x86_64/kernel/cpuid.c
deleted file mode 100644
index c8f38e2e9f9c..000000000000
--- a/arch/x86_64/kernel/cpuid.c
+++ /dev/null
@@ -1,178 +0,0 @@
-#ident "$Id: cpuid.c,v 1.4 2001/10/24 23:58:53 ak Exp $"
-/* ----------------------------------------------------------------------- *
- *   
- *   Copyright 2000 H. Peter Anvin - All Rights Reserved
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
- *   USA; either version 2 of the License, or (at your option) any later
- *   version; incorporated herein by reference.
- *
- * ----------------------------------------------------------------------- */
-
-
-/*
- * cpuid.c
- *
- * x86 CPUID access device
- *
- * This device is accessed by lseek() to the appropriate CPUID level
- * and then read in chunks of 16 bytes.  A larger size means multiple
- * reads of consecutive levels.
- *
- * This driver uses /dev/cpu/%d/cpuid where %d is the minor number, and on
- * an SMP box will direct the access to CPU %d.
- */
-
-#include <linux/module.h>
-#include <linux/config.h>
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/fcntl.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/smp.h>
-#include <linux/major.h>
-#include <linux/fs.h>
-#include <linux/smp_lock.h>
-#include <linux/fs.h>
-
-#include <asm/processor.h>
-#include <asm/msr.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#ifdef CONFIG_SMP
-
-struct cpuid_command {
-  int cpu;
-  u32 reg;
-  u32 *data;
-};
-
-static void cpuid_smp_cpuid(void *cmd_block)
-{
-  struct cpuid_command *cmd = (struct cpuid_command *) cmd_block;
-  
-  if ( cmd->cpu == smp_processor_id() )
-    cpuid(cmd->reg, &cmd->data[0], &cmd->data[1], &cmd->data[2], &cmd->data[3]);
-}
-
-static inline void do_cpuid(int cpu, u32 reg, u32 *data)
-{
-  struct cpuid_command cmd;
-  
-  preempt_disable(); 
-  if ( cpu == smp_processor_id() ) {
-    cpuid(reg, &data[0], &data[1], &data[2], &data[3]);
-  } else {
-    cmd.cpu  = cpu;
-    cmd.reg  = reg;
-    cmd.data = data;
-    
-    smp_call_function(cpuid_smp_cpuid, &cmd, 1, 1);
-  }
-  preempt_enable();
-}
-#else /* ! CONFIG_SMP */
-
-static inline void do_cpuid(int cpu, u32 reg, u32 *data)
-{
-  cpuid(reg, &data[0], &data[1], &data[2], &data[3]);
-}
-
-#endif /* ! CONFIG_SMP */
-
-static loff_t cpuid_seek(struct file *file, loff_t offset, int orig)
-{
-  loff_t ret;
-
-  lock_kernel();
-
-  switch (orig) {
-  case 0:
-    file->f_pos = offset;
-    ret = file->f_pos;
-    break;
-  case 1:
-    file->f_pos += offset;
-    ret = file->f_pos;
-    break;
-  default:
-    ret = -EINVAL;
-  }
-
-  unlock_kernel();
-  return ret;
-}
-
-static ssize_t cpuid_read(struct file * file, char * buf,
-			size_t count, loff_t *ppos)
-{
-  u32 *tmp = (u32 *)buf;
-  u32 data[4];
-  size_t rv;
-  u32 reg = *ppos;
-  int cpu = minor(file->f_dentry->d_inode->i_rdev);
-  
-  if ( count % 16 )
-    return -EINVAL; /* Invalid chunk size */
-  
-  for ( rv = 0 ; count ; count -= 16 ) {
-    do_cpuid(cpu, reg, data);
-    if ( copy_to_user(tmp,&data,16) )
-      return -EFAULT;
-    tmp += 4;
-    *ppos = reg++;
-  }
-  
-  return ((char *)tmp) - buf;
-}
-
-static int cpuid_open(struct inode *inode, struct file *file)
-{
-  int cpu = minor(file->f_dentry->d_inode->i_rdev);
-  struct cpuinfo_x86 *c = &(cpu_data)[cpu];
-
-  if ( !(cpu_online_map & (1UL << cpu)) )
-    return -ENXIO;		/* No such CPU */
-  if ( c->cpuid_level < 0 )
-    return -EIO;		/* CPUID not supported */
-  
-  return 0;
-}
-
-/*
- * File operations we support
- */
-static struct file_operations cpuid_fops = {
-  .owner =	THIS_MODULE,
-  .llseek =	cpuid_seek,
-  .read =	cpuid_read,
-  .open =	cpuid_open,
-};
-
-int __init cpuid_init(void)
-{
-  if (register_chrdev(CPUID_MAJOR, "cpu/cpuid", &cpuid_fops)) {
-    printk(KERN_ERR "cpuid: unable to get major %d for cpuid\n",
-	   CPUID_MAJOR);
-    return -EBUSY;
-  }
-
-  return 0;
-}
-
-void __exit cpuid_exit(void)
-{
-  unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
-}
-
-module_init(cpuid_init);
-module_exit(cpuid_exit)
-
-MODULE_AUTHOR("H. Peter Anvin <hpa@zytor.com>");
-MODULE_DESCRIPTION("x86 generic CPUID driver");
-MODULE_LICENSE("GPL");
diff --git a/arch/x86_64/kernel/ldt.c b/arch/x86_64/kernel/ldt.c
index 1b7c821593b9..cd14f4b67b4e 100644
--- a/arch/x86_64/kernel/ldt.c
+++ b/arch/x86_64/kernel/ldt.c
@@ -21,8 +21,7 @@
 #include <asm/system.h>
 #include <asm/ldt.h>
 #include <asm/desc.h>
-
-extern void load_gs_index(unsigned gs);
+#include <asm/proto.h>
 
 #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
 static void flush_ldt(void *null)
diff --git a/arch/x86_64/kernel/msr.c b/arch/x86_64/kernel/msr.c
index bf1cbac3cdf5..52e21f71d403 100644
--- a/arch/x86_64/kernel/msr.c
+++ b/arch/x86_64/kernel/msr.c
@@ -1,4 +1,4 @@
-#ident "$Id: msr.c,v 1.6 2001/10/24 23:58:53 ak Exp $"
+#ident "$Id$"
 /* ----------------------------------------------------------------------- *
  *   
  *   Copyright 2000 H. Peter Anvin - All Rights Reserved
@@ -22,9 +22,6 @@
  *
  * This driver uses /dev/cpu/%d/msr where %d is the minor number, and on
  * an SMP box will direct the access to CPU %d.
-
-RED-PEN: need to get power management for S3 restore
-
  */
 
 #include <linux/module.h>
@@ -44,7 +41,6 @@ RED-PEN: need to get power management for S3 restore
 #include <asm/msr.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
-#include <asm/cpufeature.h>
 
 /* Note: "err" is handled in a funny way below.  Otherwise one version
    of gcc or another breaks. */
@@ -119,12 +115,11 @@ static void msr_smp_rdmsr(void *cmd_block)
 static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx)
 {
   struct msr_command cmd;
+  int ret;
 
   preempt_disable();
   if ( cpu == smp_processor_id() ) {
-    int ret = wrmsr_eio(reg, eax, edx);
-    preempt_enable();
-    return ret;
+    ret = wrmsr_eio(reg, eax, edx);
   } else {
     cmd.cpu = cpu;
     cmd.reg = reg;
@@ -132,17 +127,20 @@ static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx)
     cmd.data[1] = edx;
     
     smp_call_function(msr_smp_wrmsr, &cmd, 1, 1);
-    preempt_enable();
-    return cmd.err;
+    ret = cmd.err;
   }
+  preempt_enable();
+  return ret;
 }
 
 static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx)
 {
   struct msr_command cmd;
+  int ret;
 
+  preempt_disable();
   if ( cpu == smp_processor_id() ) {
-    return rdmsr_eio(reg, eax, edx);
+    ret = rdmsr_eio(reg, eax, edx);
   } else {
     cmd.cpu = cpu;
     cmd.reg = reg;
@@ -152,8 +150,10 @@ static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx)
     *eax = cmd.data[0];
     *edx = cmd.data[1];
 
-    return cmd.err;
+    ret = cmd.err;
   }
+  preempt_enable();
+  return ret;
 }
 
 #else /* ! CONFIG_SMP */
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index 8ab7bb0af3ef..34e3a58da168 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -22,6 +22,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
 #include <linux/module.h>
+#include <linux/sysdev.h>
 
 #include <asm/smp.h>
 #include <asm/mtrr.h>
@@ -152,50 +153,45 @@ void enable_lapic_nmi_watchdog(void)
 
 #include <linux/device.h>
 
-static int lapic_nmi_suspend(struct device *dev, u32 state, u32 level)
-  {
-	if (level != SUSPEND_POWER_DOWN)
-		return 0;
+static int lapic_nmi_suspend(struct sys_device *dev, u32 state)
+{
 	disable_lapic_nmi_watchdog();
 	return 0;
-  }
+}
 
-static int lapic_nmi_resume(struct device *dev, u32 level)
-  {
-	if (level != RESUME_POWER_ON)
-		return 0;
+static int lapic_nmi_resume(struct sys_device *dev)
+{
 #if 0
 	enable_lapic_nmi_watchdog();
 #endif
 	return 0;
-  }
+}
 
-static struct device_driver lapic_nmi_driver = {
-	.name		= "lapic_nmi",
-	.bus		= &system_bus_type,
+static struct sysdev_class nmi_sysclass = {
+	set_kset_name("lapic_nmi"),
 	.resume		= lapic_nmi_resume,
 	.suspend	= lapic_nmi_suspend,
 };
 
 static struct sys_device device_lapic_nmi = {
-	.name		= "lapic_nmi",
 	.id		= 0,
-	.dev		= {
-		.name	= "lapic_nmi",
-		.driver	= &lapic_nmi_driver,
-		.parent = &device_lapic.dev,
-	},
+	.cls	= &nmi_sysclass,
 };
 
-static int __init init_lapic_nmi_devicefs(void)
+static int __init init_lapic_nmi_sysfs(void)
 {
+	int error;
+
 	if (nmi_active == 0)
 		return 0;
-	driver_register(&lapic_nmi_driver);
-	return sys_device_register(&device_lapic_nmi);
+
+	error = sysdev_class_register(&nmi_sysclass);
+	if (!error)
+		error = sys_device_register(&device_lapic_nmi);
+	return error;
 }
 /* must come after the local APIC's device_initcall() */
-late_initcall(init_lapic_nmi_devicefs);
+late_initcall(init_lapic_nmi_sysfs);
 
 #endif	/* CONFIG_PM */
 
@@ -332,13 +328,11 @@ asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
 {
 	int cpu = safe_smp_processor_id();
 
-	init_tss[cpu].ist[NMI_STACK] -= 2048;	/* this shouldn't be needed. */	
 	nmi_enter();
 	add_pda(__nmi_count,1);
 	if (!nmi_callback(regs, cpu))
 		default_do_nmi(regs);
 	nmi_exit();
-	init_tss[cpu].ist[NMI_STACK] += 2048;
 }
 
 void set_nmi_callback(nmi_callback_t callback)
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 12047fff5230..b8679513563a 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -38,6 +38,8 @@ possible future tuning:
 #include <asm/pgtable.h>
 #include <asm/proto.h>
 #include <asm/cacheflush.h>
+#include <asm/kdebug.h>
+#include <asm/proto.h>
 
 unsigned long iommu_bus_base;	/* GART remapping area (physical) */
 static unsigned long iommu_size; 	/* size of remapping area bytes */
@@ -53,9 +55,6 @@ int force_mmu = 1;
 int force_mmu = 0;
 #endif
 
-extern int fallback_aper_order;
-extern int fallback_aper_force;
-
 /* Allocation bitmap for the remapping area */ 
 static spinlock_t iommu_bitmap_lock = SPIN_LOCK_UNLOCKED;
 static unsigned long *iommu_gart_bitmap; /* guarded by iommu_bitmap_lock */
@@ -135,10 +134,19 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
 	void *memory;
 	int gfp = GFP_ATOMIC;
 	int i;
-	unsigned long iommu_page;
 	int flush = 0;
+	unsigned long iommu_page;
+	unsigned long dma_mask;
 
-	if (hwdev == NULL || hwdev->dma_mask < 0xffffffff || no_iommu)
+	if (hwdev == NULL) {
+		gfp |= GFP_DMA; 
+		dma_mask = 0xffffffff; 
+	} else {
+		dma_mask = hwdev->consistent_dma_mask; 
+	}
+	if (dma_mask == 0) 
+		dma_mask = 0xffffffff; 
+	if (dma_mask < 0xffffffff || no_iommu)
 		gfp |= GFP_DMA;
 
 	/* 
@@ -151,7 +159,7 @@ void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
 		return NULL; 
 	} else {
 		int high = 0, mmu;
-		if (((unsigned long)virt_to_bus(memory) + size) > 0xffffffffUL)
+		if (((unsigned long)virt_to_bus(memory) + size) > dma_mask)
 			high = 1;
 		mmu = 1;
 		if (force_mmu && !(gfp & GFP_DMA)) 
@@ -222,7 +230,6 @@ void pci_free_consistent(struct pci_dev *hwdev, size_t size,
 static void **iommu_leak_tab; 
 static int leak_trace;
 int iommu_leak_pages = 20; 
-extern unsigned long printk_address(unsigned long);
 void dump_leak(void)
 {
 	int i;
@@ -459,7 +466,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
 
 extern int agp_amdk8_init(void);
 
-void __init pci_iommu_init(void)
+int __init pci_iommu_init(void)
 { 
 	struct agp_kern_info info;
 	unsigned long aper_size;
@@ -468,6 +475,7 @@ void __init pci_iommu_init(void)
 #ifndef CONFIG_AGP_AMD_8151
 	no_agp = 1; 
 #else
+	/* Makefile puts PCI initialization via subsys_initcall first. */
 	/* Add other K8 AGP bridge drivers here */
 	no_agp = no_agp || 
 		(agp_amdk8_init() < 0) || 
@@ -477,7 +485,7 @@ void __init pci_iommu_init(void)
 	if (no_iommu || (!force_mmu && end_pfn < 0xffffffff>>PAGE_SHIFT)) { 
 		printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n"); 
 		no_iommu = 1;
-		return;
+		return -1;
 	}
 
 	if (no_agp) { 
@@ -489,7 +497,7 @@ void __init pci_iommu_init(void)
 		if (err < 0) { 
 			printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n"); 
 			no_iommu = 1;
-			return;
+			return -1;
 		}
 	} 
 	
@@ -540,8 +548,13 @@ void __init pci_iommu_init(void)
 	clear_kernel_mapping((unsigned long)__va(iommu_bus_base), iommu_size);
 
 	flush_gart();
+
+	return 0;
 } 
 
+/* Must execute after PCI subsystem */
+fs_initcall(pci_iommu_init);
+
 /* iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]]
    size  set size of iommu (in bytes) 
    noagp don't initialize the AGP driver and use full aperture.
@@ -589,4 +602,3 @@ __init int iommu_setup(char *opt)
     }
     return 1;
 } 
-
diff --git a/arch/x86_64/kernel/pci-nommu.c b/arch/x86_64/kernel/pci-nommu.c
index 4e163f83f881..8240e5557f89 100644
--- a/arch/x86_64/kernel/pci-nommu.c
+++ b/arch/x86_64/kernel/pci-nommu.c
@@ -2,13 +2,12 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/string.h>
+#include <asm/proto.h>
 
 /* 
  * Dummy IO MMU functions
  */
 
-extern unsigned long end_pfn;
-
 void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
 			   dma_addr_t *dma_handle)
 {
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 5a5b2fe81e6c..dc6b48b58dbb 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -200,8 +200,6 @@ void show_regs(struct pt_regs *regs)
 	show_trace(&regs->rsp);
 }
 
-extern void load_gs_index(unsigned);
-
 /*
  * Free current thread data structures etc..
  */
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index e04b3912f17e..fafd7d063ef8 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -585,7 +585,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
 void __init print_cpu_info(struct cpuinfo_x86 *c)
 {
 	if (c->x86_model_id[0])
-		printk("AMD %s", c->x86_model_id);
+		printk("%s", c->x86_model_id);
 
 	if (c->x86_mask || c->cpuid_level >= 0) 
 		printk(" stepping %02x\n", c->x86_mask);
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
index 2bd0172ef482..6ae0e7077e09 100644
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -475,8 +475,6 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, __u32 thread_info_
 		do_signal(regs,oldset);
 }
 
-extern int exception_trace;
-
 void signal_fault(struct pt_regs *regs, void *frame, char *where)
 { 
 	struct task_struct *me = current; 
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 00ee45c7a21b..034ffc0efeb8 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -51,8 +51,7 @@
 #include <asm/desc.h>
 #include <asm/kdebug.h>
 #include <asm/tlbflush.h>
-
-extern int disable_apic;
+#include <asm/proto.h>
 
 /* Bitmask of currently online CPUs */
 unsigned long cpu_online_map = 1;
@@ -67,8 +66,6 @@ struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
 /* Set when the idlers are all forked */
 int smp_threads_ready;
 
-extern void time_init_smp(void);
-
 /*
  * Trampoline 80x86 program as an array.
  */
@@ -128,7 +125,6 @@ static void __init synchronize_tsc_bp (void)
 	long long delta;
 	long one_usec;
 	int buggy = 0;
-	extern unsigned cpu_khz;
 
 	printk(KERN_INFO "checking TSC synchronization across %u CPUs: ",num_booting_cpus());
 
@@ -242,8 +238,6 @@ static void __init synchronize_tsc_ap (void)
 }
 #undef NR_LOOPS
 
-extern void calibrate_delay(void);
-
 static atomic_t init_deasserted;
 
 void __init smp_callin(void)
@@ -337,8 +331,6 @@ void __init smp_callin(void)
 
 int cpucount;
 
-extern int cpu_idle(void);
-
 /*
  * Activate a secondary processor.
  */
@@ -560,8 +552,6 @@ static int __init wakeup_secondary_via_INIT(int phys_apicid, unsigned int start_
 	return (send_status | accept_status);
 }
 
-extern unsigned long cpu_initialized;
-
 static void __init do_boot_cpu (int apicid)
 {
 	struct task_struct *idle;
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 02286a052580..f558d43822bf 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -27,6 +27,7 @@
 #include <asm/pgtable.h>
 #include <asm/vsyscall.h>
 #include <asm/timex.h>
+#include <asm/proto.h>
 #ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/apic.h>
 #endif
@@ -38,9 +39,6 @@ extern int using_apic_timer;
 spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
 spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
 
-extern int using_apic_timer;
-extern void smp_local_timer_interrupt(struct pt_regs * regs);
-
 #undef HPET_HACK_ENABLE_DANGEROUS
 
 
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 24d5862bdcd7..3c8c0ff57cde 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -41,13 +41,10 @@
 #include <asm/smp.h>
 #include <asm/pgalloc.h>
 #include <asm/pda.h>
+#include <asm/proto.h>
 
 #include <linux/irq.h>
 
-asmlinkage int system_call(void);
-asmlinkage int kernel_syscall(void);
-extern void ia32_syscall(void);
-
 extern struct gate_struct idt_table[256]; 
 
 asmlinkage void divide_error(void);
@@ -73,8 +70,6 @@ asmlinkage void machine_check(void);
 asmlinkage void spurious_interrupt_bug(void);
 asmlinkage void call_debug(void);
 
-extern int exception_trace;
-
 struct notifier_block *die_chain;
 
 static inline void conditional_sti(struct pt_regs *regs)
@@ -457,8 +452,6 @@ DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr2())
 DO_ERROR(18, SIGSEGV, "reserved", reserved)
 
-extern void dump_pagetable(unsigned long);
-
 asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
 {
 	conditional_sti(regs);
diff --git a/arch/x86_64/kernel/wakeup.S b/arch/x86_64/kernel/wakeup.S
deleted file mode 100644
index 8fe49f037515..000000000000
--- a/arch/x86_64/kernel/wakeup.S
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * ACPI S3 entry/exit handling.
- *		
- * Notes:
- * Relies on kernel being loaded below 4GB.
- * Needs restore_low_mappings called before.
- *			
- * Copyright 2003 by Andi Kleen, SuSE Labs.
- *	
- * Long mode entry loosely based on example code in chapter 14 of the x86-64 system 
- * programmer's manual.
- * 
- * Notebook:	
-
- FIXME need to interface with suspend.c properly. do_magic. check i386. rename to suspend64.S
-		
- Need to fix vgacon,mtrr,bluesmoke to do resume
- 	
- Interrupts should be off until the io-apic code has reinited the APIC.
- Need support for that in the pm frame work or a special hack?
-
- SMP support is non existent. Need to somehow restart the other CPUs again.
- If CPU hotplug was working it could be used. Save/Restore needs to run on the same CPU.
-
- Should check magic like i386 code
-	
- suspend code copies something. check what it is.		
- */
-	
-#include <linux/linkage.h>
-	
-#include <asm/msr.h>
-#include <asm/segment.h>
-#include <asm/page.h>
-			
-#define O(x) (x-acpi_wakeup)
-		
-	.text
-	.code16
-ENTRY(acpi_wakeup)
-	/* 16bit real mode entered from ACPI BIOS */
-	/* The machine is just through BIOS setup after power down and everything set up
-	   by Linux needs to be restored. */
-	/* The code here needs to be position independent or manually relocated,
-	   because it is copied to a <1MB page for real mode execution */
-	
-	/* A20 enabled (according to ACPI spec) */
-	/* cs = acpi_wakeup >> 4 ;  eip = acpi_wakeup & 0xF */
-		
-	movw %cs,%ax
-	movw %ax,%ds	/* make %ds point to acpi_wakeup */
-	movw %ax,%ss
-	movw $O(wakeup_stack),%sp	/* setup stack */
-
-	pushl $0
-	popfl			/* clear EFLAGS */
-	
-	lgdt %ds:O(pGDT)	/* load kernel GDT */
-	
-	movl $0x1,%eax		/* enable protected mode */
-	movl %eax,%cr0
-
-	movl %ds:O(wakeup_page_table),%edi
-	ljmpl  $__KERNEL16_CS,$0   /* -> s3_prot16 (filled in earlier by caller) */
-	
-	/* patched by s3_restore_state below */
-pGDT:
-	.short 0
-	.quad  0
-
-	.align 4
-	.globl wakeup_page_table
-wakeup_page_table:	
-	.long 0	
-	
-	.align 8
-wakeup_stack:
-	.fill 128,1,0
-	.globl acpi_wakeup_end
-acpi_wakeup_end:
-	/* end of real mode trampoline */
-		
-	/* pointed to by __KERNEL16_CS:0 */	
-	.code16	
-ENTRY(s3_prot16)
-	/* Now in 16bit protected mode, still no paging, stack/data segments invalid */
-
-	/* Prepare everything for 64bit paging, but still keep it turned off */
-	movl %cr4,%eax
-	bts  $5,%eax	/* set PAE bit */
-	movl %eax,%cr4
-	
-	movl %edi,%cr3	/* load kernel page table */
-
-	movl $0x80000001,%eax	
-	cpuid		/* no execute supported ? */
-	movl %edx,%esi	
-	
-	movl $MSR_EFER,%ecx
-	rdmsr 
-	bts $8,%eax	/* long mode */
-	bt  $20,%esi	/* NX supported ? */
-	jnc 1f
-	bt  $_EFER_NX,%eax
-1:	
-	wrmsr		/* set temporary efer - real one is restored a bit later */
-	
-	movl %cr0,%eax
-	bts  $31,%eax	/* paging */
-	movl %eax,%cr0
-
-	/* running in identity mapping now */
-
-	/* go to 64bit code segment */
-	ljmpl $__KERNEL_CS,$s3_restore_state-__START_KERNEL_map
-
-	.code64			
-	.macro	SAVEMSR msr,target
-	movl	$\msr,%ecx
-	rdmsr
-	shlq	$32,%rdx
-	orq	%rax,%rdx
-	movq	%rdx,\target(%rip)
-	.endm
-
-	.macro RESTMSR msr,src
-	movl	$\msr,%ecx
-	movq	\src(%rip),%rax
-	movq	%rax,%rdx
-	shrq	$32,%rdx
-	wrmsr
-	.endm
-	
-	.macro	SAVECTL reg
-	movq	%\reg,%rax
-	movq	%rax,saved_\reg(%rip)
-	.endm
-	
-	.macro	RESTCTL reg
-	movq	saved_\reg(%rip),%rax
-	movq	%rax,%\reg
-	.endm
-
-	/* Running in identity mapping, long mode */
-s3_restore_state_low:
-	movq	$s3_restore_state,%rax
-	jmpq	*%rax	
-
-	/* Running in real kernel mapping now */
-s3_restore_state:
-	xorl	%eax,%eax
-	movl	%eax,%ds
-	movq	saved_rsp(%rip),%rsp
-	movw	saved_ss(%rip),%ss
-	movw	saved_fs(%rip),%fs
-	movw	saved_gs(%rip),%gs
-	movw	saved_es(%rip),%es
-	movw	saved_ds(%rip),%ds
-
-	lidt	saved_idt
-	ltr	saved_tr
-	lldt	saved_ldt	
-	/* gdt is already loaded */
-	
-	RESTCTL	cr0
-	RESTCTL	cr4
-	/* cr3 is already loaded */	
-	
-	RESTMSR MSR_EFER,saved_efer
-	RESTMSR MSR_LSTAR,saved_lstar
-	RESTMSR MSR_CSTAR,saved_cstar
-	RESTMSR MSR_FS_BASE,saved_fs_base
-	RESTMSR MSR_GS_BASE,saved_gs_base
-	RESTMSR MSR_KERNEL_GS_BASE,saved_kernel_gs_base
-	RESTMSR MSR_SYSCALL_MASK,saved_syscall_mask
-				
-	fxrstor	fpustate(%rip)
-
-	RESTCTL	dr0
-	RESTCTL	dr1
-	RESTCTL	dr2
-	RESTCTL	dr3
-	RESTCTL	dr6
-	RESTCTL	dr7
-
-	movq	saved_rflags(%rip),%rax
-	pushq	%rax
-	popfq
-								
-	movq	saved_rbp(%rip),%rbp
-	movq	saved_rbx(%rip),%rbx
-	movq	saved_r12(%rip),%r12
-	movq	saved_r13(%rip),%r13
-	movq	saved_r14(%rip),%r14
-	movq	saved_r15(%rip),%r15		
-	ret
-		
-ENTRY(acpi_prepare_wakeup)
-	sgdt	saved_gdt
-	
-	/* copy gdt descr and page table to low level wakeup code so that it can 
-	   reload them early. */
-	movq	acpi_wakeup_address(%rip),%rax	
-	movw	saved_gdt+8(%rip),%cx
-	movw	%cx,O(pGDT)+8(%rax)	
-	movq	saved_gdt(%rip),%rcx
-	movq	%rcx,O(pGDT)(%rax)
-	
-	movq	%cr3,%rdi
-	movl	%edi,O(wakeup_page_table)(%rax)
-	ret
-
-	/* Save CPU state. */
-	/* Everything saved here needs to be restored above. */
-ENTRY(do_suspend_lowlevel)
-	testl	%edi,%edi
-	jnz	s3_restore_state
-		
-	SAVECTL	cr0
-	SAVECTL	cr4
-	SAVECTL	cr3
-		
-	str	saved_tr
-	sidt	saved_idt		
-	sgdt	saved_gdt
-	sldt	saved_ldt
-			
-	SAVEMSR MSR_EFER,saved_efer
-	SAVEMSR MSR_LSTAR,saved_lstar
-	SAVEMSR MSR_CSTAR,saved_cstar
-	SAVEMSR MSR_FS_BASE,saved_fs_base
-	SAVEMSR MSR_GS_BASE,saved_gs_base
-	SAVEMSR MSR_KERNEL_GS_BASE,saved_kernel_gs_base
-	SAVEMSR MSR_SYSCALL_MASK,saved_syscall_mask
-
-	movw	%ds,saved_ds(%rip)
-	movw	%es,saved_es(%rip)
-	movw	%fs,saved_fs(%rip)
-	movw	%gs,saved_gs(%rip)
-	movw	%ss,saved_ss(%rip)
-	movq	%rsp,saved_rsp(%rip)
-	
-	pushfq
-	popq	%rax
-	movq	%rax,saved_rflags(%rip)
-
-	SAVECTL  dr0
-	SAVECTL  dr1
-	SAVECTL  dr2
-	SAVECTL  dr3
-	SAVECTL  dr6
-	SAVECTL  dr7
-	
-	fxsave	fpustate(%rip) 
-	
-	/* finally save callee saved registers */
-	movq	%rbp,saved_rbp(%rip)
-	movq	%rbx,saved_rbx(%rip)
-	movq	%r12,saved_r12(%rip)
-	movq	%r13,saved_r13(%rip)
-	movq	%r14,saved_r14(%rip)
-	movq	%r15,saved_r15(%rip)
-	movq	$3,%rdi		
-	call	acpi_enter_sleep_state
-	ret	/* should not happen */
-
-	.data
-	.align 8
-saved_efer:	.quad 0
-saved_lstar:	.quad 0
-saved_cstar:	.quad 0
-saved_cr4:	.quad 0
-saved_cr3:	.quad 0
-saved_cr0:	.quad 0	
-saved_rbp:	.quad 0
-saved_rbx:	.quad 0
-saved_rsp:	.quad 0
-saved_r12:	.quad 0
-saved_r13:	.quad 0
-saved_r14:	.quad 0
-saved_r15:	.quad 0
-saved_rflags:	.quad 0
-saved_gs_base:	.quad 0
-saved_fs_base:	.quad 0
-saved_kernel_gs_base:	.quad 0
-saved_syscall_mask:	.quad 0
-saved_dr0:	.quad 0	
-saved_dr1:	.quad 0	
-saved_dr2:	.quad 0	
-saved_dr3:	.quad 0	
-saved_dr6:	.quad 0	
-saved_dr7:	.quad 0	
-saved_ds:	.short 0
-saved_fs:	.short 0
-saved_gs:	.short 0
-saved_es:	.short 0
-saved_ss:	.short 0	
-saved_idt:	.short 0
-		.quad 0
-saved_ldt:	.short 0
-saved_gdt:	.short 0
-		.quad 0		
-saved_tr:	.short 0
-			
-		.align 16
-fpustate:	.fill  512,1,0				
diff --git a/arch/x86_64/lib/delay.c b/arch/x86_64/lib/delay.c
index 16a8d8bcdada..9fcdb2d2d4cd 100644
--- a/arch/x86_64/lib/delay.c
+++ b/arch/x86_64/lib/delay.c
@@ -21,7 +21,6 @@ int x86_udelay_tsc = 0;		/* Delay via TSC */
 
 void __delay(unsigned long loops)
 {
-#ifndef CONFIG_SIMNOW
 	unsigned long bclock, now;
 	
 	rdtscl(bclock);
@@ -31,7 +30,6 @@ void __delay(unsigned long loops)
 		rdtscl(now);
 	}
 	while((now-bclock) < loops);
-#endif
 }
 
 inline void __const_udelay(unsigned long xloops)
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index dee5a42a2e9f..3be6a8e4b679 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -24,6 +24,7 @@
 #endif
 #include <linux/pagemap.h>
 #include <linux/bootmem.h>
+#include <linux/proc_fs.h>
 
 #include <asm/processor.h>
 #include <asm/system.h>
@@ -41,6 +42,8 @@
 
 #define Dprintk(x...)
 
+extern char _stext;
+
 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
 /*
@@ -393,6 +396,9 @@ static inline int page_is_ram (unsigned long pagenr)
 	return 0;
 }
 
+static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
+			 kcore_vsyscall;
+
 void __init mem_init(void)
 {
 	int codesize, reservedpages, datasize, initsize;
@@ -434,6 +440,15 @@ void __init mem_init(void)
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
+	/* Register memory areas for /proc/kcore */
+	kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
+	kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, 
+		   VMALLOC_END-VMALLOC_START);
+	kclist_add(&kcore_kernel, &_stext, &_end - &_stext); 
+	kclist_add(&kcore_modules, (void *)MODULES_VADDR, MODULES_LEN);
+	kclist_add(&kcore_vsyscall, (void *)VSYSCALL_START, 
+				 VSYSCALL_END - VSYSCALL_START);
+
 	printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
 		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
 		end_pfn << (PAGE_SHIFT-10),
@@ -462,7 +477,7 @@ void free_initmem(void)
 		ClearPageReserved(virt_to_page(addr));
 		set_page_count(virt_to_page(addr), 1);
 #ifdef CONFIG_INIT_DEBUG
-		memset(addr & ~(PAGE_SIZE-1), 0xcc, PAGE_SIZE); 
+		memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE); 
 #endif
 		free_page(addr);
 		totalram_pages++;
@@ -497,3 +512,29 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len)
 	reserve_bootmem(phys, len);    
 #endif
 }
+
+int kern_addr_valid(unsigned long addr) 
+{ 
+	unsigned long above = ((long)addr) >> __VIRTUAL_MASK_SHIFT;
+	if (above != 0 && above != -1UL)
+		return 0; 
+	
+	pml4_t *pml4 = pml4_offset_k(addr);
+	if (pml4_none(*pml4))
+		return 0;
+
+	pgd_t *pgd = pgd_offset_k(addr); 
+	if (pgd_none(*pgd))
+		return 0; 
+
+	pmd_t *pmd = pmd_offset(pgd, addr);
+	if (pmd_none(*pmd))
+		return 0;
+	if (pmd_large(*pmd))
+		return pfn_valid(pmd_pfn(*pmd));
+
+	pte_t *pte = pte_offset_kernel(pmd, addr); 
+	if (pte_none(*pte))
+		return 0;
+	return pfn_valid(pte_pfn(*pte));
+}
diff --git a/arch/x86_64/pci/Makefile b/arch/x86_64/pci/Makefile
index d113570fe828..f673692e643d 100644
--- a/arch/x86_64/pci/Makefile
+++ b/arch/x86_64/pci/Makefile
@@ -1,8 +1,29 @@
 #
 # Makefile for X86_64 specific PCI routines
 #
-obj-y		:= x86-64.o
+# Reuse the i386 PCI subsystem using symlinks
+#
+obj-y		:= i386.o
 obj-$(CONFIG_PCI_DIRECT)+= direct.o
 obj-y		+= fixup.o
 obj-$(CONFIG_ACPI_PCI)	+= acpi.o
 obj-y			+= legacy.o irq.o common.o
+
+$(obj)/direct.c: $(obj)/pci.h
+	@ln -sf ../../i386/pci/direct.c $(obj)/direct.c
+$(obj)/legacy.c: $(obj)/pci.h
+	@ln -sf ../../i386/pci/legacy.c $(obj)/legacy.c
+$(obj)/common.c: $(obj)/pci.h
+	@ln -sf ../../i386/pci/common.c $(obj)/common.c
+$(obj)/acpi.c: $(obj)/pci.h
+	@ln -sf ../../i386/pci/acpi.c $(obj)/acpi.c
+$(obj)/pci.h:
+	@ln -sf ../../i386/pci/pci.h $(obj)/pci.h
+$(obj)/irq.c: $(obj)/pci.h
+	@ln -sf ../../i386/pci/irq.c $(obj)/irq.c
+$(obj)/fixup.c: $(obj)/pci.h
+	@ln -sf ../../i386/pci/fixup.c $(obj)/fixup.c
+$(obj)/i386.c: $(obj)/pci.h
+	@ln -sf ../../i386/pci/i386.c $(obj)/i386.c
+
+clean-files += i386.c legacy.c fixup.c acpi.c irq.c pci.h common.c direct.c
diff --git a/arch/x86_64/pci/acpi.c b/arch/x86_64/pci/acpi.c
deleted file mode 100644
index 2c21bc493ce4..000000000000
--- a/arch/x86_64/pci/acpi.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <linux/pci.h>
-#include <linux/acpi.h>
-#include <linux/init.h>
-#include "pci.h"
-
-static int __init pci_acpi_init(void)
-{
-	if (pcibios_scanned)
-		return 0;
-
-	if (!(pci_probe & PCI_NO_ACPI_ROUTING)) {
-		if (!acpi_pci_irq_init()) {
-			printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
-			printk(KERN_INFO "PCI: if you experience problems, try using option 'pci=noacpi'\n");
-			pcibios_scanned++;
-			pcibios_enable_irq = acpi_pci_irq_enable;
-		} else
-			printk(KERN_WARNING "PCI: Invalid ACPI-PCI IRQ routing table\n");
-
-		/* still scan manually in case ACPI forgot some bus */
-		pcibios_fixup_peer_bridges(); 
-	}
-
-	return 0;
-}
-
-subsys_initcall(pci_acpi_init);
diff --git a/arch/x86_64/pci/changelog b/arch/x86_64/pci/changelog
deleted file mode 100644
index fcf2f4d7c0c9..000000000000
--- a/arch/x86_64/pci/changelog
+++ /dev/null
@@ -1 +0,0 @@
-See arch/i386/pci/changelog for early changelog.
diff --git a/arch/x86_64/pci/common.c b/arch/x86_64/pci/common.c
deleted file mode 100644
index 8a189e818ef1..000000000000
--- a/arch/x86_64/pci/common.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- *	Low-Level PCI Support for PC
- *
- *	(c) 1999--2000 Martin Mares <mj@ucw.cz>
-
- Note: on x86-64 there is no PCI BIOS so there is no way to sort in the 
- same order as 32bit Linux. This could cause grief for dualbooting because
- devices may wander.  May want to use ACPI for sorting eventually. 
-
- */
-
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-
-#include <asm/segment.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/cache.h>
-
-#include "pci.h"
-
-unsigned int pci_probe = PCI_PROBE_CONF1 | PCI_PROBE_CONF2;
-
-int pcibios_last_bus = 0xff; /* XXX */
-struct pci_bus *pci_root_bus = NULL;
-struct pci_ops *pci_root_ops = NULL;
-
-int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL;
-int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL;
-
-/*
- * legacy, numa, and acpi all want to call pcibios_scan_root
- * from their initcalls. This flag prevents that.
- */
-int pcibios_scanned;
-
-/*
- * This interrupt-safe spinlock protects all accesses to PCI
- * configuration space.
- */
-spinlock_t pci_config_lock = SPIN_LOCK_UNLOCKED;
-
-/*
- * Several buggy motherboards address only 16 devices and mirror
- * them to next 16 IDs. We try to detect this `feature' on all
- * primary buses (those containing host bridges as they are
- * expected to be unique) and remove the ghost devices.
- */
-
-static void __devinit pcibios_fixup_ghosts(struct pci_bus *b)
-{
-	struct list_head *ln, *mn;
-	struct pci_dev *d, *e;
-	int mirror = PCI_DEVFN(16,0);
-	int seen_host_bridge = 0;
-	int i;
-
-	DBG("PCI: Scanning for ghost devices on bus %d\n", b->number);
-	for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
-		d = pci_dev_b(ln);
-		if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST)
-			seen_host_bridge++;
-		for (mn=ln->next; mn != &b->devices; mn=mn->next) {
-			e = pci_dev_b(mn);
-			if (e->devfn != d->devfn + mirror ||
-			    e->vendor != d->vendor ||
-			    e->device != d->device ||
-			    e->class != d->class)
-				continue;
-			for(i=0; i<PCI_NUM_RESOURCES; i++)
-				if (e->resource[i].start != d->resource[i].start ||
-				    e->resource[i].end != d->resource[i].end ||
-				    e->resource[i].flags != d->resource[i].flags)
-					continue;
-			break;
-		}
-		if (mn == &b->devices)
-			return;
-	}
-	if (!seen_host_bridge)
-		return;
-	printk(KERN_WARNING "PCI: Ignoring ghost devices on bus %02x\n", b->number);
-
-	ln = &b->devices;
-	while (ln->next != &b->devices) {
-		d = pci_dev_b(ln->next);
-		if (d->devfn >= mirror) {
-			list_del(&d->global_list);
-			list_del(&d->bus_list);
-			kfree(d);
-		} else
-			ln = ln->next;
-	}
-}
-
-struct pbus_set_ranges_data;
-
-void __devinit
-pcibios_fixup_pbus_ranges (struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
-{
-}
-
-/*
- *  Called after each bus is probed, but before its children
- *  are examined.
- */
-
-void __devinit  pcibios_fixup_bus(struct pci_bus *b)
-{
-	pcibios_fixup_ghosts(b);
-	pci_read_bridge_bases(b);
-}
-
-
-struct pci_bus * __devinit pcibios_scan_root(int busnum)
-{
-	struct list_head *list;
-	struct pci_bus *bus;
-
-	list_for_each(list, &pci_root_buses) {
-		bus = pci_bus_b(list);
-		if (bus->number == busnum) {
-			/* Already scanned */
-			return bus;
-		}
-	}
-
-	printk("PCI: Probing PCI hardware (bus %02x)\n", busnum);
-
-	return pci_scan_bus(busnum, pci_root_ops, NULL);
-}
-
-extern u8 pci_cache_line_size;
-
-static int __init pcibios_init(void)
-{
-	if (!pci_root_ops) {
-		printk("PCI: System does not support PCI\n");
-		return 0;
-	}
-
-	pci_cache_line_size = boot_cpu_data.x86_clflush_size >> 2;
-	
-	pcibios_resource_survey();
-
-#ifdef CONFIG_GART_IOMMU
-	pci_iommu_init();
-#endif
-
-	/* may eventually need to do ACPI sort here. */
-	return 0;
-}
-
-subsys_initcall(pcibios_init);
-
-char * __devinit  pcibios_setup(char *str)
-{
-	if (!strcmp(str, "off")) {
-		pci_probe = 0;
-		return NULL;
-	}
-#ifdef CONFIG_PCI_DIRECT
-	else if (!strcmp(str, "conf1")) {
-		pci_probe = PCI_PROBE_CONF1 | PCI_NO_CHECKS;
-		return NULL;
-	}
-	else if (!strcmp(str, "conf2")) {
-		pci_probe = PCI_PROBE_CONF2 | PCI_NO_CHECKS;
-		return NULL;
-	}
-#endif
-#ifdef CONFIG_ACPI_PCI
-	else if (!strcmp(str, "noacpi")) {
-		pci_probe |= PCI_NO_ACPI_ROUTING;
-		return NULL;
-	}
-#endif
-	else if (!strcmp(str, "rom")) {
-		pci_probe |= PCI_ASSIGN_ROMS;
-		return NULL;
-	} else if (!strcmp(str, "assign-busses")) {
-		pci_probe |= PCI_ASSIGN_ALL_BUSSES;
-		return NULL;
-	} else if (!strcmp(str, "usepirqmask")) {
-		pci_probe |= PCI_USE_PIRQ_MASK;
-		return NULL;
-	} else if (!strncmp(str, "irqmask=", 8)) {
-		pcibios_irq_mask = simple_strtol(str+8, NULL, 0);
-		return NULL;
-	} else if (!strncmp(str, "lastbus=", 8)) {
-		pcibios_last_bus = simple_strtol(str+8, NULL, 0);
-		return NULL;
-	}
-	return str;
-}
-
-unsigned int pcibios_assign_all_busses(void)
-{
-	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
-}
-
-int pcibios_enable_device(struct pci_dev *dev, int mask)
-{
-	int err;
-
-	if ((err = pcibios_enable_resources(dev, mask)) < 0)
-		return err;
-
-	return pcibios_enable_irq(dev);
-}
diff --git a/arch/x86_64/pci/direct.c b/arch/x86_64/pci/direct.c
deleted file mode 100644
index a5971a01cdb5..000000000000
--- a/arch/x86_64/pci/direct.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * direct.c - Low-level direct PCI config space access
- */
-
-#include <linux/pci.h>
-#include <linux/init.h>
-#include "pci.h"
-
-/*
- * Functions for accessing PCI configuration space with type 1 accesses
- */
-
-#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
-	(0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
-
-static int __pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
-{
-	unsigned long flags;
-
-	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
-		return -EINVAL;
-
-	spin_lock_irqsave(&pci_config_lock, flags);
-
-	outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8);
-
-	switch (len) {
-	case 1:
-		*value = inb(0xCFC + (reg & 3));
-		break;
-	case 2:
-		*value = inw(0xCFC + (reg & 2));
-		break;
-	case 4:
-		*value = inl(0xCFC);
-		break;
-	}
-
-	spin_unlock_irqrestore(&pci_config_lock, flags);
-
-	return 0;
-}
-
-static int __pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
-{
-	unsigned long flags;
-
-	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
-		return -EINVAL;
-
-	spin_lock_irqsave(&pci_config_lock, flags);
-
-	outl(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8);
-
-	switch (len) {
-	case 1:
-		outb((u8)value, 0xCFC + (reg & 3));
-		break;
-	case 2:
-		outw((u16)value, 0xCFC + (reg & 2));
-		break;
-	case 4:
-		outl((u32)value, 0xCFC);
-		break;
-	}
-
-	spin_unlock_irqrestore(&pci_config_lock, flags);
-
-	return 0;
-}
-
-#undef PCI_CONF1_ADDRESS
-
-static int pci_conf1_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
-{
-	return __pci_conf1_read(0, bus->number, PCI_SLOT(devfn), 
-		PCI_FUNC(devfn), where, size, value);
-}
-
-static int pci_conf1_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
-{
-	return __pci_conf1_write(0, bus->number, PCI_SLOT(devfn), 
-		PCI_FUNC(devfn), where, size, value);
-}
-
-static struct pci_ops pci_direct_conf1 = {
-	.read =		pci_conf1_read,
-	.write =	pci_conf1_write,
-};
-
-
-/*
- * Functions for accessing PCI configuration space with type 2 accesses
- */
-
-#define PCI_CONF2_ADDRESS(dev, reg)	(u16)(0xC000 | (dev << 8) | reg)
-
-static int __pci_conf2_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
-{
-	unsigned long flags;
-
-	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
-		return -EINVAL;
-
-	if (dev & 0x10) 
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	spin_lock_irqsave(&pci_config_lock, flags);
-
-	outb((u8)(0xF0 | (fn << 1)), 0xCF8);
-	outb((u8)bus, 0xCFA);
-
-	switch (len) {
-	case 1:
-		*value = inb(PCI_CONF2_ADDRESS(dev, reg));
-		break;
-	case 2:
-		*value = inw(PCI_CONF2_ADDRESS(dev, reg));
-		break;
-	case 4:
-		*value = inl(PCI_CONF2_ADDRESS(dev, reg));
-		break;
-	}
-
-	outb (0, 0xCF8);
-
-	spin_unlock_irqrestore(&pci_config_lock, flags);
-
-	return 0;
-}
-
-static int __pci_conf2_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
-{
-	unsigned long flags;
-
-	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
-		return -EINVAL;
-
-	if (dev & 0x10) 
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	spin_lock_irqsave(&pci_config_lock, flags);
-
-	outb((u8)(0xF0 | (fn << 1)), 0xCF8);
-	outb((u8)bus, 0xCFA);
-
-	switch (len) {
-	case 1:
-		outb ((u8)value, PCI_CONF2_ADDRESS(dev, reg));
-		break;
-	case 2:
-		outw ((u16)value, PCI_CONF2_ADDRESS(dev, reg));
-		break;
-	case 4:
-		outl ((u32)value, PCI_CONF2_ADDRESS(dev, reg));
-		break;
-	}
-
-	outb (0, 0xCF8);    
-
-	spin_unlock_irqrestore(&pci_config_lock, flags);
-
-	return 0;
-}
-
-#undef PCI_CONF2_ADDRESS
-
-static int pci_conf2_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
-{
-	return __pci_conf2_read(0, bus->number, PCI_SLOT(devfn), 
-		PCI_FUNC(devfn), where, size, value);
-}
-
-static int pci_conf2_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value)
-{
-	return __pci_conf2_write(0, bus->number, PCI_SLOT(devfn), 
-		PCI_FUNC(devfn), where, size, value);
-}
-
-static struct pci_ops pci_direct_conf2 = {
-	.read =		pci_conf2_read,
-	.write =	pci_conf2_write,
-};
-
-
-/*
- * Before we decide to use direct hardware access mechanisms, we try to do some
- * trivial checks to ensure it at least _seems_ to be working -- we just test
- * whether bus 00 contains a host bridge (this is similar to checking
- * techniques used in XFree86, but ours should be more reliable since we
- * attempt to make use of direct access hints provided by the PCI BIOS).
- *
- * This should be close to trivial, but it isn't, because there are buggy
- * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
- */
-static int __devinit pci_sanity_check(struct pci_ops *o)
-{
-	u32 x = 0;
-	int retval = 0;
-	struct pci_bus *bus;		/* Fake bus and device */
-	struct pci_dev *dev;
-
-	if (pci_probe & PCI_NO_CHECKS)
-		return 1;
-
-	bus = kmalloc(sizeof(*bus), GFP_ATOMIC);
-	dev = kmalloc(sizeof(*dev), GFP_ATOMIC);
-	if (!bus || !dev) {
-		printk(KERN_ERR "Out of memory in %s\n", __FUNCTION__);
-		goto exit;
-	}
-
-	bus->number = 0;
-	dev->bus = bus;
-	for(dev->devfn=0; dev->devfn < 0x100; dev->devfn++)
-		if ((!o->read(bus, dev->devfn, PCI_CLASS_DEVICE, 2, &x) &&
-		     (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) ||
-		    (!o->read(bus, dev->devfn, PCI_VENDOR_ID, 2, &x) &&
-		     (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ))) {
-			retval = 1;
-			goto exit;
-		}
-	DBG("PCI: Sanity check failed\n");
-exit:
-	kfree(dev);
-	kfree(bus);
-	return retval;
-}
-
-static int __init pci_direct_init(void)
-{
-	unsigned int tmp;
-	unsigned long flags;
-
-	local_irq_save(flags);
-
-	/*
-	 * Check if configuration type 1 works.
-	 */
-	if (pci_probe & PCI_PROBE_CONF1) {
-		outb (0x01, 0xCFB);
-		tmp = inl (0xCF8);
-		outl (0x80000000, 0xCF8);
-		if (inl (0xCF8) == 0x80000000 &&
-		    pci_sanity_check(&pci_direct_conf1)) {
-			outl (tmp, 0xCF8);
-			local_irq_restore(flags);
-			printk(KERN_INFO "PCI: Using configuration type 1\n");
-			if (!request_region(0xCF8, 8, "PCI conf1"))
-				pci_root_ops = NULL;
-			else
-				pci_root_ops = &pci_direct_conf1;
-			return 0;
-		}
-		outl (tmp, 0xCF8);
-	}
-
-	/*
-	 * Check if configuration type 2 works.
-	 */
-	if (pci_probe & PCI_PROBE_CONF2) {
-		outb (0x00, 0xCFB);
-		outb (0x00, 0xCF8);
-		outb (0x00, 0xCFA);
-		if (inb (0xCF8) == 0x00 && inb (0xCFA) == 0x00 &&
-		    pci_sanity_check(&pci_direct_conf2)) {
-			local_irq_restore(flags);
-			printk(KERN_INFO "PCI: Using configuration type 2\n");
-			if (!request_region(0xCF8, 4, "PCI conf2"))
-				pci_root_ops = NULL;
-			else
-				pci_root_ops = &pci_direct_conf2;
-			return 0;
-		}
-	}
-
-	local_irq_restore(flags);
-	return 0;
-}
-
-arch_initcall(pci_direct_init);
diff --git a/arch/x86_64/pci/fixup.c b/arch/x86_64/pci/fixup.c
deleted file mode 100644
index 6f6aee48b601..000000000000
--- a/arch/x86_64/pci/fixup.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Exceptions for specific devices. Usually work-arounds for fatal design flaws.
- *
-
-Short list on x86-64........so far. 
-
- */
-
-#include <linux/pci.h>
-#include <linux/init.h>
-#include "pci.h"
-
-static void __devinit  pci_fixup_ncr53c810(struct pci_dev *d)
-{
-	/*
-	 * NCR 53C810 returns class code 0 (at least on some systems).
-	 * Fix class to be PCI_CLASS_STORAGE_SCSI
-	 */
-	if (!d->class) {
-		printk(KERN_WARNING "PCI: fixing NCR 53C810 class code for %s\n", d->slot_name);
-		d->class = PCI_CLASS_STORAGE_SCSI << 8;
-	}
-}
-
-static void __devinit pci_fixup_ide_bases(struct pci_dev *d)
-{
-	int i;
-
-	/*
-	 * PCI IDE controllers use non-standard I/O port decoding, respect it.
-	 */
-	if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
-		return;
-	DBG("PCI: IDE base address fixup for %s\n", d->slot_name);
-	for(i=0; i<4; i++) {
-		struct resource *r = &d->resource[i];
-		if ((r->start & ~0x80) == 0x374) {
-			r->start |= 2;
-			r->end = r->start;
-		}
-	}
-}
-
-struct pci_fixup pcibios_fixups[] = {
-	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,		PCI_ANY_ID,			pci_fixup_ide_bases },
-	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_NCR,	PCI_DEVICE_ID_NCR_53C810,	pci_fixup_ncr53c810 },
-	{ 0 }
-};
diff --git a/arch/x86_64/pci/irq.c b/arch/x86_64/pci/irq.c
deleted file mode 100644
index 575ede9cb389..000000000000
--- a/arch/x86_64/pci/irq.c
+++ /dev/null
@@ -1,639 +0,0 @@
-/*
- *	Low-Level PCI Support for PC -- Routing of Interrupts
- *
- *	(c) 1999--2000 Martin Mares <mj@ucw.cz>
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/io_apic.h>
-
-#include "pci.h"
-
-#define PIRQ_SIGNATURE	(('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
-#define PIRQ_VERSION 0x0100
-
-int broken_hp_bios_irq9;
-
-static struct irq_routing_table *pirq_table;
-
-/*
- * Never use: 0, 1, 2 (timer, keyboard, and cascade)
- * Avoid using: 13, 14 and 15 (FP error and IDE).
- * Penalize: 3, 4, 6, 7, 12 (known ISA uses: serial, floppy, parallel and mouse)
- */
-unsigned int pcibios_irq_mask = 0xfff8;
-
-static int pirq_penalty[16] = {
-	1000000, 1000000, 1000000, 1000, 1000, 0, 1000, 1000,
-	0, 0, 0, 0, 1000, 100000, 100000, 100000
-};
-
-struct irq_router {
-	char *name;
-	u16 vendor, device;
-	int (*get)(struct pci_dev *router, struct pci_dev *dev, int pirq);
-	int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq, int new);
-};
-
-int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL;
-
-/*
- *  Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table.
- */
-
-static struct irq_routing_table * __init pirq_find_routing_table(void)
-{
-	u8 *addr;
-	struct irq_routing_table *rt;
-	int i;
-	u8 sum;
-
-	for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) {
-		rt = (struct irq_routing_table *) addr;
-		if (rt->signature != PIRQ_SIGNATURE ||
-		    rt->version != PIRQ_VERSION ||
-		    rt->size % 16 ||
-		    rt->size < sizeof(struct irq_routing_table))
-			continue;
-		sum = 0;
-		for(i=0; i<rt->size; i++)
-			sum += addr[i];
-		if (!sum) {
-			DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt);
-			return rt;
-		}
-	}
-	return NULL;
-}
-
-/*
- *  If we have a IRQ routing table, use it to search for peer host
- *  bridges.  It's a gross hack, but since there are no other known
- *  ways how to get a list of buses, we have to go this way.
- */
-
-static void __init pirq_peer_trick(void)
-{
-	struct irq_routing_table *rt = pirq_table;
-	u8 busmap[256];
-	int i;
-	struct irq_info *e;
-
-	memset(busmap, 0, sizeof(busmap));
-	for(i=0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) {
-		e = &rt->slots[i];
-#ifdef DEBUG
-		{
-			int j;
-			DBG("%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot);
-			for(j=0; j<4; j++)
-				DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap);
-			DBG("\n");
-		}
-#endif
-		busmap[e->bus] = 1;
-	}
-	for(i=1; i<256; i++)
-		/*
-		 *  It might be a secondary bus, but in this case its parent is already
-		 *  known (ascending bus order) and therefore pci_scan_bus returns immediately.
-		 */
-		if (busmap[i] && pci_scan_bus(i, pci_root_bus->ops, NULL))
-			printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i);
-	//pcibios_last_bus = -1;
-}
-
-/*
- *  Code for querying and setting of IRQ routes on various interrupt routers.
- */
-
-void eisa_set_level_irq(unsigned int irq)
-{
-	unsigned char mask = 1 << (irq & 7);
-	unsigned int port = 0x4d0 + (irq >> 3);
-	unsigned char val = inb(port);
-
-	if (!(val & mask)) {
-		DBG(" -> edge");
-		outb(val | mask, port);
-	}
-}
-
-/*
- * Common IRQ routing practice: nybbles in config space,
- * offset by some magic constant.
- */
-static unsigned int read_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr)
-{
-	u8 x;
-	unsigned reg = offset + (nr >> 1);
-
-	pci_read_config_byte(router, reg, &x);
-	return (nr & 1) ? (x >> 4) : (x & 0xf);
-}
-
-static void write_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr, unsigned int val)
-{
-	u8 x;
-	unsigned reg = offset + (nr >> 1);
-
-	pci_read_config_byte(router, reg, &x);
-	x = (nr & 1) ? ((x & 0x0f) | (val << 4)) : ((x & 0xf0) | val);
-	pci_write_config_byte(router, reg, x);
-}
-
-#if 0 /* enable when pci ids ae known */
-/*
- * The VIA pirq rules are nibble-based, like ALI,
- * but without the ugly irq number munging.
- */
-static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-{
-	return read_config_nybble(router, 0x55, pirq);
-}
-
-static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-{
-	write_config_nybble(router, 0x55, pirq, irq);
-	return 1;
-}
-
-/*
- *	PIRQ routing for SiS 85C503 router used in several SiS chipsets
- *	According to the SiS 5595 datasheet (preliminary V1.0, 12/24/1997)
- *	the related registers work as follows:
- *	
- *	general: one byte per re-routable IRQ,
- *		 bit 7      IRQ mapping enabled (0) or disabled (1)
- *		 bits [6:4] reserved
- *		 bits [3:0] IRQ to map to
- *		     allowed: 3-7, 9-12, 14-15
- *		     reserved: 0, 1, 2, 8, 13
- *
- *	individual registers in device config space:
- *
- *	0x41/0x42/0x43/0x44:	PCI INT A/B/C/D - bits as in general case
- *
- *	0x61:			IDEIRQ: bits as in general case - but:
- *				bits [6:5] must be written 01
- *				bit 4 channel-select primary (0), secondary (1)
- *
- *	0x62:			USBIRQ: bits as in general case - but:
- *				bit 4 OHCI function disabled (0), enabled (1)
- *	
- *	0x6a:			ACPI/SCI IRQ - bits as in general case
- *
- *	0x7e:			Data Acq. Module IRQ - bits as in general case
- *
- *	Apparently there are systems implementing PCI routing table using both
- *	link values 0x01-0x04 and 0x41-0x44 for PCI INTA..D, but register offsets
- *	like 0x62 as link values for USBIRQ e.g. So there is no simple
- *	"register = offset + pirq" relation.
- *	Currently we support PCI INTA..D and USBIRQ and try our best to handle
- *	both link mappings.
- *	IDE/ACPI/DAQ mapping is currently unsupported (left untouched as set by BIOS).
- */
-
-static int pirq_sis_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-{
-	u8 x;
-	int reg = pirq;
-
-	switch(pirq) {
-		case 0x01:
-		case 0x02:
-		case 0x03:
-		case 0x04:
-			reg += 0x40;
-		case 0x41:
-		case 0x42:
-		case 0x43:
-		case 0x44:
-		case 0x62:
-			pci_read_config_byte(router, reg, &x);
-			if (reg != 0x62)
-				break;
-			if (!(x & 0x40))
-				return 0;
-			break;
-		case 0x61:
-		case 0x6a:
-		case 0x7e:
-			printk(KERN_INFO "SiS pirq: advanced IDE/ACPI/DAQ mapping not yet implemented\n");
-			return 0;
-		default:			
-			printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
-			return 0;
-	}
-	return (x & 0x80) ? 0 : (x & 0x0f);
-}
-
-static int pirq_sis_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-{
-	u8 x;
-	int reg = pirq;
-
-	switch(pirq) {
-		case 0x01:
-		case 0x02:
-		case 0x03:
-		case 0x04:
-			reg += 0x40;
-		case 0x41:
-		case 0x42:
-		case 0x43:
-		case 0x44:
-		case 0x62:
-			x = (irq&0x0f) ? (irq&0x0f) : 0x80;
-			if (reg != 0x62)
-				break;
-			/* always mark OHCI enabled, as nothing else knows about this */
-			x |= 0x40;
-			break;
-		case 0x61:
-		case 0x6a:
-		case 0x7e:
-			printk(KERN_INFO "advanced SiS pirq mapping not yet implemented\n");
-			return 0;
-		default:			
-			printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
-			return 0;
-	}
-	pci_write_config_byte(router, reg, x);
-
-	return 1;
-}
-
-#endif
-
-/* Support for AMD756 PCI IRQ Routing
- * Jhon H. Caicedo <jhcaiced@osso.org.co>
- * Jun/21/2001 0.2.0 Release, fixed to use "nybble" functions... (jhcaiced)
- * Jun/19/2001 Alpha Release 0.1.0 (jhcaiced)
- * The AMD756 pirq rules are nibble-based
- * offset 0x56 0-3 PIRQA  4-7  PIRQB
- * offset 0x57 0-3 PIRQC  4-7  PIRQD
- */
-static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
-{
-	u8 irq;
-	irq = 0;
-	if (pirq <= 4)
-	{
-		irq = read_config_nybble(router, 0x56, pirq - 1);
-	}
-	printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d get irq : %2d\n",
-		dev->vendor, dev->device, pirq, irq);
-	return irq;
-}
-
-static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
-{
-	printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d SET irq : %2d\n", 
-		dev->vendor, dev->device, pirq, irq);
-	if (pirq <= 4)
-	{
-		write_config_nybble(router, 0x56, pirq - 1, irq);
-	}
-	return 1;
-}
-
-static struct irq_router pirq_routers[] = {
-#if 0 /* all these do not exist on Hammer currently, but keep one example
-	 for each. All these vendors have announced K8 chipsets, so we'll
-	 eventually need a router for them. Luckily they tend to use the
-	 same ones, so with luck just enabling the existing ones will work
-	 when you know the final PCI ids.  */ 
-
-	{ "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set },
-
-	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, pirq_via_get, pirq_via_set },
-
-	{ "SIS", PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, pirq_sis_get, pirq_sis_set },
-
-#endif
-
-	{ "AMD756 VIPER", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B,
-		pirq_amd756_get, pirq_amd756_set },
-
-	{ "default", 0, 0, NULL, NULL }
-};
-
-static struct irq_router *pirq_router;
-static struct pci_dev *pirq_router_dev;
-
-static void __init pirq_find_router(void)
-{
-	struct irq_routing_table *rt = pirq_table;
-	struct irq_router *r;
-
-	DBG("PCI: Attempting to find IRQ router for %04x:%04x\n",
-	    rt->rtr_vendor, rt->rtr_device);
-
-	/* fall back to default router if nothing else found */
-	pirq_router = &pirq_routers[ARRAY_SIZE(pirq_routers) - 1];
-
-	pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn);
-	if (!pirq_router_dev) {
-		DBG("PCI: Interrupt router not found at %02x:%02x\n", rt->rtr_bus, rt->rtr_devfn);
-		return;
-	}
-
-	for(r=pirq_routers; r->vendor; r++) {
-		/* Exact match against router table entry? Use it! */
-		if (r->vendor == rt->rtr_vendor && r->device == rt->rtr_device) {
-			pirq_router = r;
-			break;
-		}
-		/* Match against router device entry? Use it as a fallback */
-		if (r->vendor == pirq_router_dev->vendor && r->device == pirq_router_dev->device) {
-			pirq_router = r;
-		}
-	}
-	printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n",
-		pirq_router->name,
-		pirq_router_dev->vendor,
-		pirq_router_dev->device,
-		pirq_router_dev->slot_name);
-}
-
-static struct irq_info *pirq_get_info(struct pci_dev *dev)
-{
-	struct irq_routing_table *rt = pirq_table;
-	int entries = (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
-	struct irq_info *info;
-
-	for (info = rt->slots; entries--; info++)
-		if (info->bus == dev->bus->number && PCI_SLOT(info->devfn) == PCI_SLOT(dev->devfn))
-			return info;
-	return NULL;
-}
-
-static irqreturn_t pcibios_test_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
-{
-	return IRQ_NONE; 
-}
-
-static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
-{
-	u8 pin;
-	struct irq_info *info;
-	int i, pirq, newirq;
-	int irq = 0;
-	u32 mask;
-	struct irq_router *r = pirq_router;
-	struct pci_dev *dev2 = NULL;
-	char *msg = NULL;
-
-	/* Find IRQ pin */
-	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-	if (!pin) {
-		DBG(" -> no interrupt pin\n");
-		return 0;
-	}
-	pin = pin - 1;
-
-	/* Find IRQ routing entry */
-
-	if (!pirq_table)
-		return 0;
-	
-	DBG("IRQ for %s:%d", dev->slot_name, pin);
-	info = pirq_get_info(dev);
-	if (!info) {
-		DBG(" -> not found in routing table\n");
-		return 0;
-	}
-	pirq = info->irq[pin].link;
-	mask = info->irq[pin].bitmap;
-	if (!pirq) {
-		DBG(" -> not routed\n");
-		return 0;
-	}
-	DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs);
-	mask &= pcibios_irq_mask;
-
-	/* Work around broken HP Pavilion Notebooks which assign USB to
-	   IRQ 9 even though it is actually wired to IRQ 11 */
-
-	if (broken_hp_bios_irq9 && pirq == 0x59 && dev->irq == 9) {
-		dev->irq = 11;
-		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
-		r->set(pirq_router_dev, dev, pirq, 11);
-	}
-
-	/*
-	 * Find the best IRQ to assign: use the one
-	 * reported by the device if possible.
-	 */
-	newirq = dev->irq;
-	if (!((1 << newirq) & mask)) {
-		if ( pci_probe & PCI_USE_PIRQ_MASK) newirq = 0;
-		else printk(KERN_WARNING "PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n", newirq, dev->slot_name);
-	}
-	if (!newirq && assign) {
-		for (i = 0; i < 16; i++) {
-			if (!(mask & (1 << i)))
-				continue;
-			if (pirq_penalty[i] < pirq_penalty[newirq] &&
-			    !request_irq(i, pcibios_test_irq_handler, SA_SHIRQ, "pci-test", dev)) {
-				free_irq(i, dev);
-				newirq = i;
-			}
-		}
-	}
-	DBG(" -> newirq=%d", newirq);
-
-	/* Check if it is hardcoded */
-	if ((pirq & 0xf0) == 0xf0) {
-		irq = pirq & 0xf;
-		DBG(" -> hardcoded IRQ %d\n", irq);
-		msg = "Hardcoded";
-	} else if ( r->get && (irq = r->get(pirq_router_dev, dev, pirq)) && \
-	((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask)) ) {
-		DBG(" -> got IRQ %d\n", irq);
-		msg = "Found";
-	} else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
-		DBG(" -> assigning IRQ %d", newirq);
-		if (r->set(pirq_router_dev, dev, pirq, newirq)) {
-			eisa_set_level_irq(newirq);
-			DBG(" ... OK\n");
-			msg = "Assigned";
-			irq = newirq;
-		}
-	}
-
-	if (!irq) {
-		DBG(" ... failed\n");
-		if (newirq && mask == (1 << newirq)) {
-			msg = "Guessed";
-			irq = newirq;
-		} else
-			return 0;
-	}
-	printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, dev->slot_name);
-
-	/* Update IRQ for all devices with the same pirq value */
-	while ((dev2 = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev2)) != NULL) {
-		pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin);
-		if (!pin)
-			continue;
-		pin--;
-		info = pirq_get_info(dev2);
-		if (!info)
-			continue;
-		if (info->irq[pin].link == pirq) {
-			/* We refuse to override the dev->irq information. Give a warning! */
-		    	if ( dev2->irq && dev2->irq != irq && \
-			(!(pci_probe & PCI_USE_PIRQ_MASK) || \
-			((1 << dev2->irq) & mask)) ) {
-		    		printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n",
-				       dev2->slot_name, dev2->irq, irq);
-		    		continue;
-		    	}
-			dev2->irq = irq;
-			pirq_penalty[irq]++;
-			if (dev != dev2)
-				printk(KERN_INFO "PCI: Sharing IRQ %d with %s\n", irq, dev2->slot_name);
-		}
-	}
-	return 1;
-}
-
-void __init pcibios_fixup_irqs(void)
-{
-	struct pci_dev *dev = NULL;
-	u8 pin;
-
-	DBG("PCI: IRQ fixup\n");
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		/*
-		 * If the BIOS has set an out of range IRQ number, just ignore it.
-		 * Also keep track of which IRQ's are already in use.
-		 */
-		if (dev->irq >= 16) {
-			DBG("%s: ignoring bogus IRQ %d\n", dev->slot_name, dev->irq);
-			dev->irq = 0;
-		}
-		/* If the IRQ is already assigned to a PCI device, ignore its ISA use penalty */
-		if (pirq_penalty[dev->irq] >= 100 && pirq_penalty[dev->irq] < 100000)
-			pirq_penalty[dev->irq] = 0;
-		pirq_penalty[dev->irq]++;
-	}
-
-	dev = NULL;
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-#ifdef CONFIG_X86_IO_APIC
-		/*
-		 * Recalculate IRQ numbers if we use the I/O APIC.
-		 */
-		if (io_apic_assign_pci_irqs)
-		{
-			int irq;
-
-			if (pin) {
-				pin--;		/* interrupt pins are numbered starting from 1 */
-				irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
-	/*
-	 * Busses behind bridges are typically not listed in the MP-table.
-	 * In this case we have to look up the IRQ based on the parent bus,
-	 * parent slot, and pin number. The SMP code detects such bridged
-	 * busses itself so we should get into this branch reliably.
-	 */
-				if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
-					struct pci_dev * bridge = dev->bus->self;
-
-					pin = (pin + PCI_SLOT(dev->devfn)) % 4;
-					irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 
-							PCI_SLOT(bridge->devfn), pin);
-					if (irq >= 0)
-						printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", 
-							bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
-				}
-				if (irq >= 0) {
-					printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
-						dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
-					dev->irq = irq;
-				}
-			}
-		}
-#endif
-		/*
-		 * Still no IRQ? Try to lookup one...
-		 */
-		if (pin && !dev->irq)
-			pcibios_lookup_irq(dev, 0);
-	}
-}
-
-static int __init pcibios_irq_init(void)
-{
-	DBG("PCI: IRQ init\n");
-
-	if (pcibios_enable_irq)
-		return 0;
-
-	pirq_table = pirq_find_routing_table();
-
-	if (pirq_table) {
-		pirq_peer_trick();
-		pirq_find_router();
-		if (pirq_table->exclusive_irqs) {
-			int i;
-			for (i=0; i<16; i++)
-				if (!(pirq_table->exclusive_irqs & (1 << i)))
-					pirq_penalty[i] += 100;
-		}
-		/* If we're using the I/O APIC, avoid using the PCI IRQ routing table */
-		if (io_apic_assign_pci_irqs)
-			pirq_table = NULL;
-	}
-
-	pcibios_enable_irq = pirq_enable_irq;
-
-	pcibios_fixup_irqs();
-	return 0;
-}
-
-subsys_initcall(pcibios_irq_init);
-
-
-void pcibios_penalize_isa_irq(int irq)
-{
-	/*
-	 *  If any ISAPnP device reports an IRQ in its list of possible
-	 *  IRQ's, we try to avoid assigning it to PCI devices.
-	 */
-	pirq_penalty[irq] += 100;
-}
-
-int pirq_enable_irq(struct pci_dev *dev)
-{
-	u8 pin;
-	extern int interrupt_line_quirk;
-	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-	if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) {
-		/* With IDE legacy devices the IRQ lookup failure is not a problem.. */
-		if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE && !(dev->class & 0x5))
-			return 0;
-		
-		printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.\n",
-		       'A' + pin - 1, dev->slot_name);
-	}
-	/* VIA bridges use interrupt line for apic/pci steering across
-	   the V-Link */
-	else if (interrupt_line_quirk)
-		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
-
-	return 0;
-}
diff --git a/arch/x86_64/pci/legacy.c b/arch/x86_64/pci/legacy.c
deleted file mode 100644
index e43d70fdee5c..000000000000
--- a/arch/x86_64/pci/legacy.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * legacy.c - traditional, old school PCI bus probing
- */
-#include <linux/init.h>
-#include <linux/pci.h>
-#include "pci.h"
-
-/*
- * Discover remaining PCI buses in case there are peer host bridges.
- * We use the number of last PCI bus provided by the PCI BIOS.
- */
-void __devinit pcibios_fixup_peer_bridges(void)
-{
-	int n;
-	struct pci_bus *bus;
-	struct pci_dev *dev;
-	u16 l;
-
-	if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
-		return;
-	DBG("PCI: Peer bridge fixup\n");
-
-	bus = kmalloc(sizeof(*bus), GFP_ATOMIC);
-	dev = kmalloc(sizeof(*dev), GFP_ATOMIC);
-	if (!bus || !dev) {
-		printk(KERN_ERR "Out of memory in %s\n", __FUNCTION__);
-		goto exit;
-	}
-
-	for (n=0; n <= pcibios_last_bus; n++) {
-		if (pci_bus_exists(&pci_root_buses, n))
-			continue;
-		bus->number = n;
-		bus->ops = pci_root_ops;
-		dev->bus = bus;
-		for (dev->devfn=0; dev->devfn<256; dev->devfn += 8)
-			if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
-			    l != 0x0000 && l != 0xffff) {
-				DBG("Found device at %02x:%02x [%04x]\n", n, dev->devfn, l);
-				printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
-				pci_scan_bus(n, pci_root_ops, NULL);
-				break;
-			}
-	}
-exit:
-	kfree(dev);
-	kfree(bus);
-}
-
-static int __init pci_legacy_init(void)
-{
-	if (!pci_root_ops) {
-		printk("PCI: System does not support PCI\n");
-		return 0;
-	}
-
-	if (pcibios_scanned++)
-		return 0;
-
-	printk("PCI: Probing PCI hardware\n");
-	pci_root_bus = pcibios_scan_root(0);
-
-	pcibios_fixup_peer_bridges();
-
-	return 0;
-}
-
-subsys_initcall(pci_legacy_init);
diff --git a/arch/x86_64/pci/pci.h b/arch/x86_64/pci/pci.h
deleted file mode 100644
index c89003343f9c..000000000000
--- a/arch/x86_64/pci/pci.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *	Low-Level PCI Access for x86-64 machines.
- *
- *	(c) 1999 Martin Mares <mj@ucw.cz>
- */
-
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-#define PCI_PROBE_BIOS		0x0001
-#define PCI_PROBE_CONF1		0x0002
-#define PCI_PROBE_CONF2		0x0004
-#define PCI_NO_SORT		0x0100
-#define PCI_BIOS_SORT		0x0200
-#define PCI_NO_CHECKS		0x0400
-#define PCI_USE_PIRQ_MASK	0x0800
-#define PCI_ASSIGN_ROMS		0x1000
-#define PCI_BIOS_IRQ_SCAN	0x2000
-#define PCI_ASSIGN_ALL_BUSSES	0x4000
-#define PCI_NO_ACPI_ROUTING	0x8000
-
-extern unsigned int pci_probe;
-
-extern unsigned int pcibios_max_latency;
-
-void pcibios_resource_survey(void);
-int pcibios_enable_resources(struct pci_dev *, int);
-
-/* pci-pc.c */
-
-extern int pcibios_last_bus;
-extern struct pci_bus *pci_root_bus;
-extern struct pci_ops *pci_root_ops;
-
-/* pci-irq.c */
-
-struct irq_info {
-	u8 bus, devfn;			/* Bus, device and function */
-	struct {
-		u8 link;		/* IRQ line ID, chipset dependent, 0=not routed */
-		u16 bitmap;		/* Available IRQs */
-	} __attribute__((packed)) irq[4];
-	u8 slot;			/* Slot number, 0=onboard */
-	u8 rfu;
-} __attribute__((packed));
-
-struct irq_routing_table {
-	u32 signature;			/* PIRQ_SIGNATURE should be here */
-	u16 version;			/* PIRQ_VERSION */
-	u16 size;			/* Table size in bytes */
-	u8 rtr_bus, rtr_devfn;		/* Where the interrupt router lies */
-	u16 exclusive_irqs;		/* IRQs devoted exclusively to PCI usage */
-	u16 rtr_vendor, rtr_device;	/* Vendor and device ID of interrupt router */
-	u32 miniport_data;		/* Crap */
-	u8 rfu[11];
-	u8 checksum;			/* Modulo 256 checksum must give zero */
-	struct irq_info slots[0];
-} __attribute__((packed));
-
-extern unsigned int pcibios_irq_mask;
-
-extern int pcibios_scanned;
-extern spinlock_t pci_config_lock;
-
-int pirq_enable_irq(struct pci_dev *dev);
-
-extern int (*pcibios_enable_irq)(struct pci_dev *dev);
-
-/* legacy.c */
-extern void pcibios_fixup_peer_bridges(void);
diff --git a/arch/x86_64/pci/x86-64.c b/arch/x86_64/pci/x86-64.c
deleted file mode 100644
index 15a41b747f07..000000000000
--- a/arch/x86_64/pci/x86-64.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- *	Low-Level PCI Access for x86-64 machines
- *
- * Copyright 1993, 1994 Drew Eckhardt
- *      Visionary Computing
- *      (Unix and Linux consulting and custom programming)
- *      Drew@Colorado.EDU
- *      +1 (303) 786-7975
- *
- * Drew's work was sponsored by:
- *	iX Multiuser Multitasking Magazine
- *	Hannover, Germany
- *	hm@ix.de
- *
- * Copyright 1997--2000 Martin Mares <mj@ucw.cz>
- *
- * For more information, please consult the following manuals (look at
- * http://www.pcisig.com/ for how to get them):
- *
- * PCI BIOS Specification
- * PCI Local Bus Specification
- * PCI to PCI Bridge Specification
- * PCI System Design Guide
- *
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-
-#include "pci.h"
-
-/*
- * 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)
-{
-	if (res->flags & IORESOURCE_IO) {
-		unsigned long start = res->start;
-
-		if (start & 0x300) {
-			start = (start + 0x3ff) & ~0x3ff;
-			res->start = start;
-		}
-	}
-}
-
-
-/*
- *  Handle resources of PCI devices.  If the world were perfect, we could
- *  just allocate all the resource regions and do nothing more.  It isn't.
- *  On the other hand, we cannot just re-allocate all devices, as it would
- *  require us to know lots of host bridge internals.  So we attempt to
- *  keep as much of the original configuration as possible, but tweak it
- *  when it's found to be wrong.
- *
- *  Known BIOS problems we have to work around:
- *	- I/O or memory regions not configured
- *	- regions configured, but not enabled in the command register
- *	- bogus I/O addresses above 64K used
- *	- expansion ROMs left enabled (this may sound harmless, but given
- *	  the fact the PCI specs explicitly allow address decoders to be
- *	  shared between expansion ROMs and other resource regions, it's
- *	  at least dangerous)
- *
- *  Our solution:
- *	(1) Allocate resources for all buses behind PCI-to-PCI bridges.
- *	    This gives us fixed barriers on where we can allocate.
- *	(2) Allocate resources for all enabled devices.  If there is
- *	    a collision, just mark the resource as unallocated. Also
- *	    disable expansion ROMs during this step.
- *	(3) Try to allocate resources for disabled devices.  If the
- *	    resources were assigned correctly, everything goes well,
- *	    if they weren't, they won't disturb allocation of other
- *	    resources.
- *	(4) Assign new addresses to resources which were either
- *	    not configured at all or misconfigured.  If explicitly
- *	    requested by the user, configure expansion ROM address
- *	    as well.
- */
-
-static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
-{
-	struct list_head *ln;
-	struct pci_bus *bus;
-	struct pci_dev *dev;
-	int idx;
-	struct resource *r, *pr;
-
-	/* Depth-First Search on bus tree */
-	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
-		bus = pci_bus_b(ln);
-		if ((dev = bus->self)) {
-			for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
-				r = &dev->resource[idx];
-				if (!r->start)
-					continue;
-				pr = pci_find_parent_resource(dev, r);
-				if (!pr || request_resource(pr, r) < 0)
-					printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, dev->slot_name);
-			}
-		}
-		pcibios_allocate_bus_resources(&bus->children);
-	}
-}
-
-static void __init pcibios_allocate_resources(int pass)
-{
-	struct pci_dev *dev = NULL;
-	int idx, disabled;
-	u16 command;
-	struct resource *r, *pr;
-
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		pci_read_config_word(dev, PCI_COMMAND, &command);
-		for(idx = 0; idx < 6; idx++) {
-			r = &dev->resource[idx];
-			if (r->parent)		/* Already allocated */
-				continue;
-			if (!r->start)		/* Address not assigned at all */
-				continue;
-			if (r->flags & IORESOURCE_IO)
-				disabled = !(command & PCI_COMMAND_IO);
-			else
-				disabled = !(command & PCI_COMMAND_MEMORY);
-			if (pass == disabled) {
-				DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
-				    r->start, r->end, r->flags, disabled, pass);
-				pr = pci_find_parent_resource(dev, r);
-				if (!pr || request_resource(pr, r) < 0) {
-					printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, dev->slot_name);
-					/* We'll assign a new address later */
-					r->end -= r->start;
-					r->start = 0;
-				}
-			}
-		}
-		if (!pass) {
-			r = &dev->resource[PCI_ROM_RESOURCE];
-			if (r->flags & PCI_ROM_ADDRESS_ENABLE) {
-				/* Turn the ROM off, leave the resource region, but keep it unregistered. */
-				u32 reg;
-				DBG("PCI: Switching off ROM of %s\n", dev->slot_name);
-				r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
-				pci_read_config_dword(dev, dev->rom_base_reg, &reg);
-				pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE);
-			}
-		}
-	}
-}
-
-static void __init pcibios_assign_resources(void)
-{
-	struct pci_dev *dev = NULL;
-	int idx;
-	struct resource *r;
-
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		int class = dev->class >> 8;
-
-		/* Don't touch classless devices and host bridges */
-		if (!class || class == PCI_CLASS_BRIDGE_HOST)
-			continue;
-
-		for(idx=0; idx<6; idx++) {
-			r = &dev->resource[idx];
-
-			/*
-			 *  Don't touch IDE controllers and I/O ports of video cards!
-			 */
-			if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) ||
-			    (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)))
-				continue;
-
-			/*
-			 *  We shall assign a new address to this resource, either because
-			 *  the BIOS forgot to do so or because we have decided the old
-			 *  address was unusable for some reason.
-			 */
-			if (!r->start && r->end)
-				pci_assign_resource(dev, idx);
-		}
-
-		if (pci_probe & PCI_ASSIGN_ROMS) {
-			r = &dev->resource[PCI_ROM_RESOURCE];
-			r->end -= r->start;
-			r->start = 0;
-			if (r->end)
-				pci_assign_resource(dev, PCI_ROM_RESOURCE);
-		}
-	}
-}
-
-void __init pcibios_resource_survey(void)
-{
-	DBG("PCI: Allocating resources\n");
-	pcibios_allocate_bus_resources(&pci_root_buses);
-	pcibios_allocate_resources(0);
-	pcibios_allocate_resources(1);
-	pcibios_assign_resources();
-}
-
-int pcibios_enable_resources(struct pci_dev *dev, int mask)
-{
-	u16 cmd, old_cmd;
-	int idx;
-	struct resource *r;
-
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	old_cmd = cmd;
-	for(idx=0; idx<6; idx++) {
-		if (!(mask & (1<<idx)))
-			continue;
-
-		r = &dev->resource[idx];
-		if (!r->start && r->end) {
-			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
-			return -EINVAL;
-		}
-		if (r->flags & IORESOURCE_IO)
-			cmd |= PCI_COMMAND_IO;
-		if (r->flags & IORESOURCE_MEM)
-			cmd |= PCI_COMMAND_MEMORY;
-	}
-	if (dev->resource[PCI_ROM_RESOURCE].start)
-		cmd |= PCI_COMMAND_MEMORY;
-	if (cmd != old_cmd) {
-		printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
-		pci_write_config_word(dev, PCI_COMMAND, cmd);
-	}
-	return 0;
-}
-
-/*
- *  If we set up a device for bus mastering, we need to check the latency
- *  timer as certain crappy BIOSes forget to set it properly.
- */
-unsigned int pcibios_max_latency = 255;
-
-void pcibios_set_master(struct pci_dev *dev)
-{
-	u8 lat;
-	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
-	if (lat < 16)
-		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
-	else if (lat > pcibios_max_latency)
-		lat = pcibios_max_latency;
-	else
-		return;
-	printk("PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
-	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
-}
-
-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 prot;
-
-	/* I/O space cannot be accessed via normal processor loads and
-	 * stores on this platform.
-	 */
-	if (mmap_state == pci_mmap_io)
-		return -EINVAL;
-
-	/* Leave vm_pgoff as-is, the PCI space address is the physical
-	 * address on this platform.
-	 */
-	vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO);
-
-	prot = pgprot_val(vma->vm_page_prot);
-	if (boot_cpu_data.x86 > 3)
-		prot |= _PAGE_PCD | _PAGE_PWT;
-	vma->vm_page_prot = __pgprot(prot);
-
-	/* Write-combine setting is ignored, it is changed via the mtrr
-	 * interfaces on this platform.
-	 */
-	if (remap_page_range(vma, vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
-			     vma->vm_end - vma->vm_start,
-			     vma->vm_page_prot))
-		return -EAGAIN;
-
-	return 0;
-}
diff --git a/include/asm-x86_64/fixmap.h b/include/asm-x86_64/fixmap.h
index a03fc84b2b62..cf8b16cbe8db 100644
--- a/include/asm-x86_64/fixmap.h
+++ b/include/asm-x86_64/fixmap.h
@@ -16,6 +16,7 @@
 #include <asm/apicdef.h>
 #include <asm/page.h>
 #include <asm/vsyscall.h>
+#include <asm/vsyscall32.h>
 
 /*
  * Here we define all the compile-time 'special' virtual
@@ -62,6 +63,10 @@ extern void __set_fixmap (enum fixed_addresses idx,
 #define FIXADDR_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
 #define FIXADDR_START	(FIXADDR_TOP - FIXADDR_SIZE)
 
+/* Only covers 32bit vsyscalls currently. Need another set for 64bit. */
+#define FIXADDR_USER_START	((unsigned long)VSYSCALL32_VSYSCALL)
+#define FIXADDR_USER_END	(FIXADDR_USER_START + PAGE_SIZE)
+
 #define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
 
 extern void __this_fixmap_does_not_exist(void);
diff --git a/include/asm-x86_64/io.h b/include/asm-x86_64/io.h
index 7d80bcbc798e..b2cc4f1a241a 100644
--- a/include/asm-x86_64/io.h
+++ b/include/asm-x86_64/io.h
@@ -105,7 +105,7 @@ __OUTS(l)
 
 #define IO_SPACE_LIMIT 0xffff
 
-#ifdef __KERNEL__
+#if defined(__KERNEL__) && __x86_64__
 
 #include <linux/vmalloc.h>
 
diff --git a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h
index 9db87d94b771..c1a69000c8d7 100644
--- a/include/asm-x86_64/mmzone.h
+++ b/include/asm-x86_64/mmzone.h
@@ -23,7 +23,6 @@ extern int maxnode;
 
 extern struct pglist_data *node_data[];
 
-/* kern_addr_valid below hardcodes the same algorithm*/
 static inline __attribute__((pure)) int phys_to_nid(unsigned long addr) 
 { 
 	int nid; 
@@ -46,19 +45,6 @@ static inline __attribute__((pure)) int phys_to_nid(unsigned long addr)
 
 #define local_mapnr(kvaddr) \
 	( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) )
-#define kern_addr_valid(kvaddr) ({					\
-	int ok = 0;							\
-        unsigned long index = __pa(kvaddr) >> memnode_shift;		\
-	if (index <= NODEMAPSIZE) {					\
-		unsigned nodeid = memnodemap[index];			\
-		unsigned long pfn = __pa(kvaddr) >> PAGE_SHIFT;		\
-		unsigned long start_pfn = node_start_pfn(nodeid);	\
-		ok = (nodeid != 0xff) &&				\
-		     (pfn >= start_pfn) &&				\
-		     (pfn <  start_pfn + node_size(nodeid));		\
-	}								\
-        ok;								\
-})
 
 /* AK: this currently doesn't deal with invalid addresses. We'll see 
    if the 2.5 kernel doesn't pass them
diff --git a/include/asm-x86_64/page.h b/include/asm-x86_64/page.h
index e4198d618b26..47ef9dfd93dd 100644
--- a/include/asm-x86_64/page.h
+++ b/include/asm-x86_64/page.h
@@ -76,6 +76,8 @@ extern unsigned long vm_force_exec32;
 #define __PAGE_OFFSET           0x0000010000000000	/* 1 << 40 */
 #define __PHYSICAL_MASK_SHIFT	40
 #define __PHYSICAL_MASK		((1UL << __PHYSICAL_MASK_SHIFT) - 1)
+#define __VIRTUAL_MASK_SHIFT	48
+#define __VIRTUAL_MASK		((1UL << __VIRTUAL_MASK_SHIFT) - 1)
 
 #define KERNEL_TEXT_SIZE  (40UL*1024*1024)
 #define KERNEL_TEXT_START 0xffffffff80000000UL 
diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h
index dac7f737e270..10763ac9ed18 100644
--- a/include/asm-x86_64/pci.h
+++ b/include/asm-x86_64/pci.h
@@ -45,7 +45,6 @@ int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
 struct pci_dev;
 
 extern int iommu_setup(char *opt);
-extern void pci_iommu_init(void);
 
 /* Allocate and map kernel buffer using consistent mode DMA for a device.
  * hwdev should be valid struct pci_dev pointer for PCI devices,
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
index 83a902a5550b..893dc0858734 100644
--- a/include/asm-x86_64/pgtable.h
+++ b/include/asm-x86_64/pgtable.h
@@ -339,7 +339,7 @@ static inline pgd_t *current_pgd_offset_k(unsigned long address)
 #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 pte_to_pgoff(pte) ((pte_val(pte) & PHYSICAL_PAGE_MASK) >> PAGE_SHIFT)
 #define pgoff_to_pte(off) ((pte_t) { ((off) << PAGE_SHIFT) | _PAGE_FILE })
@@ -392,9 +392,7 @@ typedef pte_t *pte_addr_t;
 
 #endif /* !__ASSEMBLY__ */
 
-#ifndef CONFIG_DISCONTIGMEM
-#define kern_addr_valid(addr)	(1)
-#endif
+extern int kern_addr_valid(unsigned long addr); 
 
 #define io_remap_page_range remap_page_range
 
@@ -403,4 +401,9 @@ typedef pte_t *pte_addr_t;
 #define pgtable_cache_init()   do { } while (0)
 #define check_pgt_cache()      do { } while (0)
 
+/* fs/proc/kcore.c */
+#define	kc_vaddr_to_offset(v) ((v) & __VIRTUAL_MASK)
+#define	kc_offset_to_vaddr(o) \
+   (((o) & (1UL << (__VIRTUAL_MASK_SHIFT-1))) ? ((o) | (~__VIRTUAL_MASK)) : (o))
+
 #endif /* _X86_64_PGTABLE_H */
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index 78f6a491449d..c2402015727b 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -16,7 +16,12 @@ extern void mcheck_init(struct cpuinfo_x86 *c);
 extern void init_memory_mapping(void);
 
 extern void system_call(void); 
+extern int kernel_syscall(void);
+extern void syscall_init(void);
+
+extern void ia32_syscall(void);
 extern void ia32_cstar_target(void); 
+
 extern void calibrate_delay(void);
 extern void cpu_idle(void);
 extern void sys_ni_syscall(void);
@@ -24,6 +29,8 @@ extern void config_acpi_tables(void);
 extern void ia32_syscall(void);
 extern void iommu_hole_init(void);
 
+extern void time_init_smp(void);
+
 extern void do_softirq_thunk(void);
 
 extern int numa_setup(char *opt);
@@ -39,8 +46,12 @@ extern unsigned long numa_free_all_bootmem(void);
 extern void reserve_bootmem_generic(unsigned long phys, unsigned len);
 extern void free_bootmem_generic(unsigned long phys, unsigned len);
 
+extern void load_gs_index(unsigned gs);
+
 extern unsigned long end_pfn_map; 
 
+extern unsigned long cpu_initialized;
+
 extern void show_stack(unsigned long * rsp);
 extern void show_trace(unsigned long * rsp);
 extern void show_registers(struct pt_regs *regs);
@@ -66,9 +77,16 @@ extern unsigned long max_mapnr;
 extern unsigned long end_pfn; 
 extern unsigned long table_start, table_end;
 
-extern void syscall_init(void);
+extern int exception_trace;
+extern int no_iommu, force_mmu;
+extern int using_apic_timer;
+extern int disable_apic;
+extern unsigned cpu_khz;
 
-struct pt_regs;
+extern int fallback_aper_order;
+extern int fallback_aper_force;
+
+extern void smp_local_timer_interrupt(struct pt_regs * regs);
 
 long do_arch_prctl(struct task_struct *task, int code, unsigned long addr);
 
-- 
2.30.9