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

Commit a10b32db authored by Atsushi Nemoto's avatar Atsushi Nemoto Committed by Linus Torvalds
Browse files

kgdb: kgdboc console poll hooks for serial_txx9 uart



Implement the serial polling hooks for the serial_txx9 uart for use with
kgdboc.

This patch once got SOB from Jason on Jul 2008 and (perhaps) merged into
kgdb-next branch, but lost somewhere then.  I resend it now with Jason's
Acked-by.

Signed-off-by: default avatarAtsushi Nemoto <anemo@mba.ocn.ne.jp>
Acked-by: default avatarJason Wessel <jason.wessel@windriver.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent be98eb2c
Loading
Loading
Loading
Loading
+92 −21
Original line number Diff line number Diff line
@@ -461,6 +461,94 @@ static void serial_txx9_break_ctl(struct uart_port *port, int break_state)
	spin_unlock_irqrestore(&up->port.lock, flags);
}

#if defined(CONFIG_SERIAL_TXX9_CONSOLE) || (CONFIG_CONSOLE_POLL)
/*
 *	Wait for transmitter & holding register to empty
 */
static void wait_for_xmitr(struct uart_txx9_port *up)
{
	unsigned int tmout = 10000;

	/* Wait up to 10ms for the character(s) to be sent. */
	while (--tmout &&
	       !(sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS))
		udelay(1);

	/* Wait up to 1s for flow control if necessary */
	if (up->port.flags & UPF_CONS_FLOW) {
		tmout = 1000000;
		while (--tmout &&
		       (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS))
			udelay(1);
	}
}
#endif

#ifdef CONFIG_CONSOLE_POLL
/*
 * Console polling routines for writing and reading from the uart while
 * in an interrupt or debug context.
 */

static int serial_txx9_get_poll_char(struct uart_port *port)
{
	unsigned int ier;
	unsigned char c;
	struct uart_txx9_port *up = (struct uart_txx9_port *)port;

	/*
	 *	First save the IER then disable the interrupts
	 */
	ier = sio_in(up, TXX9_SIDICR);
	sio_out(up, TXX9_SIDICR, 0);

	while (sio_in(up, TXX9_SIDISR) & TXX9_SIDISR_UVALID)
		;

	c = sio_in(up, TXX9_SIRFIFO);

	/*
	 *	Finally, clear RX interrupt status
	 *	and restore the IER
	 */
	sio_mask(up, TXX9_SIDISR, TXX9_SIDISR_RDIS);
	sio_out(up, TXX9_SIDICR, ier);
	return c;
}


static void serial_txx9_put_poll_char(struct uart_port *port, unsigned char c)
{
	unsigned int ier;
	struct uart_txx9_port *up = (struct uart_txx9_port *)port;

	/*
	 *	First save the IER then disable the interrupts
	 */
	ier = sio_in(up, TXX9_SIDICR);
	sio_out(up, TXX9_SIDICR, 0);

	wait_for_xmitr(up);
	/*
	 *	Send the character out.
	 *	If a LF, also do CR...
	 */
	sio_out(up, TXX9_SITFIFO, c);
	if (c == 10) {
		wait_for_xmitr(up);
		sio_out(up, TXX9_SITFIFO, 13);
	}

	/*
	 *	Finally, wait for transmitter to become empty
	 *	and restore the IER
	 */
	wait_for_xmitr(up);
	sio_out(up, TXX9_SIDICR, ier);
}

#endif /* CONFIG_CONSOLE_POLL */

static int serial_txx9_startup(struct uart_port *port)
{
	struct uart_txx9_port *up = (struct uart_txx9_port *)port;
@@ -781,6 +869,10 @@ static struct uart_ops serial_txx9_pops = {
	.release_port	= serial_txx9_release_port,
	.request_port	= serial_txx9_request_port,
	.config_port	= serial_txx9_config_port,
#ifdef CONFIG_CONSOLE_POLL
	.poll_get_char	= serial_txx9_get_poll_char,
	.poll_put_char	= serial_txx9_put_poll_char,
#endif
};

static struct uart_txx9_port serial_txx9_ports[UART_NR];
@@ -803,27 +895,6 @@ static void __init serial_txx9_register_ports(struct uart_driver *drv,

#ifdef CONFIG_SERIAL_TXX9_CONSOLE

/*
 *	Wait for transmitter & holding register to empty
 */
static inline void wait_for_xmitr(struct uart_txx9_port *up)
{
	unsigned int tmout = 10000;

	/* Wait up to 10ms for the character(s) to be sent. */
	while (--tmout &&
	       !(sio_in(up, TXX9_SICISR) & TXX9_SICISR_TXALS))
		udelay(1);

	/* Wait up to 1s for flow control if necessary */
	if (up->port.flags & UPF_CONS_FLOW) {
		tmout = 1000000;
		while (--tmout &&
		       (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS))
			udelay(1);
	}
}

static void serial_txx9_console_putchar(struct uart_port *port, int ch)
{
	struct uart_txx9_port *up = (struct uart_txx9_port *)port;