http://linux-acpi.bkbits.net/linux-acpi-test-2.6.6
len.brown@intel.com|ChangeSet|20040428081952|30039 len.brown

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/04/28 04:18:25-04:00 len.brown@intel.com 
#   [ACPI] button build fix
# 
# drivers/acpi/scan.c
#   2004/04/28 04:18:19-04:00 len.brown@intel.com +6 -7
#   button build fix
# 
# drivers/acpi/button.c
#   2004/04/28 04:18:19-04:00 len.brown@intel.com +6 -6
#   button build fix
# 
# ChangeSet
#   2004/04/28 03:29:09-04:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.5
#   into intel.com:/home/lenb/src/linux-acpi-test-2.6.6
# 
# arch/i386/kernel/dmi_scan.c
#   2004/04/28 03:29:06-04:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/28 03:27:33-04:00 len.brown@intel.com 
#   [ACPI] fix build warning in dmi_scan
# 
# arch/i386/kernel/dmi_scan.c
#   2004/04/28 03:23:43-04:00 len.brown@intel.com +14 -13
#   move ignore_timer_override inside CONFIG_ACPI_BOOT
#   to nix build warning
# 
# ChangeSet
#   2004/04/28 03:12:21-04:00 len.brown@intel.com 
#   [ACPI] support button driver unload (Luming Yu)
#   http://bugzilla.kernel.org/show_bug.cgi?id=2281
# 
# drivers/acpi/scan.c
#   2004/04/28 02:55:43-04:00 len.brown@intel.com +8 -2
#   support button driver unload
# 
# drivers/acpi/button.c
#   2004/04/28 02:58:23-04:00 len.brown@intel.com +9 -0
#   support button driver unload
# 
# ChangeSet
#   2004/04/28 03:09:42-04:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.5
#   into intel.com:/home/lenb/src/linux-acpi-test-2.6.6
# 
# arch/i386/kernel/setup.c
#   2004/04/28 03:09:40-04:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/28 02:32:44-04:00 len.brown@intel.com 
#   [ACPI] toshiba_acpi driver if acpi_disabled (David Shaohua Li)
#   http://bugzilla.kernel.org/show_bug.cgi?id=2465
# 
# drivers/acpi/toshiba_acpi.c
#   2004/04/07 03:00:07-04:00 len.brown@intel.com +2 -0
#   toshiba_acpi driver needs to look at acpi_disabled
# 
# ChangeSet
#   2004/04/28 02:19:03-04:00 len.brown@intel.com 
#   [ACPI] rmmod ACPI modules vs /proc
#   from Anil S Keshavamurthy and David Shaohua Li
#   http://bugzilla.kernel.org/show_bug.cgi?id=2457
# 
# drivers/acpi/toshiba_acpi.c
#   2004/04/15 02:43:10-04:00 len.brown@intel.com +3 -0
#   rmmod ACPI modules vs /proc
# 
# drivers/acpi/thermal.c
#   2004/04/15 02:43:10-04:00 len.brown@intel.com +7 -0
#   rmmod ACPI modules vs /proc
# 
# drivers/acpi/processor.c
#   2004/04/28 02:18:15-04:00 len.brown@intel.com +12 -0
#   rmmod ACPI modules vs /proc
# 
# drivers/acpi/fan.c
#   2004/04/15 02:43:10-04:00 len.brown@intel.com +3 -0
#   rmmod ACPI modules vs /proc
# 
# drivers/acpi/button.c
#   2004/04/15 02:43:10-04:00 len.brown@intel.com +27 -1
#   rmmod ACPI modules vs /proc
# 
# drivers/acpi/battery.c
#   2004/04/15 02:43:10-04:00 len.brown@intel.com +5 -0
#   rmmod ACPI modules vs /proc
# 
# drivers/acpi/ac.c
#   2004/04/15 02:43:10-04:00 len.brown@intel.com +3 -0
#   rmmod ACPI modules vs /proc
# 
# ChangeSet
#   2004/04/28 02:04:06-04:00 len.brown@intel.com 
#   [ACPI] pci-link may not always be SHARED (SuSE via Luming Yu)
#   http://bugzilla.kernel.org/show_bug.cgi?id=2404
# 
# drivers/acpi/pci_link.c
#   2004/04/28 02:03:16-04:00 len.brown@intel.com +8 -0
#   pci-link may not always be SHARED
# 
# ChangeSet
#   2004/04/28 01:28:10-04:00 len.brown@intel.com 
#   [ACPI] battery "charged" instead of "unknown" (Luming Yu)
#   http://bugzilla.kernel.org/show_bug.cgi?id=1863
# 
# drivers/acpi/battery.c
#   2004/04/28 01:26:37-04:00 len.brown@intel.com +7 -3
#   clarify fully charged scenario
# 
# ChangeSet
#   2004/04/28 00:41:56-04:00 sziwan@hell.org.pl 
#   [PATCH] acpi4asus 0.28 (Karol 'sziwan' Kozimor)
#   - Added support for Samsung P30
#   - Fixed an oops triggered by non-standard hardware (Samsung P30)
#   - Added support for L4400L and M6800N
#   
#   The patch also removes some superfluous data. It doesn't include the
#   copy_from_user() conversion, it will be released as a separate patch.
# 
# drivers/acpi/asus_acpi.c
#   2004/03/22 16:40:10-05:00 sziwan@hell.org.pl +68 -53
#   [PATCH] acpi4asus 0.28
# 
# ChangeSet
#   2004/04/28 00:39:07-04:00 akpm@osdl.org 
#   [PATCH] acpi build fix
#   setup.c:608: `acpi_skip_timer_override' undeclared
# 
# arch/i386/kernel/setup.c
#   2004/04/26 03:25:30-04:00 akpm@osdl.org +2 -0
#   acpi build fix
# 
# ChangeSet
#   2004/04/27 00:59:21-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi
# 
# Documentation/kernel-parameters.txt
#   2004/04/27 00:59:18-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/24 23:20:27-04:00 len.brown@intel.com 
#   ACPI irq->gsi naming (Bjorn Helgaas)
# 
# include/linux/acpi.h
#   2004/04/02 08:48:53-05:00 len.brown@intel.com +1 -0
#   irq -> gsi naming
# 
# include/acpi/acpiosxf.h
#   2004/04/02 08:52:13-05:00 len.brown@intel.com +3 -3
#   irq -> gsi naming
# 
# drivers/acpi/osl.c
#   2004/04/02 08:56:24-05:00 len.brown@intel.com +10 -14
#   irq -> gsi naming
# 
# ChangeSet
#   2004/04/24 02:18:14-04:00 len.brown@intel.com 
#   [ACPI] No IRQ known... - using IRQ 255 (Bjarni Rúnar Einarsson)
#   http://bugzilla.kernel.org/show_bug.cgi?id=2148
# 
# drivers/acpi/pci_irq.c
#   2004/04/24 02:17:22-04:00 len.brown@intel.com +1 -1
#   ACPI: No IRQ known ... - using IRQ 255 (Bjarni Rúnar Einarsson)
#   http://bugzilla.kernel.org/show_bug.cgi?id=2148
# 
# ChangeSet
#   2004/04/23 15:43:23-04:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/src/linux-acpi-test-2.6.5
#   into intel.com:/home/lenb/src/linux-acpi-test-2.6.6
# 
# arch/x86_64/kernel/setup.c
#   2004/04/23 15:43:21-04:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# arch/x86_64/kernel/mpparse.c
#   2004/04/23 15:43:21-04:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# arch/x86_64/kernel/io_apic.c
#   2004/04/23 15:43:20-04:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# arch/i386/pci/irq.c
#   2004/04/23 15:43:20-04:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# arch/i386/kernel/setup.c
#   2004/04/23 15:43:20-04:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# arch/i386/kernel/io_apic.c
#   2004/04/23 15:43:20-04:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# arch/i386/kernel/dmi_scan.c
#   2004/04/23 15:43:20-04:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/04/23 13:15:31-04:00 len.brown@intel.com 
#   [ACPI] workaround for nForce2 BIOS bug: XT-PIC timer in IOAPIC mode 
#   "acpi_skip_timer_override" boot parameter
#   dmi_scan for common platforms, may be replaced with PCI-ID in future.
#   http://bugzilla.kernel.org/show_bug.cgi?id=1203
# 
# include/asm-i386/acpi.h
#   2004/04/23 08:39:18-04:00 len.brown@intel.com +1 -0
#   add acpi_skip_timer_override
# 
# arch/i386/kernel/setup.c
#   2004/04/23 08:39:18-04:00 len.brown@intel.com +3 -0
#   add acpi_skip_timer_override
# 
# arch/i386/kernel/dmi_scan.c
#   2004/04/23 08:39:18-04:00 len.brown@intel.com +56 -0
#   add acpi_skip_timer_override
# 
# arch/i386/kernel/acpi/boot.c
#   2004/04/23 08:39:18-04:00 len.brown@intel.com +7 -0
#   add acpi_skip_timer_override
# 
# Documentation/kernel-parameters.txt
#   2004/04/23 08:39:18-04:00 len.brown@intel.com +4 -0
#   add acpi_skip_timer_override
# 
# ChangeSet
#   2004/04/23 13:14:36-04:00 len.brown@intel.com 
#   [ACPI] Workaround "_BBN 0" BIOS bug
#   enhance "pci=noacpi" to skip ACPI PCI configuration and interrupt config
#   add "acpi=noirq" to skip just ACPI interrupt config (David Shaohua Li)
#   http://bugzilla.kernel.org/show_bug.cgi?id=1662
# 
# include/asm-x86_64/acpi.h
#   2004/04/23 08:37:58-04:00 len.brown@intel.com +15 -1
#   enhance pci=noacpi to skip ACPI PCI configuration and interrupt config
#   add acpi=noirq to skip just ACPI interrupt config
# 
# include/asm-ia64/acpi.h
#   2004/04/23 08:37:58-04:00 len.brown@intel.com +1 -0
#   enhance pci=noacpi to skip ACPI PCI configuration and interrupt config
#   add acpi=noirq to skip just ACPI interrupt config
# 
# include/asm-i386/acpi.h
#   2004/04/23 08:37:58-04:00 len.brown@intel.com +14 -1
#   enhance pci=noacpi to skip ACPI PCI configuration and interrupt config
#   add acpi=noirq to skip just ACPI interrupt config
# 
# drivers/acpi/pci_root.c
#   2004/04/23 08:37:58-04:00 len.brown@intel.com +9 -1
#   enhance pci=noacpi to skip ACPI PCI configuration and interrupt config
#   add acpi=noirq to skip just ACPI interrupt config
# 
# drivers/acpi/pci_link.c
#   2004/04/23 08:37:58-04:00 len.brown@intel.com +1 -1
#   enhance pci=noacpi to skip ACPI PCI configuration and interrupt config
#   add acpi=noirq to skip just ACPI interrupt config
# 
# arch/x86_64/kernel/setup.c
#   2004/04/23 08:37:58-04:00 len.brown@intel.com +6 -4
#   enhance pci=noacpi to skip ACPI PCI configuration and interrupt config
#   add acpi=noirq to skip just ACPI interrupt config
# 
# arch/i386/kernel/setup.c
#   2004/04/23 08:37:58-04:00 len.brown@intel.com +6 -2
#   enhance pci=noacpi to skip ACPI PCI configuration and interrupt config
#   add acpi=noirq to skip just ACPI interrupt config
# 
# arch/i386/kernel/dmi_scan.c
#   2004/04/23 08:37:58-04:00 len.brown@intel.com +17 -3
#   enhance pci=noacpi to skip ACPI PCI configuration and interrupt config
#   add acpi=noirq to skip just ACPI interrupt config
# 
# arch/i386/kernel/acpi/boot.c
#   2004/04/23 08:37:58-04:00 len.brown@intel.com +6 -0
#   enhance pci=noacpi to skip ACPI PCI configuration and interrupt config
#   add acpi=noirq to skip just ACPI interrupt config
# 
# Documentation/kernel-parameters.txt
#   2004/04/23 08:37:58-04:00 len.brown@intel.com +6 -4
#   enhance pci=noacpi to skip ACPI PCI configuration and interrupt config
#   add acpi=noirq to skip just ACPI interrupt config
# 
# ChangeSet
#   2004/04/22 15:15:17-04:00 len.brown@intel.com 
#   [ACPI] allow IRQ2 to be used in ACPI/IOAPIC mode
#   http://bugzilla.kernel.org/show_bug.cgi?id=2564
# 
# ChangeSet
#   2004/04/22 15:13:43-04:00 len.brown@intel.com 
#   [ACPI] if acpi_os_name= is used, print what it finds
# 
# arch/x86_64/kernel/io_apic.c
#   2004/04/22 15:12:30-04:00 len.brown@intel.com +6 -10
#   allow IRQ2 to be used in ACPI/IOAPIC mode
# 
# arch/i386/kernel/io_apic.c
#   2004/04/22 15:12:30-04:00 len.brown@intel.com +6 -10
#   allow IRQ2 to be used in ACPI/IOAPIC mode
# 
# drivers/acpi/osl.c
#   2004/04/22 00:32:47-04:00 len.brown@intel.com +2 -1
#   if acpi_os_name= is used, print what it finds
# 
# ChangeSet
#   2004/04/20 20:55:53-04:00 len.brown@intel.com 
#   ACPI] Delete IRQ2 "cascade" in ACPI IOAPIC mode
#   no such concept exists in ACPI, frees IRQ2 for use.
# 
# arch/x86_64/kernel/i8259.c
#   2004/04/20 20:55:12-04:00 len.brown@intel.com +3 -1
#   [ACPI] Delete IRQ2 "cascade" in ACPI IOAPIC mode
# 
# arch/i386/mach-voyager/setup.c
#   2004/04/20 20:55:12-04:00 len.brown@intel.com +3 -1
#   [ACPI] Delete IRQ2 "cascade" in ACPI IOAPIC mode
# 
# arch/i386/mach-es7000/setup.c
#   2004/04/20 20:55:12-04:00 len.brown@intel.com +4 -3
#   [ACPI] Delete IRQ2 "cascade" in ACPI IOAPIC mode
# 
# arch/i386/mach-default/setup.c
#   2004/04/20 20:55:12-04:00 len.brown@intel.com +3 -1
#   [ACPI] Delete IRQ2 "cascade" in ACPI IOAPIC mode
# 
# ChangeSet
#   2004/04/20 20:54:14-04:00 len.brown@intel.com 
#   [ACPI] enhance intr-src-override parsing to handle ES7000
#   http://bugme.osdl.org/show_bug.cgi?id=2520
# 
# arch/x86_64/kernel/mpparse.c
#   2004/04/20 20:54:03-04:00 len.brown@intel.com +15 -22
#   [ACPI] process interrupt source over-rides before legacy identity mappings
# 
# arch/i386/kernel/mpparse.c
#   2004/04/20 20:54:03-04:00 len.brown@intel.com +13 -22
#   [ACPI] process interrupt source over-rides before legacy identity mappings
# 
# arch/i386/kernel/acpi/boot.c
#   2004/04/20 20:54:03-04:00 len.brown@intel.com +3 -3
#   [ACPI] process interrupt source over-rides before legacy identity mappings
# 
# ChangeSet
#   2004/04/16 22:03:45-04:00 len.brown@intel.com 
#   [ACPI] enable 440GX PIRQ router workaround
# 
# arch/i386/pci/irq.c
#   2004/04/16 22:03:06-04:00 len.brown@intel.com +1 -4
#   enable 440GX PIRQ workaround
# 
# arch/i386/kernel/dmi_scan.c
#   2004/04/16 22:03:06-04:00 len.brown@intel.com +0 -70
#   delete broken_pirq() -- it is now handled in pirq router code.
# 
# ChangeSet
#   2004/04/14 13:15:03-04:00 len.brown@intel.com 
#   [ACPI] fix x86_64 mis-merge
# 
# arch/x86_64/kernel/Makefile
#   2004/04/14 13:08:40-04:00 len.brown@intel.com +1 -1
#   fix mis-merge
# 
diff -Nru a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
--- a/Documentation/kernel-parameters.txt	Thu Apr 29 23:05:00 2004
+++ b/Documentation/kernel-parameters.txt	Thu Apr 29 23:05:00 2004
@@ -102,13 +102,14 @@
 
 	acpi=		[HW,ACPI] Advanced Configuration and Power Interface 
 			Format: { force | off | ht | strict }
