diff options
author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-08-19 23:50:39 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-16 10:52:55 -0400 |
commit | f876d213a59c363d2492e399cc6c24edd6f3c368 (patch) | |
tree | c9c9bbe98e03ecf4625ee97b527ba20418c5bd46 /arch | |
parent | d4057bdb6a3bb85dd44f9f39f41eac53696fd637 (diff) |
x86: make 64 handle sis_apic_bug like the 32 bit
do we have 64bit system with sis chipset?
[ mingo@elte.hu: nope, the problem chipset was 32-bit only.
The code symmetry is good nevertheless. ]
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/io_apic_64.c | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c index 3c66e5a8e899..915af9b87aa4 100644 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c | |||
@@ -65,7 +65,11 @@ | |||
65 | 65 | ||
66 | int ioapic_force; | 66 | int ioapic_force; |
67 | 67 | ||
68 | int sis_apic_bug; /* not actually supported, dummy for compile */ | 68 | /* |
69 | * Is the SiS APIC rmw bug present ? | ||
70 | * -1 = don't know, 0 = no, 1 = yes | ||
71 | */ | ||
72 | int sis_apic_bug = -1; | ||
69 | 73 | ||
70 | static DEFINE_SPINLOCK(ioapic_lock); | 74 | static DEFINE_SPINLOCK(ioapic_lock); |
71 | static DEFINE_SPINLOCK(vector_lock); | 75 | static DEFINE_SPINLOCK(vector_lock); |
@@ -373,9 +377,11 @@ static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned i | |||
373 | * Re-write a value: to be used for read-modify-write | 377 | * Re-write a value: to be used for read-modify-write |
374 | * cycles where the read already set up the index register. | 378 | * cycles where the read already set up the index register. |
375 | */ | 379 | */ |
376 | static inline void io_apic_modify(unsigned int apic, unsigned int value) | 380 | static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) |
377 | { | 381 | { |
378 | struct io_apic __iomem *io_apic = io_apic_base(apic); | 382 | struct io_apic __iomem *io_apic = io_apic_base(apic); |
383 | if (sis_apic_bug) | ||
384 | writel(reg, &io_apic->index); | ||
379 | writel(value, &io_apic->data); | 385 | writel(value, &io_apic->data); |
380 | } | 386 | } |
381 | 387 | ||
@@ -494,7 +500,7 @@ static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, u8 vector) | |||
494 | reg = io_apic_read(apic, 0x10 + pin*2); | 500 | reg = io_apic_read(apic, 0x10 + pin*2); |
495 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; | 501 | reg &= ~IO_APIC_REDIR_VECTOR_MASK; |
496 | reg |= vector; | 502 | reg |= vector; |
497 | io_apic_modify(apic, reg); | 503 | io_apic_modify(apic, 0x10 + pin*2, reg); |
498 | if (!entry->next) | 504 | if (!entry->next) |
499 | break; | 505 | break; |
500 | entry = entry->next; | 506 | entry = entry->next; |
@@ -624,7 +630,7 @@ static inline void io_apic_sync(unsigned int apic) | |||
624 | pin = entry->pin; \ | 630 | pin = entry->pin; \ |
625 | reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \ | 631 | reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \ |
626 | reg ACTION; \ | 632 | reg ACTION; \ |
627 | io_apic_modify(entry->apic, reg); \ | 633 | io_apic_modify(entry->apic, 0x10 + R + pin*2, reg); \ |
628 | FINAL; \ | 634 | FINAL; \ |
629 | if (!entry->next) \ | 635 | if (!entry->next) \ |
630 | break; \ | 636 | break; \ |
@@ -2450,6 +2456,20 @@ void __init setup_IO_APIC(void) | |||
2450 | check_timer(); | 2456 | check_timer(); |
2451 | } | 2457 | } |
2452 | 2458 | ||
2459 | /* | ||
2460 | * Called after all the initialization is done. If we didnt find any | ||
2461 | * APIC bugs then we can allow the modify fast path | ||
2462 | */ | ||
2463 | |||
2464 | static int __init io_apic_bug_finalize(void) | ||
2465 | { | ||
2466 | if (sis_apic_bug == -1) | ||
2467 | sis_apic_bug = 0; | ||
2468 | return 0; | ||
2469 | } | ||
2470 | |||
2471 | late_initcall(io_apic_bug_finalize); | ||
2472 | |||
2453 | struct sysfs_ioapic_data { | 2473 | struct sysfs_ioapic_data { |
2454 | struct sys_device dev; | 2474 | struct sys_device dev; |
2455 | struct IO_APIC_route_entry entry[0]; | 2475 | struct IO_APIC_route_entry entry[0]; |