summaryrefslogtreecommitdiffstats
path: root/arch/mn10300/kernel
diff options
context:
space:
mode:
authorMark Salter <msalter@redhat.com>2012-12-12 16:36:39 +0100
committerDavid Howells <dhowells@redhat.com>2012-12-12 16:46:14 +0100
commit0369c360e5825e34ff58c140aa7fbb9855ad1e4a (patch)
tree871be10d0b14cf2a48039647fbf39ca7609e49fd /arch/mn10300/kernel
parentMN10300: ttySM: clean up unnecessary casting (diff)
downloadlinux-0369c360e5825e34ff58c140aa7fbb9855ad1e4a.tar.xz
linux-0369c360e5825e34ff58c140aa7fbb9855ad1e4a.zip
MN10300: fix debug polling in ttySM driver
The debug polling interface for the SoC serial ports did not work in the case where the serial ports were not also used as a console. In that case, the uart driver startup function will not be called so tx and rx would not be enabled in the hardware control register. Also, vdma interrupts would not be enabled which the poll_get_char function relied on. This patch makes sure that the rx and tx enables are set as a consequence of the uart set_termios call which is the only initialization done for the debug polling interface. Also, the poll_get_char now handles the case where vdma interrupts are not enabled. Signed-off-by: Mark Salter <msalter@redhat.com> Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'arch/mn10300/kernel')
-rw-r--r--arch/mn10300/kernel/mn10300-serial.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c
index b7b5a4c270f5..81d5cb9b6569 100644
--- a/arch/mn10300/kernel/mn10300-serial.c
+++ b/arch/mn10300/kernel/mn10300-serial.c
@@ -1374,7 +1374,8 @@ timer_okay:
if ((new->c_cflag & CREAD) == 0)
port->uart.ignore_status_mask |= (1 << TTY_NORMAL);
- scxctr |= *port->_control & (SC01CTR_TXE | SC01CTR_RXE | SC01CTR_BKE);
+ scxctr |= SC01CTR_TXE | SC01CTR_RXE;
+ scxctr |= *port->_control & SC01CTR_BKE;
*port->_control = scxctr;
spin_unlock_irqrestore(&port->uart.lock, flags);
@@ -1720,19 +1721,29 @@ static int mn10300_serial_poll_get_char(struct uart_port *_port)
_enter("%s", port->name);
- do {
- /* pull chars out of the hat */
- ix = ACCESS_ONCE(port->rx_outp);
- if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0)
- return NO_POLL_CHAR;
+ if (mn10300_serial_int_tbl[port->rx_irq].port != NULL) {
+ do {
+ /* pull chars out of the hat */
+ ix = ACCESS_ONCE(port->rx_outp);
+ if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0)
+ return NO_POLL_CHAR;
- smp_read_barrier_depends();
- ch = port->rx_buffer[ix++];
- st = port->rx_buffer[ix++];
- smp_mb();
- port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1);
+ smp_read_barrier_depends();
+ ch = port->rx_buffer[ix++];
+ st = port->rx_buffer[ix++];
+ smp_mb();
+ port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1);
- } while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF));
+ } while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF));
+ } else {
+ do {
+ st = *port->_status;
+ if (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF))
+ continue;
+ } while (!(st & SC01STR_RBF));
+
+ ch = *port->_rxb;
+ }
return ch;
}