-			force -- enables ACPI for systems with default off
-			off -- disabled ACPI for systems with default on
+			force -- enable ACPI if default was off
+			off -- disable ACPI if default was on
+			noirq -- do not use ACPI for IRQ routing
 			ht -- run only enough ACPI to enable Hyper Threading
 			strict --  Be less tolerant of platforms that are not
 				strictly ACPI specification compliant.
 
-			See also Documentation/pm.txt.
+			See also Documentation/pm.txt, pci=noacpi
 
 	acpi_sleep=	[HW,ACPI] Sleep options
 			Format: { s3_bios, s3_mode }
@@ -133,6 +134,10 @@
 
 	acpi_serialize	[HW,ACPI] force serialization of AML methods
 
+	acpi_skip_timer_override [HW,ACPI]
+			Recognize and ignore IRQ0/pin2 Interrupt Override.
+			For broken nForce2 BIOS resulting in XT-PIC timer.
+
 	ad1816=		[HW,OSS]
 			Format: <io>,<irq>,<dma>,<dma2>
 			See also Documentation/sound/oss/AD1816.
@@ -842,7 +847,8 @@
 					and Omnibook XE3 notebooks. This will
 					have no effect if ACPI IRQ routing is
 					enabled.
-		noacpi			[IA-32] Do not use ACPI for IRQ routing.
+		noacpi			[IA-32] Do not use ACPI for IRQ routing
+					or for PCI scanning.
 
 	pcmv=		[HW,PCMCIA] BadgePAD 4
 
diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
--- a/arch/i386/kernel/acpi/boot.c	Thu Apr 29 23:05:00 2004
+++ b/arch/i386/kernel/acpi/boot.c	Thu Apr 29 23:05:00 2004
@@ -53,7 +53,13 @@
 
 #define PREFIX			"ACPI: "
 
+#ifdef CONFIG_ACPI_PCI
 int acpi_noirq __initdata;	/* skip ACPI IRQ initialization */
+int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */
+#else
+int acpi_noirq __initdata = 1;
+int acpi_pci_disabled __initdata = 1;
+#endif
 int acpi_ht __initdata = 1;	/* enable HT */
 
 int acpi_lapic;
@@ -62,6 +68,7 @@
 
 acpi_interrupt_flags acpi_sci_flags __initdata;
 int acpi_sci_override_gsi __initdata;
+int acpi_skip_timer_override __initdata;
 
 #ifdef CONFIG_X86_LOCAL_APIC
 static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
@@ -329,6 +336,12 @@
 		return 0;
 	}
 
+	if (acpi_skip_timer_override &&
+		intsrc->bus_irq == 0 && intsrc->global_irq == 2) {
+			printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n");
+			return 0;
+	}
+
 	mp_override_legacy_irq (
 		intsrc->bus_irq,
 		intsrc->flags.polarity,
@@ -653,9 +666,6 @@
 		return count;
 	}
 
-	/* Build a default routing table for legacy (ISA) interrupts. */
-	mp_config_acpi_legacy_irqs();
-
 	count = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS);
 	if (count < 0) {
 		printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
@@ -669,6 +679,9 @@
 	 */
 	if (!acpi_sci_override_gsi)
 		acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0);
