mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
serial: cpm_uart: implement the cpm_uart_early_write() function for console poll
The cpm_uart_early_write() function which was used for console poll isn't implemented in the cpm uart driver. Implementing this function both fixes the build when CONFIG_CONSOLE_POLL is set and allows kgdboc to work via the cpm uart. Signed-off-by: Dongdong Deng <dongdong.deng@windriver.com> Reviewed-by: Bruce Ashfield <bruce.ashfield@windriver.com> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
9341625307
commit
8cd774ad30
@ -930,6 +930,83 @@ static void cpm_uart_config_port(struct uart_port *port, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_CPM_CONSOLE)
|
||||||
|
/*
|
||||||
|
* Write a string to the serial port
|
||||||
|
* Note that this is called with interrupts already disabled
|
||||||
|
*/
|
||||||
|
static void cpm_uart_early_write(struct uart_cpm_port *pinfo,
|
||||||
|
const char *string, u_int count)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
cbd_t __iomem *bdp, *bdbase;
|
||||||
|
unsigned char *cpm_outp_addr;
|
||||||
|
|
||||||
|
/* Get the address of the host memory buffer.
|
||||||
|
*/
|
||||||
|
bdp = pinfo->tx_cur;
|
||||||
|
bdbase = pinfo->tx_bd_base;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now, do each character. This is not as bad as it looks
|
||||||
|
* since this is a holding FIFO and not a transmitting FIFO.
|
||||||
|
* We could add the complexity of filling the entire transmit
|
||||||
|
* buffer, but we would just wait longer between accesses......
|
||||||
|
*/
|
||||||
|
for (i = 0; i < count; i++, string++) {
|
||||||
|
/* Wait for transmitter fifo to empty.
|
||||||
|
* Ready indicates output is ready, and xmt is doing
|
||||||
|
* that, not that it is ready for us to send.
|
||||||
|
*/
|
||||||
|
while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
|
||||||
|
;
|
||||||
|
|
||||||
|
/* Send the character out.
|
||||||
|
* If the buffer address is in the CPM DPRAM, don't
|
||||||
|
* convert it.
|
||||||
|
*/
|
||||||
|
cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr),
|
||||||
|
pinfo);
|
||||||
|
*cpm_outp_addr = *string;
|
||||||
|
|
||||||
|
out_be16(&bdp->cbd_datlen, 1);
|
||||||
|
setbits16(&bdp->cbd_sc, BD_SC_READY);
|
||||||
|
|
||||||
|
if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
|
||||||
|
bdp = bdbase;
|
||||||
|
else
|
||||||
|
bdp++;
|
||||||
|
|
||||||
|
/* if a LF, also do CR... */
|
||||||
|
if (*string == 10) {
|
||||||
|
while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
|
||||||
|
;
|
||||||
|
|
||||||
|
cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr),
|
||||||
|
pinfo);
|
||||||
|
*cpm_outp_addr = 13;
|
||||||
|
|
||||||
|
out_be16(&bdp->cbd_datlen, 1);
|
||||||
|
setbits16(&bdp->cbd_sc, BD_SC_READY);
|
||||||
|
|
||||||
|
if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
|
||||||
|
bdp = bdbase;
|
||||||
|
else
|
||||||
|
bdp++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Finally, Wait for transmitter & holding register to empty
|
||||||
|
* and restore the IER
|
||||||
|
*/
|
||||||
|
while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
|
||||||
|
;
|
||||||
|
|
||||||
|
pinfo->tx_cur = bdp;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_CONSOLE_POLL
|
#ifdef CONFIG_CONSOLE_POLL
|
||||||
/* Serial polling routines for writing and reading from the uart while
|
/* Serial polling routines for writing and reading from the uart while
|
||||||
* in an interrupt or debug context.
|
* in an interrupt or debug context.
|
||||||
@ -999,7 +1076,7 @@ static void cpm_put_poll_char(struct uart_port *port,
|
|||||||
static char ch[2];
|
static char ch[2];
|
||||||
|
|
||||||
ch[0] = (char)c;
|
ch[0] = (char)c;
|
||||||
cpm_uart_early_write(pinfo->port.line, ch, 1);
|
cpm_uart_early_write(pinfo, ch, 1);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_CONSOLE_POLL */
|
#endif /* CONFIG_CONSOLE_POLL */
|
||||||
|
|
||||||
@ -1130,9 +1207,6 @@ static void cpm_uart_console_write(struct console *co, const char *s,
|
|||||||
u_int count)
|
u_int count)
|
||||||
{
|
{
|
||||||
struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index];
|
struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index];
|
||||||
unsigned int i;
|
|
||||||
cbd_t __iomem *bdp, *bdbase;
|
|
||||||
unsigned char *cp;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int nolock = oops_in_progress;
|
int nolock = oops_in_progress;
|
||||||
|
|
||||||
@ -1142,66 +1216,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
|
|||||||
spin_lock_irqsave(&pinfo->port.lock, flags);
|
spin_lock_irqsave(&pinfo->port.lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the address of the host memory buffer.
|
cpm_uart_early_write(pinfo, s, count);
|
||||||
*/
|
|
||||||
bdp = pinfo->tx_cur;
|
|
||||||
bdbase = pinfo->tx_bd_base;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now, do each character. This is not as bad as it looks
|
|
||||||
* since this is a holding FIFO and not a transmitting FIFO.
|
|
||||||
* We could add the complexity of filling the entire transmit
|
|
||||||
* buffer, but we would just wait longer between accesses......
|
|
||||||
*/
|
|
||||||
for (i = 0; i < count; i++, s++) {
|
|
||||||
/* Wait for transmitter fifo to empty.
|
|
||||||
* Ready indicates output is ready, and xmt is doing
|
|
||||||
* that, not that it is ready for us to send.
|
|
||||||
*/
|
|
||||||
while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
|
|
||||||
;
|
|
||||||
|
|
||||||
/* Send the character out.
|
|
||||||
* If the buffer address is in the CPM DPRAM, don't
|
|
||||||
* convert it.
|
|
||||||
*/
|
|
||||||
cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
|
|
||||||
*cp = *s;
|
|
||||||
|
|
||||||
out_be16(&bdp->cbd_datlen, 1);
|
|
||||||
setbits16(&bdp->cbd_sc, BD_SC_READY);
|
|
||||||
|
|
||||||
if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
|
|
||||||
bdp = bdbase;
|
|
||||||
else
|
|
||||||
bdp++;
|
|
||||||
|
|
||||||
/* if a LF, also do CR... */
|
|
||||||
if (*s == 10) {
|
|
||||||
while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
|
|
||||||
;
|
|
||||||
|
|
||||||
cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
|
|
||||||
*cp = 13;
|
|
||||||
|
|
||||||
out_be16(&bdp->cbd_datlen, 1);
|
|
||||||
setbits16(&bdp->cbd_sc, BD_SC_READY);
|
|
||||||
|
|
||||||
if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
|
|
||||||
bdp = bdbase;
|
|
||||||
else
|
|
||||||
bdp++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Finally, Wait for transmitter & holding register to empty
|
|
||||||
* and restore the IER
|
|
||||||
*/
|
|
||||||
while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0)
|
|
||||||
;
|
|
||||||
|
|
||||||
pinfo->tx_cur = bdp;
|
|
||||||
|
|
||||||
if (unlikely(nolock)) {
|
if (unlikely(nolock)) {
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user