aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2006-07-10 07:45:05 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-10 16:24:23 -0400
commitaceb343464a136e1c0de5294b097a1f9ab018870 (patch)
treedb42e6d7b059948b3ef0d957fb9dcc87462c7fd3 /arch/um
parent598d188af1a0645dc75c9541eff0017a4f6d9987 (diff)
[PATCH] uml: timer initialization cleanup
This cleans up the mess that is the timer initialization. There used to be two timer handlers - one that basically ran during delay loop calibration and one that handled the timer afterwards. There were also two sets of timer initialization code - one that starts in user code and calls into the kernel side of the house, and one that starts in kernel code and calls user code. This eliminates one timer handler and consolidates the two sets of initialization code. [akpm@osdl.org: use new INTF_ flags] Signed-off-by: Jeff Dike <jdike@addtoit.com> Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/include/kern_util.h1
-rw-r--r--arch/um/kernel/time_kern.c64
-rw-r--r--arch/um/os-Linux/irq.c11
-rw-r--r--arch/um/os-Linux/signal.c23
-rw-r--r--arch/um/os-Linux/time.c16
5 files changed, 30 insertions, 85 deletions
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 310980b32173..7a64190c1e53 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -75,7 +75,6 @@ extern int hz(void);
75extern void uml_idle_timer(void); 75extern void uml_idle_timer(void);
76extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs); 76extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
77extern int external_pid(void *t); 77extern int external_pid(void *t);
78extern void boot_timer_handler(int sig);
79extern void interrupt_end(void); 78extern void interrupt_end(void);
80extern void initial_thread_cb(void (*proc)(void *), void *arg); 79extern void initial_thread_cb(void (*proc)(void *), void *arg);
81extern int debugger_signal(int status, int pid); 80extern int debugger_signal(int status, int pid);
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
index d7e044b5e5ee..8e56c58320ba 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time_kern.c
@@ -84,29 +84,6 @@ void timer_irq(union uml_pt_regs *regs)
84 } 84 }
85} 85}
86 86
87
88void time_init_kern(void)
89{
90 long long nsecs;
91
92 nsecs = os_nsecs();
93 set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
94 -nsecs % BILLION);
95}
96
97void do_boot_timer_handler(struct sigcontext * sc)
98{
99 unsigned long flags;
100 struct pt_regs regs;
101
102 CHOOSE_MODE((void) (UPT_SC(&regs.regs) = sc),
103 (void) (regs.regs.skas.is_user = 0));
104
105 write_seqlock_irqsave(&xtime_lock, flags);
106 do_timer(&regs);
107 write_sequnlock_irqrestore(&xtime_lock, flags);
108}
109
110static DEFINE_SPINLOCK(timer_spinlock); 87static DEFINE_SPINLOCK(timer_spinlock);
111 88
112static unsigned long long local_offset = 0; 89static unsigned long long local_offset = 0;
@@ -142,6 +119,32 @@ irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
142 return IRQ_HANDLED; 119 return IRQ_HANDLED;
143} 120}
144 121
122static void register_timer(void)
123{
124 int err;
125
126 err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
127 if(err != 0)
128 printk(KERN_ERR "timer_init : request_irq failed - "
129 "errno = %d\n", -err);
130
131 timer_irq_inited = 1;
132
133 user_time_init();
134}
135
136extern void (*late_time_init)(void);
137
138void time_init(void)
139{
140 long long nsecs;
141
142 nsecs = os_nsecs();
143 set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
144 -nsecs % BILLION);
145 late_time_init = register_timer;
146}
147
145void do_gettimeofday(struct timeval *tv) 148void do_gettimeofday(struct timeval *tv)
146{ 149{
147 unsigned long long nsecs = get_time(); 150 unsigned long long nsecs = get_time();
@@ -189,18 +192,3 @@ void timer_handler(int sig, union uml_pt_regs *regs)
189 if(current_thread->cpu == 0) 192 if(current_thread->cpu == 0)
190 timer_irq(regs); 193 timer_irq(regs);
191} 194}
192
193int __init timer_init(void)
194{
195 int err;
196
197 user_time_init();
198 err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
199 if(err != 0)
200 printk(KERN_ERR "timer_init : request_irq failed - "
201 "errno = %d\n", -err);
202 timer_irq_inited = 1;
203 return(0);
204}
205
206arch_initcall(timer_init);
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index 3788d4568d33..64c114b02701 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -142,17 +142,14 @@ void os_set_ioignore(void)
142 142
143void init_irq_signals(int on_sigstack) 143void init_irq_signals(int on_sigstack)
144{ 144{
145 __sighandler_t h;
146 int flags; 145 int flags;
147 146
148 flags = on_sigstack ? SA_ONSTACK : 0; 147 flags = on_sigstack ? SA_ONSTACK : 0;
149 if (timer_irq_inited)
150 h = (__sighandler_t)alarm_handler;
151 else
152 h = boot_timer_handler;
153 148
154 set_handler(SIGVTALRM, h, flags | SA_RESTART, 149 set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
155 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); 150 flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
151 set_handler(SIGALRM, (__sighandler_t) alarm_handler,
152 flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
156 set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART, 153 set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
157 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 154 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
158 signal(SIGWINCH, SIG_IGN); 155 signal(SIGWINCH, SIG_IGN);
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index f11b3124a0c8..60e4faedf254 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -106,29 +106,6 @@ void alarm_handler(ARCH_SIGHDLR_PARAM)
106 set_signals(enabled); 106 set_signals(enabled);
107} 107}
108 108
109extern void do_boot_timer_handler(struct sigcontext * sc);
110
111void boot_timer_handler(ARCH_SIGHDLR_PARAM)
112{
113 struct sigcontext *sc;
114 int enabled;
115
116 ARCH_GET_SIGCONTEXT(sc, sig);
117
118 enabled = signals_enabled;
119 if(!enabled){
120 if(sig == SIGVTALRM)
121 pending |= SIGVTALRM_MASK;
122 else pending |= SIGALRM_MASK;
123 return;
124 }
125
126 block_signals();
127
128 do_boot_timer_handler(sc);
129 set_signals(enabled);
130}
131
132void set_sigstack(void *sig_stack, int size) 109void set_sigstack(void *sig_stack, int size)
133{ 110{
134 stack_t stack = ((stack_t) { .ss_flags = 0, 111 stack_t stack = ((stack_t) { .ss_flags = 0,
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 280c4fb9b585..beb7f9666de3 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -81,14 +81,6 @@ void uml_idle_timer(void)
81 set_interval(ITIMER_REAL); 81 set_interval(ITIMER_REAL);
82} 82}
83 83
84void time_init(void)
85{
86 if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
87 panic("Couldn't set SIGVTALRM handler");
88 set_interval(ITIMER_VIRTUAL);
89 time_init_kern();
90}
91
92unsigned long long os_nsecs(void) 84unsigned long long os_nsecs(void)
93{ 85{
94 struct timeval tv; 86 struct timeval tv;
@@ -106,15 +98,7 @@ void idle_sleep(int secs)
106 nanosleep(&ts, NULL); 98 nanosleep(&ts, NULL);
107} 99}
108 100
109/* XXX This partly duplicates init_irq_signals */
110
111void user_time_init(void) 101void user_time_init(void)
112{ 102{
113 set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
114 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
115 SIGALRM, SIGUSR2, -1);
116 set_handler(SIGALRM, (__sighandler_t) alarm_handler,
117 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH,
118 SIGVTALRM, SIGUSR2, -1);
119 set_interval(ITIMER_VIRTUAL); 103 set_interval(ITIMER_VIRTUAL);
120} 104}