mirror of https://gitee.com/openkylin/linux.git
kgdb: kgdboc console poll hooks for cpm uart
Add in console polling hooks for the cpm uart for use with kgdb and kgdboc. Signed-off-by: Jason Wessel <jason.wessel@windriver.com> CC: galak@kernel.crashing.org
This commit is contained in:
parent
17ce452f7e
commit
8e21d04c07
|
@ -201,6 +201,10 @@ static void cpm_uart_int_tx(struct uart_port *port)
|
|||
cpm_uart_tx_pump(port);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
static int serial_polled;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Receive characters
|
||||
*/
|
||||
|
@ -222,6 +226,12 @@ static void cpm_uart_int_rx(struct uart_port *port)
|
|||
*/
|
||||
bdp = pinfo->rx_cur;
|
||||
for (;;) {
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
if (unlikely(serial_polled)) {
|
||||
serial_polled = 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/* get status */
|
||||
status = in_be16(&bdp->cbd_sc);
|
||||
/* If this one is empty, return happy */
|
||||
|
@ -253,7 +263,12 @@ static void cpm_uart_int_rx(struct uart_port *port)
|
|||
goto handle_error;
|
||||
if (uart_handle_sysrq_char(port, ch))
|
||||
continue;
|
||||
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
if (unlikely(serial_polled)) {
|
||||
serial_polled = 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
error_return:
|
||||
tty_insert_flip_char(tty, ch, flg);
|
||||
|
||||
|
@ -865,6 +880,80 @@ static void cpm_uart_config_port(struct uart_port *port, int flags)
|
|||
cpm_uart_request_port(port);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
/* Serial polling routines for writing and reading from the uart while
|
||||
* in an interrupt or debug context.
|
||||
*/
|
||||
|
||||
#define GDB_BUF_SIZE 512 /* power of 2, please */
|
||||
|
||||
static char poll_buf[GDB_BUF_SIZE];
|
||||
static char *pollp;
|
||||
static int poll_chars;
|
||||
|
||||
static int poll_wait_key(char *obuf, struct uart_cpm_port *pinfo)
|
||||
{
|
||||
u_char c, *cp;
|
||||
volatile cbd_t *bdp;
|
||||
int i;
|
||||
|
||||
/* Get the address of the host memory buffer.
|
||||
*/
|
||||
bdp = pinfo->rx_cur;
|
||||
while (bdp->cbd_sc & BD_SC_EMPTY)
|
||||
;
|
||||
|
||||
/* If the buffer address is in the CPM DPRAM, don't
|
||||
* convert it.
|
||||
*/
|
||||
cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
|
||||
|
||||
if (obuf) {
|
||||
i = c = bdp->cbd_datlen;
|
||||
while (i-- > 0)
|
||||
*obuf++ = *cp++;
|
||||
} else
|
||||
c = *cp;
|
||||
bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID);
|
||||
bdp->cbd_sc |= BD_SC_EMPTY;
|
||||
|
||||
if (bdp->cbd_sc & BD_SC_WRAP)
|
||||
bdp = pinfo->rx_bd_base;
|
||||
else
|
||||
bdp++;
|
||||
pinfo->rx_cur = (cbd_t *)bdp;
|
||||
|
||||
return (int)c;
|
||||
}
|
||||
|
||||
static int cpm_get_poll_char(struct uart_port *port)
|
||||
{
|
||||
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
|
||||
|
||||
if (!serial_polled) {
|
||||
serial_polled = 1;
|
||||
poll_chars = 0;
|
||||
}
|
||||
if (poll_chars <= 0) {
|
||||
poll_chars = poll_wait_key(poll_buf, pinfo);
|
||||
pollp = poll_buf;
|
||||
}
|
||||
poll_chars--;
|
||||
return *pollp++;
|
||||
}
|
||||
|
||||
static void cpm_put_poll_char(struct uart_port *port,
|
||||
unsigned char c)
|
||||
{
|
||||
struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
|
||||
static char ch[2];
|
||||
|
||||
ch[0] = (char)c;
|
||||
cpm_uart_early_write(pinfo->port.line, ch, 1);
|
||||
}
|
||||
#endif /* CONFIG_CONSOLE_POLL */
|
||||
|
||||
static struct uart_ops cpm_uart_pops = {
|
||||
.tx_empty = cpm_uart_tx_empty,
|
||||
.set_mctrl = cpm_uart_set_mctrl,
|
||||
|
@ -882,6 +971,10 @@ static struct uart_ops cpm_uart_pops = {
|
|||
.request_port = cpm_uart_request_port,
|
||||
.config_port = cpm_uart_config_port,
|
||||
.verify_port = cpm_uart_verify_port,
|
||||
#ifdef CONFIG_CONSOLE_POLL
|
||||
.poll_get_char = cpm_get_poll_char,
|
||||
.poll_put_char = cpm_put_poll_char,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct uart_cpm_port cpm_uart_ports[UART_NR];
|
||||
|
|
Loading…
Reference in New Issue