Messages in this thread Patch in this message |  | | Date | Fri, 2 Jun 2006 23:23:41 +0100 (BST) | | From | Esben Nielsen <> | | Subject | [patch 4/5] [PREEMPT_RT] Changing interrupt handlers from running in thread to hardirq and back runtime. |
| |
Makes it possible for the 8250 serial driver to have it's interrupt handler in both hard-irq and threaded context under PREEMPT_RT.
Index: linux-2.6.16-rt23.spin_mutex/drivers/serial/8250.c =================================================================== --- linux-2.6.16-rt23.spin_mutex.orig/drivers/serial/8250.c +++ linux-2.6.16-rt23.spin_mutex/drivers/serial/8250.c @@ -140,7 +140,7 @@ struct uart_8250_port { };
struct irq_info { - spinlock_t lock; + spin_mutex_t lock; struct list_head *head; };
@@ -1287,6 +1287,47 @@ serial8250_handle_port(struct uart_8250_ spin_unlock(&up->port.lock); }
+ +static int serial8250_change_context(int irq, void *dev_id, + enum change_context_cmd cmd) +{ + struct irq_info *i = dev_id; + struct list_head *l; + + switch(cmd) { + case IRQ_TO_HARDIRQ: + /* Spin mutexes not available: */ + if(!spin_mutexes_can_spin()) + return -ENOSYS; + + /* First do the inner locks */ + l = i->head; + do { + struct uart_8250_port *up; + up = list_entry(l, struct uart_8250_port, list); + spin_mutex_to_spin(&up->port.lock); + l = l->next; + } while(l != i->head && l != NULL); + spin_mutex_to_spin(&i->lock); + break; + case IRQ_CAN_THREAD: + break; + case IRQ_TO_THREADED: + spin_mutex_to_mutex(&i->lock); + l = i->head; + + do { + struct uart_8250_port *up; + up = list_entry(l, struct uart_8250_port, list); + spin_mutex_to_mutex(&up->port.lock); + l = l->next; + } while(l != i->head && l != NULL); + break; + } + + return 0; +} + /* * This is the serial driver's interrupt routine. * @@ -1393,8 +1434,10 @@ static int serial_link_irq_chain(struct i->head = &up->list; spin_unlock_irq(&i->lock);
- ret = request_irq(up->port.irq, serial8250_interrupt, - irq_flags, "serial", i); + ret = request_irq2(up->port.irq, serial8250_interrupt, + irq_flags | SA_MUST_THREAD_RT, + "serial", i, + serial8250_change_context); if (ret < 0) serial_do_unlink(i, up); } Index: linux-2.6.16-rt23.spin_mutex/include/linux/serial_core.h =================================================================== --- linux-2.6.16-rt23.spin_mutex.orig/include/linux/serial_core.h +++ linux-2.6.16-rt23.spin_mutex/include/linux/serial_core.h @@ -206,7 +206,7 @@ struct uart_icount { typedef unsigned int __bitwise__ upf_t;
struct uart_port { - spinlock_t lock; /* port lock */ + spin_mutex_t lock; /* port lock */ unsigned int iobase; /* in/out[bwl] */ unsigned char __iomem *membase; /* read/write[bwl] */ unsigned int irq; /* irq number */ -- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |