http://linux-acpi.bkbits.net/linux-acpi-test-2.6.6 len.brown@intel.com|ChangeSet|20040503042941|47515 len.brown # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/05/02 21:51:20-07:00 akpm@bix.(none) # Merge http://linux-acpi.bkbits.net/linux-acpi-test-2.6.6 # into bix.(none):/usr/src/bk-acpi # # Documentation/kernel-parameters.txt # 2004/05/02 21:51:18-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/03 00:29:06-04:00 len.brown@intel.com # [ACPI] export symbols to button module # # drivers/acpi/scan.c # 2004/05/03 00:23:06-04:00 len.brown@intel.com +5 -0 # export symbols to button driver (module) # # ChangeSet # 2004/05/02 20:39:52-04:00 len.brown@intel.com # Merge intel.com:/home/lenb/bk/linux-2.6.6 # into intel.com:/home/lenb/src/linux-acpi-test-2.6.6 # # Documentation/kernel-parameters.txt # 2004/05/02 20:39:47-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/05/01 01:28:00-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/io_apic.c # 2004/05/01 01:27:57-04:00 len.brown@intel.com +0 -0 # Auto merged # # ChangeSet # 2004/05/01 01:27:30-04:00 len.brown@intel.com # [ACPI] PCI Interrupt Link fixes # Handle BIOS that reference disabled PCI Interrupt Link Devices # http://bugme.osdl.org/show_bug.cgi?id=1581 # # Clean up VIA _CRS = 0 BIOS workaround # # Handle BIOS returning _CRS outside _PRS # http://bugme.osdl.org/show_bug.cgi?id=2567 # # delete now unused _SRS retry code # disable redundant console messages # # drivers/acpi/pci_link.c # 2004/05/01 01:27:25-04:00 len.brown@intel.com +94 -95 # andle BIOS that reference disabled PCI Interrupt Link Devices # http://bugme.osdl.org/show_bug.cgi?id=1581 # # Clean up VIA _CRS = 0 BIOS workaround # # Handle BIOS returning _CRS outside _PRS # http://bugme.osdl.org/show_bug.cgi?id=2567 # # delete now unused _SRS retry code # # arch/i386/pci/acpi.c # 2004/05/01 01:27:25-04:00 len.brown@intel.com +0 -1 # delete dmesg spam # # arch/i386/kernel/mpparse.c # 2004/05/01 01:27:25-04:00 len.brown@intel.com +3 -2 # reduce console messages # # arch/i386/kernel/io_apic.c # 2004/05/01 01:27:25-04:00 len.brown@intel.com +1 -1 # disable redundant console message # # 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 Tue May 4 21:54:43 2004 +++ b/Documentation/kernel-parameters.txt Tue May 4 21:54:43 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: ,,, 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 Tue May 4 21:54:43 2004 +++ b/arch/i386/kernel/acpi/boot.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/arch/i386/kernel/dmi_scan.c Tue May 4 21:54:43 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, ""), @@ -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, ""), /* 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 Tue May 4 21:54:43 2004 +++ b/arch/i386/kernel/io_apic.c Tue May 4 21:54:43 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"); /* @@ -2455,7 +2451,7 @@ entry.vector = assign_irq_vector(irq); - printk(KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> " + Dprintk(KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry (%d-%d -> 0x%x -> " "IRQ %d Mode:%i Active:%i)\n", ioapic, mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, edge_level, active_high_low); diff -Nru a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c --- a/arch/i386/kernel/mpparse.c Tue May 4 21:54:43 2004 +++ b/arch/i386/kernel/mpparse.c Tue May 4 21:54:43 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 */ @@ -1111,11 +1102,12 @@ if (!io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, edge_level, active_high_low)) { acpi_gsi_to_irq(gsi, &entry->irq); } - printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n", + printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d %s %s\n", entry->id.segment, entry->id.bus, entry->id.device, ('A' + entry->pin), mp_ioapic_routing[ioapic].apic_id, ioapic_pin, - entry->irq); + entry->irq, edge_level ? "level" : "edge", + active_high_low ? "low" : "high"); } print_IO_APIC(); diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c --- a/arch/i386/kernel/setup.c Tue May 4 21:54:43 2004 +++ b/arch/i386/kernel/setup.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/arch/i386/mach-default/setup.c Tue May 4 21:54:43 2004 @@ -7,6 +7,7 @@ #include #include #include +#include #include /** @@ -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 Tue May 4 21:54:43 2004 +++ b/arch/i386/mach-es7000/setup.c Tue May 4 21:54:43 2004 @@ -7,6 +7,7 @@ #include #include #include +#include #include /** @@ -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 Tue May 4 21:54:43 2004 +++ b/arch/i386/mach-voyager/setup.c Tue May 4 21:54:43 2004 @@ -6,6 +6,7 @@ #include #include #include +#include #include 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/acpi.c b/arch/i386/pci/acpi.c --- a/arch/i386/pci/acpi.c Tue May 4 21:54:43 2004 +++ b/arch/i386/pci/acpi.c Tue May 4 21:54:43 2004 @@ -21,7 +21,6 @@ if (!acpi_noirq) { 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' or even 'acpi=off'\n"); pcibios_scanned++; pcibios_enable_irq = acpi_pci_irq_enable; } else diff -Nru a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c --- a/arch/i386/pci/irq.c Tue May 4 21:54:43 2004 +++ b/arch/i386/pci/irq.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/arch/x86_64/kernel/Makefile Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/arch/x86_64/kernel/i8259.c Tue May 4 21:54:43 2004 @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -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 Tue May 4 21:54:43 2004 +++ b/arch/x86_64/kernel/io_apic.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/arch/x86_64/kernel/mpparse.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/arch/x86_64/kernel/setup.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/drivers/acpi/ac.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/drivers/acpi/asus_acpi.c Tue May 4 21:54:43 2004 @@ -41,7 +41,7 @@ #include #include -#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 Tue May 4 21:54:43 2004 +++ b/drivers/acpi/battery.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/drivers/acpi/button.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/drivers/acpi/fan.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/drivers/acpi/osl.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/drivers/acpi/pci_irq.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/drivers/acpi/pci_link.c Tue May 4 21:54:43 2004 @@ -94,6 +94,9 @@ PCI Link Device Management -------------------------------------------------------------------------- */ +/* + * set context (link) possible list from resource list + */ static acpi_status acpi_pci_link_check_possible ( struct acpi_resource *resource, @@ -132,7 +135,7 @@ struct acpi_resource_ext_irq *p = &resource->data.extended_irq; if (!p || !p->number_of_interrupts) { ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Blank IRQ resource\n")); + "Blank EXT IRQ resource\n")); return AE_OK; } for (i = 0; (inumber_of_interrupts && idata.irq; if (!p || !p->number_of_interrupts) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Blank IRQ resource\n")); + /* + * IRQ descriptors may have no IRQ# bits set, + * particularly those those w/ _STA disabled + */ + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Blank IRQ resource\n")); return AE_OK; } *irq = p->interrupts[0]; @@ -208,8 +215,12 @@ { struct acpi_resource_ext_irq *p = &resource->data.extended_irq; if (!p || !p->number_of_interrupts) { + /* + * extended IRQ descriptors must + * return at least 1 IRQ + */ ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Blank IRQ resource\n")); + "Blank EXT IRQ resource\n")); return AE_OK; } *irq = p->interrupts[0]; @@ -223,6 +234,13 @@ return AE_CTRL_TERMINATE; } +/* + * Run _CRS and set link->irq.active + * + * return value: + * 0 - success + * !0 - failure + */ static int acpi_pci_link_get_current ( struct acpi_pci_link *link) @@ -238,15 +256,19 @@ link->irq.active = 0; - /* Make sure the link is enabled (no use querying if it isn't). */ - result = acpi_bus_get_status(link->device); - if (result) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n")); - goto end; - } - if (!link->device->status.enabled) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link disabled\n")); - return_VALUE(0); + /* in practice, status disabled is meaningless, ignore it */ + if (acpi_strict) { + /* Query _STA, set link->device->status */ + result = acpi_bus_get_status(link->device); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n")); + goto end; + } + + if (!link->device->status.enabled) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link disabled\n")); + return_VALUE(0); + } } /* @@ -261,18 +283,11 @@ goto end; } - if (!irq) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No IRQ resource found\n")); + if (acpi_strict && !irq) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "_CRS returned 0\n")); result = -ENODEV; - goto end; } - /* - * Note that we don't validate that the current IRQ (_CRS) exists - * within the possible IRQs (_PRS): we blindly assume that whatever - * IRQ a boot-enabled Link device is set to is the correct one. - * (Required to support systems such as the Toshiba 5005-S504.) - */ link->irq.active = irq; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Link at IRQ %d \n", link->irq.active)); @@ -282,32 +297,6 @@ } static int -acpi_pci_link_try_get_current ( - struct acpi_pci_link *link, - int irq) -{ - int result; - - ACPI_FUNCTION_TRACE("acpi_pci_link_try_get_current"); - - result = acpi_pci_link_get_current(link); - if (result && link->irq.active) { - return_VALUE(result); - } - - if (!link->irq.active) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No active IRQ resource found\n")); - printk(KERN_WARNING "_CRS returns NULL! Using IRQ %d for" - "device (%s [%s]).\n", irq, - acpi_device_name(link->device), - acpi_device_bid(link->device)); - link->irq.active = irq; - } - - return 0; -} - -static int acpi_pci_link_set ( struct acpi_pci_link *link, int irq) @@ -321,7 +310,6 @@ struct acpi_buffer buffer = {sizeof(resource)+1, &resource}; int i = 0; int valid = 0; - int resource_type = 0; ACPI_FUNCTION_TRACE("acpi_pci_link_set"); @@ -345,32 +333,18 @@ } } - resource_type = link->irq.resource_type; - - if (resource_type != ACPI_RSTYPE_IRQ && - resource_type != ACPI_RSTYPE_EXT_IRQ){ - /* If IRQ<=15, first try with a "normal" IRQ descriptor. If that fails, try with - * an extended one */ - if (irq <= 15) { - resource_type = ACPI_RSTYPE_IRQ; - } else { - resource_type = ACPI_RSTYPE_EXT_IRQ; - } - } - -retry_programming: - memset(&resource, 0, sizeof(resource)); - /* NOTE: PCI interrupts are always level / active_low / shared. But not all - interrupts > 15 are PCI interrupts. Rely on the ACPI IRQ definition for - parameters */ - switch(resource_type) { + switch(link->irq.resource_type) { case ACPI_RSTYPE_IRQ: resource.res.id = ACPI_RSTYPE_IRQ; 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,53 +355,64 @@ 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 */ break; + default: + printk("ACPI BUG: resource_type %d\n", link->irq.resource_type); + return_VALUE(-EINVAL); + } resource.end.id = ACPI_RSTYPE_END_TAG; /* Attempt to set the resource */ status = acpi_set_current_resources(link->handle, &buffer); - /* if we failed and IRQ <= 15, try again with an extended descriptor */ - if (ACPI_FAILURE(status) && (resource_type == ACPI_RSTYPE_IRQ)) { - resource_type = ACPI_RSTYPE_EXT_IRQ; - printk(PREFIX "Retrying with extended IRQ descriptor\n"); - goto retry_programming; - } - /* check for total failure */ if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _SRS\n")); return_VALUE(-ENODEV); } - /* Make sure the device is enabled. */ + /* Query _STA, set device->status */ result = acpi_bus_get_status(link->device); if (result) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to read status\n")); return_VALUE(result); } if (!link->device->status.enabled) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link disabled\n")); - return_VALUE(-ENODEV); + printk(KERN_WARNING PREFIX + "%s [%s] disabled and referenced, BIOS bug.\n", + acpi_device_name(link->device), + acpi_device_bid(link->device)); } - /* Make sure the active IRQ is the one we requested. */ - result = acpi_pci_link_try_get_current(link, irq); + /* Query _CRS, set link->irq.active */ + result = acpi_pci_link_get_current(link); if (result) { return_VALUE(result); } - + + /* + * Is current setting not what we set? + * set link->irq.active + */ if (link->irq.active != irq) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Attempt to enable at IRQ %d resulted in IRQ %d\n", - irq, link->irq.active)); - link->irq.active = 0; - acpi_ut_evaluate_object (link->handle, "_DIS", 0, NULL); - return_VALUE(-ENODEV); + /* + * policy: when _CRS doesn't return what we just _SRS + * assume _SRS worked and override _CRS value. + */ + printk(KERN_WARNING PREFIX + "%s [%s] BIOS reported IRQ %d, using IRQ %d\n", + acpi_device_name(link->device), + acpi_device_bid(link->device), + link->irq.active, irq); + link->irq.active = irq; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Set IRQ %d\n", link->irq.active)); @@ -481,7 +466,7 @@ #define PIRQ_PENALTY_ISA_USED (16*16*16*16*16) #define PIRQ_PENALTY_ISA_ALWAYS (16*16*16*16*16*16) -static int acpi_irq_penalty[ACPI_MAX_IRQS] = { +static int __initdata acpi_irq_penalty[ACPI_MAX_IRQS] = { PIRQ_PENALTY_ISA_ALWAYS, /* IRQ0 timer */ PIRQ_PENALTY_ISA_ALWAYS, /* IRQ1 keyboard */ PIRQ_PENALTY_ISA_ALWAYS, /* IRQ2 cascade */ @@ -554,10 +539,24 @@ if (link->irq.setonboot) return_VALUE(0); - if (link->irq.active) { + /* + * search for active IRQ in list of possible IRQs. + */ + for (i = 0; i < link->irq.possible_count; ++i) { + if (link->irq.active == link->irq.possible[i]) + break; + } + + /* + * if active found, use it; else pick entry from end of possible list. + */ + if (i != link->irq.possible_count) { irq = link->irq.active; } else { - irq = link->irq.possible[0]; + irq = link->irq.possible[link->irq.possible_count - 1]; + if (acpi_strict) + printk(KERN_WARNING PREFIX "_CRS %d not found" + " in _PRS\n", link->irq.active); } if (acpi_irq_balance || !link->irq.active) { @@ -573,7 +572,8 @@ /* Attempt to enable the link device at this IRQ. */ if (acpi_pci_link_set(link, irq)) { - printk(PREFIX "Unable to set IRQ for %s [%s] (likely buggy ACPI BIOS). Aborting ACPI-based IRQ routing. Try pci=noacpi or acpi=off\n", + printk(PREFIX "Unable to set IRQ for %s [%s] (likely buggy ACPI BIOS).\n" + "Try pci=noacpi or acpi=off\n", acpi_device_name(link->device), acpi_device_bid(link->device)); return_VALUE(-ENODEV); @@ -625,7 +625,7 @@ return_VALUE(0); if (!link->irq.active) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link disabled\n")); + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link active IRQ is 0!\n")); return_VALUE(0); } @@ -671,7 +671,6 @@ /* query and set link->irq.active */ acpi_pci_link_get_current(link); -//#ifdef CONFIG_ACPI_DEBUG printk(PREFIX "%s [%s] (IRQs", acpi_device_name(device), acpi_device_bid(device)); for (i = 0; i < link->irq.possible_count; i++) { @@ -682,8 +681,16 @@ else printk(" %d", link->irq.possible[i]); } - printk(")\n"); -//#endif /* CONFIG_ACPI_DEBUG */ + + printk(")"); + + if (!found) + printk(" *%d", link->irq.active); + + if(!link->device->status.enabled) + printk(", disabled."); + + printk("\n"); /* TBD: Acquire/release lock */ list_add_tail(&link->node, &acpi_link.entries); @@ -793,7 +800,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 Tue May 4 21:54:43 2004 +++ b/drivers/acpi/pci_root.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/drivers/acpi/processor.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/drivers/acpi/scan.c Tue May 4 21:54:43 2004 @@ -4,6 +4,7 @@ #include #include +#include #include #include /* for acpi_ex_eisa_id_to_string() */ @@ -15,6 +16,12 @@ #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; + +EXPORT_SYMBOL(acpi_fixed_pwr_button); +EXPORT_SYMBOL(acpi_fixed_sleep_button); + #define ACPI_BUS_CLASS "system_bus" @@ -900,10 +907,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 +921,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 Tue May 4 21:54:43 2004 +++ b/drivers/acpi/thermal.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/drivers/acpi/toshiba_acpi.c Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/include/acpi/acpiosxf.h Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/include/asm-i386/acpi.h Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/include/asm-ia64/acpi.h Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/include/asm-x86_64/acpi.h Tue May 4 21:54:43 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 Tue May 4 21:54:43 2004 +++ b/include/linux/acpi.h Tue May 4 21:54:43 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;