Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 59e76486 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6:
  serial: cpm_uart: implement the cpm_uart_early_write() function for console poll
parents c01ec7b1 8cd774ad
Loading
Loading
Loading
Loading
+79 −64
Original line number Original line Diff line number Diff line
@@ -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);