Skip to content

Commit

Permalink
MN10300: Allow KGDB to use the MN10300 serial ports
Browse files Browse the repository at this point in the history
Allow KGDB to use the MN10300 serial ports through the polled I/O interface
provided via the TTY/serial layer and the kgdboc driver.  This allows the
kernel to be started with something like:

	kgdboc=ttySM0,115200

added to the command line.

Signed-off-by: David Howells <dhowells@redhat.com>
  • Loading branch information
David Howells committed Mar 18, 2011
1 parent 5141c46 commit 52885b3
Showing 1 changed file with 75 additions and 0 deletions.
75 changes: 75 additions & 0 deletions arch/mn10300/kernel/mn10300-serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ static int mn10300_serial_request_port(struct uart_port *);
static void mn10300_serial_config_port(struct uart_port *, int);
static int mn10300_serial_verify_port(struct uart_port *,
struct serial_struct *);
#ifdef CONFIG_CONSOLE_POLL
static void mn10300_serial_poll_put_char(struct uart_port *, unsigned char);
static int mn10300_serial_poll_get_char(struct uart_port *);
#endif

static const struct uart_ops mn10300_serial_ops = {
.tx_empty = mn10300_serial_tx_empty,
Expand All @@ -138,6 +142,10 @@ static const struct uart_ops mn10300_serial_ops = {
.request_port = mn10300_serial_request_port,
.config_port = mn10300_serial_config_port,
.verify_port = mn10300_serial_verify_port,
#ifdef CONFIG_CONSOLE_POLL
.poll_put_char = mn10300_serial_poll_put_char,
.poll_get_char = mn10300_serial_poll_get_char,
#endif
};

static irqreturn_t mn10300_serial_interrupt(int irq, void *dev_id);
Expand Down Expand Up @@ -1634,3 +1642,70 @@ static int __init mn10300_serial_console_init(void)

console_initcall(mn10300_serial_console_init);
#endif

#ifdef CONFIG_CONSOLE_POLL
/*
* Polled character reception for the kernel debugger
*/
static int mn10300_serial_poll_get_char(struct uart_port *_port)
{
struct mn10300_serial_port *port =
container_of(_port, struct mn10300_serial_port, uart);
unsigned ix;
u8 st, ch;

_enter("%s", port->name);

do {
/* pull chars out of the hat */
ix = port->rx_outp;
if (ix == port->rx_inp)
return NO_POLL_CHAR;

ch = port->rx_buffer[ix++];
st = port->rx_buffer[ix++];
smp_rmb();
port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1);

} while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF));

return ch;
}


/*
* Polled character transmission for the kernel debugger
*/
static void mn10300_serial_poll_put_char(struct uart_port *_port,
unsigned char ch)
{
struct mn10300_serial_port *port =
container_of(_port, struct mn10300_serial_port, uart);
u8 intr, tmp;

/* wait for the transmitter to finish anything it might be doing (and
* this includes the virtual DMA handler, so it might take a while) */
while (*port->_status & (SC01STR_TBF | SC01STR_TXF))
continue;

/* disable the Tx ready interrupt */
intr = *port->_intr;
*port->_intr = intr & ~SC01ICR_TI;
tmp = *port->_intr;

if (ch == 0x0a) {
*(u8 *) port->_txb = 0x0d;
while (*port->_status & SC01STR_TBF)
continue;
}

*(u8 *) port->_txb = ch;
while (*port->_status & SC01STR_TBF)
continue;

/* restore the Tx interrupt flag */
*port->_intr = intr;
tmp = *port->_intr;
}

#endif /* CONFIG_CONSOLE_POLL */

0 comments on commit 52885b3

Please sign in to comment.