linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Frank Rowand <frowand.list@gmail.com>
To: Stephen Boyd <sboyd@codeaurora.org>
Cc: David Brown <davidb@codeaurora.org>,
	Daniel Walker <dwalker@fifo99.com>,
	Bryan Huntsman <bryanh@codeaurora.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jiri Slaby <jslaby@suse.cz>,
	"linux-arm-msm@vger.kernel.org" <linux-arm-msm@vger.kernel.org>,
	linux-serial@vger.kernel.org,
	Linux Kernel list <linux-kernel@vger.kernel.org>,
	Jason Wessel <jason.wessel@windriver.com>,
	kgdb-bugreport@lists.sourceforge.net
Subject: [test patch 1/4] fix msm_serial for kgdb
Date: Mon, 04 Aug 2014 18:03:04 -0700	[thread overview]
Message-ID: <53E02D48.1080002@gmail.com> (raw)
In-Reply-To: <53E02C7C.4090206@gmail.com>

From: Frank Rowand <frank.rowand@sonymobile.com>

f7e54d7ad743 added support for poll_{get,put}_char()
Additional fixes to cope with single character mode on RX FIFO for
qcom,msm-uartdm-v1.4.

With these fixes, kgdb properly communicates with the dragon board, but
following the continue command, the serial driver does not get any stale
(UART_IMR_RXSTALE) interrupts until 48 characters have been read, which
triggers a high water interrupt.  After the high water interrupt has been
processed, the driver resumes properly getting stale interrupts.

Not-signed-off-by-yet: Frank Rowand <frank.rowand@sonymobile.com>

---
 drivers/tty/serial/msm_serial.c |   74 ++++++++++++++++++++++++++++++++--------
 1 file changed, 61 insertions(+), 13 deletions(-)

Index: b/drivers/tty/serial/msm_serial.c
===================================================================
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -54,6 +54,7 @@ struct msm_port {
 	unsigned int		imr;
 	void __iomem		*gsbi_base;
 	int			is_uartdm;
+	int			rx_sc_enabled;
 	unsigned int		old_snap_state;
 };
 
@@ -104,7 +105,10 @@ static void handle_rx_dm(struct uart_por
 	struct tty_port *tport = &port->state->port;
 	unsigned int sr;
 	int count = 0;
+	int imr_rx_stale = misr & UART_IMR_RXSTALE;
 	struct msm_port *msm_port = UART_TO_MSM(port);
+	int res;
+	char *cp;
 
 	if ((msm_read(port, UART_SR) & UART_SR_OVERRUN)) {
 		port->icount.overrun++;
@@ -112,12 +116,14 @@ static void handle_rx_dm(struct uart_por
 		msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR);
 	}
 
-	if (misr & UART_IMR_RXSTALE) {
+	if (imr_rx_stale) {
 		count = msm_read(port, UARTDM_RX_TOTAL_SNAP) -
 			msm_port->old_snap_state;
 		msm_port->old_snap_state = 0;
 	} else {
-		count = 4 * (msm_read(port, UART_RFWR));
+		count = msm_read(port, UART_RFWR);
+		if (!msm_port->rx_sc_enabled)
+			count = 4 * count;
 		msm_port->old_snap_state += count;
 	}
 
@@ -130,28 +136,60 @@ static void handle_rx_dm(struct uart_por
 
 		sr = msm_read(port, UART_SR);
 		if ((sr & UART_SR_RX_READY) == 0) {
-			msm_port->old_snap_state -= count;
+			if (!imr_rx_stale)
+				msm_port->old_snap_state -= count;
 			break;
 		}
+
 		c = msm_read(port, UARTDM_RF);
+
 		if (sr & UART_SR_RX_BREAK) {
 			port->icount.brk++;
-			if (uart_handle_break(port))
-				continue;
+			uart_handle_break(port);
+			if (msm_port->rx_sc_enabled)
+				count -= 1;
+			else
+				count -= 4;
+			continue;
 		} else if (sr & UART_SR_PAR_FRAME_ERR)
 			port->icount.frame++;
 
-		/* TODO: handle sysrq */
-		tty_insert_flip_string(tport, (char *)&c,
-				       (count > 4) ? 4 : count);
-		count -= 4;
+		if (msm_port->rx_sc_enabled) {
+			cp = (char *)&c;
+
+			spin_unlock(&port->lock);
+			res = uart_handle_sysrq_char(port, *cp);
+			spin_lock(&port->lock);
+
+			if (!res)
+				tty_insert_flip_string(tport, cp, 1);
+			count -= 1;
+		} else {
+			cp = (char *)&c;
+
+			spin_unlock(&port->lock);
+			res = uart_handle_sysrq_char(port, *cp);
+			spin_lock(&port->lock);
+
+			if (res) {
+				count -= 1;
+				cp++;
+				tty_insert_flip_string(tport, cp,
+					       (count > 3) ? 3 : count);
+				count -= 3;
+			} else {
+				tty_insert_flip_string(tport, cp,
+						       (count > 4) ? 4 : count);
+				count -= 4;
+			}
+		}
 	}
 
 	spin_unlock(&port->lock);
 	tty_flip_buffer_push(tport);
 	spin_lock(&port->lock);
 
-	if (misr & (UART_IMR_RXSTALE))
+	if (imr_rx_stale)
 		msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR);
 	msm_write(port, 0xFFFFFF, UARTDM_DMRX);
 	msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR);
@@ -413,8 +451,11 @@ static int msm_set_baud_rate(struct uart
 	watermark |= UART_IPR_STALE_TIMEOUT_MSB & (rxstale << 2);
 	msm_write(port, watermark, UART_IPR);
 
-	/* set RX watermark */
-	watermark = (port->fifosize * 3) / 4;
+	/* set RX watermark (number of words) */
+	if (msm_port->rx_sc_enabled)
+		watermark = (port->fifosize * 3) / 4;  /* 1 byte per word */
+	else
+		watermark = (port->fifosize * 3) / 16;  /* 4 bytes per word */
 	msm_write(port, watermark, UART_RFWR);
 
 	/* set TX watermark */
@@ -728,10 +769,17 @@ static void msm_power(struct uart_port *
 static int msm_poll_init(struct uart_port *port)
 {
 	struct msm_port *msm_port = UART_TO_MSM(port);
+	unsigned int watermark;
 
 	/* Enable single character mode on RX FIFO */
-	if (msm_port->is_uartdm >= UARTDM_1P4)
+	if (msm_port->is_uartdm >= UARTDM_1P4) {
 		msm_write(port, UARTDM_DMEN_RX_SC_ENABLE, UARTDM_DMEN);
+		msm_port->rx_sc_enabled = 1;
+	}
+
+	/* set RX watermark (number of words) */
+	watermark = (port->fifosize * 3) / 4;  /* 1 byte per word */
+	msm_write(port, watermark, UART_RFWR);
 
 	return 0;
 }

  reply	other threads:[~2014-08-05  1:03 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-05  0:59 [request for help] tty: serial: kgdb: fix msm_serial for kgdb Frank Rowand
2014-08-05  1:03 ` Frank Rowand [this message]
2014-08-05  1:04 ` [test patch 2/4] add poll_post_exception framework Frank Rowand
2014-08-05  1:06 ` [test patch 3/4] use poll_post_exception in msm_serial Frank Rowand
2014-08-05  1:08 ` [test patch 4/4] debug hackery to trace msm_serial receive interrupts Frank Rowand
2014-08-05  1:33 ` [request for help] tty: serial: kgdb: fix msm_serial for kgdb Stephen Boyd
2014-08-05  2:09   ` Frank Rowand
2014-08-05 19:22     ` Stephen Boyd
2014-08-05 23:53       ` Stephen Boyd
2014-08-06  0:55         ` Frank Rowand
2014-08-06  1:19           ` Stephen Boyd

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53E02D48.1080002@gmail.com \
    --to=frowand.list@gmail.com \
    --cc=bryanh@codeaurora.org \
    --cc=davidb@codeaurora.org \
    --cc=dwalker@fifo99.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jason.wessel@windriver.com \
    --cc=jslaby@suse.cz \
    --cc=kgdb-bugreport@lists.sourceforge.net \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=sboyd@codeaurora.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).