aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/hpet.c
diff options
context:
space:
mode:
authorJens Axboe <jaxboe@fusionio.com>2010-10-19 03:13:04 -0400
committerJens Axboe <jaxboe@fusionio.com>2010-10-19 03:13:04 -0400
commitfa251f89903d73989e2f63e13d0eaed1e07ce0da (patch)
tree3f7fe779941e3b6d67754dd7c44a32f48ea47c74 /arch/x86/kernel/hpet.c
parentdd3932eddf428571762596e17b65f5dc92ca361b (diff)
parentcd07202cc8262e1669edff0d97715f3dd9260917 (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.c33
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 @@
35unsigned long hpet_address; 35unsigned long hpet_address;
36u8 hpet_blockid; /* OS timer block num */ 36u8 hpet_blockid; /* OS timer block num */
37u8 hpet_msi_disable; 37u8 hpet_msi_disable;
38u8 hpet_readback_cmp;
39 38
40#ifdef CONFIG_PCI_MSI 39#ifdef CONFIG_PCI_MSI
41static unsigned long hpet_num_timers; 40static 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