diff options
Diffstat (limited to 'drivers/tty/serial/sunsab.c')
| -rw-r--r-- | drivers/tty/serial/sunsab.c | 57 |
1 files changed, 24 insertions, 33 deletions
diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index bd8b3b63410..2f57df9a71d 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -107,11 +107,11 @@ static __inline__ void sunsab_cec_wait(struct uart_sunsab_port *up) udelay(1); } -static struct tty_struct * +static struct tty_port * receive_chars(struct uart_sunsab_port *up, union sab82532_irq_status *stat) { - struct tty_struct *tty = NULL; + struct tty_port *port = NULL; unsigned char buf[32]; int saw_console_brk = 0; int free_fifo = 0; @@ -119,7 +119,7 @@ receive_chars(struct uart_sunsab_port *up, int i; if (up->port.state != NULL) /* Unopened serial console */ - tty = up->port.state->port.tty; + port = &up->port.state->port; /* Read number of BYTES (Character + Status) available. */ if (stat->sreg.isr0 & SAB82532_ISR0_RPF) { @@ -136,7 +136,7 @@ receive_chars(struct uart_sunsab_port *up, if (stat->sreg.isr0 & SAB82532_ISR0_TIME) { sunsab_cec_wait(up); writeb(SAB82532_CMDR_RFRD, &up->regs->w.cmdr); - return tty; + return port; } if (stat->sreg.isr0 & SAB82532_ISR0_RFO) @@ -160,11 +160,6 @@ receive_chars(struct uart_sunsab_port *up, for (i = 0; i < count; i++) { unsigned char ch = buf[i], flag; - if (tty == NULL) { - uart_handle_sysrq_char(&up->port, ch); - continue; - } - flag = TTY_NORMAL; up->port.icount.rx++; @@ -208,20 +203,20 @@ receive_chars(struct uart_sunsab_port *up, flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&up->port, ch)) + if (uart_handle_sysrq_char(&up->port, ch) || !port) continue; if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 && (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0) - tty_insert_flip_char(tty, ch, flag); + tty_insert_flip_char(port, ch, flag); if (stat->sreg.isr0 & SAB82532_ISR0_RFO) - tty_insert_flip_char(tty, 0, TTY_OVERRUN); + tty_insert_flip_char(port, 0, TTY_OVERRUN); } if (saw_console_brk) sun_do_break(); - return tty; + return port; } static void sunsab_stop_tx(struct uart_port *); @@ -304,7 +299,7 @@ static void check_status(struct uart_sunsab_port *up, static irqreturn_t sunsab_interrupt(int irq, void *dev_id) { struct uart_sunsab_port *up = dev_id; - struct tty_struct *tty; + struct tty_port *port = NULL; union sab82532_irq_status status; unsigned long flags; unsigned char gis; @@ -318,12 +313,11 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) if (gis & 2) status.sreg.isr1 = readb(&up->regs->r.isr1); - tty = NULL; if (status.stat) { if ((status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF)) || (status.sreg.isr1 & SAB82532_ISR1_BRK)) - tty = receive_chars(up, &status); + port = receive_chars(up, &status); if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) || (status.sreg.isr1 & SAB82532_ISR1_CSC)) check_status(up, &status); @@ -333,8 +327,8 @@ static irqreturn_t sunsab_interrupt(int irq, void *dev_id) spin_unlock_irqrestore(&up->port.lock, flags); - if (tty) - tty_flip_buffer_push(tty); + if (port) + tty_flip_buffer_push(port); return IRQ_HANDLED; } @@ -433,6 +427,9 @@ static void sunsab_start_tx(struct uart_port *port) struct circ_buf *xmit = &up->port.state->xmit; int i; + if (uart_circ_empty(xmit)) + return; + up->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS|SAB82532_IMR1_XPR); writeb(up->interrupt_mask1, &up->regs->w.imr1); @@ -725,7 +722,7 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla if (iflag & INPCK) up->port.read_status_mask |= (SAB82532_ISR0_PERR | SAB82532_ISR0_FERR); - if (iflag & (BRKINT | PARMRK)) + if (iflag & (IGNBRK | BRKINT | PARMRK)) up->port.read_status_mask |= (SAB82532_ISR1_BRK << 8); /* @@ -850,20 +847,16 @@ static void sunsab_console_write(struct console *con, const char *s, unsigned n) unsigned long flags; int locked = 1; - local_irq_save(flags); - if (up->port.sysrq) { - locked = 0; - } else if (oops_in_progress) { - locked = spin_trylock(&up->port.lock); - } else - spin_lock(&up->port.lock); + if (up->port.sysrq || oops_in_progress) + locked = spin_trylock_irqsave(&up->port.lock, flags); + else + spin_lock_irqsave(&up->port.lock, flags); uart_console_write(&up->port, s, n, sunsab_console_putchar); sunsab_tec_wait(up); if (locked) - spin_unlock(&up->port.lock); - local_irq_restore(flags); + spin_unlock_irqrestore(&up->port.lock, flags); } static int sunsab_console_setup(struct console *con, char *options) @@ -900,7 +893,7 @@ static int sunsab_console_setup(struct console *con, char *options) case B115200: baud = 115200; break; case B230400: baud = 230400; break; case B460800: baud = 460800; break; - }; + } /* * Temporary fix. @@ -1043,7 +1036,7 @@ static int sab_probe(struct platform_device *op) if (err) goto out3; - dev_set_drvdata(&op->dev, &up[0]); + platform_set_drvdata(op, &up[0]); inst++; @@ -1065,7 +1058,7 @@ out: static int sab_remove(struct platform_device *op) { - struct uart_sunsab_port *up = dev_get_drvdata(&op->dev); + struct uart_sunsab_port *up = platform_get_drvdata(op); uart_remove_one_port(&sunsab_reg, &up[1].port); uart_remove_one_port(&sunsab_reg, &up[0].port); @@ -1076,8 +1069,6 @@ static int sab_remove(struct platform_device *op) up[0].port.membase, sizeof(union sab82532_async_regs)); - dev_set_drvdata(&op->dev, NULL); - return 0; } |