+
+	/* Fill in identity legacy mapings where no override */
+	mp_config_acpi_legacy_irqs();
 
 	count = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS);
 	if (count < 0) {
diff -Nru a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
--- a/arch/i386/kernel/dmi_scan.c	Thu Apr 29 23:05:00 2004
+++ b/arch/i386/kernel/dmi_scan.c	Thu Apr 29 23:05:00 2004
@@ -413,30 +413,6 @@
 }
 
 /*
- * The Intel 440GX hall of shame. 
- *
- * On many (all we have checked) of these boxes the $PIRQ table is wrong.
- * The MP1.4 table is right however and so SMP kernels tend to work. 
- */
- 
-static __init int broken_pirq(struct dmi_blacklist *d)
-{
-
-	printk(KERN_INFO " *** Possibly defective BIOS detected (irqtable)\n");
-	printk(KERN_INFO " *** Many BIOSes matching this signature have incorrect IRQ routing tables.\n");
-	printk(KERN_INFO " *** If you see IRQ problems, in particular SCSI resets and hangs at boot\n");
-	printk(KERN_INFO " *** contact your hardware vendor and ask about updates.\n");
-	printk(KERN_INFO " *** Building an SMP kernel may evade the bug some of the time.\n");
-#ifdef CONFIG_X86_IO_APIC
-	{
-		extern int skip_ioapic_setup;
-		skip_ioapic_setup = 0;
-	}
-#endif
-	return 0;
-}
-
-/*
  * ASUS K7V-RM has broken ACPI table defining sleep modes
  */
 
@@ -552,15 +528,35 @@
 	}
 	return 0;
 } 
+
+/*
+ * early nForce2 reference BIOS shipped with a
+ * bogus ACPI IRQ0 -> pin2 interrupt override -- ignore it
+ */
+static __init int ignore_timer_override(struct dmi_blacklist *d)
+{
+	extern int acpi_skip_timer_override;
+	printk(KERN_NOTICE "%s detected: BIOS IRQ0 pin2 override"
+		" will be ignored\n", d->ident); 	
+
+	acpi_skip_timer_override = 1;
+	return 0;
+}
 #endif
 
 #ifdef	CONFIG_ACPI_PCI
+static __init int disable_acpi_irq(struct dmi_blacklist *d) 
+{ 
+	printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n", d->ident); 	
+	acpi_noirq_set();
+	return 0;
+}
 static __init int disable_acpi_pci(struct dmi_blacklist *d) 
 { 
 	printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n", d->ident); 	
-	acpi_noirq_set();
+	acpi_disable_pci();
 	return 0;
-} 
+}  
 #endif
 
 /*
@@ -815,52 +811,6 @@
 			NO_MATCH, NO_MATCH
 			} },
 
-	/* Problem Intel 440GX bioses */
-
-	{ broken_pirq, "SABR1 Bios", {			/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"SABR1"),
-			NO_MATCH, NO_MATCH
-			} },
-	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0094.P10"),
-			NO_MATCH, NO_MATCH
-                        } },
-	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0115.P12"),
-			NO_MATCH, NO_MATCH
-                        } },
-	{ broken_pirq, "l44GX Bios", {        		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0120.P12"),
-			NO_MATCH, NO_MATCH
-                        } },
-	{ broken_pirq, "l44GX Bios", {		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0125.P13"),
-			NO_MATCH, NO_MATCH
-			} },
-	{ broken_pirq, "l44GX Bios", {		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "Intel Corporation"),
-			MATCH(DMI_BIOS_VERSION,"L440GX0.86B.0066.P07.9906041405"),
-			NO_MATCH, NO_MATCH
-			} },
-
-	{ broken_pirq, "IBM xseries 370", {		/* Bad $PIR */
-			MATCH(DMI_BIOS_VENDOR, "IBM"),
-			MATCH(DMI_BIOS_VERSION,"MMKT33AUS"),
-			NO_MATCH, NO_MATCH
-			} },
-                        
-	/* Intel in disguise - In this case they can't hide and they don't run
-	   too well either... */
-	{ broken_pirq, "Dell PowerEdge 8450", {		/* Bad $PIR */
-			MATCH(DMI_PRODUCT_NAME, "Dell PowerEdge 8450"),
-			NO_MATCH, NO_MATCH, NO_MATCH
-			} },
-			
 	{ broken_acpi_Sx, "ASUS K7V-RM", {		/* Bad ACPI Sx table */
 			MATCH(DMI_BIOS_VERSION,"ASUS K7V-RM ACPI BIOS Revision 1003A"),
 			MATCH(DMI_BOARD_NAME, "<K7V-RM>"),
@@ -1018,6 +968,49 @@
 			MATCH(DMI_BOARD_VENDOR, "IBM"),
 			MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
 			NO_MATCH, NO_MATCH }},
+
+	/*
+	 * Systems with nForce2 BIOS timer override bug
+	 * nVidia claims all nForce have timer on pin0,
+	 * and applying this workaround is a NOP on fixed BIOS,
+	 * so prospects are good for replacing these entries
+	 * with something to key of chipset PCI-ID.
+	 */
+	{ ignore_timer_override, "Abit NF7-S v2", {
+			MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"),
+			MATCH(DMI_BOARD_NAME, "NF7-S/NF7,NF7-V (nVidia-nForce2)"),
+			MATCH(DMI_BIOS_VERSION, "6.00 PG"),
+			MATCH(DMI_BIOS_DATE, "03/24/2004") }},
+
+	{ ignore_timer_override, "Asus A7N8X v2", {
+			MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			MATCH(DMI_BOARD_NAME, "A7N8X2.0"),
+			MATCH(DMI_BIOS_VERSION, "ASUS A7N8X2.0 Deluxe ACPI BIOS Rev 1007"),
+			MATCH(DMI_BIOS_DATE, "10/06/2003") }},
+
+	{ ignore_timer_override, "Asus A7N8X-X", {
+			MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			MATCH(DMI_BOARD_NAME, "A7N8X-X"),
+			MATCH(DMI_BIOS_VERSION, "ASUS A7N8X-X ACPI BIOS Rev 1009"),
+			MATCH(DMI_BIOS_DATE, "2/3/2004") }},
+
+	{ ignore_timer_override, "MSI K7N2-Delta", {
+			MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+			MATCH(DMI_BOARD_NAME, "MS-6570"),
+			MATCH(DMI_BIOS_VERSION, "6.00 PG"),
+			MATCH(DMI_BIOS_DATE, "03/29/2004") }},
+
+	{ ignore_timer_override, "Shuttle SN41G2", {
+			MATCH(DMI_BOARD_VENDOR, "Shuttle Inc"),
+			MATCH(DMI_BOARD_NAME, "FN41"),
+			MATCH(DMI_BIOS_VERSION, "6.00 PG"),
+			MATCH(DMI_BIOS_DATE, "01/14/2004") }},
+
+	{ ignore_timer_override, "Shuttle AN35N", {
+			MATCH(DMI_BOARD_VENDOR, "Shuttle Inc"),
+			MATCH(DMI_BOARD_NAME, "AN35"),
+			MATCH(DMI_BIOS_VERSION, "6.00 PG"),
+			MATCH(DMI_BIOS_DATE, "12/05/2003") }},
 #endif	// CONFIG_ACPI_BOOT
 
 #ifdef	CONFIG_ACPI_PCI
@@ -1025,13 +1018,21 @@
 	 *	Boxes that need ACPI PCI IRQ routing disabled
 	 */
 
-	{ disable_acpi_pci, "ASUS A7V", {
+	{ disable_acpi_irq, "ASUS A7V", {
 			MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
 			MATCH(DMI_BOARD_NAME, "<A7V>"),
 			/* newer BIOS, Revision 1011, does work */
 			MATCH(DMI_BIOS_VERSION, "ASUS A7V ACPI BIOS Revision 1007"),
 			NO_MATCH }},
 
+	/*
+	 *	Boxes that need ACPI PCI IRQ routing and PCI scan disabled
+	 */
+	{ disable_acpi_pci, "ASUS PR-DLS", {	/* _BBN 0 bug */
+			MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			MATCH(DMI_BOARD_NAME, "PR-DLS"),
+			MATCH(DMI_BIOS_VERSION, "ASUS PR-DLS ACPI BIOS Revision 1010"),
+			MATCH(DMI_BIOS_DATE, "03/21/2003") }},
 #endif
 
 	{ NULL, }
diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c	Thu Apr 29 23:05:00 2004
+++ b/arch/i386/kernel/io_apic.c	Thu Apr 29 23:05:00 2004
@@ -2266,18 +2266,10 @@
 
 /*
  *
- * IRQ's that are handled by the old PIC in all cases:
+ * IRQ's that are handled by the PIC in the MPS IOAPIC case.
  * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ.
  *   Linux doesn't really care, as it's not actually used
  *   for any interrupt handling anyway.
- * - There used to be IRQ13 here as well, but all
- *   MPS-compliant must not use it for FPU coupling and we
- *   want to use exception 16 anyway.  And there are
- *   systems who connect it to an I/O APIC for other uses.
- *   Thus we don't mark it special any longer.
- *
- * Additionally, something is definitely wrong with irq9
- * on PIIX4 boards.
  */
 #define PIC_IRQS	(1 << PIC_CASCADE_IR)
 
@@ -2285,7 +2277,11 @@
 {
 	enable_IO_APIC();
 
-	io_apic_irqs = ~PIC_IRQS;
+	if (acpi_ioapic)
+		io_apic_irqs = ~0;	/* all IRQs go through IOAPIC */
+	else
+		io_apic_irqs = ~PIC_IRQS;
+
 	printk("ENABLING IO-APIC IRQs\n");
 
 	/*
diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
--- a/arch/i386/kernel/mpparse.c	Thu Apr 29 23:05:00 2004
+++ b/arch/i386/kernel/mpparse.c	Thu Apr 29 23:05:00 2004
@@ -929,8 +929,6 @@
 	u32			gsi)
 {
 	struct mpc_config_intsrc intsrc;
-	int			i = 0;
-	int			found = 0;
 	int			ioapic = -1;
 	int			pin = -1;
 
@@ -963,23 +961,9 @@
 		(intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, 
 		intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq);
 
-	/* 
-	 * If an existing [IOAPIC.PIN -> IRQ] routing entry exists we override it.
-	 * Otherwise create a new entry (e.g. gsi == 2).
-	 */
-	for (i = 0; i < mp_irq_entries; i++) {
-		if ((mp_irqs[i].mpc_srcbus == intsrc.mpc_srcbus) 
-			&& (mp_irqs[i].mpc_srcbusirq == intsrc.mpc_srcbusirq)) {
-			mp_irqs[i] = intsrc;
-			found = 1;
-			break;
-		}
-	}
-	if (!found) {
-		mp_irqs[mp_irq_entries] = intsrc;
-		if (++mp_irq_entries == MAX_IRQ_SOURCES)
-			panic("Max # of irq sources exceeded!\n");
-	}
+	mp_irqs[mp_irq_entries] = intsrc;
+	if (++mp_irq_entries == MAX_IRQ_SOURCES)
+		panic("Max # of irq sources exceeded!\n");
 
 	return;
 }
@@ -1010,13 +994,20 @@
 	intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid;
 
 	/* 
-	 * Use the default configuration for the IRQs 0-15.  These may be
+	 * Use the default configuration for the IRQs 0-15.  Unless
 	 * overriden by (MADT) interrupt source override entries.
 	 */
 	for (i = 0; i < 16; i++) {
+		int idx;
+
+		for (idx = 0; idx < mp_irq_entries; idx++)
+			if (mp_irqs[idx].mpc_srcbus == MP_ISA_BUS &&
+				(mp_irqs[idx].mpc_srcbusirq == i ||
+				mp_irqs[idx].mpc_dstirq == i))
+					break;
 
-		if (i == 2)
-			continue;			/* Don't connect IRQ2 */
+		if (idx != mp_irq_entries)
+			continue;			  /* IRQ already used */
 
 		intsrc.mpc_irqtype = mp_INT;
 		intsrc.mpc_srcbusirq = i;		   /* Identity mapped */
diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
--- a/arch/i386/kernel/setup.c	Thu Apr 29 23:05:00 2004
+++ b/arch/i386/kernel/setup.c	Thu Apr 29 23:05:00 2004
@@ -583,9 +583,13 @@
 				disable_acpi();
 			acpi_ht = 1;
 		}
-
-		/* "pci=noacpi" disables ACPI interrupt routing */
+		
+		/* "pci=noacpi" disable ACPI IRQ routing and PCI scan */
 		else if (!memcmp(from, "pci=noacpi", 10)) {
+			acpi_disable_pci();
+		}
+		/* "acpi=noirq" disables ACPI interrupt routing */
+		else if (!memcmp(from, "acpi=noirq", 10)) {
 			acpi_noirq_set();
 		}
 
@@ -600,6 +604,11 @@
 
 		else if (!memcmp(from, "acpi_sci=low", 12))
 			acpi_sci_flags.polarity = 3;
+
+#ifdef CONFIG_X86_IO_APIC
+		else if (!memcmp(from, "acpi_skip_timer_override", 24))
+			acpi_skip_timer_override = 1;
+#endif
 
 #ifdef CONFIG_X86_LOCAL_APIC
 		/* disable IO-APIC */
diff -Nru a/arch/i386/mach-default/setup.c b/arch/i386/mach-default/setup.c
--- a/arch/i386/mach-default/setup.c	Thu Apr 29 23:05:00 2004
+++ b/arch/i386/mach-default/setup.c	Thu Apr 29 23:05:00 2004
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <asm/acpi.h>
 #include <asm/arch_hooks.h>
 
 /**
@@ -43,7 +44,8 @@
 	apic_intr_init();
 #endif
 
-	setup_irq(2, &irq2);
+	if (!acpi_ioapic)
+		setup_irq(2, &irq2);
 }
 
 /**
diff -Nru a/arch/i386/mach-es7000/setup.c b/arch/i386/mach-es7000/setup.c
--- a/arch/i386/mach-es7000/setup.c	Thu Apr 29 23:05:00 2004
+++ b/arch/i386/mach-es7000/setup.c	Thu Apr 29 23:05:00 2004
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <asm/acpi.h>
 #include <asm/arch_hooks.h>
 
 /**
@@ -17,8 +18,7 @@
  *	the "ordinary" interrupt call gates.  For legacy reasons, the ISA
  *	interrupts should be initialised here if the machine emulates a PC
  *	in any way.
- **/
-void __init pre_intr_init_hook(void)
+ **/void __init pre_intr_init_hook(void)
 {
 	init_ISA_irqs();
 }
@@ -43,7 +43,8 @@
 	apic_intr_init();
 #endif
 
-	setup_irq(2, &irq2);
+	if (!acpi_ioapic)
+		setup_irq(2, &irq2);
 }
 
 /**
diff -Nru a/arch/i386/mach-voyager/setup.c b/arch/i386/mach-voyager/setup.c
--- a/arch/i386/mach-voyager/setup.c	Thu Apr 29 23:05:00 2004
+++ b/arch/i386/mach-voyager/setup.c	Thu Apr 29 23:05:00 2004
@@ -6,6 +6,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <asm/acpi.h>
 #include <asm/arch_hooks.h>
 
 void __init pre_intr_init_hook(void)
@@ -24,7 +25,8 @@
 	smp_intr_init();
 #endif
 
-	setup_irq(2, &irq2);
+	if (!acpi_ioapic)
+		setup_irq(2, &irq2);
 }
 
 void __init pre_setup_arch_hook(void)
diff -Nru a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
--- a/arch/i386/pci/irq.c	Thu Apr 29 23:05:00 2004
+++ b/arch/i386/pci/irq.c	Thu Apr 29 23:05:00 2004
@@ -453,15 +453,12 @@
 
 static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device)
 {
-#if 0 /* Let's see what chip this is supposed to be ... */
-	/* We must not touch 440GX even if we have tables. 440GX has
-	   different IRQ routing weirdness */
+	/* 440GX has a proprietary PIRQ router -- don't use it */
 	if (	pci_find_device(PCI_VENDOR_ID_INTEL,
 				PCI_DEVICE_ID_INTEL_82443GX_0, NULL) ||
 		pci_find_device(PCI_VENDOR_ID_INTEL,
 				PCI_DEVICE_ID_INTEL_82443GX_2, NULL))
 		return 0;
-#endif
 
 	switch(device)
 	{
diff -Nru a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
--- a/arch/x86_64/kernel/Makefile	Thu Apr 29 23:05:00 2004
+++ b/arch/x86_64/kernel/Makefile	Thu Apr 29 23:05:00 2004
@@ -8,7 +8,7 @@
 		ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_x86_64.o \
 		x8664_ksyms.o i387.o syscall.o vsyscall.o \
 		setup64.o bootflag.o e820.o reboot.o warmreboot.o
-obj-y += mce.o acpi/
+obj-y += mce.o
 
 obj-$(CONFIG_MTRR)		+= ../../i386/kernel/cpu/mtrr/
 obj-$(CONFIG_ACPI_BOOT)		+= acpi/
diff -Nru a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
--- a/arch/x86_64/kernel/i8259.c	Thu Apr 29 23:05:00 2004
+++ b/arch/x86_64/kernel/i8259.c	Thu Apr 29 23:05:00 2004
@@ -13,6 +13,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/sysdev.h>
 
+#include <asm/acpi.h>
 #include <asm/atomic.h>
 #include <asm/system.h>
 #include <asm/io.h>
@@ -490,5 +491,6 @@
 	 */
 	setup_timer();
 
-	setup_irq(2, &irq2);
+	if (!acpi_ioapic)
+		setup_irq(2, &irq2);
 }
diff -Nru a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
--- a/arch/x86_64/kernel/io_apic.c	Thu Apr 29 23:05:00 2004
+++ b/arch/x86_64/kernel/io_apic.c	Thu Apr 29 23:05:00 2004
@@ -1740,18 +1740,10 @@
 
 /*
  *
- * IRQ's that are handled by the old PIC in all cases:
+ * IRQ's that are handled by the PIC in the MPS IOAPIC case.
  * - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ.
  *   Linux doesn't really care, as it's not actually used
  *   for any interrupt handling anyway.
- * - There used to be IRQ13 here as well, but all
- *   MPS-compliant must not use it for FPU coupling and we
- *   want to use exception 16 anyway.  And there are
- *   systems who connect it to an I/O APIC for other uses.
- *   Thus we don't mark it special any longer.
- *
- * Additionally, something is definitely wrong with irq9
- * on PIIX4 boards.
  */
 #define PIC_IRQS	(1<<2)
 
@@ -1759,7 +1751,11 @@
 {
 	enable_IO_APIC();
 
-	io_apic_irqs = ~PIC_IRQS;
+	if (acpi_ioapic)
+		io_apic_irqs = ~0;	/* all IRQs go through IOAPIC */
+	else
+		io_apic_irqs = ~PIC_IRQS;
+
 	printk("ENABLING IO-APIC IRQs\n");
 
 	/*
diff -Nru a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
--- a/arch/x86_64/kernel/mpparse.c	Thu Apr 29 23:05:00 2004
+++ b/arch/x86_64/kernel/mpparse.c	Thu Apr 29 23:05:00 2004
@@ -784,8 +784,6 @@
 	u32			gsi)
 {
 	struct mpc_config_intsrc intsrc;
-	int			i = 0;
-	int			found = 0;
 	int			ioapic = -1;
 	int			pin = -1;
 
@@ -818,23 +816,9 @@
 		(intsrc.mpc_irqflag >> 2) & 3, intsrc.mpc_srcbus, 
 		intsrc.mpc_srcbusirq, intsrc.mpc_dstapic, intsrc.mpc_dstirq);
 
-	/* 
-	 * If an existing [IOAPIC.PIN -> IRQ] routing entry exists we override it.
-	 * Otherwise create a new entry (e.g. gsi == 2).
-	 */
-	for (i = 0; i < mp_irq_entries; i++) {
-		if ((mp_irqs[i].mpc_srcbus == intsrc.mpc_srcbus) 
-			&& (mp_irqs[i].mpc_srcbusirq == intsrc.mpc_srcbusirq)) {
-			mp_irqs[i] = intsrc;
-			found = 1;
-			break;
-		}
-	}
-	if (!found) {
-		mp_irqs[mp_irq_entries] = intsrc;
-		if (++mp_irq_entries == MAX_IRQ_SOURCES)
-			panic("Max # of irq sources exceeded!\n");
-	}
+	mp_irqs[mp_irq_entries] = intsrc;
+	if (++mp_irq_entries == MAX_IRQ_SOURCES)
+		panic("Max # of irq sources exceeded!\n");
 
 	return;
 }
@@ -865,13 +849,22 @@
 	intsrc.mpc_dstapic = mp_ioapics[ioapic].mpc_apicid;
 
 	/* 
-	 * Use the default configuration for the IRQs 0-15.  These may be
+	 * Use the default configuration for the IRQs 0-15.  Unless
 	 * overridden by (MADT) interrupt source override entries.
 	 */
 	for (i = 0; i < 16; i++) {
+		int idx;
 
-		if (i == 2)
-			continue;			/* Don't connect IRQ2 */
+		for (idx = 0; idx < mp_irq_entries; idx++)
+			if (mp_irqs[idx].mpc_srcbus == MP_ISA_BUS &&
+				(mp_irqs[idx].mpc_srcbusirq == i ||
+				mp_irqs[idx].mpc_dstirq == i))
+					break;
+
+		if (idx != mp_irq_entries) {
+			printk(KERN_DEBUG "ACPI: IRQ%d used by override.\n", i);
+			continue;			 /* IRQ already used */
+		}
 
 		intsrc.mpc_irqtype = mp_INT;
 		intsrc.mpc_srcbusirq = i;		   /* Identity mapped */
diff -Nru a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
--- a/arch/x86_64/kernel/setup.c	Thu Apr 29 23:05:00 2004
+++ b/arch/x86_64/kernel/setup.c	Thu Apr 29 23:05:00 2004
@@ -65,8 +65,8 @@
 unsigned long mmu_cr4_features;
 EXPORT_SYMBOL_GPL(mmu_cr4_features);
 
-int acpi_disabled = 0;
-
+int acpi_disabled;
+EXPORT_SYMBOL(acpi_disabled);
 #ifdef	CONFIG_ACPI_BOOT
 extern int __initdata acpi_ht;
 extern acpi_interrupt_flags	acpi_sci_flags;
@@ -242,7 +242,7 @@
 #ifdef CONFIG_ACPI_BOOT
 		/* "acpi=off" disables both ACPI table parsing and interpreter init */
 		if (!memcmp(from, "acpi=off", 8))
-			acpi_disabled = 1;
+			disable_acpi();
 
 		if (!memcmp(from, "acpi=force", 10)) { 
 			/* add later when we do DMI horrors: */
@@ -256,7 +256,9 @@
 			acpi_ht = 1; 
 		}
                 else if (!memcmp(from, "pci=noacpi", 10)) 
-                        acpi_noirq_set();
+			acpi_disable_pci();
+		else if (!memcmp(from, "acpi=noirq", 10))
+			acpi_noirq_set();
 
 		else if (!memcmp(from, "acpi_sci=edge", 13))
 			acpi_sci_flags.trigger =  1;
diff -Nru a/drivers/acpi/ac.c b/drivers/acpi/ac.c
--- a/drivers/acpi/ac.c	Thu Apr 29 23:05:00 2004
+++ b/drivers/acpi/ac.c	Thu Apr 29 23:05:00 2004
@@ -158,6 +158,7 @@
 			acpi_ac_dir);
 		if (!acpi_device_dir(device))
 			return_VALUE(-ENODEV);
+		acpi_device_dir(device)->owner = THIS_MODULE;
 	}
 
 	/* 'state' [R] */
