#include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/init.h>
-#include <linux/timer.h>
+#include <linux/hrtimer.h>
 #include <linux/list.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 struct dummy_hcd {
        struct dummy                    *dum;
        enum dummy_rh_state             rh_state;
-       struct timer_list               timer;
+       struct hrtimer                  timer;
        u32                             port_status;
        u32                             old_status;
        unsigned long                   re_timeout;
                urb->error_count = 1;           /* mark as a new urb */
 
        /* kick the scheduler, it'll do the rest */
-       if (!timer_pending(&dum_hcd->timer))
-               mod_timer(&dum_hcd->timer, jiffies + 1);
+       if (!hrtimer_active(&dum_hcd->timer))
+               hrtimer_start(&dum_hcd->timer, ms_to_ktime(1), HRTIMER_MODE_REL);
 
  done:
        spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
        rc = usb_hcd_check_unlink_urb(hcd, urb, status);
        if (!rc && dum_hcd->rh_state != DUMMY_RH_RUNNING &&
                        !list_empty(&dum_hcd->urbp_list))
-               mod_timer(&dum_hcd->timer, jiffies);
+               hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL);
 
        spin_unlock_irqrestore(&dum_hcd->dum->lock, flags);
        return rc;
  * drivers except that the callbacks are invoked from soft interrupt
  * context.
  */
-static void dummy_timer(struct timer_list *t)
+static enum hrtimer_restart dummy_timer(struct hrtimer *t)
 {
        struct dummy_hcd        *dum_hcd = from_timer(dum_hcd, t, timer);
        struct dummy            *dum = dum_hcd->dum;
                break;
        }
 
-       /* FIXME if HZ != 1000 this will probably misbehave ... */
-
        /* look at each urb queued by the host side driver */
        spin_lock_irqsave(&dum->lock, flags);
 
                dev_err(dummy_dev(dum_hcd),
                                "timer fired with no URBs pending?\n");
                spin_unlock_irqrestore(&dum->lock, flags);
-               return;
+               return HRTIMER_NORESTART;
        }
        dum_hcd->next_frame_urbp = NULL;
 
                dum_hcd->udev = NULL;
        } else if (dum_hcd->rh_state == DUMMY_RH_RUNNING) {
                /* want a 1 msec delay here */
-               mod_timer(&dum_hcd->timer, jiffies + msecs_to_jiffies(1));
+               hrtimer_start(&dum_hcd->timer, ms_to_ktime(1), HRTIMER_MODE_REL);
        }
 
        spin_unlock_irqrestore(&dum->lock, flags);
+
+       return HRTIMER_NORESTART;
 }
 
 /*-------------------------------------------------------------------------*/
                dum_hcd->rh_state = DUMMY_RH_RUNNING;
                set_link_state(dum_hcd);
                if (!list_empty(&dum_hcd->urbp_list))
-                       mod_timer(&dum_hcd->timer, jiffies);
+                       hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL);
                hcd->state = HC_STATE_RUNNING;
        }
        spin_unlock_irq(&dum_hcd->dum->lock);
 
 static int dummy_start_ss(struct dummy_hcd *dum_hcd)
 {
-       timer_setup(&dum_hcd->timer, dummy_timer, 0);
+       hrtimer_init(&dum_hcd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       dum_hcd->timer.function = dummy_timer;
        dum_hcd->rh_state = DUMMY_RH_RUNNING;
        dum_hcd->stream_en_ep = 0;
        INIT_LIST_HEAD(&dum_hcd->urbp_list);
                return dummy_start_ss(dum_hcd);
 
        spin_lock_init(&dum_hcd->dum->lock);
-       timer_setup(&dum_hcd->timer, dummy_timer, 0);
+       hrtimer_init(&dum_hcd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       dum_hcd->timer.function = dummy_timer;
        dum_hcd->rh_state = DUMMY_RH_RUNNING;
 
        INIT_LIST_HEAD(&dum_hcd->urbp_list);
 
 static void dummy_stop(struct usb_hcd *hcd)
 {
-       device_remove_file(dummy_dev(hcd_to_dummy_hcd(hcd)), &dev_attr_urbs);
-       dev_info(dummy_dev(hcd_to_dummy_hcd(hcd)), "stopped\n");
+       struct dummy_hcd        *dum_hcd = hcd_to_dummy_hcd(hcd);
+
+       hrtimer_cancel(&dum_hcd->timer);
+       device_remove_file(dummy_dev(dum_hcd), &dev_attr_urbs);
+       dev_info(dummy_dev(dum_hcd), "stopped\n");
 }
 
 /*-------------------------------------------------------------------------*/