| From 18ed61da985c57eea3fe8038b13fa2837c9b3c3f Mon Sep 17 00:00:00 2001 |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Fri, 27 Nov 2009 15:24:44 +0100 |
| Subject: x86: hpet: Make WARN_ON understandable |
| |
| From: Thomas Gleixner <tglx@linutronix.de> |
| |
| commit 18ed61da985c57eea3fe8038b13fa2837c9b3c3f upstream. |
| |
| Andrew complained rightly that the WARN_ON in hpet_next_event() is |
| confusing and the code comment not really helpful. |
| |
| Change it to WARN_ONCE and print the reason in clear text. Change the |
| comment to explain what kind of hardware wreckage we deal with. |
| |
| Pointed-out-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Cc: Venki Pallipadi <venkatesh.pallipadi@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| arch/x86/kernel/hpet.c | 19 +++++++++++++++---- |
| 1 file changed, 15 insertions(+), 4 deletions(-) |
| |
| --- a/arch/x86/kernel/hpet.c |
| +++ b/arch/x86/kernel/hpet.c |
| @@ -385,11 +385,22 @@ static int hpet_next_event(unsigned long |
| hpet_writel(cnt, HPET_Tn_CMP(timer)); |
| |
| /* |
| - * We need to read back the CMP register to make sure that |
| - * what we wrote hit the chip before we compare it to the |
| - * counter. |
| + * We need to read back the CMP register on certain HPET |
| + * implementations (ATI chipsets) which seem to delay the |
| + * transfer of the compare register into the internal compare |
| + * logic. With small deltas this might actually be too late as |
| + * the counter could already be higher than the compare value |
| + * at that point and we would wait for the next hpet interrupt |
| + * forever. We found out that reading the CMP register back |
| + * forces the transfer so we can rely on the comparison with |
| + * the counter register below. If the read back from the |
| + * compare register does not match the value we programmed |
| + * then we might have a real hardware problem. We can not do |
| + * much about it here, but at least alert the user/admin with |
| + * a prominent warning. |
| */ |
| - WARN_ON_ONCE((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt); |
| + WARN_ONCE((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt, |
| + KERN_WARNING "hpet: compare register read back failed.\n"); |
| |
| return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0; |
| } |