From: Andi Kleen <ak@suse.de>
To: Andrew Morton <akpm@osdl.org>
Cc: torvalds@osdl.org, linux-kernel@vger.kernel.org,
Chuck Ebbert <76306.1226@compuserve.com>
Subject: Re: [patch] i386: port ATI timer fix from x86_64 to i386 II
Date: Thu, 2 Mar 2006 06:02:59 +0100 [thread overview]
Message-ID: <200603020603.00210.ak@suse.de> (raw)
In-Reply-To: <20060301025219.2034924c.akpm@osdl.org>
On Wednesday 01 March 2006 11:52, Andrew Morton wrote:
> Well.. the patch had a flagrant won't-compile if CONFIG_X86_IO_APIC=y, so
> I'd consider it a bit green.
I did my own version of it then. Tested it a bit in various configurations
and it works for me.
I would consider it a 2.6.16 candidate because it fixes an important bug.
Port the x86-64 ATI timer fix over to i386
ATI chipsets tend to generate double timer interrupts for the local
APIC timer when both the 8254 and the IO-APIC timer pins are enabled.
This is because they route it to both and the result is anded
together and the CPU ends up processing it twice.
This patch changes check_timer to disable the 8254 routing
for interruopt 0.
I think it would be safe on all chipsets actually (i tested it on
a couple and it worked everywhere) and Windows seems to do
it in a similar way, but to be conservative this patch only
enables this mode on ATI (and adds options to enable/disable too)
Ported over from a similar x86-64 change.
I reused the ACPI earlyquirk infrastructure for the ATI bridge check, but
tweaked it a bit to work even without ACPI.
Inspired by a patch from Chuck Ebbert, but redone.
Cc: Chuck Ebbert <76306.1226@compuserve.com>
Cc: len.brown@intel.com
Signed-off-by: Andi Kleen <ak@suse.de>
Index: linux/arch/i386/kernel/Makefile
===================================================================
--- linux.orig/arch/i386/kernel/Makefile
+++ linux/arch/i386/kernel/Makefile
@@ -11,7 +11,7 @@ obj-y := process.o semaphore.o signal.o
obj-y += cpu/
obj-y += timers/
-obj-$(CONFIG_ACPI) += acpi/
+obj-y += acpi/
obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o
obj-$(CONFIG_MCA) += mca.o
obj-$(CONFIG_X86_MSR) += msr.o
Index: linux/arch/i386/kernel/acpi/Makefile
===================================================================
--- linux.orig/arch/i386/kernel/acpi/Makefile
+++ linux/arch/i386/kernel/acpi/Makefile
@@ -1,4 +1,4 @@
-obj-y := boot.o
+obj-$(CONFIG_ACPI) += boot.o
obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o
obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o
Index: linux/arch/i386/kernel/acpi/earlyquirk.c
===================================================================
--- linux.orig/arch/i386/kernel/acpi/earlyquirk.c
+++ linux/arch/i386/kernel/acpi/earlyquirk.c
@@ -7,14 +7,22 @@
#include <linux/pci.h>
#include <asm/pci-direct.h>
#include <asm/acpi.h>
+#include <asm/apic.h>
static int __init check_bridge(int vendor, int device)
{
+#ifdef CONFIG_ACPI
/* According to Nvidia all timer overrides are bogus. Just ignore
them all. */
if (vendor == PCI_VENDOR_ID_NVIDIA) {
acpi_skip_timer_override = 1;
}
+#endif
+ if (vendor == PCI_VENDOR_ID_ATI && timer_over_8254 == 1) {
+ timer_over_8254 = 0;
+ printk(KERN_INFO
+ "ATI board detected. Disabling timer routing over 8254.\n");
+ }
return 0;
}
Index: linux/arch/i386/kernel/io_apic.c
===================================================================
--- linux.orig/arch/i386/kernel/io_apic.c
+++ linux/arch/i386/kernel/io_apic.c
@@ -51,6 +51,8 @@ static struct { int pin, apic; } ioapic_
static DEFINE_SPINLOCK(ioapic_lock);
+int timer_over_8254 __initdata = 1;
+
/*
* Is the SiS APIC rmw bug present ?
* -1 = don't know, 0 = no, 1 = yes
@@ -2267,7 +2269,8 @@ static inline void check_timer(void)
apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
init_8259A(1);
timer_ack = 1;
- enable_8259A_irq(0);
+ if (timer_over_8254 > 0)
+ enable_8259A_irq(0);
pin1 = find_isa_irq_pin(0, mp_INT);
apic1 = find_isa_irq_apic(0, mp_INT);
@@ -2392,6 +2395,20 @@ void __init setup_IO_APIC(void)
print_IO_APIC();
}
+static int __init setup_disable_8254_timer(char *s)
+{
+ timer_over_8254 = -1;
+ return 1;
+}
+static int __init setup_enable_8254_timer(char *s)
+{
+ timer_over_8254 = 2;
+ return 1;
+}
+
+__setup("disable_8254_timer", setup_disable_8254_timer);
+__setup("enable_8254_timer", setup_enable_8254_timer);
+
/*
* Called after all the initialization is done. If we didnt find any
* APIC bugs then we can allow the modify fast path
Index: linux/include/asm-i386/apic.h
===================================================================
--- linux.orig/include/asm-i386/apic.h
+++ linux/include/asm-i386/apic.h
@@ -137,6 +137,8 @@ void switch_APIC_timer_to_ipi(void *cpum
void switch_ipi_to_APIC_timer(void *cpumask);
#define ARCH_APICTIMER_STOPS_ON_C3 1
+extern int timer_over_8254;
+
#else /* !CONFIG_X86_LOCAL_APIC */
static inline void lapic_shutdown(void) { }
Index: linux/Documentation/i386/boot-options.txt
===================================================================
--- /dev/null
+++ linux/Documentation/i386/boot-options.txt
@@ -0,0 +1,8 @@
+
+Some i386 specific boot options
+
+ disable_8254_timer / enable_8254_timer
+ Enable interrupt 0 timer routing over the 8254 in addition to
+ over the IO-APIC. The kernel tries to set a sensible default.
+
+
Index: linux/arch/i386/kernel/acpi/boot.c
===================================================================
--- linux.orig/arch/i386/kernel/acpi/boot.c
+++ linux/arch/i386/kernel/acpi/boot.c
@@ -1111,9 +1111,6 @@ int __init acpi_boot_table_init(void)
disable_acpi();
return error;
}
-#ifdef __i386__
- check_acpi_pci();
-#endif
acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
Index: linux/arch/i386/kernel/setup.c
===================================================================
--- linux.orig/arch/i386/kernel/setup.c
+++ linux/arch/i386/kernel/setup.c
@@ -1599,6 +1599,10 @@ void __init setup_arch(char **cmdline_p)
if (efi_enabled)
efi_map_memmap();
+#ifdef CONFIG_X86_IO_APIC
+ check_acpi_pci(); /* Checks more than just ACPI actually */
+#endif
+
#ifdef CONFIG_ACPI
/*
* Parse the ACPI tables for possible boot-time SMP configuration.
prev parent reply other threads:[~2006-03-02 5:03 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-03-01 0:03 [patch] i386: port ATI timer fix from x86_64 to i386 Chuck Ebbert
2006-03-01 0:15 ` Andrew Morton
2006-03-01 10:40 ` Andi Kleen
2006-03-01 10:52 ` Andrew Morton
2006-03-01 11:07 ` Andi Kleen
2006-03-02 5:02 ` Andi Kleen [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200603020603.00210.ak@suse.de \
--to=ak@suse.de \
--cc=76306.1226@compuserve.com \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.