mirror of
https://github.com/fail0verflow/switch-linux.git
synced 2025-05-04 02:34:21 -04:00
kgdb: kgdboc console poll hooks for mpsc uart
Add in console polling hooks for the mpsc uart for use with kgdb and kgdboc. Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
This commit is contained in:
parent
8e21d04c07
commit
3b216c9ed3
1 changed files with 147 additions and 1 deletions
|
@ -921,6 +921,10 @@ static int mpsc_make_ready(struct mpsc_port_info *pi)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_CONSOLE_POLL
|
||||||
|
static int serial_polled;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
|
@ -956,7 +960,12 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi)
|
||||||
while (!((cmdstat = be32_to_cpu(rxre->cmdstat))
|
while (!((cmdstat = be32_to_cpu(rxre->cmdstat))
|
||||||
& SDMA_DESC_CMDSTAT_O)) {
|
& SDMA_DESC_CMDSTAT_O)) {
|
||||||
bytes_in = be16_to_cpu(rxre->bytecnt);
|
bytes_in = be16_to_cpu(rxre->bytecnt);
|
||||||
|
#ifdef CONFIG_CONSOLE_POLL
|
||||||
|
if (unlikely(serial_polled)) {
|
||||||
|
serial_polled = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* Following use of tty struct directly is deprecated */
|
/* Following use of tty struct directly is deprecated */
|
||||||
if (unlikely(tty_buffer_request_room(tty, bytes_in)
|
if (unlikely(tty_buffer_request_room(tty, bytes_in)
|
||||||
< bytes_in)) {
|
< bytes_in)) {
|
||||||
|
@ -1017,6 +1026,12 @@ static int mpsc_rx_intr(struct mpsc_port_info *pi)
|
||||||
if (uart_handle_sysrq_char(&pi->port, *bp)) {
|
if (uart_handle_sysrq_char(&pi->port, *bp)) {
|
||||||
bp++;
|
bp++;
|
||||||
bytes_in--;
|
bytes_in--;
|
||||||
|
#ifdef CONFIG_CONSOLE_POLL
|
||||||
|
if (unlikely(serial_polled)) {
|
||||||
|
serial_polled = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
goto next_frame;
|
goto next_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1519,6 +1534,133 @@ static int mpsc_verify_port(struct uart_port *port, struct serial_struct *ser)
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_CONSOLE_POLL
|
||||||
|
/* Serial polling routines for writing and reading from the uart while
|
||||||
|
* in an interrupt or debug context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static char poll_buf[2048];
|
||||||
|
static int poll_ptr;
|
||||||
|
static int poll_cnt;
|
||||||
|
static void mpsc_put_poll_char(struct uart_port *port,
|
||||||
|
unsigned char c);
|
||||||
|
|
||||||
|
static int mpsc_get_poll_char(struct uart_port *port)
|
||||||
|
{
|
||||||
|
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
|
||||||
|
struct mpsc_rx_desc *rxre;
|
||||||
|
u32 cmdstat, bytes_in, i;
|
||||||
|
u8 *bp;
|
||||||
|
|
||||||
|
if (!serial_polled)
|
||||||
|
serial_polled = 1;
|
||||||
|
|
||||||
|
pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line);
|
||||||
|
|
||||||
|
if (poll_cnt) {
|
||||||
|
poll_cnt--;
|
||||||
|
return poll_buf[poll_ptr++];
|
||||||
|
}
|
||||||
|
poll_ptr = 0;
|
||||||
|
poll_cnt = 0;
|
||||||
|
|
||||||
|
while (poll_cnt == 0) {
|
||||||
|
rxre = (struct mpsc_rx_desc *)(pi->rxr +
|
||||||
|
(pi->rxr_posn*MPSC_RXRE_SIZE));
|
||||||
|
dma_cache_sync(pi->port.dev, (void *)rxre,
|
||||||
|
MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
|
||||||
|
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
|
||||||
|
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
|
||||||
|
invalidate_dcache_range((ulong)rxre,
|
||||||
|
(ulong)rxre + MPSC_RXRE_SIZE);
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Loop through Rx descriptors handling ones that have
|
||||||
|
* been completed.
|
||||||
|
*/
|
||||||
|
while (poll_cnt == 0 &&
|
||||||
|
!((cmdstat = be32_to_cpu(rxre->cmdstat)) &
|
||||||
|
SDMA_DESC_CMDSTAT_O)){
|
||||||
|
bytes_in = be16_to_cpu(rxre->bytecnt);
|
||||||
|
bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE);
|
||||||
|
dma_cache_sync(pi->port.dev, (void *) bp,
|
||||||
|
MPSC_RXBE_SIZE, DMA_FROM_DEVICE);
|
||||||
|
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
|
||||||
|
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
|
||||||
|
invalidate_dcache_range((ulong)bp,
|
||||||
|
(ulong)bp + MPSC_RXBE_SIZE);
|
||||||
|
#endif
|
||||||
|
if ((unlikely(cmdstat & (SDMA_DESC_CMDSTAT_BR |
|
||||||
|
SDMA_DESC_CMDSTAT_FR | SDMA_DESC_CMDSTAT_OR))) &&
|
||||||
|
!(cmdstat & pi->port.ignore_status_mask)) {
|
||||||
|
poll_buf[poll_cnt] = *bp;
|
||||||
|
poll_cnt++;
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < bytes_in; i++) {
|
||||||
|
poll_buf[poll_cnt] = *bp++;
|
||||||
|
poll_cnt++;
|
||||||
|
}
|
||||||
|
pi->port.icount.rx += bytes_in;
|
||||||
|
}
|
||||||
|
rxre->bytecnt = cpu_to_be16(0);
|
||||||
|
wmb();
|
||||||
|
rxre->cmdstat = cpu_to_be32(SDMA_DESC_CMDSTAT_O |
|
||||||
|
SDMA_DESC_CMDSTAT_EI |
|
||||||
|
SDMA_DESC_CMDSTAT_F |
|
||||||
|
SDMA_DESC_CMDSTAT_L);
|
||||||
|
wmb();
|
||||||
|
dma_cache_sync(pi->port.dev, (void *)rxre,
|
||||||
|
MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL);
|
||||||
|
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
|
||||||
|
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
|
||||||
|
flush_dcache_range((ulong)rxre,
|
||||||
|
(ulong)rxre + MPSC_RXRE_SIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Advance to next descriptor */
|
||||||
|
pi->rxr_posn = (pi->rxr_posn + 1) &
|
||||||
|
(MPSC_RXR_ENTRIES - 1);
|
||||||
|
rxre = (struct mpsc_rx_desc *)(pi->rxr +
|
||||||
|
(pi->rxr_posn * MPSC_RXRE_SIZE));
|
||||||
|
dma_cache_sync(pi->port.dev, (void *)rxre,
|
||||||
|
MPSC_RXRE_SIZE, DMA_FROM_DEVICE);
|
||||||
|
#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
|
||||||
|
if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */
|
||||||
|
invalidate_dcache_range((ulong)rxre,
|
||||||
|
(ulong)rxre + MPSC_RXRE_SIZE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restart rx engine, if its stopped */
|
||||||
|
if ((readl(pi->sdma_base + SDMA_SDCM) & SDMA_SDCM_ERD) == 0)
|
||||||
|
mpsc_start_rx(pi);
|
||||||
|
}
|
||||||
|
if (poll_cnt) {
|
||||||
|
poll_cnt--;
|
||||||
|
return poll_buf[poll_ptr++];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void mpsc_put_poll_char(struct uart_port *port,
|
||||||
|
unsigned char c)
|
||||||
|
{
|
||||||
|
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
|
||||||
|
u32 data;
|
||||||
|
|
||||||
|
data = readl(pi->mpsc_base + MPSC_MPCR);
|
||||||
|
writeb(c, pi->mpsc_base + MPSC_CHR_1);
|
||||||
|
mb();
|
||||||
|
data = readl(pi->mpsc_base + MPSC_CHR_2);
|
||||||
|
data |= MPSC_CHR_2_TTCS;
|
||||||
|
writel(data, pi->mpsc_base + MPSC_CHR_2);
|
||||||
|
mb();
|
||||||
|
|
||||||
|
while (readl(pi->mpsc_base + MPSC_CHR_2) & MPSC_CHR_2_TTCS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct uart_ops mpsc_pops = {
|
static struct uart_ops mpsc_pops = {
|
||||||
.tx_empty = mpsc_tx_empty,
|
.tx_empty = mpsc_tx_empty,
|
||||||
|
@ -1537,6 +1679,10 @@ static struct uart_ops mpsc_pops = {
|
||||||
.request_port = mpsc_request_port,
|
.request_port = mpsc_request_port,
|
||||||
.config_port = mpsc_config_port,
|
.config_port = mpsc_config_port,
|
||||||
.verify_port = mpsc_verify_port,
|
.verify_port = mpsc_verify_port,
|
||||||
|
#ifdef CONFIG_CONSOLE_POLL
|
||||||
|
.poll_get_char = mpsc_get_poll_char,
|
||||||
|
.poll_put_char = mpsc_put_poll_char,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Reference in a new issue