diff options
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/include/irq_user.h | 2 | ||||
-rw-r--r-- | arch/um/kernel/irq.c | 45 |
2 files changed, 16 insertions, 31 deletions
diff --git a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h index 09e9e38920d5..15d311b9be9e 100644 --- a/arch/um/include/irq_user.h +++ b/arch/um/include/irq_user.h | |||
@@ -29,8 +29,6 @@ extern void reactivate_fd(int fd, int irqnum); | |||
29 | extern void deactivate_fd(int fd, int irqnum); | 29 | extern void deactivate_fd(int fd, int irqnum); |
30 | extern int deactivate_all_fds(void); | 30 | extern int deactivate_all_fds(void); |
31 | extern int activate_ipi(int fd, int pid); | 31 | extern int activate_ipi(int fd, int pid); |
32 | extern unsigned long irq_lock(void); | ||
33 | extern void irq_unlock(unsigned long flags); | ||
34 | 32 | ||
35 | #ifdef CONFIG_MODE_TT | 33 | #ifdef CONFIG_MODE_TT |
36 | extern void forward_interrupts(int pid); | 34 | extern void forward_interrupts(int pid); |
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 519cdb0a7708..27bc58ad38fd 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c | |||
@@ -123,6 +123,8 @@ static void maybe_sigio_broken(int fd, int type) | |||
123 | } | 123 | } |
124 | } | 124 | } |
125 | 125 | ||
126 | static DEFINE_SPINLOCK(irq_lock); | ||
127 | |||
126 | int activate_fd(int irq, int fd, int type, void *dev_id) | 128 | int activate_fd(int irq, int fd, int type, void *dev_id) |
127 | { | 129 | { |
128 | struct pollfd *tmp_pfd; | 130 | struct pollfd *tmp_pfd; |
@@ -166,7 +168,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 | 168 | * this is called only from process context, and can be locked with |
167 | * a semaphore. | 169 | * a semaphore. |
168 | */ | 170 | */ |
169 | flags = irq_lock(); | 171 | spin_lock_irqsave(&irq_lock, flags); |
170 | for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { | 172 | for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { |
171 | if ((irq_fd->fd == fd) && (irq_fd->type == type)) { | 173 | if ((irq_fd->fd == fd) && (irq_fd->type == type)) { |
172 | printk("Registering fd %d twice\n", fd); | 174 | printk("Registering fd %d twice\n", fd); |
@@ -199,7 +201,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 | 201 | * so we will not be able to put new pollfd struct to pollfds |
200 | * then we free the buffer tmp_fds and try again. | 202 | * then we free the buffer tmp_fds and try again. |
201 | */ | 203 | */ |
202 | irq_unlock(flags); | 204 | spin_unlock_irqrestore(&irq_lock, flags); |
203 | kfree(tmp_pfd); | 205 | kfree(tmp_pfd); |
204 | tmp_pfd = NULL; | 206 | tmp_pfd = NULL; |
205 | 207 | ||
@@ -207,14 +209,14 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
207 | if (tmp_pfd == NULL) | 209 | if (tmp_pfd == NULL) |
208 | goto out_kfree; | 210 | goto out_kfree; |
209 | 211 | ||
210 | flags = irq_lock(); | 212 | spin_lock_irqsave(&irq_lock, flags); |
211 | } | 213 | } |
212 | /*-------------*/ | 214 | /*-------------*/ |
213 | 215 | ||
214 | *last_irq_ptr = new_fd; | 216 | *last_irq_ptr = new_fd; |
215 | last_irq_ptr = &new_fd->next; | 217 | last_irq_ptr = &new_fd->next; |
216 | 218 | ||
217 | irq_unlock(flags); | 219 | spin_unlock_irqrestore(&irq_lock, flags); |
218 | 220 | ||
219 | /* This calls activate_fd, so it has to be outside the critical | 221 | /* This calls activate_fd, so it has to be outside the critical |
220 | * section. | 222 | * section. |
@@ -224,7 +226,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
224 | return(0); | 226 | return(0); |
225 | 227 | ||
226 | out_unlock: | 228 | out_unlock: |
227 | irq_unlock(flags); | 229 | spin_unlock_irqrestore(&irq_lock, flags); |
228 | out_kfree: | 230 | out_kfree: |
229 | kfree(new_fd); | 231 | kfree(new_fd); |
230 | out: | 232 | out: |
@@ -235,9 +237,9 @@ static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg) | |||
235 | { | 237 | { |
236 | unsigned long flags; | 238 | unsigned long flags; |
237 | 239 | ||
238 | flags = irq_lock(); | 240 | spin_lock_irqsave(&irq_lock, flags); |
239 | os_free_irq_by_cb(test, arg, active_fds, &last_irq_ptr); | 241 | os_free_irq_by_cb(test, arg, active_fds, &last_irq_ptr); |
240 | irq_unlock(flags); | 242 | spin_unlock_irqrestore(&irq_lock, flags); |
241 | } | 243 | } |
242 | 244 | ||
243 | struct irq_and_dev { | 245 | struct irq_and_dev { |
@@ -304,14 +306,14 @@ void reactivate_fd(int fd, int irqnum) | |||
304 | unsigned long flags; | 306 | unsigned long flags; |
305 | int i; | 307 | int i; |
306 | 308 | ||
307 | flags = irq_lock(); | 309 | spin_lock_irqsave(&irq_lock, flags); |
308 | irq = find_irq_by_fd(fd, irqnum, &i); | 310 | irq = find_irq_by_fd(fd, irqnum, &i); |
309 | if (irq == NULL) { | 311 | if (irq == NULL) { |
310 | irq_unlock(flags); | 312 | spin_unlock_irqrestore(&irq_lock, flags); |
311 | return; | 313 | return; |
312 | } | 314 | } |
313 | os_set_pollfd(i, irq->fd); | 315 | os_set_pollfd(i, irq->fd); |
314 | irq_unlock(flags); | 316 | spin_unlock_irqrestore(&irq_lock, flags); |
315 | 317 | ||
316 | /* This calls activate_fd, so it has to be outside the critical | 318 | /* This calls activate_fd, so it has to be outside the critical |
317 | * section. | 319 | * section. |
@@ -325,13 +327,13 @@ void deactivate_fd(int fd, int irqnum) | |||
325 | unsigned long flags; | 327 | unsigned long flags; |
326 | int i; | 328 | int i; |
327 | 329 | ||
328 | flags = irq_lock(); | 330 | spin_lock_irqsave(&irq_lock, flags); |
329 | irq = find_irq_by_fd(fd, irqnum, &i); | 331 | irq = find_irq_by_fd(fd, irqnum, &i); |
330 | if (irq == NULL) | 332 | if (irq == NULL) |
331 | goto out; | 333 | goto out; |
332 | os_set_pollfd(i, -1); | 334 | os_set_pollfd(i, -1); |
333 | out: | 335 | out: |
334 | irq_unlock(flags); | 336 | spin_unlock_irqrestore(&irq_lock, flags); |
335 | } | 337 | } |
336 | 338 | ||
337 | int deactivate_all_fds(void) | 339 | int deactivate_all_fds(void) |
@@ -357,7 +359,7 @@ void forward_interrupts(int pid) | |||
357 | unsigned long flags; | 359 | unsigned long flags; |
358 | int err; | 360 | int err; |
359 | 361 | ||
360 | flags = irq_lock(); | 362 | spin_lock_irqsave(&irq_lock, flags); |
361 | for (irq = active_fds; irq != NULL; irq = irq->next) { | 363 | for (irq = active_fds; irq != NULL; irq = irq->next) { |
362 | err = os_set_owner(irq->fd, pid); | 364 | err = os_set_owner(irq->fd, pid); |
363 | if (err < 0) { | 365 | if (err < 0) { |
@@ -370,7 +372,7 @@ void forward_interrupts(int pid) | |||
370 | 372 | ||
371 | irq->pid = pid; | 373 | irq->pid = pid; |
372 | } | 374 | } |
373 | irq_unlock(flags); | 375 | spin_unlock_irqrestore(&irq_lock, flags); |
374 | } | 376 | } |
375 | #endif | 377 | #endif |
376 | 378 | ||
@@ -405,21 +407,6 @@ int um_request_irq(unsigned int irq, int fd, int type, | |||
405 | EXPORT_SYMBOL(um_request_irq); | 407 | EXPORT_SYMBOL(um_request_irq); |
406 | EXPORT_SYMBOL(reactivate_fd); | 408 | EXPORT_SYMBOL(reactivate_fd); |
407 | 409 | ||
408 | static DEFINE_SPINLOCK(irq_spinlock); | ||
409 | |||
410 | unsigned long irq_lock(void) | ||
411 | { | ||
412 | unsigned long flags; | ||
413 | |||
414 | spin_lock_irqsave(&irq_spinlock, flags); | ||
415 | return flags; | ||
416 | } | ||
417 | |||
418 | void irq_unlock(unsigned long flags) | ||
419 | { | ||
420 | spin_unlock_irqrestore(&irq_spinlock, flags); | ||
421 | } | ||
422 | |||
423 | /* hw_interrupt_type must define (startup || enable) && | 410 | /* hw_interrupt_type must define (startup || enable) && |
424 | * (shutdown || disable) && end */ | 411 | * (shutdown || disable) && end */ |
425 | static void dummy(unsigned int irq) | 412 | static void dummy(unsigned int irq) |