diff options
author | Jens Axboe <jaxboe@fusionio.com> | 2010-10-19 03:13:04 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-10-19 03:13:04 -0400 |
commit | fa251f89903d73989e2f63e13d0eaed1e07ce0da (patch) | |
tree | 3f7fe779941e3b6d67754dd7c44a32f48ea47c74 /arch/x86/kernel/hpet.c | |
parent | dd3932eddf428571762596e17b65f5dc92ca361b (diff) | |
parent | cd07202cc8262e1669edff0d97715f3dd9260917 (diff) |
Merge branch 'v2.6.36-rc8' into for-2.6.37/barrier
Conflicts:
block/blk-core.c
drivers/block/loop.c
mm/swapfile.c
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'arch/x86/kernel/hpet.c')
-rw-r--r-- | arch/x86/kernel/hpet.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 351f9c0fea1f..7494999141b3 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -35,7 +35,6 @@ | |||
35 | unsigned long hpet_address; | 35 | unsigned long hpet_address; |
36 | u8 hpet_blockid; /* OS timer block num */ | 36 | u8 hpet_blockid; /* OS timer block num */ |
37 | u8 hpet_msi_disable; | 37 | u8 hpet_msi_disable; |
38 | u8 hpet_readback_cmp; | ||
39 | 38 | ||
40 | #ifdef CONFIG_PCI_MSI | 39 | #ifdef CONFIG_PCI_MSI |
41 | static unsigned long hpet_num_timers; | 40 | static unsigned long hpet_num_timers; |
@@ -395,23 +394,27 @@ static int hpet_next_event(unsigned long delta, | |||
395 | * at that point and we would wait for the next hpet interrupt | 394 | * at that point and we would wait for the next hpet interrupt |
396 | * forever. We found out that reading the CMP register back | 395 | * forever. We found out that reading the CMP register back |
397 | * forces the transfer so we can rely on the comparison with | 396 | * forces the transfer so we can rely on the comparison with |
398 | * the counter register below. | 397 | * the counter register below. If the read back from the |
398 | * compare register does not match the value we programmed | ||
399 | * then we might have a real hardware problem. We can not do | ||
400 | * much about it here, but at least alert the user/admin with | ||
401 | * a prominent warning. | ||
399 | * | 402 | * |
400 | * That works fine on those ATI chipsets, but on newer Intel | 403 | * An erratum on some chipsets (ICH9,..), results in |
401 | * chipsets (ICH9...) this triggers due to an erratum: Reading | 404 | * comparator read immediately following a write returning old |
402 | * the comparator immediately following a write is returning | 405 | * value. Workaround for this is to read this value second |
403 | * the old value. | 406 | * time, when first read returns old value. |
404 | * | 407 | * |
405 | * We restrict the read back to the affected ATI chipsets (set | 408 | * In fact the write to the comparator register is delayed up |
406 | * by quirks) and also run it with hpet=verbose for debugging | 409 | * to two HPET cycles so the workaround we tried to restrict |
407 | * purposes. | 410 | * the readback to those known to be borked ATI chipsets |
411 | * failed miserably. So we give up on optimizations forever | ||
412 | * and penalize all HPET incarnations unconditionally. | ||
408 | */ | 413 | */ |
409 | if (hpet_readback_cmp || hpet_verbose) { | 414 | if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) { |
410 | u32 cmp = hpet_readl(HPET_Tn_CMP(timer)); | 415 | if (hpet_readl(HPET_Tn_CMP(timer)) != cnt) |
411 | |||
412 | if (cmp != cnt) | ||
413 | printk_once(KERN_WARNING | 416 | printk_once(KERN_WARNING |
414 | "hpet: compare register read back failed.\n"); | 417 | "hpet: compare register read back failed.\n"); |
415 | } | 418 | } |
416 | 419 | ||
417 | return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0; | 420 | return (s32)(hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0; |
@@ -503,7 +506,7 @@ static int hpet_assign_irq(struct hpet_dev *dev) | |||
503 | { | 506 | { |
504 | unsigned int irq; | 507 | unsigned int irq; |
505 | 508 | ||
506 | irq = create_irq(); | 509 | irq = create_irq_nr(0, -1); |
507 | if (!irq) | 510 | if (!irq) |
508 | return -EINVAL; | 511 | return -EINVAL; |
509 | 512 | ||