@@ -170,6 +171,7 @@
 	else {
 		entry->proc_fops = &acpi_ac_fops;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	return_VALUE(0);
@@ -320,6 +322,7 @@
 	acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir);
 	if (!acpi_ac_dir)
 		return_VALUE(-ENODEV);
+	acpi_ac_dir->owner = THIS_MODULE;
 
 	result = acpi_bus_register_driver(&acpi_ac_driver);
 	if (result < 0) {
diff -Nru a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
--- a/drivers/acpi/asus_acpi.c	Thu Apr 29 23:05:00 2004
+++ b/drivers/acpi/asus_acpi.c	Thu Apr 29 23:05:00 2004
@@ -41,7 +41,7 @@
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 
-#define ASUS_ACPI_VERSION "0.27"
+#define ASUS_ACPI_VERSION "0.28"
 
 #define PROC_ASUS       "asus"	//the directory
 #define PROC_MLED       "mled"
@@ -125,12 +125,11 @@
 		L5x,      //L5800C 
 		L8L,      //L8400L
 		M1A,      //M1300A
-		M2E,      //M2400E
+		M2E,      //M2400E, L4400L
+		P30,	  //Samsung P30
 		S1x,      //S1300A, but also L1400B and M2400A (L84F)
 		S2x,      //S200 (J1 reported), Victor MP-XP7210
-		          //TODO  A1370D does not seem to have an ATK device 
-		          // L8400 model doesn't have ATK
-		xxN,      //M2400N, M3700N, S1300N (Centrino)
+		xxN,      //M2400N, M3700N, M6800N, S1300N, S5200N (Centrino)
 		END_MODEL
 	} model;              //Models currently supported
 	u16 event_count[128]; //count for each event TODO make this better
@@ -140,6 +139,7 @@
 #define A1x_PREFIX "\\_SB.PCI0.ISA.EC0."
 #define L3C_PREFIX "\\_SB.PCI0.PX40.ECD0."
 #define M1A_PREFIX "\\_SB.PCI0.PX40.EC0."
+#define P30_PREFIX "\\_SB.PCI0.LPCB.EC0."
 #define S1x_PREFIX "\\_SB.PCI0.PX40."
 #define S2x_PREFIX A1x_PREFIX
 #define xxN_PREFIX "\\_SB.PCI0.SBRG.EC0."
@@ -166,7 +166,7 @@
 		.mt_lcd_switch     = A1x_PREFIX "_Q10",
 		.lcd_status        = "\\BKLI",
 		.brightness_up     = A1x_PREFIX "_Q0E",
-		.brightness_down   = A1x_PREFIX "_Q0F",
+		.brightness_down   = A1x_PREFIX "_Q0F"
 	},
 
 	{
@@ -176,11 +176,8 @@
 		.wled_status       = "\\SG66",
 		.mt_lcd_switch     = "\\Q10",
 		.lcd_status        = "\\BAOF",
-		.brightness_up     = "\\Q0E",
-		.brightness_down   = "\\Q0F",
 		.brightness_set    = "SPLV",
 		.brightness_get    = "GPLV",
-		.brightness_status = "\\CMOD",
 		.display_set       = "SDSP",
 		.display_get       = "\\INFB"
 	},
@@ -217,11 +214,8 @@
 		.mt_wled           = "WLED",
 		.mt_lcd_switch     = L3C_PREFIX "_Q10",
 		.lcd_status        = "\\GL32",
-		.brightness_up     = L3C_PREFIX "_Q0F",
-		.brightness_down   = L3C_PREFIX "_Q0E",
 		.brightness_set    = "SPLV",
 		.brightness_get    = "GPLV",
-		.brightness_status = "\\BLVL",
 		.display_set       = "SDSP",
 		.display_get       = "\\_SB.PCI0.PCI1.VGAC.NMAP"
 	},
@@ -233,11 +227,8 @@
 		.mt_wled           = "WLED",
 		.mt_lcd_switch     = "\\Q10",
 		.lcd_status        = "\\BKLG",
-		.brightness_up     = "\\Q0E",
-		.brightness_down   = "\\Q0F",
 		.brightness_set    = "SPLV",
 		.brightness_get    = "GPLV",
-		.brightness_status = "\\BLVL",
 		.display_set       = "SDSP",
 		.display_get       = "\\INFB"
 	},
@@ -257,14 +248,10 @@
 	{
 		.name              = "L5x",
 		.mt_mled           = "MLED",
-//		.mt_wled           = "WLED",
-//		.wled_status       = "\\WRED",
-/* Present, but not controlled by ACPI */
+/* WLED present, but not controlled by ACPI */
 		.mt_tled           = "TLED",
 		.mt_lcd_switch     = "\\Q0D",
 		.lcd_status        = "\\BAOF",
-		.brightness_up     = "\\Q0C",
-		.brightness_down   = "\\Q0B",
 		.brightness_set    = "SPLV",
 		.brightness_get    = "GPLV",
 		.display_set       = "SDSP",
@@ -294,8 +281,6 @@
 		.mt_wled           = "WLED",
 		.mt_lcd_switch     = "\\Q10",
 		.lcd_status        = "\\GP06",
-		.brightness_up     = "\\Q0E",
-		.brightness_down   = "\\Q0F",
 		.brightness_set    = "SPLV",
 		.brightness_get    = "GPLV",
 		.display_set       = "SDSP",
@@ -303,17 +288,26 @@
 	},
 
 	{
+		.name              = "P30",
+		.mt_wled           = "WLED",
+		.mt_lcd_switch     = P30_PREFIX "_Q0E",
+		.lcd_status        = "\\BKLT",
+		.brightness_up     = P30_PREFIX "_Q68",
+		.brightness_down   = P30_PREFIX "_Q69",
+		.brightness_get    = "GPLV",
+		.display_set       = "SDSP",
+		.display_get       = "\\DNXT"
+	},
+
+	{
 		.name              = "S1x",
 		.mt_mled           = "MLED",
 		.mled_status       = "\\EMLE",
 		.mt_wled           = "WLED",
 		.mt_lcd_switch     = S1x_PREFIX "Q10" ,
 		.lcd_status        = "\\PNOF",
-		.brightness_up     = S1x_PREFIX "Q0F",
-		.brightness_down   = S1x_PREFIX "Q0E",
 		.brightness_set    = "SPLV",
-		.brightness_get    = "GPLV",
-		.brightness_status = "\\BRIT",
+		.brightness_get    = "GPLV"
 	},
 
 	{
@@ -323,22 +317,17 @@
 		.mt_lcd_switch     = S2x_PREFIX "_Q10",
 		.lcd_status        = "\\BKLI",
 		.brightness_up     = S2x_PREFIX "_Q0B",
-		.brightness_down   = S2x_PREFIX "_Q0A",
+		.brightness_down   = S2x_PREFIX "_Q0A"
 	},
 
 	{
 		.name              = "xxN",
 		.mt_mled           = "MLED",
-//		.mt_wled           = "WLED",
-//		.wled_status       = "\\PO33",
-/* Present, but not controlled by ACPI */
+/* WLED present, but not controlled by ACPI */
 		.mt_lcd_switch     = xxN_PREFIX "_Q10",
 		.lcd_status        = "\\BKLT",
-		.brightness_up     = xxN_PREFIX "_Q0F",
-		.brightness_down   = xxN_PREFIX "_Q0E",
 		.brightness_set    = "SPLV",
 		.brightness_get    = "GPLV",
-		.brightness_status = "\\LBTN",
 		.display_set       = "SDSP",
 		.display_get       = "\\ADVG"
 	}
