rk29: add hr_msleep/hr_msleep_interruptible/usleep
author黄涛 <huangtao@rock-chips.com>
Fri, 22 Jul 2011 08:19:53 +0000 (16:19 +0800)
committer黄涛 <huangtao@rock-chips.com>
Fri, 22 Jul 2011 08:20:36 +0000 (16:20 +0800)
include/linux/delay.h
kernel/timer.c

index a6ecb34cf547da29ad16edf8b109de2511d10cd5..b39e4c9703d019d6f60a89d29027fe006d3c349d 100644 (file)
@@ -52,4 +52,13 @@ static inline void ssleep(unsigned int seconds)
        msleep(seconds * 1000);
 }
 
+#ifdef CONFIG_ARCH_RK29
+void hr_msleep(unsigned int msecs);
+unsigned long hr_msleep_interruptible(unsigned int msecs);
+
+static inline void usleep(unsigned long usecs)
+{
+       usleep_range(usecs, usecs);
+}
+#endif /* CONFIG_ARCH_RK29 */
 #endif /* defined(_LINUX_DELAY_H) */
index 0015407e18b16c1254bedb07b795b985a45f9820..289419bdd4cd1c4220df219ac9c6b1e27b24e0d0 100644 (file)
@@ -1712,3 +1712,62 @@ void usleep_range(unsigned long min, unsigned long max)
        do_usleep_range(min, max);
 }
 EXPORT_SYMBOL(usleep_range);
+
+#ifdef CONFIG_ARCH_RK29
+static void do_nsleep(unsigned int nsecs, struct hrtimer_sleeper *sleeper,
+       int sigs)
+{
+       enum hrtimer_mode mode = HRTIMER_MODE_REL;
+       int state = sigs ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE;
+
+       /*
+        * This is really just a reworked and simplified version
+        * of do_nanosleep().
+        */
+       hrtimer_init(&sleeper->timer, CLOCK_MONOTONIC, mode);
+       sleeper->timer._expires = ktime_set(0, nsecs);
+       hrtimer_init_sleeper(sleeper, current);
+
+       do {
+               set_current_state(state);
+               hrtimer_start(&sleeper->timer, sleeper->timer._expires, mode);
+               if (sleeper->task)
+                       schedule();
+               hrtimer_cancel(&sleeper->timer);
+               mode = HRTIMER_MODE_ABS;
+       } while (sleeper->task && !(sigs && signal_pending(current)));
+}
+
+/**
+ * msleep - sleep safely even with waitqueue interruptions
+ * @msecs: Time in milliseconds to sleep for
+ */
+void hr_msleep(unsigned int msecs)
+{
+       struct hrtimer_sleeper sleeper;
+
+       do_nsleep(msecs * NSEC_PER_MSEC, &sleeper, 0);
+}
+
+EXPORT_SYMBOL(hr_msleep);
+
+/**
+ * msleep_interruptible - sleep waiting for signals
+ * @msecs: Time in milliseconds to sleep for
+ */
+unsigned long hr_msleep_interruptible(unsigned int msecs)
+{
+       struct hrtimer_sleeper sleeper;
+       ktime_t left;
+
+       do_nsleep(msecs * NSEC_PER_MSEC, &sleeper, 1);
+
+       if (!sleeper.task)
+               return 0;
+       left = ktime_sub(sleeper.timer._expires,
+                        sleeper.timer.base->get_time());
+       return max(((long) ktime_to_ns(left))/(long)NSEC_PER_MSEC, 1L);
+}
+
+EXPORT_SYMBOL(hr_msleep_interruptible);
+#endif /* CONFIG_ARCH_RK29 */