diff options
Diffstat (limited to 'arch/x86/kernel/hpet.c')
-rw-r--r-- | arch/x86/kernel/hpet.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index cd759ad90690..a00545fe5cdd 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -269,6 +269,8 @@ static void hpet_set_mode(enum clock_event_mode mode, | |||
269 | now = hpet_readl(HPET_COUNTER); | 269 | now = hpet_readl(HPET_COUNTER); |
270 | cmp = now + (unsigned long) delta; | 270 | cmp = now + (unsigned long) delta; |
271 | cfg = hpet_readl(HPET_Tn_CFG(timer)); | 271 | cfg = hpet_readl(HPET_Tn_CFG(timer)); |
272 | /* Make sure we use edge triggered interrupts */ | ||
273 | cfg &= ~HPET_TN_LEVEL; | ||
272 | cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | | 274 | cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | |
273 | HPET_TN_SETVAL | HPET_TN_32BIT; | 275 | HPET_TN_SETVAL | HPET_TN_32BIT; |
274 | hpet_writel(cfg, HPET_Tn_CFG(timer)); | 276 | hpet_writel(cfg, HPET_Tn_CFG(timer)); |
@@ -628,11 +630,12 @@ static int hpet_cpuhp_notify(struct notifier_block *n, | |||
628 | 630 | ||
629 | switch (action & 0xf) { | 631 | switch (action & 0xf) { |
630 | case CPU_ONLINE: | 632 | case CPU_ONLINE: |
631 | INIT_DELAYED_WORK(&work.work, hpet_work); | 633 | INIT_DELAYED_WORK_ON_STACK(&work.work, hpet_work); |
632 | init_completion(&work.complete); | 634 | init_completion(&work.complete); |
633 | /* FIXME: add schedule_work_on() */ | 635 | /* FIXME: add schedule_work_on() */ |
634 | schedule_delayed_work_on(cpu, &work.work, 0); | 636 | schedule_delayed_work_on(cpu, &work.work, 0); |
635 | wait_for_completion(&work.complete); | 637 | wait_for_completion(&work.complete); |
638 | destroy_timer_on_stack(&work.work.timer); | ||
636 | break; | 639 | break; |
637 | case CPU_DEAD: | 640 | case CPU_DEAD: |
638 | if (hdev) { | 641 | if (hdev) { |
@@ -896,7 +899,7 @@ static unsigned long hpet_rtc_flags; | |||
896 | static int hpet_prev_update_sec; | 899 | static int hpet_prev_update_sec; |
897 | static struct rtc_time hpet_alarm_time; | 900 | static struct rtc_time hpet_alarm_time; |
898 | static unsigned long hpet_pie_count; | 901 | static unsigned long hpet_pie_count; |
899 | static unsigned long hpet_t1_cmp; | 902 | static u32 hpet_t1_cmp; |
900 | static unsigned long hpet_default_delta; | 903 | static unsigned long hpet_default_delta; |
901 | static unsigned long hpet_pie_delta; | 904 | static unsigned long hpet_pie_delta; |
902 | static unsigned long hpet_pie_limit; | 905 | static unsigned long hpet_pie_limit; |
@@ -904,6 +907,14 @@ static unsigned long hpet_pie_limit; | |||
904 | static rtc_irq_handler irq_handler; | 907 | static rtc_irq_handler irq_handler; |
905 | 908 | ||
906 | /* | 909 | /* |
910 | * Check that the hpet counter c1 is ahead of the c2 | ||
911 | */ | ||
912 | static inline int hpet_cnt_ahead(u32 c1, u32 c2) | ||
913 | { | ||
914 | return (s32)(c2 - c1) < 0; | ||
915 | } | ||
916 | |||
917 | /* | ||
907 | * Registers a IRQ handler. | 918 | * Registers a IRQ handler. |
908 | */ | 919 | */ |
909 | int hpet_register_irq_handler(rtc_irq_handler handler) | 920 | int hpet_register_irq_handler(rtc_irq_handler handler) |
@@ -1074,7 +1085,7 @@ static void hpet_rtc_timer_reinit(void) | |||
1074 | hpet_t1_cmp += delta; | 1085 | hpet_t1_cmp += delta; |
1075 | hpet_writel(hpet_t1_cmp, HPET_T1_CMP); | 1086 | hpet_writel(hpet_t1_cmp, HPET_T1_CMP); |
1076 | lost_ints++; | 1087 | lost_ints++; |
1077 | } while ((long)(hpet_readl(HPET_COUNTER) - hpet_t1_cmp) > 0); | 1088 | } while (!hpet_cnt_ahead(hpet_t1_cmp, hpet_readl(HPET_COUNTER))); |
1078 | 1089 | ||
1079 | if (lost_ints) { | 1090 | if (lost_ints) { |
1080 | if (hpet_rtc_flags & RTC_PIE) | 1091 | if (hpet_rtc_flags & RTC_PIE) |