Merge master.kernel.org:/home/rmk/linux-2.6-serial
[pandora-kernel.git] / drivers / serial / 8250.c
index 9c5d36f..0ae9ced 100644 (file)
@@ -48,7 +48,7 @@
 
 /*
  * Configuration:
- *   share_irqs - whether we pass SA_SHIRQ to request_irq().  This option
+ *   share_irqs - whether we pass IRQF_SHARED to request_irq().  This option
  *                is unsafe when used on edge-triggered interrupts.
  */
 static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
@@ -299,6 +299,7 @@ static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
 
 static unsigned int serial_in(struct uart_8250_port *up, int offset)
 {
+       unsigned int tmp;
        offset = map_8250_in_reg(up, offset) << up->port.regshift;
 
        switch (up->port.iotype) {
@@ -317,6 +318,13 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset)
                return __raw_readl(up->port.membase + offset);
 #endif
 
+       case UPIO_TSI:
+               if (offset == UART_IIR) {
+                       tmp = readl((u32 *)(up->port.membase + UART_RX));
+                       return (cpu_to_le32(tmp) >> 8) & 0xff;
+               } else
+                       return readb(up->port.membase + offset);
+
        default:
                return inb(up->port.iobase + offset);
        }
@@ -346,6 +354,10 @@ serial_out(struct uart_8250_port *up, int offset, int value)
                __raw_writel(value, up->port.membase + offset);
                break;
 #endif
+       case UPIO_TSI:
+               if (!((offset == UART_IER) && (value & UART_IER_UUE)))
+                       writeb(value, up->port.membase + offset);
+               break;
 
        default:
                outb(value, up->port.iobase + offset);
@@ -1400,7 +1412,7 @@ static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
 static int serial_link_irq_chain(struct uart_8250_port *up)
 {
        struct irq_info *i = irq_lists + up->port.irq;
-       int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? SA_SHIRQ : 0;
+       int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
 
        spin_lock_irq(&i->lock);
 
@@ -2240,10 +2252,14 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
 
        touch_nmi_watchdog();
 
-       if (oops_in_progress) {
-               locked = spin_trylock_irqsave(&up->port.lock, flags);
+       local_irq_save(flags);
+       if (up->port.sysrq) {
+               /* serial8250_handle_port() already took the lock */
+               locked = 0;
+       } else if (oops_in_progress) {
+               locked = spin_trylock(&up->port.lock);
        } else
-               spin_lock_irqsave(&up->port.lock, flags);
+               spin_lock(&up->port.lock);
 
        /*
         *      First save the IER then disable the interrupts
@@ -2265,7 +2281,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
        serial_out(up, UART_IER, ier);
 
        if (locked)
-               spin_unlock_irqrestore(&up->port.lock, flags);
+               spin_unlock(&up->port.lock);
+       local_irq_restore(flags);
 }
 
 static int serial8250_console_setup(struct console *co, char *options)