@@ -663,6 +652,23 @@
 }
 
 
+static int read_brightness(struct asus_hotk *hotk)
+{
+	int value;
+	
+	if(hotk->methods->brightness_get) { /* SPLV/GPLV laptop */
+		if (!read_acpi_int(hotk->handle, hotk->methods->brightness_get, 
+				   &value))
+			printk(KERN_WARNING "Asus ACPI: Error reading brightness\n");
+	} else if (hotk->methods->brightness_status) { /* For D1 for example */
+		if (!read_acpi_int(NULL, hotk->methods->brightness_status, 
+				   &value))
+			printk(KERN_WARNING "Asus ACPI: Error reading brightness\n");
+	} else /* No GPLV method */
+		value = hotk->brightness;
+	return value;
+}
+
 /*
  * Change the brightness level
  */
@@ -679,7 +685,7 @@
 	}
 
 	/* No SPLV method if we are here, act as appropriate */
-	value -= hotk->brightness;
+	value -= read_brightness(hotk);
 	while (value != 0) {
 		status = acpi_evaluate_object(NULL, (value > 0) ? 
 					      hotk->methods->brightness_up : 
@@ -692,23 +698,6 @@
 	return;
 }
 
-static int read_brightness(struct asus_hotk *hotk)
-{
-	int value;
-	
-	if(hotk->methods->brightness_get) { /* SPLV/GPLV laptop */
-		if (!read_acpi_int(hotk->handle, hotk->methods->brightness_get, 
-				   &value))
-			printk(KERN_WARNING "Asus ACPI: Error reading brightness\n");
-	} else if (hotk->methods->brightness_status) { /* For D1 for example */
-		if (!read_acpi_int(NULL, hotk->methods->brightness_status, 
-				   &value))
-			printk(KERN_WARNING "Asus ACPI: Error reading brightness\n");
-	} else /* No GPLV method */
-		value = hotk->brightness;
-	return value;
-}
-
 static int
 proc_read_brn(char *page, char **start, off_t off, int count, int *eof,
 	      void *data)
@@ -929,12 +918,29 @@
 		return -ENODEV;
 	}
 
-	/* For testing purposes */
+	/* This needs to be called for some laptops to init properly */
 	if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result))
 		printk(KERN_WARNING "  Error calling BSTS\n");
 	else if (bsts_result)
 		printk(KERN_NOTICE "  BSTS called, 0x%02x returned\n", bsts_result);
 
+	/* Samsung P30 has a device with a valid _HID whose INIT does not 
+	 * return anything. Catch this one and any similar here */
+	if (buffer.pointer == NULL) {
+		if (asus_info && /* Samsung P30 */
+		    strncmp(asus_info->oem_table_id, "ODEM", 4) == 0) {
+			hotk->model = P30;
+			printk(KERN_NOTICE "  Samsung P30 detected, supported\n");
+		} else {
+			hotk->model = M2E;
+			printk(KERN_WARNING "  no string returned by INIT\n");
+			printk(KERN_WARNING "  trying default values, supply "
+			       "the developers with your DSDT\n");
+		}
+		hotk->methods = &model_conf[hotk->model];
+		return AE_OK;
+	}
+	
 	model = (union acpi_object *) buffer.pointer;
 	if (model->type == ACPI_TYPE_STRING) {
 		printk(KERN_NOTICE "  %s model detected, ", model->string.pointer);
@@ -953,12 +959,14 @@
 		hotk->model = L8L;
 	else if (strncmp(model->string.pointer, "M2N", 3) == 0 ||
 		 strncmp(model->string.pointer, "M3N", 3) == 0 ||
+		 strncmp(model->string.pointer, "M6N", 3) == 0 ||
 		 strncmp(model->string.pointer, "S1N", 3) == 0 ||
 		 strncmp(model->string.pointer, "S5N", 3) == 0)
 		hotk->model = xxN;
 	else if (strncmp(model->string.pointer, "M1", 2) == 0)
 		hotk->model = M1A;
-	else if (strncmp(model->string.pointer, "M2", 2) == 0)
+	else if (strncmp(model->string.pointer, "M2", 2) == 0 ||
+		 strncmp(model->string.pointer, "L4E", 3) == 0)
 		hotk->model = M2E;
 	else if (strncmp(model->string.pointer, "L2", 2) == 0)
 		hotk->model = L2D;
@@ -994,6 +1002,13 @@
 	else if (strncmp(model->string.pointer, "S5N", 3) == 0)
 		hotk->methods->mt_mled = NULL; 
 	/* S5N has no MLED */
+	else if (strncmp(model->string.pointer, "M6N", 3) == 0) {
+		hotk->methods->display_get = NULL; //TODO
+		hotk->methods->lcd_status = "\\_SB.BKLT";
+		hotk->methods->mt_wled = "WLED";
+		hotk->methods->wled_status = "\\_SB.PCI0.SBRG.SG13";
+	/* M6N differs slightly and has a usable WLED */
+	}
 	else if (asus_info) {
 		if (strncmp(asus_info->oem_table_id, "L1", 2) == 0)
 			hotk->methods->mled_status = NULL;
diff -Nru a/drivers/acpi/battery.c b/drivers/acpi/battery.c
--- a/drivers/acpi/battery.c	Thu Apr 29 23:05:00 2004
+++ b/drivers/acpi/battery.c	Thu Apr 29 23:05:00 2004
@@ -486,14 +486,18 @@
 	else
 		p += sprintf(p, "capacity state:          critical\n");
 
-	if ((bst->state & 0x01) && (bst->state & 0x02))
+	if ((bst->state & 0x01) && (bst->state & 0x02)){
 		p += sprintf(p, "charging state:          charging/discharging\n");
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Battery Charging and Discharging?\n"));
+	}
 	else if (bst->state & 0x01)
 		p += sprintf(p, "charging state:          discharging\n");
 	else if (bst->state & 0x02)
 		p += sprintf(p, "charging state:          charging\n");
-	else
-		p += sprintf(p, "charging state:          unknown\n");
+	else {
+		p += sprintf(p, "charging state:          charged\n");
+	}
 
 	if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN)
 		p += sprintf(p, "present rate:            unknown\n");
@@ -621,6 +625,7 @@
 			acpi_battery_dir);
 		if (!acpi_device_dir(device))
 			return_VALUE(-ENODEV);
+		acpi_device_dir(device)->owner = THIS_MODULE;
 	}
 
 	/* 'info' [R] */
@@ -633,6 +638,7 @@
 	else {
 		entry->read_proc = acpi_battery_read_info;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	/* 'status' [R] */
@@ -645,6 +651,7 @@
 	else {
 		entry->read_proc = acpi_battery_read_state;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	/* 'alarm' [R/W] */
@@ -658,6 +665,7 @@
 		entry->read_proc = acpi_battery_read_alarm;
 		entry->write_proc = acpi_battery_write_alarm;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	return_VALUE(0);
@@ -809,6 +817,7 @@
 	acpi_battery_dir = proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir);
 	if (!acpi_battery_dir)
 		return_VALUE(-ENODEV);
+	acpi_battery_dir->owner = THIS_MODULE;
 
 	result = acpi_bus_register_driver(&acpi_battery_driver);
 	if (result < 0) {
diff -Nru a/drivers/acpi/button.c b/drivers/acpi/button.c
--- a/drivers/acpi/button.c	Thu Apr 29 23:05:00 2004
+++ b/drivers/acpi/button.c	Thu Apr 29 23:05:00 2004
@@ -108,6 +108,9 @@
    -------------------------------------------------------------------------- */
 
 static struct proc_dir_entry	*acpi_button_dir;
+extern struct acpi_device 	*acpi_fixed_pwr_button;
+extern struct acpi_device	*acpi_fixed_sleep_button;
+
 
 static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
 {
@@ -187,9 +190,14 @@
 		break;
 	}
 
+	if (!entry)
+		return_VALUE(-ENODEV);
+	entry->owner = THIS_MODULE;
+
 	acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry);
 	if (!acpi_device_dir(device))
 		return_VALUE(-ENODEV);
+	acpi_device_dir(device)->owner = THIS_MODULE;
 
 	/* 'info' [R] */
 	entry = create_proc_entry(ACPI_BUTTON_FILE_INFO,
@@ -201,6 +209,7 @@
 	else {
 		entry->proc_fops = &acpi_button_info_fops;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	/* show lid state [R] */
@@ -214,6 +223,7 @@
 		else {
 			entry->proc_fops = &acpi_button_state_fops;
 			entry->data = acpi_driver_data(device);
+			entry->owner = THIS_MODULE;
 		}
 	}
 
@@ -225,10 +235,28 @@
 acpi_button_remove_fs (
 	struct acpi_device	*device)
 {
+	struct acpi_button	*button = NULL;
+
 	ACPI_FUNCTION_TRACE("acpi_button_remove_fs");
 
+	button = acpi_driver_data(device);
 	if (acpi_device_dir(device)) {
-		remove_proc_entry(acpi_device_bid(device), acpi_button_dir);
+		switch (button->type) {
+			case ACPI_BUTTON_TYPE_POWER:
+			case ACPI_BUTTON_TYPE_POWERF:
+				remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, 
+					acpi_button_dir);
+				break;
+			case ACPI_BUTTON_TYPE_SLEEP:
+			case ACPI_BUTTON_TYPE_SLEEPF:
+				remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, 
+					acpi_button_dir);
+				break;
+			case ACPI_BUTTON_TYPE_LID:
+				remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, 
+					acpi_button_dir);
+				break;
+		}
 		acpi_device_dir(device) = NULL;
 	}
 
@@ -485,6 +513,7 @@
 	acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
 	if (!acpi_button_dir)
 		return_VALUE(-ENODEV);
+	acpi_button_dir->owner = THIS_MODULE;
 
 	result = acpi_bus_register_driver(&acpi_button_driver);
 	if (result < 0) {
@@ -500,6 +529,12 @@
 acpi_button_exit (void)
 {
 	ACPI_FUNCTION_TRACE("acpi_button_exit");
+
+	if(acpi_fixed_pwr_button) 
+		acpi_button_remove(acpi_fixed_pwr_button, ACPI_BUS_TYPE_POWER_BUTTON);
+
+	if(acpi_fixed_sleep_button)
+		acpi_button_remove(acpi_fixed_sleep_button, ACPI_BUS_TYPE_SLEEP_BUTTON);
 
 	acpi_bus_unregister_driver(&acpi_button_driver);
 
diff -Nru a/drivers/acpi/fan.c b/drivers/acpi/fan.c
--- a/drivers/acpi/fan.c	Thu Apr 29 23:05:00 2004
+++ b/drivers/acpi/fan.c	Thu Apr 29 23:05:00 2004
@@ -157,6 +157,7 @@
 			acpi_fan_dir);
 		if (!acpi_device_dir(device))
 			return_VALUE(-ENODEV);
+		acpi_device_dir(device)->owner = THIS_MODULE;
 	}
 
 	/* 'status' [R/W] */
@@ -170,6 +171,7 @@
 		entry->read_proc = acpi_fan_read_state;
 		entry->write_proc = acpi_fan_write_state;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	return_VALUE(0);
@@ -273,6 +275,7 @@
 	acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir);
 	if (!acpi_fan_dir)
 		return_VALUE(-ENODEV);
+	acpi_fan_dir->owner = THIS_MODULE;
 
 	result = acpi_bus_register_driver(&acpi_fan_driver);
 	if (result < 0) {
diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c
--- a/drivers/acpi/osl.c	Thu Apr 29 23:05:00 2004
+++ b/drivers/acpi/osl.c	Thu Apr 29 23:05:00 2004
@@ -63,7 +63,7 @@
 extern char line_buf[80];
 #endif /*ENABLE_DEBUGGER*/
 
-static int acpi_irq_irq;
+static unsigned int acpi_irq_irq;
 static OSD_HANDLER acpi_irq_handler;
 static void *acpi_irq_context;
 
@@ -215,7 +215,8 @@
 
 	*new_val = NULL;
 	if (!memcmp (init_val->name, "_OS_", 4) && strlen(acpi_os_name)) {
-		printk(KERN_INFO PREFIX "Overriding _OS definition\n");
+		printk(KERN_INFO PREFIX "Overriding _OS definition %s\n",
+			acpi_os_name);
 		*new_val = acpi_os_name;
 	}
 
@@ -240,23 +241,22 @@
 }
 
 acpi_status
-acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context)
+acpi_os_install_interrupt_handler(u32 gsi, OSD_HANDLER handler, void *context)
 {
+	unsigned int irq;
+
 	/*
-	 * Ignore the irq from the core, and use the value in our copy of the
+	 * Ignore the GSI from the core, and use the value in our copy of the
 	 * FADT. It may not be the same if an interrupt source override exists
 	 * for the SCI.
 	 */
-	irq = acpi_fadt.sci_int;
-
-#if defined(CONFIG_IA64) || defined(CONFIG_PCI_USE_VECTOR)
-	irq = acpi_irq_to_vector(irq);
-	if (irq < 0) {
-		printk(KERN_ERR PREFIX "SCI (ACPI interrupt %d) not registered\n",
-		       acpi_fadt.sci_int);
+	gsi = acpi_fadt.sci_int;
+	if (acpi_gsi_to_irq(gsi, &irq) < 0) {
+		printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n",
+		       gsi);
 		return AE_OK;
 	}
-#endif
+
 	acpi_irq_handler = handler;
 	acpi_irq_context = context;
 	if (request_irq(irq, acpi_irq, SA_SHIRQ, "acpi", acpi_irq)) {
@@ -272,9 +272,6 @@
 acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler)
 {
 	if (irq) {
-#if defined(CONFIG_IA64) || defined(CONFIG_PCI_USE_VECTOR)
-		irq = acpi_irq_to_vector(irq);
-#endif
 		free_irq(irq, acpi_irq);
 		acpi_irq_handler = NULL;
 		acpi_irq_irq = 0;
diff -Nru a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
--- a/drivers/acpi/pci_irq.c	Thu Apr 29 23:05:00 2004
+++ b/drivers/acpi/pci_irq.c	Thu Apr 29 23:05:00 2004
@@ -368,7 +368,7 @@
 	if (!irq) {
 		printk(KERN_WARNING PREFIX "No IRQ known for interrupt pin %c of device %s", ('A' + pin), pci_name(dev));
 		/* Interrupt Line values above 0xF are forbidden */
-		if (dev->irq && dev->irq >= 0xF) {
+		if (dev->irq && (dev->irq <= 0xF)) {
 			printk(" - using IRQ %d\n", dev->irq);
 			return_VALUE(dev->irq);
 		}
diff -Nru a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
--- a/drivers/acpi/pci_link.c	Thu Apr 29 23:05:00 2004
+++ b/drivers/acpi/pci_link.c	Thu Apr 29 23:05:00 2004
@@ -371,6 +371,10 @@
 		resource.res.length = sizeof(struct acpi_resource);
 		resource.res.data.irq.edge_level = link->irq.edge_level;
 		resource.res.data.irq.active_high_low = link->irq.active_high_low;
+		if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
+			resource.res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
+		else
+			resource.res.data.irq.shared_exclusive = ACPI_SHARED;
 		resource.res.data.irq.number_of_interrupts = 1;
 		resource.res.data.irq.interrupts[0] = irq;
 		break;
@@ -381,6 +385,10 @@
 		resource.res.data.extended_irq.producer_consumer = ACPI_CONSUMER;
 		resource.res.data.extended_irq.edge_level = link->irq.edge_level;
 		resource.res.data.extended_irq.active_high_low = link->irq.active_high_low;
+		if (link->irq.edge_level == ACPI_EDGE_SENSITIVE)
+			resource.res.data.irq.shared_exclusive = ACPI_EXCLUSIVE;
+		else
+			resource.res.data.irq.shared_exclusive = ACPI_SHARED;
 		resource.res.data.extended_irq.number_of_interrupts = 1;
 		resource.res.data.extended_irq.interrupts[0] = irq;
 		/* ignore resource_source, it's optional */
@@ -793,7 +801,7 @@
 {
 	ACPI_FUNCTION_TRACE("acpi_pci_link_init");
 
-	if (acpi_disabled)
+	if (acpi_pci_disabled)
 		return_VALUE(0);
 
 	acpi_link.count = 0;
diff -Nru a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
--- a/drivers/acpi/pci_root.c	Thu Apr 29 23:05:00 2004
+++ b/drivers/acpi/pci_root.c	Thu Apr 29 23:05:00 2004
@@ -119,6 +119,7 @@
 {
 	int			result = 0;
 	struct acpi_pci_root	*root = NULL;
+	struct acpi_pci_root	*tmp;
 	acpi_status		status = AE_OK;
 	unsigned long		value = 0;
 	acpi_handle		handle = NULL;
@@ -186,6 +187,13 @@
 		goto end;
 	}
 
+	/* Some systems have wrong _BBN */
+	list_for_each_entry(tmp, &acpi_pci_roots, node) {
+		if ((tmp->id.segment == root->id.segment)
+				&& (tmp->id.bus == root->id.bus))
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+				"Wrong _BBN value, please reboot and using option 'pci=noacpi'\n"));
+	}
 	/*
 	 * Device & Function
 	 * -----------------
@@ -272,7 +280,7 @@
 {
 	ACPI_FUNCTION_TRACE("acpi_pci_root_init");
 
-	if (acpi_disabled)
+	if (acpi_pci_disabled)
 		return_VALUE(0);
 
 	/* DEBUG:
diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c
--- a/drivers/acpi/processor.c	Thu Apr 29 23:05:00 2004
+++ b/drivers/acpi/processor.c	Thu Apr 29 23:05:00 2004
@@ -1190,6 +1190,7 @@
 		entry->proc_fops = &acpi_processor_perf_fops;
 		entry->proc_fops->write = acpi_processor_write_performance;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 	return_VOID;
 }
@@ -2066,6 +2067,7 @@
 		if (!acpi_device_dir(device))
 			return_VALUE(-ENODEV);
 	}
+	acpi_device_dir(device)->owner = THIS_MODULE;
 
 	/* 'info' [R] */
 	entry = create_proc_entry(ACPI_PROCESSOR_FILE_INFO,
@@ -2077,6 +2079,7 @@
 	else {
 		entry->proc_fops = &acpi_processor_info_fops;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	/* 'power' [R] */
@@ -2089,6 +2092,7 @@
 	else {
 		entry->proc_fops = &acpi_processor_power_fops;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	/* 'throttling' [R/W] */
@@ -2102,6 +2106,7 @@
 		entry->proc_fops = &acpi_processor_throttling_fops;
 		entry->proc_fops->write = acpi_processor_write_throttling;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	/* 'limit' [R/W] */
@@ -2115,6 +2120,7 @@
 		entry->proc_fops = &acpi_processor_limit_fops;
 		entry->proc_fops->write = acpi_processor_write_limit;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	return_VALUE(0);
@@ -2128,6 +2134,11 @@
 	ACPI_FUNCTION_TRACE("acpi_processor_remove_fs");
 
 	if (acpi_device_dir(device)) {
+		remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,acpi_device_dir(device));
+		remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,acpi_device_dir(device));
+		remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
+			acpi_device_dir(device));
+		remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,acpi_device_dir(device));
 		remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
 		acpi_device_dir(device) = NULL;
 	}
@@ -2385,6 +2396,7 @@
 	acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
 	if (!acpi_processor_dir)
 		return_VALUE(-ENODEV);
+	acpi_processor_dir->owner = THIS_MODULE;
 
 	result = acpi_bus_register_driver(&acpi_processor_driver);
 	if (result < 0) {
diff -Nru a/drivers/acpi/scan.c b/drivers/acpi/scan.c
--- a/drivers/acpi/scan.c	Thu Apr 29 23:05:00 2004
+++ b/drivers/acpi/scan.c	Thu Apr 29 23:05:00 2004
@@ -15,6 +15,8 @@
 #define STRUCT_TO_INT(s)	(*((int*)&s))
 
 extern struct acpi_device		*acpi_root;
+struct acpi_device 		*acpi_fixed_pwr_button;
+struct acpi_device 		*acpi_fixed_sleep_button;
 
 
 #define ACPI_BUS_CLASS			"system_bus"
@@ -900,10 +902,13 @@
 	struct acpi_device	*root)
 {
 	int			result = 0;
-	struct acpi_device	*device = NULL;
 
 	ACPI_FUNCTION_TRACE("acpi_bus_scan_fixed");
 
+	acpi_fixed_pwr_button = NULL;
+	acpi_fixed_sleep_button = NULL;
+
+
 	if (!root)
 		return_VALUE(-ENODEV);
 
@@ -911,11 +916,11 @@
 	 * Enumerate all fixed-feature devices.
 	 */
 	if (acpi_fadt.pwr_button == 0)
-		result = acpi_bus_add(&device, acpi_root, 
+		result = acpi_bus_add(&acpi_fixed_pwr_button, acpi_root, 
 			NULL, ACPI_BUS_TYPE_POWER_BUTTON);
 
 	if (acpi_fadt.sleep_button == 0)
-		result = acpi_bus_add(&device, acpi_root, 
+		result = acpi_bus_add(&acpi_fixed_sleep_button, acpi_root, 
 			NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
 
 	return_VALUE(result);
diff -Nru a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
--- a/drivers/acpi/thermal.c	Thu Apr 29 23:05:00 2004
+++ b/drivers/acpi/thermal.c	Thu Apr 29 23:05:00 2004
@@ -1060,6 +1060,7 @@
 			acpi_thermal_dir);
 		if (!acpi_device_dir(device))
 			return_VALUE(-ENODEV);
+		acpi_device_dir(device)->owner = THIS_MODULE;
 	}
 
 	/* 'state' [R] */
@@ -1072,6 +1073,7 @@
 	else {
 		entry->proc_fops = &acpi_thermal_state_fops;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	/* 'temperature' [R] */
@@ -1084,6 +1086,7 @@
 	else {
 		entry->proc_fops = &acpi_thermal_temp_fops;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	/* 'trip_points' [R/W] */
@@ -1096,6 +1099,7 @@
 	else {
 		entry->proc_fops = &acpi_thermal_trip_fops;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	/* 'cooling_mode' [R/W] */
@@ -1108,6 +1112,7 @@
 	else {
 		entry->proc_fops = &acpi_thermal_cooling_fops;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	/* 'polling_frequency' [R/W] */
@@ -1120,6 +1125,7 @@
 	else {
 		entry->proc_fops = &acpi_thermal_polling_fops;
 		entry->data = acpi_driver_data(device);
+		entry->owner = THIS_MODULE;
 	}
 
 	return_VALUE(0);
@@ -1338,6 +1344,7 @@
 	acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
 	if (!acpi_thermal_dir)
 		return_VALUE(-ENODEV);
+	acpi_thermal_dir->owner = THIS_MODULE;
 
 	result = acpi_bus_register_driver(&acpi_thermal_driver);
 	if (result < 0) {
diff -Nru a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
--- a/drivers/acpi/toshiba_acpi.c	Thu Apr 29 23:05:00 2004
+++ b/drivers/acpi/toshiba_acpi.c	Thu Apr 29 23:05:00 2004
@@ -502,6 +502,8 @@
 		proc = create_proc_read_entry(item->name,
 			S_IFREG | S_IRUGO | S_IWUSR,
 			toshiba_proc_dir, (read_proc_t*)dispatch_read, item);
+		if (proc)
+			proc->owner = THIS_MODULE;
 		if (proc && item->write_func)
 			proc->write_proc = (write_proc_t*)dispatch_write;
 	}
@@ -525,6 +527,8 @@
 	acpi_status status = AE_OK;
 	u32 hci_result;
 
+	if (acpi_disabled)
+		return -ENODEV;
 	/* simple device detection: look for HCI method */
 	if (is_valid_acpi_path(METHOD_HCI_1))
 		method_hci = METHOD_HCI_1;
@@ -547,6 +551,7 @@
 	if (!toshiba_proc_dir) {
 		status = AE_ERROR;
 	} else {
+		toshiba_proc_dir->owner = THIS_MODULE;
 		status = add_device();
 		if (ACPI_FAILURE(status))
 			remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
diff -Nru a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
--- a/include/acpi/acpiosxf.h	Thu Apr 29 23:05:00 2004
+++ b/include/acpi/acpiosxf.h	Thu Apr 29 23:05:00 2004
@@ -188,14 +188,14 @@
 
 acpi_status
 acpi_os_install_interrupt_handler (
-	u32                             interrupt_number,
-	OSD_HANDLER             service_routine,
+	u32                             gsi,
+	OSD_HANDLER                     service_routine,
 	void                            *context);
 
 acpi_status
 acpi_os_remove_interrupt_handler (
 	u32                             interrupt_number,
-	OSD_HANDLER             service_routine);
+	OSD_HANDLER                     service_routine);
 
 
 /*
diff -Nru a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
--- a/include/asm-i386/acpi.h	Thu Apr 29 23:05:00 2004
+++ b/include/asm-i386/acpi.h	Thu Apr 29 23:05:00 2004
@@ -109,7 +109,14 @@
 extern int acpi_strict;
 extern int acpi_disabled;
 extern int acpi_ht;
-static inline void disable_acpi(void) { acpi_disabled = 1; acpi_ht = 0; }
+extern int acpi_pci_disabled;
+static inline void disable_acpi(void) 
+{ 
+	acpi_disabled = 1; 
+	acpi_ht = 0;
+	acpi_pci_disabled = 1;
+	acpi_noirq = 1;
+}
 
 /* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
 #define FIX_ACPI_PAGES 4
@@ -118,6 +125,7 @@
 #ifdef CONFIG_X86_IO_APIC
 extern int skip_ioapic_setup;
 extern int acpi_irq_to_vector(u32 irq);	/* deprecated in favor of acpi_gsi_to_irq */
+extern int acpi_skip_timer_override;
 
 static inline void disable_ioapic_setup(void)
 {
@@ -143,9 +151,15 @@
 
 #ifdef CONFIG_ACPI_PCI
 static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
+static inline void acpi_disable_pci(void) 
+{
+	acpi_pci_disabled = 1; 
+	acpi_noirq_set();
+}
 extern int acpi_irq_balance_set(char *str);
 #else
 static inline void acpi_noirq_set(void) { }
+static inline void acpi_disable_pci(void) { }
 static inline int acpi_irq_balance_set(char *str) { return 0; }
 #endif
 
diff -Nru a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h
--- a/include/asm-ia64/acpi.h	Thu Apr 29 23:05:00 2004
+++ b/include/asm-ia64/acpi.h	Thu Apr 29 23:05:00 2004
@@ -89,6 +89,7 @@
 	((Acq) = ia64_acpi_release_global_lock((unsigned int *) GLptr))
 
 #define acpi_disabled 0	/* ACPI always enabled on IA64 */
+#define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */
 #define acpi_strict 1	/* no ACPI spec workarounds on IA64 */
 static inline void disable_acpi(void) { }
 
diff -Nru a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h
--- a/include/asm-x86_64/acpi.h	Thu Apr 29 23:05:00 2004
+++ b/include/asm-x86_64/acpi.h	Thu Apr 29 23:05:00 2004
@@ -106,8 +106,15 @@
 extern int acpi_noirq;
 extern int acpi_strict;
 extern int acpi_disabled;
+extern int acpi_pci_disabled;
 extern int acpi_ht;
-static inline void disable_acpi(void) { acpi_disabled = 1; acpi_ht = 0; }
+static inline void disable_acpi(void) 
+{ 
+	acpi_disabled = 1; 
+	acpi_ht = 0; 
+	acpi_pci_disabled = 1;
+	acpi_noirq = 1;
+}
 
 /* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
 #define FIX_ACPI_PAGES 4
@@ -121,9 +128,15 @@
 
 #ifdef CONFIG_ACPI_PCI
 static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
+static inline void acpi_disable_pci(void) 
+{
+	acpi_pci_disabled = 1; 
+	acpi_noirq_set();
+}
 extern int acpi_irq_balance_set(char *str);
 #else
 static inline void acpi_noirq_set(void) { }
+static inline void acpi_disable_pci(void) { }
 static inline int acpi_irq_balance_set(char *str) { return 0; }
 #endif
 
@@ -144,6 +157,7 @@
 #define boot_cpu_physical_apicid boot_cpu_id
 
 extern int acpi_disabled;
+extern int acpi_pci_disabled;
 
 #define dmi_broken (0)
 #define BROKEN_ACPI_Sx		0x0001
diff -Nru a/include/linux/acpi.h b/include/linux/acpi.h
--- a/include/linux/acpi.h	Thu Apr 29 23:05:00 2004
+++ b/include/linux/acpi.h	Thu Apr 29 23:05:00 2004
@@ -438,6 +438,7 @@
 
 int acpi_pci_irq_enable (struct pci_dev *dev);
 int acpi_pci_irq_init (void);
+int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 
 struct acpi_pci_driver {
 	struct acpi_pci_driver *next;
