static long clock_cmos_diff, sleep_start;
 
+static struct timer_opts *last_timer;
 static int timer_suspend(struct sys_device *dev, pm_message_t state)
 {
        /*
        clock_cmos_diff = -get_cmos_time();
        clock_cmos_diff += get_seconds();
        sleep_start = get_cmos_time();
+       last_timer = cur_timer;
+       cur_timer = &timer_none;
+       if (last_timer->suspend)
+               last_timer->suspend(state);
        return 0;
 }
 
        if (is_hpet_enabled())
                hpet_reenable();
 #endif
+       setup_pit_timer();
        sec = get_cmos_time() + clock_cmos_diff;
        sleep_length = (get_cmos_time() - sleep_start) * HZ;
        write_seqlock_irqsave(&xtime_lock, flags);
        write_sequnlock_irqrestore(&xtime_lock, flags);
        jiffies += sleep_length;
        wall_jiffies += sleep_length;
+       if (last_timer->resume)
+               last_timer->resume();
+       cur_timer = last_timer;
+       last_timer = NULL;
        return 0;
 }
 
 
        return 0;
 }
 
+static int hpet_resume(void)
+{
+       write_seqlock(&monotonic_lock);
+       /* Assume this is the last mark offset time */
+       rdtsc(last_tsc_low, last_tsc_high);
+
+       if (hpet_use_timer)
+               hpet_last = hpet_readl(HPET_T0_CMP) - hpet_tick;
+       else
+               hpet_last = hpet_readl(HPET_COUNTER);
+       write_sequnlock(&monotonic_lock);
+       return 0;
+}
 /************************************************************/
 
 /* tsc timer_opts struct */
        .get_offset =           get_offset_hpet,
        .monotonic_clock =      monotonic_clock_hpet,
        .delay =                delay_hpet,
+       .resume =               hpet_resume,
 };
 
 struct init_timer_opts __initdata timer_hpet_init = {
 
        outb(LATCH >> 8 , PIT_CH0);     /* MSB */
        spin_unlock_irqrestore(&i8253_lock, flags);
 }
-
-static int timer_resume(struct sys_device *dev)
-{
-       setup_pit_timer();
-       return 0;
-}
-
-static struct sysdev_class timer_sysclass = {
-       set_kset_name("timer_pit"),
-       .resume = timer_resume,
-};
-
-static struct sys_device device_timer = {
-       .id     = 0,
-       .cls    = &timer_sysclass,
-};
-
-static int __init init_timer_sysfs(void)
-{
-       int error = sysdev_class_register(&timer_sysclass);
-       if (!error)
-               error = sysdev_register(&device_timer);
-       return error;
-}
-
-device_initcall(init_timer_sysfs);
-
 
        }
 }
 
+static int pmtmr_resume(void)
+{
+       write_seqlock(&monotonic_lock);
+       /* Assume this is the last mark offset time */
+       offset_tick = read_pmtmr();
+       write_sequnlock(&monotonic_lock);
+       return 0;
+}
 
 static unsigned long long monotonic_clock_pmtmr(void)
 {
        .monotonic_clock        = monotonic_clock_pmtmr,
        .delay                  = delay_pmtmr,
        .read_timer             = read_timer_tsc,
+       .resume                 = pmtmr_resume,
 };
 
 struct init_timer_opts __initdata timer_pmtmr_init = {
 
        return -ENODEV;
 }
 
+static int tsc_resume(void)
+{
+       write_seqlock(&monotonic_lock);
+       /* Assume this is the last mark offset time */
+       rdtsc(last_tsc_low, last_tsc_high);
+#ifdef CONFIG_HPET_TIMER
+       if (is_hpet_enabled() && hpet_use_timer)
+               hpet_last = hpet_readl(HPET_COUNTER);
+#endif
+       write_sequnlock(&monotonic_lock);
+       return 0;
+}
+
 #ifndef CONFIG_X86_TSC
 /* disable flag for tsc.  Takes effect by clearing the TSC cpu flag
  * in cpu/common.c */
        .monotonic_clock = monotonic_clock_tsc,
        .delay = delay_tsc,
        .read_timer = read_timer_tsc,
+       .resume = tsc_resume,
 };
 
 struct init_timer_opts __initdata timer_tsc_init = {
 
 #ifndef _ASMi386_TIMER_H
 #define _ASMi386_TIMER_H
 #include <linux/init.h>
+#include <linux/pm.h>
 
 /**
  * struct timer_ops - used to define a timer source
        unsigned long long (*monotonic_clock)(void);
        void (*delay)(unsigned long);
        unsigned long (*read_timer)(void);
+       int (*suspend)(pm_message_t state);
+       int (*resume)(void);
 };
 
 struct init_timer_opts {