aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/kernel/irq.c')
-rw-r--r--arch/um/kernel/irq.c62
1 files changed, 19 insertions, 43 deletions
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index bfd0bdc8cd40..589c69a75043 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -110,18 +110,7 @@ void sigio_handler(int sig, union uml_pt_regs *regs)
110 free_irqs(); 110 free_irqs();
111} 111}
112 112
113static void maybe_sigio_broken(int fd, int type) 113static DEFINE_SPINLOCK(irq_lock);
114{
115 if (os_isatty(fd)) {
116 if ((type == IRQ_WRITE) && !pty_output_sigio) {
117 write_sigio_workaround();
118 add_sigio_fd(fd, 0);
119 } else if ((type == IRQ_READ) && !pty_close_sigio) {
120 write_sigio_workaround();
121 add_sigio_fd(fd, 1);
122 }
123 }
124}
125 114
126int activate_fd(int irq, int fd, int type, void *dev_id) 115int activate_fd(int irq, int fd, int type, void *dev_id)
127{ 116{
@@ -166,7 +155,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
166 * this is called only from process context, and can be locked with 155 * this is called only from process context, and can be locked with
167 * a semaphore. 156 * a semaphore.
168 */ 157 */
169 flags = irq_lock(); 158 spin_lock_irqsave(&irq_lock, flags);
170 for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { 159 for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
171 if ((irq_fd->fd == fd) && (irq_fd->type == type)) { 160 if ((irq_fd->fd == fd) && (irq_fd->type == type)) {
172 printk("Registering fd %d twice\n", fd); 161 printk("Registering fd %d twice\n", fd);
@@ -199,7 +188,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
199 * so we will not be able to put new pollfd struct to pollfds 188 * so we will not be able to put new pollfd struct to pollfds
200 * then we free the buffer tmp_fds and try again. 189 * then we free the buffer tmp_fds and try again.
201 */ 190 */
202 irq_unlock(flags); 191 spin_unlock_irqrestore(&irq_lock, flags);
203 kfree(tmp_pfd); 192 kfree(tmp_pfd);
204 tmp_pfd = NULL; 193 tmp_pfd = NULL;
205 194
@@ -207,24 +196,24 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
207 if (tmp_pfd == NULL) 196 if (tmp_pfd == NULL)
208 goto out_kfree; 197 goto out_kfree;
209 198
210 flags = irq_lock(); 199 spin_lock_irqsave(&irq_lock, flags);
211 } 200 }
212 /*-------------*/ 201 /*-------------*/
213 202
214 *last_irq_ptr = new_fd; 203 *last_irq_ptr = new_fd;
215 last_irq_ptr = &new_fd->next; 204 last_irq_ptr = &new_fd->next;
216 205
217 irq_unlock(flags); 206 spin_unlock_irqrestore(&irq_lock, flags);
218 207
219 /* This calls activate_fd, so it has to be outside the critical 208 /* This calls activate_fd, so it has to be outside the critical
220 * section. 209 * section.
221 */ 210 */
222 maybe_sigio_broken(fd, type); 211 maybe_sigio_broken(fd, (type == IRQ_READ));
223 212
224 return(0); 213 return(0);
225 214
226 out_unlock: 215 out_unlock:
227 irq_unlock(flags); 216 spin_unlock_irqrestore(&irq_lock, flags);
228 out_kfree: 217 out_kfree:
229 kfree(new_fd); 218 kfree(new_fd);
230 out: 219 out:
@@ -235,9 +224,9 @@ static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
235{ 224{
236 unsigned long flags; 225 unsigned long flags;
237 226
238 flags = irq_lock(); 227 spin_lock_irqsave(&irq_lock, flags);
239 os_free_irq_by_cb(test, arg, active_fds, &last_irq_ptr); 228 os_free_irq_by_cb(test, arg, active_fds, &last_irq_ptr);
240 irq_unlock(flags); 229 spin_unlock_irqrestore(&irq_lock, flags);
241} 230}
242 231
243struct irq_and_dev { 232struct irq_and_dev {
@@ -304,19 +293,19 @@ void reactivate_fd(int fd, int irqnum)
304 unsigned long flags; 293 unsigned long flags;
305 int i; 294 int i;
306 295
307 flags = irq_lock(); 296 spin_lock_irqsave(&irq_lock, flags);
308 irq = find_irq_by_fd(fd, irqnum, &i); 297 irq = find_irq_by_fd(fd, irqnum, &i);
309 if (irq == NULL) { 298 if (irq == NULL) {
310 irq_unlock(flags); 299 spin_unlock_irqrestore(&irq_lock, flags);
311 return; 300 return;
312 } 301 }
313 os_set_pollfd(i, irq->fd); 302 os_set_pollfd(i, irq->fd);
314 irq_unlock(flags); 303 spin_unlock_irqrestore(&irq_lock, flags);
315 304
316 /* This calls activate_fd, so it has to be outside the critical 305 /* This calls activate_fd, so it has to be outside the critical
317 * section. 306 * section.
318 */ 307 */
319 maybe_sigio_broken(fd, irq->type); 308 maybe_sigio_broken(fd, (irq->type == IRQ_READ));
320} 309}
321 310
322void deactivate_fd(int fd, int irqnum) 311void deactivate_fd(int fd, int irqnum)
@@ -325,13 +314,13 @@ void deactivate_fd(int fd, int irqnum)
325 unsigned long flags; 314 unsigned long flags;
326 int i; 315 int i;
327 316
328 flags = irq_lock(); 317 spin_lock_irqsave(&irq_lock, flags);
329 irq = find_irq_by_fd(fd, irqnum, &i); 318 irq = find_irq_by_fd(fd, irqnum, &i);
330 if (irq == NULL) 319 if (irq == NULL)
331 goto out; 320 goto out;
332 os_set_pollfd(i, -1); 321 os_set_pollfd(i, -1);
333 out: 322 out:
334 irq_unlock(flags); 323 spin_unlock_irqrestore(&irq_lock, flags);
335} 324}
336 325
337int deactivate_all_fds(void) 326int deactivate_all_fds(void)
@@ -350,13 +339,14 @@ int deactivate_all_fds(void)
350 return 0; 339 return 0;
351} 340}
352 341
342#ifdef CONFIG_MODE_TT
353void forward_interrupts(int pid) 343void forward_interrupts(int pid)
354{ 344{
355 struct irq_fd *irq; 345 struct irq_fd *irq;
356 unsigned long flags; 346 unsigned long flags;
357 int err; 347 int err;
358 348
359 flags = irq_lock(); 349 spin_lock_irqsave(&irq_lock, flags);
360 for (irq = active_fds; irq != NULL; irq = irq->next) { 350 for (irq = active_fds; irq != NULL; irq = irq->next) {
361 err = os_set_owner(irq->fd, pid); 351 err = os_set_owner(irq->fd, pid);
362 if (err < 0) { 352 if (err < 0) {
@@ -369,8 +359,9 @@ void forward_interrupts(int pid)
369 359
370 irq->pid = pid; 360 irq->pid = pid;
371 } 361 }
372 irq_unlock(flags); 362 spin_unlock_irqrestore(&irq_lock, flags);
373} 363}
364#endif
374 365
375/* 366/*
376 * do_IRQ handles all normal device IRQ's (the special 367 * do_IRQ handles all normal device IRQ's (the special
@@ -403,21 +394,6 @@ int um_request_irq(unsigned int irq, int fd, int type,
403EXPORT_SYMBOL(um_request_irq); 394EXPORT_SYMBOL(um_request_irq);
404EXPORT_SYMBOL(reactivate_fd); 395EXPORT_SYMBOL(reactivate_fd);
405 396
406static DEFINE_SPINLOCK(irq_spinlock);
407
408unsigned long irq_lock(void)
409{
410 unsigned long flags;
411
412 spin_lock_irqsave(&irq_spinlock, flags);
413 return flags;
414}
415
416void irq_unlock(unsigned long flags)
417{
418 spin_unlock_irqrestore(&irq_spinlock, flags);
419}
420
421/* hw_interrupt_type must define (startup || enable) && 397/* hw_interrupt_type must define (startup || enable) &&
422 * (shutdown || disable) && end */ 398 * (shutdown || disable) && end */
423static void dummy(unsigned int irq) 399static void dummy(unsigned int irq)