|
@@ -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
|
|
|
/* Serial polling routines for writing and reading from the uart while
|
|
|
* in an interrupt or debug context.
|
|
@@ -999,7 +1076,7 @@ static void cpm_put_poll_char(struct uart_port *port,
|
|
|
static char ch[2];
|
|
|
|
|
|
ch[0] = (char)c;
|
|
|
- cpm_uart_early_write(pinfo->port.line, ch, 1);
|
|
|
+ cpm_uart_early_write(pinfo, ch, 1);
|
|
|
}
|
|
|
#endif /* CONFIG_CONSOLE_POLL */
|
|
|
|
|
@@ -1130,9 +1207,6 @@ static void cpm_uart_console_write(struct console *co, const char *s,
|
|
|
u_int count)
|
|
|
{
|
|
|
struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index];
|
|
|
- unsigned int i;
|
|
|
- cbd_t __iomem *bdp, *bdbase;
|
|
|
- unsigned char *cp;
|
|
|
unsigned long flags;
|
|
|
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);
|
|
|
}
|
|
|
|
|
|
- /* 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++, 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;
|
|
|
+ cpm_uart_early_write(pinfo, s, count);
|
|
|
|
|
|
if (unlikely(nolock)) {
|
|
|
local_irq_restore(flags);
|