All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH -mm 0/1] max3100: Fixes for the MAX31x0 console
@ 2010-04-08 17:02 christian pellegrin
  2010-04-08 17:02 ` [PATCH -mm 1/1] " Christian Pellegrin
  0 siblings, 1 reply; 2+ messages in thread
From: christian pellegrin @ 2010-04-08 17:02 UTC (permalink / raw)
  To: Andrew Morton, Feng Tang, Grant Likely, Alan Cox, linux-serial

This patch fixes the problems reported by Feng Tang in the console
code. After this I intend to do a complete rework to apply the ideas
outlined by Grant Likely to avoid the use of delayed work and, if I
find a way, the batching of TX requests proposed by Feng Tang and Alan
Cox (I guess I will have at least to add a new function to the SPI
core to know the real bit/rate the system is using to make this work).
The relevant patches from the -mm kernel were tested on a 2.6.34-rc2
kernel on a S3C ARM machine. This patch ris based on them.

-- 
Christian Pellegrin, see http://www.evolware.org/chri/
"Real Programmers don't play tennis, or any other sport which requires
you to change clothes. Mountain climbing is OK, and Real Programmers
wear their climbing boots to work in case a mountain should suddenly
spring up in the middle of the computer room."

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH -mm 1/1] max3100: Fixes for the MAX31x0 console
  2010-04-08 17:02 [PATCH -mm 0/1] max3100: Fixes for the MAX31x0 console christian pellegrin
@ 2010-04-08 17:02 ` Christian Pellegrin
  0 siblings, 0 replies; 2+ messages in thread
From: Christian Pellegrin @ 2010-04-08 17:02 UTC (permalink / raw)
  To: akpm, feng.tang, grant.likely, alan, linux-serial, spi-devel-general
  Cc: Christian Pellegrin

This patch fixes problems reported about the MAX31x0 console. RTS is
asserted only if flow control is explicitly enabled on kernel command
line. Chars inputed during console output are not lost.

Signed-off-by: Christian Pellegrin <chripell@fsfe.org>
---
 drivers/serial/max3100.c |   48 +++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/drivers/serial/max3100.c b/drivers/serial/max3100.c
index 6644222..c7def2f 100644
--- a/drivers/serial/max3100.c
+++ b/drivers/serial/max3100.c
@@ -147,6 +147,8 @@ struct max3100_port {
 	struct work_struct console_work;
 	/* char tx timeout */
 	int console_tout;
+	/* lock on receiving chars */
+	struct mutex rx_lock;
 #endif
 };
 
@@ -192,6 +194,19 @@ static void max3100_calc_parity(struct max3100_port *s, u16 *c)
 		*c |= max3100_do_parity(s, *c) << 8;
 }
 
+static void max3100_flip(struct max3100_port *s)
+{
+	if (s->port.state->port.tty != NULL) {
+#ifdef CONFIG_SERIAL_MAX3100_CONSOLE
+		mutex_lock(&s->rx_lock);
+#endif
+		tty_flip_buffer_push(s->port.state->port.tty);
+#ifdef CONFIG_SERIAL_MAX3100_CONSOLE
+		mutex_unlock(&s->rx_lock);
+#endif
+	}
+}
+
 static void max3100_resume_work(struct work_struct *w)
 {
 	struct max3100_port *s = container_of(w, struct max3100_port,
@@ -242,6 +257,10 @@ static int max3100_handlerx(struct max3100_port *s, u16 rx)
 	unsigned int ch, flg, status = 0;
 	int ret = 0, cts;
 
+#ifdef CONFIG_SERIAL_MAX3100_CONSOLE
+	mutex_lock(&s->rx_lock);
+#endif
+
 	if (rx & MAX3100_R && s->rx_enabled) {
 		dev_dbg(&s->spi->dev, "%s\n", __func__);
 		ch = rx & (s->parity & MAX3100_7BIT ? 0x7f : 0xff);
@@ -274,6 +293,10 @@ static int max3100_handlerx(struct max3100_port *s, u16 rx)
 		uart_handle_cts_change(&s->port, cts ? TIOCM_CTS : 0);
 	}
 
+#ifdef CONFIG_SERIAL_MAX3100_CONSOLE
+	mutex_unlock(&s->rx_lock);
+#endif
+
 	return ret;
 }
 
@@ -329,8 +352,8 @@ static irqreturn_t max3100_ist(int irq, void *dev_id)
 			}
 		}
 
-		if (rxchars > 16 && s->port.state->port.tty != NULL) {
-			tty_flip_buffer_push(s->port.state->port.tty);
+		if (rxchars > 16) {
+			max3100_flip(s);
 			rxchars = 0;
 		}
 		if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
@@ -341,8 +364,8 @@ static irqreturn_t max3100_ist(int irq, void *dev_id)
 		  (!uart_circ_empty(xmit) &&
 		   !uart_tx_stopped(&s->port))));
 
-	if (rxchars > 0 && s->port.state->port.tty != NULL)
-		tty_flip_buffer_push(s->port.state->port.tty);
+	if (rxchars > 0)
+		max3100_flip(s);
 
 	return IRQ_HANDLED;
 }
@@ -699,6 +722,7 @@ static void max3100_console_work(struct work_struct *w)
 					      console_work);
 	unsigned long start;
 	u16 tx, rx;
+	int rxchars = 0;
 
 	while (s->console_head != s->console_tail &&
 	       (s->console_flags & MAX3100_SUSPENDING) == 0) {
@@ -710,10 +734,19 @@ static void max3100_console_work(struct work_struct *w)
 			 !time_after(jiffies, start + s->console_tout));
 		tx = s->console_buf[s->console_tail];
 		max3100_calc_parity(s, &tx);
-		tx |= MAX3100_WD | MAX3100_RTS;
+		tx |= MAX3100_WD | (s->rts ? MAX3100_RTS : 0);
 		max3100_sr(s, tx, &rx);
+		if (s->port.state->port.tty != NULL) {
+			rxchars += max3100_handlerx(s, rx);
+			if (rxchars > 16) {
+				max3100_flip(s);
+				rxchars = 0;
+			}
+		}
 		s->console_tail = (s->console_tail + 1) % CONSOLE_BUF_SIZE;
 	}
+	if (rxchars)
+		max3100_flip(s);
 }
 
 static void max3100_console_putchar(struct uart_port *port, int ch)
@@ -809,6 +842,10 @@ static int max3100_console_setup(struct console *co, char *options)
 	if (parity == 'o')
 		s->parity |= MAX3100_PARITY_ODD;
 	s->console_tout = 1 + (20 * HZ) / baud; /* jiffies to send 20 bits */
+	if (flow != 'n')
+		s->rts = 1;
+	else
+		s->rts = 0;
 
 	tx |= MAX3100_WC;
 	max3100_sr(s, tx, &rx);
@@ -912,6 +949,7 @@ static int __devinit max3100_probe(struct spi_device *spi)
 			 i, retval);
 
 #ifdef CONFIG_SERIAL_MAX3100_CONSOLE
+	mutex_init(&max3100s[i]->rx_lock);
 	if (pdata->console && !max3100_console_registered) {
 		register_console(&max3100_console);
 		max3100_console_registered = 1;
-- 
1.5.6.5


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-04-08 17:02 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-08 17:02 [PATCH -mm 0/1] max3100: Fixes for the MAX31x0 console christian pellegrin
2010-04-08 17:02 ` [PATCH -mm 1/1] " Christian Pellegrin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.