aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/kernel')
-rw-r--r--arch/um/kernel/process.c3
-rw-r--r--arch/um/kernel/time.c45
2 files changed, 13 insertions, 35 deletions
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 56d75afedbf7..aef494b6b81a 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -13,6 +13,7 @@
13#include "linux/ptrace.h" 13#include "linux/ptrace.h"
14#include "linux/random.h" 14#include "linux/random.h"
15#include "linux/sched.h" 15#include "linux/sched.h"
16#include "linux/tick.h"
16#include "linux/threads.h" 17#include "linux/threads.h"
17#include "asm/pgtable.h" 18#include "asm/pgtable.h"
18#include "asm/uaccess.h" 19#include "asm/uaccess.h"
@@ -244,9 +245,11 @@ void default_idle(void)
244 if (need_resched()) 245 if (need_resched())
245 schedule(); 246 schedule();
246 247
248 tick_nohz_stop_sched_tick();
247 switch_timers(1); 249 switch_timers(1);
248 idle_sleep(10); 250 idle_sleep(10);
249 switch_timers(0); 251 switch_timers(0);
252 tick_nohz_restart_sched_tick();
250 } 253 }
251} 254}
252 255
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 3cb7135e5c47..2acdc7efb2ac 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -20,41 +20,12 @@ unsigned long long sched_clock(void)
20 return (unsigned long long)jiffies_64 * (1000000000 / HZ); 20 return (unsigned long long)jiffies_64 * (1000000000 / HZ);
21} 21}
22 22
23#ifdef CONFIG_UML_REAL_TIME_CLOCK
24static unsigned long long prev_nsecs[NR_CPUS];
25static long long delta[NR_CPUS]; /* Deviation per interval */
26#endif
27
28void timer_handler(int sig, struct uml_pt_regs *regs) 23void timer_handler(int sig, struct uml_pt_regs *regs)
29{ 24{
30 unsigned long long ticks = 0;
31 unsigned long flags; 25 unsigned long flags;
32#ifdef CONFIG_UML_REAL_TIME_CLOCK
33 int c = cpu();
34 if (prev_nsecs[c]) {
35 /* We've had 1 tick */
36 unsigned long long nsecs = os_nsecs();
37
38 delta[c] += nsecs - prev_nsecs[c];
39 prev_nsecs[c] = nsecs;
40
41 /* Protect against the host clock being set backwards */
42 if (delta[c] < 0)
43 delta[c] = 0;
44
45 ticks += (delta[c] * HZ) / BILLION;
46 delta[c] -= (ticks * BILLION) / HZ;
47 }
48 else prev_nsecs[c] = os_nsecs();
49#else
50 ticks = 1;
51#endif
52 26
53 local_irq_save(flags); 27 local_irq_save(flags);
54 while (ticks > 0) { 28 do_IRQ(TIMER_IRQ, regs);
55 do_IRQ(TIMER_IRQ, regs);
56 ticks--;
57 }
58 local_irq_restore(flags); 29 local_irq_restore(flags);
59} 30}
60 31
@@ -68,10 +39,8 @@ static void itimer_set_mode(enum clock_event_mode mode,
68 39
69 case CLOCK_EVT_MODE_SHUTDOWN: 40 case CLOCK_EVT_MODE_SHUTDOWN:
70 case CLOCK_EVT_MODE_UNUSED: 41 case CLOCK_EVT_MODE_UNUSED:
71 disable_timer();
72 break;
73 case CLOCK_EVT_MODE_ONESHOT: 42 case CLOCK_EVT_MODE_ONESHOT:
74 BUG(); 43 disable_timer();
75 break; 44 break;
76 45
77 case CLOCK_EVT_MODE_RESUME: 46 case CLOCK_EVT_MODE_RESUME:
@@ -79,13 +48,19 @@ static void itimer_set_mode(enum clock_event_mode mode,
79 } 48 }
80} 49}
81 50
51static int itimer_next_event(unsigned long delta,
52 struct clock_event_device *evt)
53{
54 return timer_one_shot(delta + 1);
55}
56
82static struct clock_event_device itimer_clockevent = { 57static struct clock_event_device itimer_clockevent = {
83 .name = "itimer", 58 .name = "itimer",
84 .rating = 250, 59 .rating = 250,
85 .cpumask = CPU_MASK_ALL, 60 .cpumask = CPU_MASK_ALL,
86 .features = CLOCK_EVT_FEAT_PERIODIC, 61 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
87 .set_mode = itimer_set_mode, 62 .set_mode = itimer_set_mode,
88 .set_next_event = NULL, 63 .set_next_event = itimer_next_event,
89 .shift = 32, 64 .shift = 32,
90 .irq = 0, 65 .irq = 0,
91}; 66};