Commit b6335e73 authored by Pete Zaitcev's avatar Pete Zaitcev Committed by David S. Miller

[SUNZILOG]: Fix TX and interrupt bugs.

- Make sure to clear SUNZILOG_FLAG_TX_ACTIVE
- Handle TX completion events properly
- Do not forget R1 reg initialization for ttys.
parent 1b44f7f6
...@@ -488,6 +488,8 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up, ...@@ -488,6 +488,8 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
return; return;
} }
up->flags &= ~SUNZILOG_FLAG_TX_ACTIVE;
if (ZS_REGS_HELD(up)) { if (ZS_REGS_HELD(up)) {
__load_zsregs(channel, up->curregs); __load_zsregs(channel, up->curregs);
up->flags &= ~SUNZILOG_FLAG_REGS_HELD; up->flags &= ~SUNZILOG_FLAG_REGS_HELD;
...@@ -495,15 +497,11 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up, ...@@ -495,15 +497,11 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
if (ZS_TX_STOPPED(up)) { if (ZS_TX_STOPPED(up)) {
up->flags &= ~SUNZILOG_FLAG_TX_STOPPED; up->flags &= ~SUNZILOG_FLAG_TX_STOPPED;
goto ack_tx_int;
sbus_writeb(RES_Tx_P, &channel->control);
ZSDELAY();
ZS_WSYNC(channel);
return;
} }
if (up->port.x_char) { if (up->port.x_char) {
up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
sbus_writeb(up->port.x_char, &channel->data); sbus_writeb(up->port.x_char, &channel->data);
ZSDELAY(); ZSDELAY();
ZS_WSYNC(channel); ZS_WSYNC(channel);
...@@ -516,9 +514,14 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up, ...@@ -516,9 +514,14 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
if (up->port.info == NULL) if (up->port.info == NULL)
goto ack_tx_int; goto ack_tx_int;
xmit = &up->port.info->xmit; xmit = &up->port.info->xmit;
if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) if (uart_circ_empty(xmit)) {
uart_write_wakeup(&up->port);
goto ack_tx_int;
}
if (uart_tx_stopped(&up->port))
goto ack_tx_int; goto ack_tx_int;
up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
sbus_writeb(xmit->buf[xmit->tail], &channel->data); sbus_writeb(xmit->buf[xmit->tail], &channel->data);
ZSDELAY(); ZSDELAY();
ZS_WSYNC(channel); ZS_WSYNC(channel);
...@@ -529,9 +532,6 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up, ...@@ -529,9 +532,6 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(&up->port); uart_write_wakeup(&up->port);
if (uart_circ_empty(xmit))
goto ack_tx_int;
return; return;
ack_tx_int: ack_tx_int:
...@@ -725,6 +725,9 @@ static void sunzilog_stop_rx(struct uart_port *port) ...@@ -725,6 +725,9 @@ static void sunzilog_stop_rx(struct uart_port *port)
struct zilog_channel *channel; struct zilog_channel *channel;
unsigned long flags; unsigned long flags;
if (ZS_IS_CONS(up))
return;
spin_lock_irqsave(&port->lock, flags); spin_lock_irqsave(&port->lock, flags);
channel = ZILOG_CHANNEL_FROM_PORT(port); channel = ZILOG_CHANNEL_FROM_PORT(port);
...@@ -1588,6 +1591,7 @@ static void __init sunzilog_init_hw(void) ...@@ -1588,6 +1591,7 @@ static void __init sunzilog_init_hw(void)
} else { } else {
/* Normal serial TTY. */ /* Normal serial TTY. */
up->parity_mask = 0xff; up->parity_mask = 0xff;
up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;
up->curregs[R4] = PAR_EVEN | X16CLK | SB1; up->curregs[R4] = PAR_EVEN | X16CLK | SB1;
up->curregs[R3] = RxENAB | Rx8; up->curregs[R3] = RxENAB | Rx8;
up->curregs[R5] = TxENAB | Tx8; up->curregs[R5] = TxENAB | Tx8;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment