All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
@ 2015-08-17  7:22 ` Michal Simek
  0 siblings, 0 replies; 39+ messages in thread
From: Michal Simek @ 2015-08-17  7:22 UTC (permalink / raw)
  To: linux-kernel, monstr
  Cc: Anirudha Sarangi, Sören Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>

Existing set_termios does not handle the option for enabling
odd parity. This patch fixes it.

Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 drivers/tty/serial/xilinx_uartps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 009e0dbc12d2..a3020344ac9d 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port *port,
 	else
 		cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
 
-	if (termios->c_cflag & PARENB) {
+	if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
 		/* Mark or Space parity */
 		if (termios->c_cflag & CMSPAR) {
 			if (termios->c_cflag & PARODD)
-- 
2.3.5


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

* [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
@ 2015-08-17  7:22 ` Michal Simek
  0 siblings, 0 replies; 39+ messages in thread
From: Michal Simek @ 2015-08-17  7:22 UTC (permalink / raw)
  To: linux-kernel, monstr
  Cc: Anirudha Sarangi, Jiri Slaby, Sören Brinkmann, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>

Existing set_termios does not handle the option for enabling
odd parity. This patch fixes it.

Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 drivers/tty/serial/xilinx_uartps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 009e0dbc12d2..a3020344ac9d 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port *port,
 	else
 		cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
 
-	if (termios->c_cflag & PARENB) {
+	if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
 		/* Mark or Space parity */
 		if (termios->c_cflag & CMSPAR) {
 			if (termios->c_cflag & PARODD)
-- 
2.3.5

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

* [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
@ 2015-08-17  7:22 ` Michal Simek
  0 siblings, 0 replies; 39+ messages in thread
From: Michal Simek @ 2015-08-17  7:22 UTC (permalink / raw)
  To: linux-arm-kernel

From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>

Existing set_termios does not handle the option for enabling
odd parity. This patch fixes it.

Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 drivers/tty/serial/xilinx_uartps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 009e0dbc12d2..a3020344ac9d 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port *port,
 	else
 		cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
 
-	if (termios->c_cflag & PARENB) {
+	if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
 		/* Mark or Space parity */
 		if (termios->c_cflag & CMSPAR) {
 			if (termios->c_cflag & PARODD)
-- 
2.3.5

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

* [PATCH 2/4] serial: xuartps: Do not handle overrun errors under IGNPAR option
  2015-08-17  7:22 ` Michal Simek
@ 2015-08-17  7:22   ` Michal Simek
  -1 siblings, 0 replies; 39+ messages in thread
From: Michal Simek @ 2015-08-17  7:22 UTC (permalink / raw)
  To: linux-kernel, monstr
  Cc: Anirudha Sarangi, Sören Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>

The existing implementation includes overrun errors under IGNPAR
option. This patch fixes it by including only parity and framing
error under IGNPAR option.

Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 drivers/tty/serial/xilinx_uartps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index a3020344ac9d..c4437e8929ff 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct uart_port *port,
 
 	if (termios->c_iflag & IGNPAR)
 		port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
-			CDNS_UART_IXR_FRAMING | CDNS_UART_IXR_OVERRUN;
+					    CDNS_UART_IXR_FRAMING;
 
 	/* ignore all characters if CREAD is not set */
 	if ((termios->c_cflag & CREAD) == 0)
-- 
2.3.5


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

* [PATCH 2/4] serial: xuartps: Do not handle overrun errors under IGNPAR option
@ 2015-08-17  7:22   ` Michal Simek
  0 siblings, 0 replies; 39+ messages in thread
From: Michal Simek @ 2015-08-17  7:22 UTC (permalink / raw)
  To: linux-arm-kernel

From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>

The existing implementation includes overrun errors under IGNPAR
option. This patch fixes it by including only parity and framing
error under IGNPAR option.

Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 drivers/tty/serial/xilinx_uartps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index a3020344ac9d..c4437e8929ff 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct uart_port *port,
 
 	if (termios->c_iflag & IGNPAR)
 		port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
-			CDNS_UART_IXR_FRAMING | CDNS_UART_IXR_OVERRUN;
+					    CDNS_UART_IXR_FRAMING;
 
 	/* ignore all characters if CREAD is not set */
 	if ((termios->c_cflag & CREAD) == 0)
-- 
2.3.5

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

* [PATCH 3/4] serial: xuartps: Do not enable parity error interrupt
  2015-08-17  7:22 ` Michal Simek
@ 2015-08-17  7:22   ` Michal Simek
  -1 siblings, 0 replies; 39+ messages in thread
From: Michal Simek @ 2015-08-17  7:22 UTC (permalink / raw)
  To: linux-kernel, monstr
  Cc: Anirudha Sarangi, Sören Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>

The patch makes changes not to enable parity error interrupt.
With the current implementation, each parity error results in
two distinct interrupts (almost always). The first one is normal
parity error interrupt with no data in the fifo and the second one
is a proper Rx interrupt with the received data in the fifo. By
disabling parity error interrupt we still ensure handling of
parity errors as for the Rx fifo interrupt the parity error still
shows up in the interrupt status register. Considering the fact
that the by default INPCK and IGNPAR are not set, this is the
optimal implementation for parity error handling.

Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 drivers/tty/serial/xilinx_uartps.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index c4437e8929ff..2dc26e5f1384 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -803,8 +803,18 @@ static int cdns_uart_startup(struct uart_port *port)
 	writel(readl(port->membase + CDNS_UART_ISR_OFFSET),
 			port->membase + CDNS_UART_ISR_OFFSET);
 
-	/* Set the Interrupt Registers with desired interrupts */
-	writel(CDNS_UART_IXR_TXEMPTY | CDNS_UART_IXR_PARITY |
+	/*
+	 * Set the Interrupt Registers with desired interrupts. Do not
+	 * enable parity error interrupt for the following reason:
+	 * When parity error interrupt is enabled, each Rx parity error always
+	 * results in 2 events. The first one being parity error interrupt
+	 * and the second one with a proper Rx interrupt with the incoming data.
+	 * Disabling parity error interrupt ensures better handling of parity
+	 * error events. With this change, for a parity error case, we get a
+	 * Rx interrupt with parity error set in ISR register and we still
+	 * handle parity errors in the desired way.
+	 */
+	writel(CDNS_UART_IXR_TXEMPTY |
 		CDNS_UART_IXR_FRAMING | CDNS_UART_IXR_OVERRUN |
 		CDNS_UART_IXR_RXTRIG | CDNS_UART_IXR_TOUT,
 		port->membase + CDNS_UART_IER_OFFSET);
-- 
2.3.5


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

* [PATCH 3/4] serial: xuartps: Do not enable parity error interrupt
@ 2015-08-17  7:22   ` Michal Simek
  0 siblings, 0 replies; 39+ messages in thread
From: Michal Simek @ 2015-08-17  7:22 UTC (permalink / raw)
  To: linux-arm-kernel

From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>

The patch makes changes not to enable parity error interrupt.
With the current implementation, each parity error results in
two distinct interrupts (almost always). The first one is normal
parity error interrupt with no data in the fifo and the second one
is a proper Rx interrupt with the received data in the fifo. By
disabling parity error interrupt we still ensure handling of
parity errors as for the Rx fifo interrupt the parity error still
shows up in the interrupt status register. Considering the fact
that the by default INPCK and IGNPAR are not set, this is the
optimal implementation for parity error handling.

Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 drivers/tty/serial/xilinx_uartps.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index c4437e8929ff..2dc26e5f1384 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -803,8 +803,18 @@ static int cdns_uart_startup(struct uart_port *port)
 	writel(readl(port->membase + CDNS_UART_ISR_OFFSET),
 			port->membase + CDNS_UART_ISR_OFFSET);
 
-	/* Set the Interrupt Registers with desired interrupts */
-	writel(CDNS_UART_IXR_TXEMPTY | CDNS_UART_IXR_PARITY |
+	/*
+	 * Set the Interrupt Registers with desired interrupts. Do not
+	 * enable parity error interrupt for the following reason:
+	 * When parity error interrupt is enabled, each Rx parity error always
+	 * results in 2 events. The first one being parity error interrupt
+	 * and the second one with a proper Rx interrupt with the incoming data.
+	 * Disabling parity error interrupt ensures better handling of parity
+	 * error events. With this change, for a parity error case, we get a
+	 * Rx interrupt with parity error set in ISR register and we still
+	 * handle parity errors in the desired way.
+	 */
+	writel(CDNS_UART_IXR_TXEMPTY |
 		CDNS_UART_IXR_FRAMING | CDNS_UART_IXR_OVERRUN |
 		CDNS_UART_IXR_RXTRIG | CDNS_UART_IXR_TOUT,
 		port->membase + CDNS_UART_IER_OFFSET);
-- 
2.3.5

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

* [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
  2015-08-17  7:22 ` Michal Simek
@ 2015-08-17  7:22   ` Michal Simek
  -1 siblings, 0 replies; 39+ messages in thread
From: Michal Simek @ 2015-08-17  7:22 UTC (permalink / raw)
  To: linux-kernel, monstr
  Cc: Anirudha Sarangi, Sören Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>

The existing interrupt handling logic has followins issues.
- Upon a parity error with default configuration, the control
  never comes out of the ISR thereby hanging Linux.
- The error handling logic around framing and parity error are buggy.
  There are chances that the errors will never be captured.
- The existing ISR is just too long.
This patch fixes all these concerns. It separates out the Tx and Rx
hanling logic into separate functions. It ensures that the status
registers are cleared on all cases so that a hang situation never
arises.

Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 drivers/tty/serial/xilinx_uartps.c | 194 ++++++++++++++++++++-----------------
 1 file changed, 104 insertions(+), 90 deletions(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 2dc26e5f1384..c771dbbf6161 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -173,61 +173,86 @@ struct cdns_uart {
 		clk_rate_change_nb);
 
 /**
- * cdns_uart_isr - Interrupt handler
- * @irq: Irq number
- * @dev_id: Id of the port
- *
- * Return: IRQHANDLED
+ * cdns_uart_handle_tx - Handle the bytes to be Txed.
+ * @dev_id: Id of the UART port
+ * Return: None
  */
-static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
+static void cdns_uart_handle_tx(void *dev_id)
 {
 	struct uart_port *port = (struct uart_port *)dev_id;
-	unsigned long flags;
-	unsigned int isrstatus, numbytes;
-	unsigned int data;
-	char status = TTY_NORMAL;
+	unsigned int numbytes;
 
-	spin_lock_irqsave(&port->lock, flags);
+	if (uart_circ_empty(&port->state->xmit)) {
+		writel(CDNS_UART_IXR_TXEMPTY, port->membase +
+		       CDNS_UART_IDR_OFFSET);
+	} else {
+		numbytes = port->fifosize;
+		/* Break if no more data available in the UART buffer */
+		while (numbytes--) {
+			if (uart_circ_empty(&port->state->xmit))
+				break;
+			/*
+			 * Get the data from the UART circular buffer
+			 * and write it to the cdns_uart's TX_FIFO
+			 * register.
+			 */
+			writel(port->state->xmit.buf[port->state->xmit.tail],
+			       port->membase + CDNS_UART_FIFO_OFFSET);
 
-	/* Read the interrupt status register to determine which
-	 * interrupt(s) is/are active.
-	 */
-	isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
+			port->icount.tx++;
 
-	/*
-	 * There is no hardware break detection, so we interpret framing
-	 * error with all-zeros data as a break sequence. Most of the time,
-	 * there's another non-zero byte at the end of the sequence.
-	 */
-	if (isrstatus & CDNS_UART_IXR_FRAMING) {
-		while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
-					CDNS_UART_SR_RXEMPTY)) {
-			if (!readl(port->membase + CDNS_UART_FIFO_OFFSET)) {
-				port->read_status_mask |= CDNS_UART_IXR_BRK;
-				isrstatus &= ~CDNS_UART_IXR_FRAMING;
-			}
+			/*
+			 * Adjust the tail of the UART buffer and wrap
+			 * the buffer if it reaches limit.
+			 */
+			port->state->xmit.tail =
+				(port->state->xmit.tail + 1) &
+					(UART_XMIT_SIZE - 1);
 		}
-		writel(CDNS_UART_IXR_FRAMING,
-				port->membase + CDNS_UART_ISR_OFFSET);
-	}
 
-	/* drop byte with parity error if IGNPAR specified */
-	if (isrstatus & port->ignore_status_mask & CDNS_UART_IXR_PARITY)
-		isrstatus &= ~(CDNS_UART_IXR_RXTRIG | CDNS_UART_IXR_TOUT);
+		if (uart_circ_chars_pending(
+				&port->state->xmit) < WAKEUP_CHARS)
+			uart_write_wakeup(port);
+	}
+}
 
-	isrstatus &= port->read_status_mask;
-	isrstatus &= ~port->ignore_status_mask;
+/**
+ * cdns_uart_handle_rx - Handle the received bytes along with Rx errors.
+ * @dev_id: Id of the UART port
+ * @isrstatus: The interrupt status register value as read
+ * Return: None
+ */
+static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus)
+{
+	struct uart_port *port = (struct uart_port *)dev_id;
+	unsigned int data;
+	unsigned int framerrprocessed = 0;
+	char status = TTY_NORMAL;
 
-	if ((isrstatus & CDNS_UART_IXR_TOUT) ||
-		(isrstatus & CDNS_UART_IXR_RXTRIG)) {
-		/* Receive Timeout Interrupt */
-		while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
-					CDNS_UART_SR_RXEMPTY)) {
-			data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
+	while ((readl(port->membase + CDNS_UART_SR_OFFSET) &
+		CDNS_UART_SR_RXEMPTY) != CDNS_UART_SR_RXEMPTY) {
+		data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
+		port->icount.rx++;
+		/*
+		 * There is no hardware break detection, so we interpret
+		 * framing error with all-zeros data as a break sequence.
+		 * Most of the time, there's another non-zero byte at the
+		 * end of the sequence.
+		 */
+		if (isrstatus & CDNS_UART_IXR_FRAMING) {
+			if (!data) {
+				port->read_status_mask |= CDNS_UART_IXR_BRK;
+				framerrprocessed = 1;
+				continue;
+			}
+		}
+		isrstatus &= port->read_status_mask;
+		isrstatus &= ~port->ignore_status_mask;
 
-			/* Non-NULL byte after BREAK is garbage (99%) */
-			if (data && (port->read_status_mask &
-						CDNS_UART_IXR_BRK)) {
+		if ((isrstatus & CDNS_UART_IXR_TOUT) ||
+		    (isrstatus & CDNS_UART_IXR_RXTRIG)) {
+			if (data &&
+			    (port->read_status_mask & CDNS_UART_IXR_BRK)) {
 				port->read_status_mask &= ~CDNS_UART_IXR_BRK;
 				port->icount.brk++;
 				if (uart_handle_break(port))
@@ -249,67 +274,56 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
 				spin_lock(&port->lock);
 			}
 #endif
-
-			port->icount.rx++;
-
 			if (isrstatus & CDNS_UART_IXR_PARITY) {
 				port->icount.parity++;
 				status = TTY_PARITY;
-			} else if (isrstatus & CDNS_UART_IXR_FRAMING) {
+			}
+			if ((isrstatus & CDNS_UART_IXR_FRAMING) &&
+			    !framerrprocessed) {
 				port->icount.frame++;
 				status = TTY_FRAME;
-			} else if (isrstatus & CDNS_UART_IXR_OVERRUN) {
+			}
+			if (isrstatus & CDNS_UART_IXR_OVERRUN) {
 				port->icount.overrun++;
+				tty_insert_flip_char(&port->state->port, 0,
+						     TTY_OVERRUN);
 			}
-
-			uart_insert_char(port, isrstatus, CDNS_UART_IXR_OVERRUN,
-					data, status);
+			tty_insert_flip_char(&port->state->port, data, status);
 		}
-		spin_unlock(&port->lock);
-		tty_flip_buffer_push(&port->state->port);
-		spin_lock(&port->lock);
 	}
+	spin_unlock(&port->lock);
+	tty_flip_buffer_push(&port->state->port);
+	spin_lock(&port->lock);
+}
 
-	/* Dispatch an appropriate handler */
-	if ((isrstatus & CDNS_UART_IXR_TXEMPTY) == CDNS_UART_IXR_TXEMPTY) {
-		if (uart_circ_empty(&port->state->xmit)) {
-			writel(CDNS_UART_IXR_TXEMPTY,
-					port->membase + CDNS_UART_IDR_OFFSET);
-		} else {
-			numbytes = port->fifosize;
-			/* Break if no more data available in the UART buffer */
-			while (numbytes--) {
-				if (uart_circ_empty(&port->state->xmit))
-					break;
-				/* Get the data from the UART circular buffer
-				 * and write it to the cdns_uart's TX_FIFO
-				 * register.
-				 */
-				writel(port->state->xmit.buf[
-						port->state->xmit.tail],
-					port->membase + CDNS_UART_FIFO_OFFSET);
-
-				port->icount.tx++;
-
-				/* Adjust the tail of the UART buffer and wrap
-				 * the buffer if it reaches limit.
-				 */
-				port->state->xmit.tail =
-					(port->state->xmit.tail + 1) &
-						(UART_XMIT_SIZE - 1);
-			}
+/**
+ * cdns_uart_isr - Interrupt handler
+ * @irq: Irq number
+ * @dev_id: Id of the port
+ *
+ * Return: IRQHANDLED
+ */
+static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
+{
+	struct uart_port *port = (struct uart_port *)dev_id;
+	unsigned int isrstatus;
 
-			if (uart_circ_chars_pending(
-					&port->state->xmit) < WAKEUP_CHARS)
-				uart_write_wakeup(port);
-		}
-	}
+	spin_lock(&port->lock);
 
+	/* Read the interrupt status register to determine which
+	 * interrupt(s) is/are active and clear them.
+	 */
+	isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
 	writel(isrstatus, port->membase + CDNS_UART_ISR_OFFSET);
 
-	/* be sure to release the lock and tty before leaving */
-	spin_unlock_irqrestore(&port->lock, flags);
+	if (isrstatus & CDNS_UART_IXR_TXEMPTY) {
+		cdns_uart_handle_tx(dev_id);
+		isrstatus &= ~CDNS_UART_IXR_TXEMPTY;
+	}
+	if (isrstatus & CDNS_UART_IXR_MASK)
+		cdns_uart_handle_rx(dev_id, isrstatus);
 
+	spin_unlock(&port->lock);
 	return IRQ_HANDLED;
 }
 
-- 
2.3.5


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

* [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
@ 2015-08-17  7:22   ` Michal Simek
  0 siblings, 0 replies; 39+ messages in thread
From: Michal Simek @ 2015-08-17  7:22 UTC (permalink / raw)
  To: linux-arm-kernel

From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>

The existing interrupt handling logic has followins issues.
- Upon a parity error with default configuration, the control
  never comes out of the ISR thereby hanging Linux.
- The error handling logic around framing and parity error are buggy.
  There are chances that the errors will never be captured.
- The existing ISR is just too long.
This patch fixes all these concerns. It separates out the Tx and Rx
hanling logic into separate functions. It ensures that the status
registers are cleared on all cases so that a hang situation never
arises.

Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---

 drivers/tty/serial/xilinx_uartps.c | 194 ++++++++++++++++++++-----------------
 1 file changed, 104 insertions(+), 90 deletions(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index 2dc26e5f1384..c771dbbf6161 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -173,61 +173,86 @@ struct cdns_uart {
 		clk_rate_change_nb);
 
 /**
- * cdns_uart_isr - Interrupt handler
- * @irq: Irq number
- * @dev_id: Id of the port
- *
- * Return: IRQHANDLED
+ * cdns_uart_handle_tx - Handle the bytes to be Txed.
+ * @dev_id: Id of the UART port
+ * Return: None
  */
-static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
+static void cdns_uart_handle_tx(void *dev_id)
 {
 	struct uart_port *port = (struct uart_port *)dev_id;
-	unsigned long flags;
-	unsigned int isrstatus, numbytes;
-	unsigned int data;
-	char status = TTY_NORMAL;
+	unsigned int numbytes;
 
-	spin_lock_irqsave(&port->lock, flags);
+	if (uart_circ_empty(&port->state->xmit)) {
+		writel(CDNS_UART_IXR_TXEMPTY, port->membase +
+		       CDNS_UART_IDR_OFFSET);
+	} else {
+		numbytes = port->fifosize;
+		/* Break if no more data available in the UART buffer */
+		while (numbytes--) {
+			if (uart_circ_empty(&port->state->xmit))
+				break;
+			/*
+			 * Get the data from the UART circular buffer
+			 * and write it to the cdns_uart's TX_FIFO
+			 * register.
+			 */
+			writel(port->state->xmit.buf[port->state->xmit.tail],
+			       port->membase + CDNS_UART_FIFO_OFFSET);
 
-	/* Read the interrupt status register to determine which
-	 * interrupt(s) is/are active.
-	 */
-	isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
+			port->icount.tx++;
 
-	/*
-	 * There is no hardware break detection, so we interpret framing
-	 * error with all-zeros data as a break sequence. Most of the time,
-	 * there's another non-zero byte at the end of the sequence.
-	 */
-	if (isrstatus & CDNS_UART_IXR_FRAMING) {
-		while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
-					CDNS_UART_SR_RXEMPTY)) {
-			if (!readl(port->membase + CDNS_UART_FIFO_OFFSET)) {
-				port->read_status_mask |= CDNS_UART_IXR_BRK;
-				isrstatus &= ~CDNS_UART_IXR_FRAMING;
-			}
+			/*
+			 * Adjust the tail of the UART buffer and wrap
+			 * the buffer if it reaches limit.
+			 */
+			port->state->xmit.tail =
+				(port->state->xmit.tail + 1) &
+					(UART_XMIT_SIZE - 1);
 		}
-		writel(CDNS_UART_IXR_FRAMING,
-				port->membase + CDNS_UART_ISR_OFFSET);
-	}
 
-	/* drop byte with parity error if IGNPAR specified */
-	if (isrstatus & port->ignore_status_mask & CDNS_UART_IXR_PARITY)
-		isrstatus &= ~(CDNS_UART_IXR_RXTRIG | CDNS_UART_IXR_TOUT);
+		if (uart_circ_chars_pending(
+				&port->state->xmit) < WAKEUP_CHARS)
+			uart_write_wakeup(port);
+	}
+}
 
-	isrstatus &= port->read_status_mask;
-	isrstatus &= ~port->ignore_status_mask;
+/**
+ * cdns_uart_handle_rx - Handle the received bytes along with Rx errors.
+ * @dev_id: Id of the UART port
+ * @isrstatus: The interrupt status register value as read
+ * Return: None
+ */
+static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus)
+{
+	struct uart_port *port = (struct uart_port *)dev_id;
+	unsigned int data;
+	unsigned int framerrprocessed = 0;
+	char status = TTY_NORMAL;
 
-	if ((isrstatus & CDNS_UART_IXR_TOUT) ||
-		(isrstatus & CDNS_UART_IXR_RXTRIG)) {
-		/* Receive Timeout Interrupt */
-		while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
-					CDNS_UART_SR_RXEMPTY)) {
-			data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
+	while ((readl(port->membase + CDNS_UART_SR_OFFSET) &
+		CDNS_UART_SR_RXEMPTY) != CDNS_UART_SR_RXEMPTY) {
+		data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
+		port->icount.rx++;
+		/*
+		 * There is no hardware break detection, so we interpret
+		 * framing error with all-zeros data as a break sequence.
+		 * Most of the time, there's another non-zero byte at the
+		 * end of the sequence.
+		 */
+		if (isrstatus & CDNS_UART_IXR_FRAMING) {
+			if (!data) {
+				port->read_status_mask |= CDNS_UART_IXR_BRK;
+				framerrprocessed = 1;
+				continue;
+			}
+		}
+		isrstatus &= port->read_status_mask;
+		isrstatus &= ~port->ignore_status_mask;
 
-			/* Non-NULL byte after BREAK is garbage (99%) */
-			if (data && (port->read_status_mask &
-						CDNS_UART_IXR_BRK)) {
+		if ((isrstatus & CDNS_UART_IXR_TOUT) ||
+		    (isrstatus & CDNS_UART_IXR_RXTRIG)) {
+			if (data &&
+			    (port->read_status_mask & CDNS_UART_IXR_BRK)) {
 				port->read_status_mask &= ~CDNS_UART_IXR_BRK;
 				port->icount.brk++;
 				if (uart_handle_break(port))
@@ -249,67 +274,56 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
 				spin_lock(&port->lock);
 			}
 #endif
-
-			port->icount.rx++;
-
 			if (isrstatus & CDNS_UART_IXR_PARITY) {
 				port->icount.parity++;
 				status = TTY_PARITY;
-			} else if (isrstatus & CDNS_UART_IXR_FRAMING) {
+			}
+			if ((isrstatus & CDNS_UART_IXR_FRAMING) &&
+			    !framerrprocessed) {
 				port->icount.frame++;
 				status = TTY_FRAME;
-			} else if (isrstatus & CDNS_UART_IXR_OVERRUN) {
+			}
+			if (isrstatus & CDNS_UART_IXR_OVERRUN) {
 				port->icount.overrun++;
+				tty_insert_flip_char(&port->state->port, 0,
+						     TTY_OVERRUN);
 			}
-
-			uart_insert_char(port, isrstatus, CDNS_UART_IXR_OVERRUN,
-					data, status);
+			tty_insert_flip_char(&port->state->port, data, status);
 		}
-		spin_unlock(&port->lock);
-		tty_flip_buffer_push(&port->state->port);
-		spin_lock(&port->lock);
 	}
+	spin_unlock(&port->lock);
+	tty_flip_buffer_push(&port->state->port);
+	spin_lock(&port->lock);
+}
 
-	/* Dispatch an appropriate handler */
-	if ((isrstatus & CDNS_UART_IXR_TXEMPTY) == CDNS_UART_IXR_TXEMPTY) {
-		if (uart_circ_empty(&port->state->xmit)) {
-			writel(CDNS_UART_IXR_TXEMPTY,
-					port->membase + CDNS_UART_IDR_OFFSET);
-		} else {
-			numbytes = port->fifosize;
-			/* Break if no more data available in the UART buffer */
-			while (numbytes--) {
-				if (uart_circ_empty(&port->state->xmit))
-					break;
-				/* Get the data from the UART circular buffer
-				 * and write it to the cdns_uart's TX_FIFO
-				 * register.
-				 */
-				writel(port->state->xmit.buf[
-						port->state->xmit.tail],
-					port->membase + CDNS_UART_FIFO_OFFSET);
-
-				port->icount.tx++;
-
-				/* Adjust the tail of the UART buffer and wrap
-				 * the buffer if it reaches limit.
-				 */
-				port->state->xmit.tail =
-					(port->state->xmit.tail + 1) &
-						(UART_XMIT_SIZE - 1);
-			}
+/**
+ * cdns_uart_isr - Interrupt handler
+ * @irq: Irq number
+ * @dev_id: Id of the port
+ *
+ * Return: IRQHANDLED
+ */
+static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
+{
+	struct uart_port *port = (struct uart_port *)dev_id;
+	unsigned int isrstatus;
 
-			if (uart_circ_chars_pending(
-					&port->state->xmit) < WAKEUP_CHARS)
-				uart_write_wakeup(port);
-		}
-	}
+	spin_lock(&port->lock);
 
+	/* Read the interrupt status register to determine which
+	 * interrupt(s) is/are active and clear them.
+	 */
+	isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
 	writel(isrstatus, port->membase + CDNS_UART_ISR_OFFSET);
 
-	/* be sure to release the lock and tty before leaving */
-	spin_unlock_irqrestore(&port->lock, flags);
+	if (isrstatus & CDNS_UART_IXR_TXEMPTY) {
+		cdns_uart_handle_tx(dev_id);
+		isrstatus &= ~CDNS_UART_IXR_TXEMPTY;
+	}
+	if (isrstatus & CDNS_UART_IXR_MASK)
+		cdns_uart_handle_rx(dev_id, isrstatus);
 
+	spin_unlock(&port->lock);
 	return IRQ_HANDLED;
 }
 
-- 
2.3.5

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

* Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
  2015-08-17  7:22 ` Michal Simek
@ 2015-08-17 15:39   ` Peter Hurley
  -1 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 15:39 UTC (permalink / raw)
  To: Michal Simek
  Cc: linux-kernel, monstr, Anirudha Sarangi, Sören Brinkmann,
	Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel

On 08/17/2015 03:22 AM, Michal Simek wrote:
> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> 
> Existing set_termios does not handle the option for enabling
> odd parity. This patch fixes it.

NAK. PARODD does not enable parity generation or detection.

Regards,
Peter Hurley

> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> ---
> 
>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
> index 009e0dbc12d2..a3020344ac9d 100644
> --- a/drivers/tty/serial/xilinx_uartps.c
> +++ b/drivers/tty/serial/xilinx_uartps.c
> @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port *port,
>  	else
>  		cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
>  
> -	if (termios->c_cflag & PARENB) {
> +	if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
>  		/* Mark or Space parity */
>  		if (termios->c_cflag & CMSPAR) {
>  			if (termios->c_cflag & PARODD)
> 


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

* [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
@ 2015-08-17 15:39   ` Peter Hurley
  0 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 15:39 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/17/2015 03:22 AM, Michal Simek wrote:
> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> 
> Existing set_termios does not handle the option for enabling
> odd parity. This patch fixes it.

NAK. PARODD does not enable parity generation or detection.

Regards,
Peter Hurley

> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> ---
> 
>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
> index 009e0dbc12d2..a3020344ac9d 100644
> --- a/drivers/tty/serial/xilinx_uartps.c
> +++ b/drivers/tty/serial/xilinx_uartps.c
> @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port *port,
>  	else
>  		cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
>  
> -	if (termios->c_cflag & PARENB) {
> +	if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
>  		/* Mark or Space parity */
>  		if (termios->c_cflag & CMSPAR) {
>  			if (termios->c_cflag & PARODD)
> 

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

* Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under IGNPAR option
  2015-08-17  7:22   ` Michal Simek
@ 2015-08-17 15:49     ` Peter Hurley
  -1 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 15:49 UTC (permalink / raw)
  To: Michal Simek
  Cc: linux-kernel, monstr, Anirudha Sarangi, Sören Brinkmann,
	Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel

On 08/17/2015 03:22 AM, Michal Simek wrote:
> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> 
> The existing implementation includes overrun errors under IGNPAR
> option. This patch fixes it by including only parity and framing
> error under IGNPAR option.

The convention adopted by Linux serial drivers is to ignore overrun
errors if both IGNPAR and IGNBRK are set.

Regards,
Peter Hurley

> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> ---
> 
>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
> index a3020344ac9d..c4437e8929ff 100644
> --- a/drivers/tty/serial/xilinx_uartps.c
> +++ b/drivers/tty/serial/xilinx_uartps.c
> @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct uart_port *port,
>  
>  	if (termios->c_iflag & IGNPAR)
>  		port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
> -			CDNS_UART_IXR_FRAMING | CDNS_UART_IXR_OVERRUN;
> +					    CDNS_UART_IXR_FRAMING;
>  
>  	/* ignore all characters if CREAD is not set */
>  	if ((termios->c_cflag & CREAD) == 0)
> 


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

* [PATCH 2/4] serial: xuartps: Do not handle overrun errors under IGNPAR option
@ 2015-08-17 15:49     ` Peter Hurley
  0 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 15:49 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/17/2015 03:22 AM, Michal Simek wrote:
> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> 
> The existing implementation includes overrun errors under IGNPAR
> option. This patch fixes it by including only parity and framing
> error under IGNPAR option.

The convention adopted by Linux serial drivers is to ignore overrun
errors if both IGNPAR and IGNBRK are set.

Regards,
Peter Hurley

> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> ---
> 
>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
> index a3020344ac9d..c4437e8929ff 100644
> --- a/drivers/tty/serial/xilinx_uartps.c
> +++ b/drivers/tty/serial/xilinx_uartps.c
> @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct uart_port *port,
>  
>  	if (termios->c_iflag & IGNPAR)
>  		port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
> -			CDNS_UART_IXR_FRAMING | CDNS_UART_IXR_OVERRUN;
> +					    CDNS_UART_IXR_FRAMING;
>  
>  	/* ignore all characters if CREAD is not set */
>  	if ((termios->c_cflag & CREAD) == 0)
> 

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

* RE: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
  2015-08-17 15:39   ` Peter Hurley
  (?)
@ 2015-08-17 15:55     ` Anirudha Sarangi
  -1 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 15:55 UTC (permalink / raw)
  To: Peter Hurley, Michal Simek
  Cc: linux-kernel, monstr, Soren Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 2342 bytes --]

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:09 PM
> To: Michal Simek
> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Anirudha Sarangi; Soren
> Brinkmann; Jiri Slaby; linux-serial@vger.kernel.org; Greg Kroah-Hartman; linux-
> arm-kernel@lists.infradead.org
> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
>
> On 08/17/2015 03:22 AM, Michal Simek wrote:
> > From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >
> > Existing set_termios does not handle the option for enabling odd
> > parity. This patch fixes it.
>
> NAK. PARODD does not enable parity generation or detection.
>
What if someone is trying to change from even to odd parity?
In this conditional case, we setup some register bit for the same.
Is the above use case not a valid one?

Regards
Anirudha

> Regards,
> Peter Hurley
>
> > Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> > Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> > ---
> >
> >  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/tty/serial/xilinx_uartps.c
> > b/drivers/tty/serial/xilinx_uartps.c
> > index 009e0dbc12d2..a3020344ac9d 100644
> > --- a/drivers/tty/serial/xilinx_uartps.c
> > +++ b/drivers/tty/serial/xilinx_uartps.c
> > @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port
> *port,
> >     else
> >             cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
> >
> > -   if (termios->c_cflag & PARENB) {
> > +   if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
> >             /* Mark or Space parity */
> >             if (termios->c_cflag & CMSPAR) {
> >                     if (termios->c_cflag & PARODD)
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* RE: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
@ 2015-08-17 15:55     ` Anirudha Sarangi
  0 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 15:55 UTC (permalink / raw)
  To: Peter Hurley, Michal Simek
  Cc: monstr, Greg Kroah-Hartman, linux-kernel, Soren Brinkmann,
	linux-serial, Jiri Slaby, linux-arm-kernel

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:09 PM
> To: Michal Simek
> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Anirudha Sarangi; Soren
> Brinkmann; Jiri Slaby; linux-serial@vger.kernel.org; Greg Kroah-Hartman; linux-
> arm-kernel@lists.infradead.org
> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
>
> On 08/17/2015 03:22 AM, Michal Simek wrote:
> > From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >
> > Existing set_termios does not handle the option for enabling odd
> > parity. This patch fixes it.
>
> NAK. PARODD does not enable parity generation or detection.
>
What if someone is trying to change from even to odd parity?
In this conditional case, we setup some register bit for the same.
Is the above use case not a valid one?

Regards
Anirudha

> Regards,
> Peter Hurley
>
> > Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> > Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> > ---
> >
> >  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/tty/serial/xilinx_uartps.c
> > b/drivers/tty/serial/xilinx_uartps.c
> > index 009e0dbc12d2..a3020344ac9d 100644
> > --- a/drivers/tty/serial/xilinx_uartps.c
> > +++ b/drivers/tty/serial/xilinx_uartps.c
> > @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port
> *port,
> >     else
> >             cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
> >
> > -   if (termios->c_cflag & PARENB) {
> > +   if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
> >             /* Mark or Space parity */
> >             if (termios->c_cflag & CMSPAR) {
> >                     if (termios->c_cflag & PARODD)
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
@ 2015-08-17 15:55     ` Anirudha Sarangi
  0 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 15:55 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:09 PM
> To: Michal Simek
> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Anirudha Sarangi; Soren
> Brinkmann; Jiri Slaby; linux-serial at vger.kernel.org; Greg Kroah-Hartman; linux-
> arm-kernel at lists.infradead.org
> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
>
> On 08/17/2015 03:22 AM, Michal Simek wrote:
> > From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >
> > Existing set_termios does not handle the option for enabling odd
> > parity. This patch fixes it.
>
> NAK. PARODD does not enable parity generation or detection.
>
What if someone is trying to change from even to odd parity?
In this conditional case, we setup some register bit for the same.
Is the above use case not a valid one?

Regards
Anirudha

> Regards,
> Peter Hurley
>
> > Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> > Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> > ---
> >
> >  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/tty/serial/xilinx_uartps.c
> > b/drivers/tty/serial/xilinx_uartps.c
> > index 009e0dbc12d2..a3020344ac9d 100644
> > --- a/drivers/tty/serial/xilinx_uartps.c
> > +++ b/drivers/tty/serial/xilinx_uartps.c
> > @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port
> *port,
> >     else
> >             cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
> >
> > -   if (termios->c_cflag & PARENB) {
> > +   if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
> >             /* Mark or Space parity */
> >             if (termios->c_cflag & CMSPAR) {
> >                     if (termios->c_cflag & PARODD)
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* Re: [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
  2015-08-17  7:22   ` Michal Simek
@ 2015-08-17 15:55     ` Peter Hurley
  -1 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 15:55 UTC (permalink / raw)
  To: Michal Simek
  Cc: linux-kernel, monstr, Anirudha Sarangi, Sören Brinkmann,
	Jiri Slaby, linux-serial, Greg Kroah-Hartman, linux-arm-kernel

On 08/17/2015 03:22 AM, Michal Simek wrote:
> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> 
> The existing interrupt handling logic has followins issues.
> - Upon a parity error with default configuration, the control
>   never comes out of the ISR thereby hanging Linux.
> - The error handling logic around framing and parity error are buggy.
>   There are chances that the errors will never be captured.
> - The existing ISR is just too long.
> This patch fixes all these concerns.

This patch is unreviewable. Please break this down into multiple patches.

Regards,
Peter Hurley

> It separates out the Tx and Rx
> hanling logic into separate functions. It ensures that the status
> registers are cleared on all cases so that a hang situation never
> arises.
> 
> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> ---
> 
>  drivers/tty/serial/xilinx_uartps.c | 194 ++++++++++++++++++++-----------------
>  1 file changed, 104 insertions(+), 90 deletions(-)
> 
> diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
> index 2dc26e5f1384..c771dbbf6161 100644
> --- a/drivers/tty/serial/xilinx_uartps.c
> +++ b/drivers/tty/serial/xilinx_uartps.c
> @@ -173,61 +173,86 @@ struct cdns_uart {
>  		clk_rate_change_nb);
>  
>  /**
> - * cdns_uart_isr - Interrupt handler
> - * @irq: Irq number
> - * @dev_id: Id of the port
> - *
> - * Return: IRQHANDLED
> + * cdns_uart_handle_tx - Handle the bytes to be Txed.
> + * @dev_id: Id of the UART port
> + * Return: None
>   */
> -static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
> +static void cdns_uart_handle_tx(void *dev_id)
>  {
>  	struct uart_port *port = (struct uart_port *)dev_id;
> -	unsigned long flags;
> -	unsigned int isrstatus, numbytes;
> -	unsigned int data;
> -	char status = TTY_NORMAL;
> +	unsigned int numbytes;
>  
> -	spin_lock_irqsave(&port->lock, flags);
> +	if (uart_circ_empty(&port->state->xmit)) {
> +		writel(CDNS_UART_IXR_TXEMPTY, port->membase +
> +		       CDNS_UART_IDR_OFFSET);
> +	} else {
> +		numbytes = port->fifosize;
> +		/* Break if no more data available in the UART buffer */
> +		while (numbytes--) {
> +			if (uart_circ_empty(&port->state->xmit))
> +				break;
> +			/*
> +			 * Get the data from the UART circular buffer
> +			 * and write it to the cdns_uart's TX_FIFO
> +			 * register.
> +			 */
> +			writel(port->state->xmit.buf[port->state->xmit.tail],
> +			       port->membase + CDNS_UART_FIFO_OFFSET);
>  
> -	/* Read the interrupt status register to determine which
> -	 * interrupt(s) is/are active.
> -	 */
> -	isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
> +			port->icount.tx++;
>  
> -	/*
> -	 * There is no hardware break detection, so we interpret framing
> -	 * error with all-zeros data as a break sequence. Most of the time,
> -	 * there's another non-zero byte at the end of the sequence.
> -	 */
> -	if (isrstatus & CDNS_UART_IXR_FRAMING) {
> -		while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
> -					CDNS_UART_SR_RXEMPTY)) {
> -			if (!readl(port->membase + CDNS_UART_FIFO_OFFSET)) {
> -				port->read_status_mask |= CDNS_UART_IXR_BRK;
> -				isrstatus &= ~CDNS_UART_IXR_FRAMING;
> -			}
> +			/*
> +			 * Adjust the tail of the UART buffer and wrap
> +			 * the buffer if it reaches limit.
> +			 */
> +			port->state->xmit.tail =
> +				(port->state->xmit.tail + 1) &
> +					(UART_XMIT_SIZE - 1);
>  		}
> -		writel(CDNS_UART_IXR_FRAMING,
> -				port->membase + CDNS_UART_ISR_OFFSET);
> -	}
>  
> -	/* drop byte with parity error if IGNPAR specified */
> -	if (isrstatus & port->ignore_status_mask & CDNS_UART_IXR_PARITY)
> -		isrstatus &= ~(CDNS_UART_IXR_RXTRIG | CDNS_UART_IXR_TOUT);
> +		if (uart_circ_chars_pending(
> +				&port->state->xmit) < WAKEUP_CHARS)
> +			uart_write_wakeup(port);
> +	}
> +}
>  
> -	isrstatus &= port->read_status_mask;
> -	isrstatus &= ~port->ignore_status_mask;
> +/**
> + * cdns_uart_handle_rx - Handle the received bytes along with Rx errors.
> + * @dev_id: Id of the UART port
> + * @isrstatus: The interrupt status register value as read
> + * Return: None
> + */
> +static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus)
> +{
> +	struct uart_port *port = (struct uart_port *)dev_id;
> +	unsigned int data;
> +	unsigned int framerrprocessed = 0;
> +	char status = TTY_NORMAL;
>  
> -	if ((isrstatus & CDNS_UART_IXR_TOUT) ||
> -		(isrstatus & CDNS_UART_IXR_RXTRIG)) {
> -		/* Receive Timeout Interrupt */
> -		while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
> -					CDNS_UART_SR_RXEMPTY)) {
> -			data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
> +	while ((readl(port->membase + CDNS_UART_SR_OFFSET) &
> +		CDNS_UART_SR_RXEMPTY) != CDNS_UART_SR_RXEMPTY) {
> +		data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
> +		port->icount.rx++;
> +		/*
> +		 * There is no hardware break detection, so we interpret
> +		 * framing error with all-zeros data as a break sequence.
> +		 * Most of the time, there's another non-zero byte at the
> +		 * end of the sequence.
> +		 */
> +		if (isrstatus & CDNS_UART_IXR_FRAMING) {
> +			if (!data) {
> +				port->read_status_mask |= CDNS_UART_IXR_BRK;
> +				framerrprocessed = 1;
> +				continue;
> +			}
> +		}
> +		isrstatus &= port->read_status_mask;
> +		isrstatus &= ~port->ignore_status_mask;
>  
> -			/* Non-NULL byte after BREAK is garbage (99%) */
> -			if (data && (port->read_status_mask &
> -						CDNS_UART_IXR_BRK)) {
> +		if ((isrstatus & CDNS_UART_IXR_TOUT) ||
> +		    (isrstatus & CDNS_UART_IXR_RXTRIG)) {
> +			if (data &&
> +			    (port->read_status_mask & CDNS_UART_IXR_BRK)) {
>  				port->read_status_mask &= ~CDNS_UART_IXR_BRK;
>  				port->icount.brk++;
>  				if (uart_handle_break(port))
> @@ -249,67 +274,56 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
>  				spin_lock(&port->lock);
>  			}
>  #endif
> -
> -			port->icount.rx++;
> -
>  			if (isrstatus & CDNS_UART_IXR_PARITY) {
>  				port->icount.parity++;
>  				status = TTY_PARITY;
> -			} else if (isrstatus & CDNS_UART_IXR_FRAMING) {
> +			}
> +			if ((isrstatus & CDNS_UART_IXR_FRAMING) &&
> +			    !framerrprocessed) {
>  				port->icount.frame++;
>  				status = TTY_FRAME;
> -			} else if (isrstatus & CDNS_UART_IXR_OVERRUN) {
> +			}
> +			if (isrstatus & CDNS_UART_IXR_OVERRUN) {
>  				port->icount.overrun++;
> +				tty_insert_flip_char(&port->state->port, 0,
> +						     TTY_OVERRUN);
>  			}
> -
> -			uart_insert_char(port, isrstatus, CDNS_UART_IXR_OVERRUN,
> -					data, status);
> +			tty_insert_flip_char(&port->state->port, data, status);
>  		}
> -		spin_unlock(&port->lock);
> -		tty_flip_buffer_push(&port->state->port);
> -		spin_lock(&port->lock);
>  	}
> +	spin_unlock(&port->lock);
> +	tty_flip_buffer_push(&port->state->port);
> +	spin_lock(&port->lock);
> +}
>  
> -	/* Dispatch an appropriate handler */
> -	if ((isrstatus & CDNS_UART_IXR_TXEMPTY) == CDNS_UART_IXR_TXEMPTY) {
> -		if (uart_circ_empty(&port->state->xmit)) {
> -			writel(CDNS_UART_IXR_TXEMPTY,
> -					port->membase + CDNS_UART_IDR_OFFSET);
> -		} else {
> -			numbytes = port->fifosize;
> -			/* Break if no more data available in the UART buffer */
> -			while (numbytes--) {
> -				if (uart_circ_empty(&port->state->xmit))
> -					break;
> -				/* Get the data from the UART circular buffer
> -				 * and write it to the cdns_uart's TX_FIFO
> -				 * register.
> -				 */
> -				writel(port->state->xmit.buf[
> -						port->state->xmit.tail],
> -					port->membase + CDNS_UART_FIFO_OFFSET);
> -
> -				port->icount.tx++;
> -
> -				/* Adjust the tail of the UART buffer and wrap
> -				 * the buffer if it reaches limit.
> -				 */
> -				port->state->xmit.tail =
> -					(port->state->xmit.tail + 1) &
> -						(UART_XMIT_SIZE - 1);
> -			}
> +/**
> + * cdns_uart_isr - Interrupt handler
> + * @irq: Irq number
> + * @dev_id: Id of the port
> + *
> + * Return: IRQHANDLED
> + */
> +static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
> +{
> +	struct uart_port *port = (struct uart_port *)dev_id;
> +	unsigned int isrstatus;
>  
> -			if (uart_circ_chars_pending(
> -					&port->state->xmit) < WAKEUP_CHARS)
> -				uart_write_wakeup(port);
> -		}
> -	}
> +	spin_lock(&port->lock);
>  
> +	/* Read the interrupt status register to determine which
> +	 * interrupt(s) is/are active and clear them.
> +	 */
> +	isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
>  	writel(isrstatus, port->membase + CDNS_UART_ISR_OFFSET);
>  
> -	/* be sure to release the lock and tty before leaving */
> -	spin_unlock_irqrestore(&port->lock, flags);
> +	if (isrstatus & CDNS_UART_IXR_TXEMPTY) {
> +		cdns_uart_handle_tx(dev_id);
> +		isrstatus &= ~CDNS_UART_IXR_TXEMPTY;
> +	}
> +	if (isrstatus & CDNS_UART_IXR_MASK)
> +		cdns_uart_handle_rx(dev_id, isrstatus);
>  
> +	spin_unlock(&port->lock);
>  	return IRQ_HANDLED;
>  }
>  
> 


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

* [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
@ 2015-08-17 15:55     ` Peter Hurley
  0 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 15:55 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/17/2015 03:22 AM, Michal Simek wrote:
> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> 
> The existing interrupt handling logic has followins issues.
> - Upon a parity error with default configuration, the control
>   never comes out of the ISR thereby hanging Linux.
> - The error handling logic around framing and parity error are buggy.
>   There are chances that the errors will never be captured.
> - The existing ISR is just too long.
> This patch fixes all these concerns.

This patch is unreviewable. Please break this down into multiple patches.

Regards,
Peter Hurley

> It separates out the Tx and Rx
> hanling logic into separate functions. It ensures that the status
> registers are cleared on all cases so that a hang situation never
> arises.
> 
> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> ---
> 
>  drivers/tty/serial/xilinx_uartps.c | 194 ++++++++++++++++++++-----------------
>  1 file changed, 104 insertions(+), 90 deletions(-)
> 
> diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
> index 2dc26e5f1384..c771dbbf6161 100644
> --- a/drivers/tty/serial/xilinx_uartps.c
> +++ b/drivers/tty/serial/xilinx_uartps.c
> @@ -173,61 +173,86 @@ struct cdns_uart {
>  		clk_rate_change_nb);
>  
>  /**
> - * cdns_uart_isr - Interrupt handler
> - * @irq: Irq number
> - * @dev_id: Id of the port
> - *
> - * Return: IRQHANDLED
> + * cdns_uart_handle_tx - Handle the bytes to be Txed.
> + * @dev_id: Id of the UART port
> + * Return: None
>   */
> -static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
> +static void cdns_uart_handle_tx(void *dev_id)
>  {
>  	struct uart_port *port = (struct uart_port *)dev_id;
> -	unsigned long flags;
> -	unsigned int isrstatus, numbytes;
> -	unsigned int data;
> -	char status = TTY_NORMAL;
> +	unsigned int numbytes;
>  
> -	spin_lock_irqsave(&port->lock, flags);
> +	if (uart_circ_empty(&port->state->xmit)) {
> +		writel(CDNS_UART_IXR_TXEMPTY, port->membase +
> +		       CDNS_UART_IDR_OFFSET);
> +	} else {
> +		numbytes = port->fifosize;
> +		/* Break if no more data available in the UART buffer */
> +		while (numbytes--) {
> +			if (uart_circ_empty(&port->state->xmit))
> +				break;
> +			/*
> +			 * Get the data from the UART circular buffer
> +			 * and write it to the cdns_uart's TX_FIFO
> +			 * register.
> +			 */
> +			writel(port->state->xmit.buf[port->state->xmit.tail],
> +			       port->membase + CDNS_UART_FIFO_OFFSET);
>  
> -	/* Read the interrupt status register to determine which
> -	 * interrupt(s) is/are active.
> -	 */
> -	isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
> +			port->icount.tx++;
>  
> -	/*
> -	 * There is no hardware break detection, so we interpret framing
> -	 * error with all-zeros data as a break sequence. Most of the time,
> -	 * there's another non-zero byte at the end of the sequence.
> -	 */
> -	if (isrstatus & CDNS_UART_IXR_FRAMING) {
> -		while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
> -					CDNS_UART_SR_RXEMPTY)) {
> -			if (!readl(port->membase + CDNS_UART_FIFO_OFFSET)) {
> -				port->read_status_mask |= CDNS_UART_IXR_BRK;
> -				isrstatus &= ~CDNS_UART_IXR_FRAMING;
> -			}
> +			/*
> +			 * Adjust the tail of the UART buffer and wrap
> +			 * the buffer if it reaches limit.
> +			 */
> +			port->state->xmit.tail =
> +				(port->state->xmit.tail + 1) &
> +					(UART_XMIT_SIZE - 1);
>  		}
> -		writel(CDNS_UART_IXR_FRAMING,
> -				port->membase + CDNS_UART_ISR_OFFSET);
> -	}
>  
> -	/* drop byte with parity error if IGNPAR specified */
> -	if (isrstatus & port->ignore_status_mask & CDNS_UART_IXR_PARITY)
> -		isrstatus &= ~(CDNS_UART_IXR_RXTRIG | CDNS_UART_IXR_TOUT);
> +		if (uart_circ_chars_pending(
> +				&port->state->xmit) < WAKEUP_CHARS)
> +			uart_write_wakeup(port);
> +	}
> +}
>  
> -	isrstatus &= port->read_status_mask;
> -	isrstatus &= ~port->ignore_status_mask;
> +/**
> + * cdns_uart_handle_rx - Handle the received bytes along with Rx errors.
> + * @dev_id: Id of the UART port
> + * @isrstatus: The interrupt status register value as read
> + * Return: None
> + */
> +static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus)
> +{
> +	struct uart_port *port = (struct uart_port *)dev_id;
> +	unsigned int data;
> +	unsigned int framerrprocessed = 0;
> +	char status = TTY_NORMAL;
>  
> -	if ((isrstatus & CDNS_UART_IXR_TOUT) ||
> -		(isrstatus & CDNS_UART_IXR_RXTRIG)) {
> -		/* Receive Timeout Interrupt */
> -		while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
> -					CDNS_UART_SR_RXEMPTY)) {
> -			data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
> +	while ((readl(port->membase + CDNS_UART_SR_OFFSET) &
> +		CDNS_UART_SR_RXEMPTY) != CDNS_UART_SR_RXEMPTY) {
> +		data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
> +		port->icount.rx++;
> +		/*
> +		 * There is no hardware break detection, so we interpret
> +		 * framing error with all-zeros data as a break sequence.
> +		 * Most of the time, there's another non-zero byte at the
> +		 * end of the sequence.
> +		 */
> +		if (isrstatus & CDNS_UART_IXR_FRAMING) {
> +			if (!data) {
> +				port->read_status_mask |= CDNS_UART_IXR_BRK;
> +				framerrprocessed = 1;
> +				continue;
> +			}
> +		}
> +		isrstatus &= port->read_status_mask;
> +		isrstatus &= ~port->ignore_status_mask;
>  
> -			/* Non-NULL byte after BREAK is garbage (99%) */
> -			if (data && (port->read_status_mask &
> -						CDNS_UART_IXR_BRK)) {
> +		if ((isrstatus & CDNS_UART_IXR_TOUT) ||
> +		    (isrstatus & CDNS_UART_IXR_RXTRIG)) {
> +			if (data &&
> +			    (port->read_status_mask & CDNS_UART_IXR_BRK)) {
>  				port->read_status_mask &= ~CDNS_UART_IXR_BRK;
>  				port->icount.brk++;
>  				if (uart_handle_break(port))
> @@ -249,67 +274,56 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
>  				spin_lock(&port->lock);
>  			}
>  #endif
> -
> -			port->icount.rx++;
> -
>  			if (isrstatus & CDNS_UART_IXR_PARITY) {
>  				port->icount.parity++;
>  				status = TTY_PARITY;
> -			} else if (isrstatus & CDNS_UART_IXR_FRAMING) {
> +			}
> +			if ((isrstatus & CDNS_UART_IXR_FRAMING) &&
> +			    !framerrprocessed) {
>  				port->icount.frame++;
>  				status = TTY_FRAME;
> -			} else if (isrstatus & CDNS_UART_IXR_OVERRUN) {
> +			}
> +			if (isrstatus & CDNS_UART_IXR_OVERRUN) {
>  				port->icount.overrun++;
> +				tty_insert_flip_char(&port->state->port, 0,
> +						     TTY_OVERRUN);
>  			}
> -
> -			uart_insert_char(port, isrstatus, CDNS_UART_IXR_OVERRUN,
> -					data, status);
> +			tty_insert_flip_char(&port->state->port, data, status);
>  		}
> -		spin_unlock(&port->lock);
> -		tty_flip_buffer_push(&port->state->port);
> -		spin_lock(&port->lock);
>  	}
> +	spin_unlock(&port->lock);
> +	tty_flip_buffer_push(&port->state->port);
> +	spin_lock(&port->lock);
> +}
>  
> -	/* Dispatch an appropriate handler */
> -	if ((isrstatus & CDNS_UART_IXR_TXEMPTY) == CDNS_UART_IXR_TXEMPTY) {
> -		if (uart_circ_empty(&port->state->xmit)) {
> -			writel(CDNS_UART_IXR_TXEMPTY,
> -					port->membase + CDNS_UART_IDR_OFFSET);
> -		} else {
> -			numbytes = port->fifosize;
> -			/* Break if no more data available in the UART buffer */
> -			while (numbytes--) {
> -				if (uart_circ_empty(&port->state->xmit))
> -					break;
> -				/* Get the data from the UART circular buffer
> -				 * and write it to the cdns_uart's TX_FIFO
> -				 * register.
> -				 */
> -				writel(port->state->xmit.buf[
> -						port->state->xmit.tail],
> -					port->membase + CDNS_UART_FIFO_OFFSET);
> -
> -				port->icount.tx++;
> -
> -				/* Adjust the tail of the UART buffer and wrap
> -				 * the buffer if it reaches limit.
> -				 */
> -				port->state->xmit.tail =
> -					(port->state->xmit.tail + 1) &
> -						(UART_XMIT_SIZE - 1);
> -			}
> +/**
> + * cdns_uart_isr - Interrupt handler
> + * @irq: Irq number
> + * @dev_id: Id of the port
> + *
> + * Return: IRQHANDLED
> + */
> +static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
> +{
> +	struct uart_port *port = (struct uart_port *)dev_id;
> +	unsigned int isrstatus;
>  
> -			if (uart_circ_chars_pending(
> -					&port->state->xmit) < WAKEUP_CHARS)
> -				uart_write_wakeup(port);
> -		}
> -	}
> +	spin_lock(&port->lock);
>  
> +	/* Read the interrupt status register to determine which
> +	 * interrupt(s) is/are active and clear them.
> +	 */
> +	isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
>  	writel(isrstatus, port->membase + CDNS_UART_ISR_OFFSET);
>  
> -	/* be sure to release the lock and tty before leaving */
> -	spin_unlock_irqrestore(&port->lock, flags);
> +	if (isrstatus & CDNS_UART_IXR_TXEMPTY) {
> +		cdns_uart_handle_tx(dev_id);
> +		isrstatus &= ~CDNS_UART_IXR_TXEMPTY;
> +	}
> +	if (isrstatus & CDNS_UART_IXR_MASK)
> +		cdns_uart_handle_rx(dev_id, isrstatus);
>  
> +	spin_unlock(&port->lock);
>  	return IRQ_HANDLED;
>  }
>  
> 

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

* RE: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under IGNPAR option
  2015-08-17 15:49     ` Peter Hurley
  (?)
@ 2015-08-17 15:58       ` Anirudha Sarangi
  -1 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 15:58 UTC (permalink / raw)
  To: Peter Hurley, Michal Simek
  Cc: linux-kernel, monstr, Soren Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 2519 bytes --]

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:20 PM
> To: Michal Simek
> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Anirudha Sarangi; Soren
> Brinkmann; Jiri Slaby; linux-serial@vger.kernel.org; Greg Kroah-Hartman; linux-
> arm-kernel@lists.infradead.org
> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
> IGNPAR option
>
> On 08/17/2015 03:22 AM, Michal Simek wrote:
> > From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >
> > The existing implementation includes overrun errors under IGNPAR
> > option. This patch fixes it by including only parity and framing error
> > under IGNPAR option.
>
> The convention adopted by Linux serial drivers is to ignore overrun errors if both
> IGNPAR and IGNBRK are set.
>
I just followed the set_termios documentation, which says that IGNPAR is for parity and framing.
The current controller does not support break detection reliably.
That is probably why we don’t have IGNBRK.

Regards
Anirudha

> Regards,
> Peter Hurley
>
> > Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> > Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> > ---
> >
> >  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/tty/serial/xilinx_uartps.c
> > b/drivers/tty/serial/xilinx_uartps.c
> > index a3020344ac9d..c4437e8929ff 100644
> > --- a/drivers/tty/serial/xilinx_uartps.c
> > +++ b/drivers/tty/serial/xilinx_uartps.c
> > @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct uart_port
> > *port,
> >
> >     if (termios->c_iflag & IGNPAR)
> >             port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
> > -                   CDNS_UART_IXR_FRAMING |
> CDNS_UART_IXR_OVERRUN;
> > +                                       CDNS_UART_IXR_FRAMING;
> >
> >     /* ignore all characters if CREAD is not set */
> >     if ((termios->c_cflag & CREAD) == 0)
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* RE: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under IGNPAR option
@ 2015-08-17 15:58       ` Anirudha Sarangi
  0 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 15:58 UTC (permalink / raw)
  To: Peter Hurley, Michal Simek
  Cc: monstr, Greg Kroah-Hartman, linux-kernel, Soren Brinkmann,
	linux-serial, Jiri Slaby, linux-arm-kernel

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:20 PM
> To: Michal Simek
> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Anirudha Sarangi; Soren
> Brinkmann; Jiri Slaby; linux-serial@vger.kernel.org; Greg Kroah-Hartman; linux-
> arm-kernel@lists.infradead.org
> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
> IGNPAR option
>
> On 08/17/2015 03:22 AM, Michal Simek wrote:
> > From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >
> > The existing implementation includes overrun errors under IGNPAR
> > option. This patch fixes it by including only parity and framing error
> > under IGNPAR option.
>
> The convention adopted by Linux serial drivers is to ignore overrun errors if both
> IGNPAR and IGNBRK are set.
>
I just followed the set_termios documentation, which says that IGNPAR is for parity and framing.
The current controller does not support break detection reliably.
That is probably why we don’t have IGNBRK.

Regards
Anirudha

> Regards,
> Peter Hurley
>
> > Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> > Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> > ---
> >
> >  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/tty/serial/xilinx_uartps.c
> > b/drivers/tty/serial/xilinx_uartps.c
> > index a3020344ac9d..c4437e8929ff 100644
> > --- a/drivers/tty/serial/xilinx_uartps.c
> > +++ b/drivers/tty/serial/xilinx_uartps.c
> > @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct uart_port
> > *port,
> >
> >     if (termios->c_iflag & IGNPAR)
> >             port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
> > -                   CDNS_UART_IXR_FRAMING |
> CDNS_UART_IXR_OVERRUN;
> > +                                       CDNS_UART_IXR_FRAMING;
> >
> >     /* ignore all characters if CREAD is not set */
> >     if ((termios->c_cflag & CREAD) == 0)
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 2/4] serial: xuartps: Do not handle overrun errors under IGNPAR option
@ 2015-08-17 15:58       ` Anirudha Sarangi
  0 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 15:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:20 PM
> To: Michal Simek
> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Anirudha Sarangi; Soren
> Brinkmann; Jiri Slaby; linux-serial at vger.kernel.org; Greg Kroah-Hartman; linux-
> arm-kernel at lists.infradead.org
> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
> IGNPAR option
>
> On 08/17/2015 03:22 AM, Michal Simek wrote:
> > From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >
> > The existing implementation includes overrun errors under IGNPAR
> > option. This patch fixes it by including only parity and framing error
> > under IGNPAR option.
>
> The convention adopted by Linux serial drivers is to ignore overrun errors if both
> IGNPAR and IGNBRK are set.
>
I just followed the set_termios documentation, which says that IGNPAR is for parity and framing.
The current controller does not support break detection reliably.
That is probably why we don?t have IGNBRK.

Regards
Anirudha

> Regards,
> Peter Hurley
>
> > Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> > Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> > ---
> >
> >  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/tty/serial/xilinx_uartps.c
> > b/drivers/tty/serial/xilinx_uartps.c
> > index a3020344ac9d..c4437e8929ff 100644
> > --- a/drivers/tty/serial/xilinx_uartps.c
> > +++ b/drivers/tty/serial/xilinx_uartps.c
> > @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct uart_port
> > *port,
> >
> >     if (termios->c_iflag & IGNPAR)
> >             port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
> > -                   CDNS_UART_IXR_FRAMING |
> CDNS_UART_IXR_OVERRUN;
> > +                                       CDNS_UART_IXR_FRAMING;
> >
> >     /* ignore all characters if CREAD is not set */
> >     if ((termios->c_cflag & CREAD) == 0)
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* RE: [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
  2015-08-17 15:55     ` Peter Hurley
  (?)
@ 2015-08-17 16:00       ` Anirudha Sarangi
  -1 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 16:00 UTC (permalink / raw)
  To: Peter Hurley, Michal Simek
  Cc: linux-kernel, monstr, Soren Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 12843 bytes --]

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:26 PM
> To: Michal Simek
> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Anirudha Sarangi; Soren
> Brinkmann; Jiri Slaby; linux-serial@vger.kernel.org; Greg Kroah-Hartman; linux-
> arm-kernel@lists.infradead.org
> Subject: Re: [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
>
> On 08/17/2015 03:22 AM, Michal Simek wrote:
> > From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >
> > The existing interrupt handling logic has followins issues.
> > - Upon a parity error with default configuration, the control
> >   never comes out of the ISR thereby hanging Linux.
> > - The error handling logic around framing and parity error are buggy.
> >   There are chances that the errors will never be captured.
> > - The existing ISR is just too long.
> > This patch fixes all these concerns.
>
> This patch is unreviewable. Please break this down into multiple patches.
>
Thanks. Let me give a shot. It is just breaking the single big ISR that has both Rx and Tx in a single function into smaller ones.
Not sure how I will create smaller patches, but I will try and get back.

Regards
Anirudha

> Regards,
> Peter Hurley
>
> > It separates out the Tx and Rx
> > hanling logic into separate functions. It ensures that the status
> > registers are cleared on all cases so that a hang situation never
> > arises.
> >
> > Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> > Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> > ---
> >
> >  drivers/tty/serial/xilinx_uartps.c | 194
> > ++++++++++++++++++++-----------------
> >  1 file changed, 104 insertions(+), 90 deletions(-)
> >
> > diff --git a/drivers/tty/serial/xilinx_uartps.c
> > b/drivers/tty/serial/xilinx_uartps.c
> > index 2dc26e5f1384..c771dbbf6161 100644
> > --- a/drivers/tty/serial/xilinx_uartps.c
> > +++ b/drivers/tty/serial/xilinx_uartps.c
> > @@ -173,61 +173,86 @@ struct cdns_uart {
> >             clk_rate_change_nb);
> >
> >  /**
> > - * cdns_uart_isr - Interrupt handler
> > - * @irq: Irq number
> > - * @dev_id: Id of the port
> > - *
> > - * Return: IRQHANDLED
> > + * cdns_uart_handle_tx - Handle the bytes to be Txed.
> > + * @dev_id: Id of the UART port
> > + * Return: None
> >   */
> > -static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
> > +static void cdns_uart_handle_tx(void *dev_id)
> >  {
> >     struct uart_port *port = (struct uart_port *)dev_id;
> > -   unsigned long flags;
> > -   unsigned int isrstatus, numbytes;
> > -   unsigned int data;
> > -   char status = TTY_NORMAL;
> > +   unsigned int numbytes;
> >
> > -   spin_lock_irqsave(&port->lock, flags);
> > +   if (uart_circ_empty(&port->state->xmit)) {
> > +           writel(CDNS_UART_IXR_TXEMPTY, port->membase +
> > +                  CDNS_UART_IDR_OFFSET);
> > +   } else {
> > +           numbytes = port->fifosize;
> > +           /* Break if no more data available in the UART buffer */
> > +           while (numbytes--) {
> > +                   if (uart_circ_empty(&port->state->xmit))
> > +                           break;
> > +                   /*
> > +                    * Get the data from the UART circular buffer
> > +                    * and write it to the cdns_uart's TX_FIFO
> > +                    * register.
> > +                    */
> > +                   writel(port->state->xmit.buf[port->state->xmit.tail],
> > +                          port->membase + CDNS_UART_FIFO_OFFSET);
> >
> > -   /* Read the interrupt status register to determine which
> > -    * interrupt(s) is/are active.
> > -    */
> > -   isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
> > +                   port->icount.tx++;
> >
> > -   /*
> > -    * There is no hardware break detection, so we interpret framing
> > -    * error with all-zeros data as a break sequence. Most of the time,
> > -    * there's another non-zero byte at the end of the sequence.
> > -    */
> > -   if (isrstatus & CDNS_UART_IXR_FRAMING) {
> > -           while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
> > -                                   CDNS_UART_SR_RXEMPTY)) {
> > -                   if (!readl(port->membase + CDNS_UART_FIFO_OFFSET))
> {
> > -                           port->read_status_mask |=
> CDNS_UART_IXR_BRK;
> > -                           isrstatus &= ~CDNS_UART_IXR_FRAMING;
> > -                   }
> > +                   /*
> > +                    * Adjust the tail of the UART buffer and wrap
> > +                    * the buffer if it reaches limit.
> > +                    */
> > +                   port->state->xmit.tail =
> > +                           (port->state->xmit.tail + 1) &
> > +                                   (UART_XMIT_SIZE - 1);
> >             }
> > -           writel(CDNS_UART_IXR_FRAMING,
> > -                           port->membase + CDNS_UART_ISR_OFFSET);
> > -   }
> >
> > -   /* drop byte with parity error if IGNPAR specified */
> > -   if (isrstatus & port->ignore_status_mask & CDNS_UART_IXR_PARITY)
> > -           isrstatus &= ~(CDNS_UART_IXR_RXTRIG |
> CDNS_UART_IXR_TOUT);
> > +           if (uart_circ_chars_pending(
> > +                           &port->state->xmit) < WAKEUP_CHARS)
> > +                   uart_write_wakeup(port);
> > +   }
> > +}
> >
> > -   isrstatus &= port->read_status_mask;
> > -   isrstatus &= ~port->ignore_status_mask;
> > +/**
> > + * cdns_uart_handle_rx - Handle the received bytes along with Rx errors.
> > + * @dev_id: Id of the UART port
> > + * @isrstatus: The interrupt status register value as read
> > + * Return: None
> > + */
> > +static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus)
> > +{
> > +   struct uart_port *port = (struct uart_port *)dev_id;
> > +   unsigned int data;
> > +   unsigned int framerrprocessed = 0;
> > +   char status = TTY_NORMAL;
> >
> > -   if ((isrstatus & CDNS_UART_IXR_TOUT) ||
> > -           (isrstatus & CDNS_UART_IXR_RXTRIG)) {
> > -           /* Receive Timeout Interrupt */
> > -           while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
> > -                                   CDNS_UART_SR_RXEMPTY)) {
> > -                   data = readl(port->membase +
> CDNS_UART_FIFO_OFFSET);
> > +   while ((readl(port->membase + CDNS_UART_SR_OFFSET) &
> > +           CDNS_UART_SR_RXEMPTY) != CDNS_UART_SR_RXEMPTY) {
> > +           data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
> > +           port->icount.rx++;
> > +           /*
> > +            * There is no hardware break detection, so we interpret
> > +            * framing error with all-zeros data as a break sequence.
> > +            * Most of the time, there's another non-zero byte at the
> > +            * end of the sequence.
> > +            */
> > +           if (isrstatus & CDNS_UART_IXR_FRAMING) {
> > +                   if (!data) {
> > +                           port->read_status_mask |=
> CDNS_UART_IXR_BRK;
> > +                           framerrprocessed = 1;
> > +                           continue;
> > +                   }
> > +           }
> > +           isrstatus &= port->read_status_mask;
> > +           isrstatus &= ~port->ignore_status_mask;
> >
> > -                   /* Non-NULL byte after BREAK is garbage (99%) */
> > -                   if (data && (port->read_status_mask &
> > -                                           CDNS_UART_IXR_BRK)) {
> > +           if ((isrstatus & CDNS_UART_IXR_TOUT) ||
> > +               (isrstatus & CDNS_UART_IXR_RXTRIG)) {
> > +                   if (data &&
> > +                       (port->read_status_mask & CDNS_UART_IXR_BRK)) {
> >                             port->read_status_mask &=
> ~CDNS_UART_IXR_BRK;
> >                             port->icount.brk++;
> >                             if (uart_handle_break(port))
> > @@ -249,67 +274,56 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
> >                             spin_lock(&port->lock);
> >                     }
> >  #endif
> > -
> > -                   port->icount.rx++;
> > -
> >                     if (isrstatus & CDNS_UART_IXR_PARITY) {
> >                             port->icount.parity++;
> >                             status = TTY_PARITY;
> > -                   } else if (isrstatus & CDNS_UART_IXR_FRAMING) {
> > +                   }
> > +                   if ((isrstatus & CDNS_UART_IXR_FRAMING) &&
> > +                       !framerrprocessed) {
> >                             port->icount.frame++;
> >                             status = TTY_FRAME;
> > -                   } else if (isrstatus & CDNS_UART_IXR_OVERRUN) {
> > +                   }
> > +                   if (isrstatus & CDNS_UART_IXR_OVERRUN) {
> >                             port->icount.overrun++;
> > +                           tty_insert_flip_char(&port->state->port, 0,
> > +                                                TTY_OVERRUN);
> >                     }
> > -
> > -                   uart_insert_char(port, isrstatus,
> CDNS_UART_IXR_OVERRUN,
> > -                                   data, status);
> > +                   tty_insert_flip_char(&port->state->port, data, status);
> >             }
> > -           spin_unlock(&port->lock);
> > -           tty_flip_buffer_push(&port->state->port);
> > -           spin_lock(&port->lock);
> >     }
> > +   spin_unlock(&port->lock);
> > +   tty_flip_buffer_push(&port->state->port);
> > +   spin_lock(&port->lock);
> > +}
> >
> > -   /* Dispatch an appropriate handler */
> > -   if ((isrstatus & CDNS_UART_IXR_TXEMPTY) ==
> CDNS_UART_IXR_TXEMPTY) {
> > -           if (uart_circ_empty(&port->state->xmit)) {
> > -                   writel(CDNS_UART_IXR_TXEMPTY,
> > -                                   port->membase +
> CDNS_UART_IDR_OFFSET);
> > -           } else {
> > -                   numbytes = port->fifosize;
> > -                   /* Break if no more data available in the UART buffer */
> > -                   while (numbytes--) {
> > -                           if (uart_circ_empty(&port->state->xmit))
> > -                                   break;
> > -                           /* Get the data from the UART circular buffer
> > -                            * and write it to the cdns_uart's TX_FIFO
> > -                            * register.
> > -                            */
> > -                           writel(port->state->xmit.buf[
> > -                                           port->state->xmit.tail],
> > -                                   port->membase +
> CDNS_UART_FIFO_OFFSET);
> > -
> > -                           port->icount.tx++;
> > -
> > -                           /* Adjust the tail of the UART buffer and wrap
> > -                            * the buffer if it reaches limit.
> > -                            */
> > -                           port->state->xmit.tail =
> > -                                   (port->state->xmit.tail + 1) &
> > -                                           (UART_XMIT_SIZE - 1);
> > -                   }
> > +/**
> > + * cdns_uart_isr - Interrupt handler
> > + * @irq: Irq number
> > + * @dev_id: Id of the port
> > + *
> > + * Return: IRQHANDLED
> > + */
> > +static irqreturn_t cdns_uart_isr(int irq, void *dev_id) {
> > +   struct uart_port *port = (struct uart_port *)dev_id;
> > +   unsigned int isrstatus;
> >
> > -                   if (uart_circ_chars_pending(
> > -                                   &port->state->xmit) < WAKEUP_CHARS)
> > -                           uart_write_wakeup(port);
> > -           }
> > -   }
> > +   spin_lock(&port->lock);
> >
> > +   /* Read the interrupt status register to determine which
> > +    * interrupt(s) is/are active and clear them.
> > +    */
> > +   isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
> >     writel(isrstatus, port->membase + CDNS_UART_ISR_OFFSET);
> >
> > -   /* be sure to release the lock and tty before leaving */
> > -   spin_unlock_irqrestore(&port->lock, flags);
> > +   if (isrstatus & CDNS_UART_IXR_TXEMPTY) {
> > +           cdns_uart_handle_tx(dev_id);
> > +           isrstatus &= ~CDNS_UART_IXR_TXEMPTY;
> > +   }
> > +   if (isrstatus & CDNS_UART_IXR_MASK)
> > +           cdns_uart_handle_rx(dev_id, isrstatus);
> >
> > +   spin_unlock(&port->lock);
> >     return IRQ_HANDLED;
> >  }
> >
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* RE: [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
@ 2015-08-17 16:00       ` Anirudha Sarangi
  0 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 16:00 UTC (permalink / raw)
  To: Peter Hurley, Michal Simek
  Cc: monstr, Greg Kroah-Hartman, linux-kernel, Soren Brinkmann,
	linux-serial, Jiri Slaby, linux-arm-kernel

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:26 PM
> To: Michal Simek
> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Anirudha Sarangi; Soren
> Brinkmann; Jiri Slaby; linux-serial@vger.kernel.org; Greg Kroah-Hartman; linux-
> arm-kernel@lists.infradead.org
> Subject: Re: [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
>
> On 08/17/2015 03:22 AM, Michal Simek wrote:
> > From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >
> > The existing interrupt handling logic has followins issues.
> > - Upon a parity error with default configuration, the control
> >   never comes out of the ISR thereby hanging Linux.
> > - The error handling logic around framing and parity error are buggy.
> >   There are chances that the errors will never be captured.
> > - The existing ISR is just too long.
> > This patch fixes all these concerns.
>
> This patch is unreviewable. Please break this down into multiple patches.
>
Thanks. Let me give a shot. It is just breaking the single big ISR that has both Rx and Tx in a single function into smaller ones.
Not sure how I will create smaller patches, but I will try and get back.

Regards
Anirudha

> Regards,
> Peter Hurley
>
> > It separates out the Tx and Rx
> > hanling logic into separate functions. It ensures that the status
> > registers are cleared on all cases so that a hang situation never
> > arises.
> >
> > Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> > Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> > ---
> >
> >  drivers/tty/serial/xilinx_uartps.c | 194
> > ++++++++++++++++++++-----------------
> >  1 file changed, 104 insertions(+), 90 deletions(-)
> >
> > diff --git a/drivers/tty/serial/xilinx_uartps.c
> > b/drivers/tty/serial/xilinx_uartps.c
> > index 2dc26e5f1384..c771dbbf6161 100644
> > --- a/drivers/tty/serial/xilinx_uartps.c
> > +++ b/drivers/tty/serial/xilinx_uartps.c
> > @@ -173,61 +173,86 @@ struct cdns_uart {
> >             clk_rate_change_nb);
> >
> >  /**
> > - * cdns_uart_isr - Interrupt handler
> > - * @irq: Irq number
> > - * @dev_id: Id of the port
> > - *
> > - * Return: IRQHANDLED
> > + * cdns_uart_handle_tx - Handle the bytes to be Txed.
> > + * @dev_id: Id of the UART port
> > + * Return: None
> >   */
> > -static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
> > +static void cdns_uart_handle_tx(void *dev_id)
> >  {
> >     struct uart_port *port = (struct uart_port *)dev_id;
> > -   unsigned long flags;
> > -   unsigned int isrstatus, numbytes;
> > -   unsigned int data;
> > -   char status = TTY_NORMAL;
> > +   unsigned int numbytes;
> >
> > -   spin_lock_irqsave(&port->lock, flags);
> > +   if (uart_circ_empty(&port->state->xmit)) {
> > +           writel(CDNS_UART_IXR_TXEMPTY, port->membase +
> > +                  CDNS_UART_IDR_OFFSET);
> > +   } else {
> > +           numbytes = port->fifosize;
> > +           /* Break if no more data available in the UART buffer */
> > +           while (numbytes--) {
> > +                   if (uart_circ_empty(&port->state->xmit))
> > +                           break;
> > +                   /*
> > +                    * Get the data from the UART circular buffer
> > +                    * and write it to the cdns_uart's TX_FIFO
> > +                    * register.
> > +                    */
> > +                   writel(port->state->xmit.buf[port->state->xmit.tail],
> > +                          port->membase + CDNS_UART_FIFO_OFFSET);
> >
> > -   /* Read the interrupt status register to determine which
> > -    * interrupt(s) is/are active.
> > -    */
> > -   isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
> > +                   port->icount.tx++;
> >
> > -   /*
> > -    * There is no hardware break detection, so we interpret framing
> > -    * error with all-zeros data as a break sequence. Most of the time,
> > -    * there's another non-zero byte at the end of the sequence.
> > -    */
> > -   if (isrstatus & CDNS_UART_IXR_FRAMING) {
> > -           while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
> > -                                   CDNS_UART_SR_RXEMPTY)) {
> > -                   if (!readl(port->membase + CDNS_UART_FIFO_OFFSET))
> {
> > -                           port->read_status_mask |=
> CDNS_UART_IXR_BRK;
> > -                           isrstatus &= ~CDNS_UART_IXR_FRAMING;
> > -                   }
> > +                   /*
> > +                    * Adjust the tail of the UART buffer and wrap
> > +                    * the buffer if it reaches limit.
> > +                    */
> > +                   port->state->xmit.tail =
> > +                           (port->state->xmit.tail + 1) &
> > +                                   (UART_XMIT_SIZE - 1);
> >             }
> > -           writel(CDNS_UART_IXR_FRAMING,
> > -                           port->membase + CDNS_UART_ISR_OFFSET);
> > -   }
> >
> > -   /* drop byte with parity error if IGNPAR specified */
> > -   if (isrstatus & port->ignore_status_mask & CDNS_UART_IXR_PARITY)
> > -           isrstatus &= ~(CDNS_UART_IXR_RXTRIG |
> CDNS_UART_IXR_TOUT);
> > +           if (uart_circ_chars_pending(
> > +                           &port->state->xmit) < WAKEUP_CHARS)
> > +                   uart_write_wakeup(port);
> > +   }
> > +}
> >
> > -   isrstatus &= port->read_status_mask;
> > -   isrstatus &= ~port->ignore_status_mask;
> > +/**
> > + * cdns_uart_handle_rx - Handle the received bytes along with Rx errors.
> > + * @dev_id: Id of the UART port
> > + * @isrstatus: The interrupt status register value as read
> > + * Return: None
> > + */
> > +static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus)
> > +{
> > +   struct uart_port *port = (struct uart_port *)dev_id;
> > +   unsigned int data;
> > +   unsigned int framerrprocessed = 0;
> > +   char status = TTY_NORMAL;
> >
> > -   if ((isrstatus & CDNS_UART_IXR_TOUT) ||
> > -           (isrstatus & CDNS_UART_IXR_RXTRIG)) {
> > -           /* Receive Timeout Interrupt */
> > -           while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
> > -                                   CDNS_UART_SR_RXEMPTY)) {
> > -                   data = readl(port->membase +
> CDNS_UART_FIFO_OFFSET);
> > +   while ((readl(port->membase + CDNS_UART_SR_OFFSET) &
> > +           CDNS_UART_SR_RXEMPTY) != CDNS_UART_SR_RXEMPTY) {
> > +           data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
> > +           port->icount.rx++;
> > +           /*
> > +            * There is no hardware break detection, so we interpret
> > +            * framing error with all-zeros data as a break sequence.
> > +            * Most of the time, there's another non-zero byte at the
> > +            * end of the sequence.
> > +            */
> > +           if (isrstatus & CDNS_UART_IXR_FRAMING) {
> > +                   if (!data) {
> > +                           port->read_status_mask |=
> CDNS_UART_IXR_BRK;
> > +                           framerrprocessed = 1;
> > +                           continue;
> > +                   }
> > +           }
> > +           isrstatus &= port->read_status_mask;
> > +           isrstatus &= ~port->ignore_status_mask;
> >
> > -                   /* Non-NULL byte after BREAK is garbage (99%) */
> > -                   if (data && (port->read_status_mask &
> > -                                           CDNS_UART_IXR_BRK)) {
> > +           if ((isrstatus & CDNS_UART_IXR_TOUT) ||
> > +               (isrstatus & CDNS_UART_IXR_RXTRIG)) {
> > +                   if (data &&
> > +                       (port->read_status_mask & CDNS_UART_IXR_BRK)) {
> >                             port->read_status_mask &=
> ~CDNS_UART_IXR_BRK;
> >                             port->icount.brk++;
> >                             if (uart_handle_break(port))
> > @@ -249,67 +274,56 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
> >                             spin_lock(&port->lock);
> >                     }
> >  #endif
> > -
> > -                   port->icount.rx++;
> > -
> >                     if (isrstatus & CDNS_UART_IXR_PARITY) {
> >                             port->icount.parity++;
> >                             status = TTY_PARITY;
> > -                   } else if (isrstatus & CDNS_UART_IXR_FRAMING) {
> > +                   }
> > +                   if ((isrstatus & CDNS_UART_IXR_FRAMING) &&
> > +                       !framerrprocessed) {
> >                             port->icount.frame++;
> >                             status = TTY_FRAME;
> > -                   } else if (isrstatus & CDNS_UART_IXR_OVERRUN) {
> > +                   }
> > +                   if (isrstatus & CDNS_UART_IXR_OVERRUN) {
> >                             port->icount.overrun++;
> > +                           tty_insert_flip_char(&port->state->port, 0,
> > +                                                TTY_OVERRUN);
> >                     }
> > -
> > -                   uart_insert_char(port, isrstatus,
> CDNS_UART_IXR_OVERRUN,
> > -                                   data, status);
> > +                   tty_insert_flip_char(&port->state->port, data, status);
> >             }
> > -           spin_unlock(&port->lock);
> > -           tty_flip_buffer_push(&port->state->port);
> > -           spin_lock(&port->lock);
> >     }
> > +   spin_unlock(&port->lock);
> > +   tty_flip_buffer_push(&port->state->port);
> > +   spin_lock(&port->lock);
> > +}
> >
> > -   /* Dispatch an appropriate handler */
> > -   if ((isrstatus & CDNS_UART_IXR_TXEMPTY) ==
> CDNS_UART_IXR_TXEMPTY) {
> > -           if (uart_circ_empty(&port->state->xmit)) {
> > -                   writel(CDNS_UART_IXR_TXEMPTY,
> > -                                   port->membase +
> CDNS_UART_IDR_OFFSET);
> > -           } else {
> > -                   numbytes = port->fifosize;
> > -                   /* Break if no more data available in the UART buffer */
> > -                   while (numbytes--) {
> > -                           if (uart_circ_empty(&port->state->xmit))
> > -                                   break;
> > -                           /* Get the data from the UART circular buffer
> > -                            * and write it to the cdns_uart's TX_FIFO
> > -                            * register.
> > -                            */
> > -                           writel(port->state->xmit.buf[
> > -                                           port->state->xmit.tail],
> > -                                   port->membase +
> CDNS_UART_FIFO_OFFSET);
> > -
> > -                           port->icount.tx++;
> > -
> > -                           /* Adjust the tail of the UART buffer and wrap
> > -                            * the buffer if it reaches limit.
> > -                            */
> > -                           port->state->xmit.tail =
> > -                                   (port->state->xmit.tail + 1) &
> > -                                           (UART_XMIT_SIZE - 1);
> > -                   }
> > +/**
> > + * cdns_uart_isr - Interrupt handler
> > + * @irq: Irq number
> > + * @dev_id: Id of the port
> > + *
> > + * Return: IRQHANDLED
> > + */
> > +static irqreturn_t cdns_uart_isr(int irq, void *dev_id) {
> > +   struct uart_port *port = (struct uart_port *)dev_id;
> > +   unsigned int isrstatus;
> >
> > -                   if (uart_circ_chars_pending(
> > -                                   &port->state->xmit) < WAKEUP_CHARS)
> > -                           uart_write_wakeup(port);
> > -           }
> > -   }
> > +   spin_lock(&port->lock);
> >
> > +   /* Read the interrupt status register to determine which
> > +    * interrupt(s) is/are active and clear them.
> > +    */
> > +   isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
> >     writel(isrstatus, port->membase + CDNS_UART_ISR_OFFSET);
> >
> > -   /* be sure to release the lock and tty before leaving */
> > -   spin_unlock_irqrestore(&port->lock, flags);
> > +   if (isrstatus & CDNS_UART_IXR_TXEMPTY) {
> > +           cdns_uart_handle_tx(dev_id);
> > +           isrstatus &= ~CDNS_UART_IXR_TXEMPTY;
> > +   }
> > +   if (isrstatus & CDNS_UART_IXR_MASK)
> > +           cdns_uart_handle_rx(dev_id, isrstatus);
> >
> > +   spin_unlock(&port->lock);
> >     return IRQ_HANDLED;
> >  }
> >
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
@ 2015-08-17 16:00       ` Anirudha Sarangi
  0 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 16:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:26 PM
> To: Michal Simek
> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Anirudha Sarangi; Soren
> Brinkmann; Jiri Slaby; linux-serial at vger.kernel.org; Greg Kroah-Hartman; linux-
> arm-kernel at lists.infradead.org
> Subject: Re: [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
>
> On 08/17/2015 03:22 AM, Michal Simek wrote:
> > From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >
> > The existing interrupt handling logic has followins issues.
> > - Upon a parity error with default configuration, the control
> >   never comes out of the ISR thereby hanging Linux.
> > - The error handling logic around framing and parity error are buggy.
> >   There are chances that the errors will never be captured.
> > - The existing ISR is just too long.
> > This patch fixes all these concerns.
>
> This patch is unreviewable. Please break this down into multiple patches.
>
Thanks. Let me give a shot. It is just breaking the single big ISR that has both Rx and Tx in a single function into smaller ones.
Not sure how I will create smaller patches, but I will try and get back.

Regards
Anirudha

> Regards,
> Peter Hurley
>
> > It separates out the Tx and Rx
> > hanling logic into separate functions. It ensures that the status
> > registers are cleared on all cases so that a hang situation never
> > arises.
> >
> > Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> > Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> > ---
> >
> >  drivers/tty/serial/xilinx_uartps.c | 194
> > ++++++++++++++++++++-----------------
> >  1 file changed, 104 insertions(+), 90 deletions(-)
> >
> > diff --git a/drivers/tty/serial/xilinx_uartps.c
> > b/drivers/tty/serial/xilinx_uartps.c
> > index 2dc26e5f1384..c771dbbf6161 100644
> > --- a/drivers/tty/serial/xilinx_uartps.c
> > +++ b/drivers/tty/serial/xilinx_uartps.c
> > @@ -173,61 +173,86 @@ struct cdns_uart {
> >             clk_rate_change_nb);
> >
> >  /**
> > - * cdns_uart_isr - Interrupt handler
> > - * @irq: Irq number
> > - * @dev_id: Id of the port
> > - *
> > - * Return: IRQHANDLED
> > + * cdns_uart_handle_tx - Handle the bytes to be Txed.
> > + * @dev_id: Id of the UART port
> > + * Return: None
> >   */
> > -static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
> > +static void cdns_uart_handle_tx(void *dev_id)
> >  {
> >     struct uart_port *port = (struct uart_port *)dev_id;
> > -   unsigned long flags;
> > -   unsigned int isrstatus, numbytes;
> > -   unsigned int data;
> > -   char status = TTY_NORMAL;
> > +   unsigned int numbytes;
> >
> > -   spin_lock_irqsave(&port->lock, flags);
> > +   if (uart_circ_empty(&port->state->xmit)) {
> > +           writel(CDNS_UART_IXR_TXEMPTY, port->membase +
> > +                  CDNS_UART_IDR_OFFSET);
> > +   } else {
> > +           numbytes = port->fifosize;
> > +           /* Break if no more data available in the UART buffer */
> > +           while (numbytes--) {
> > +                   if (uart_circ_empty(&port->state->xmit))
> > +                           break;
> > +                   /*
> > +                    * Get the data from the UART circular buffer
> > +                    * and write it to the cdns_uart's TX_FIFO
> > +                    * register.
> > +                    */
> > +                   writel(port->state->xmit.buf[port->state->xmit.tail],
> > +                          port->membase + CDNS_UART_FIFO_OFFSET);
> >
> > -   /* Read the interrupt status register to determine which
> > -    * interrupt(s) is/are active.
> > -    */
> > -   isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
> > +                   port->icount.tx++;
> >
> > -   /*
> > -    * There is no hardware break detection, so we interpret framing
> > -    * error with all-zeros data as a break sequence. Most of the time,
> > -    * there's another non-zero byte at the end of the sequence.
> > -    */
> > -   if (isrstatus & CDNS_UART_IXR_FRAMING) {
> > -           while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
> > -                                   CDNS_UART_SR_RXEMPTY)) {
> > -                   if (!readl(port->membase + CDNS_UART_FIFO_OFFSET))
> {
> > -                           port->read_status_mask |=
> CDNS_UART_IXR_BRK;
> > -                           isrstatus &= ~CDNS_UART_IXR_FRAMING;
> > -                   }
> > +                   /*
> > +                    * Adjust the tail of the UART buffer and wrap
> > +                    * the buffer if it reaches limit.
> > +                    */
> > +                   port->state->xmit.tail =
> > +                           (port->state->xmit.tail + 1) &
> > +                                   (UART_XMIT_SIZE - 1);
> >             }
> > -           writel(CDNS_UART_IXR_FRAMING,
> > -                           port->membase + CDNS_UART_ISR_OFFSET);
> > -   }
> >
> > -   /* drop byte with parity error if IGNPAR specified */
> > -   if (isrstatus & port->ignore_status_mask & CDNS_UART_IXR_PARITY)
> > -           isrstatus &= ~(CDNS_UART_IXR_RXTRIG |
> CDNS_UART_IXR_TOUT);
> > +           if (uart_circ_chars_pending(
> > +                           &port->state->xmit) < WAKEUP_CHARS)
> > +                   uart_write_wakeup(port);
> > +   }
> > +}
> >
> > -   isrstatus &= port->read_status_mask;
> > -   isrstatus &= ~port->ignore_status_mask;
> > +/**
> > + * cdns_uart_handle_rx - Handle the received bytes along with Rx errors.
> > + * @dev_id: Id of the UART port
> > + * @isrstatus: The interrupt status register value as read
> > + * Return: None
> > + */
> > +static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus)
> > +{
> > +   struct uart_port *port = (struct uart_port *)dev_id;
> > +   unsigned int data;
> > +   unsigned int framerrprocessed = 0;
> > +   char status = TTY_NORMAL;
> >
> > -   if ((isrstatus & CDNS_UART_IXR_TOUT) ||
> > -           (isrstatus & CDNS_UART_IXR_RXTRIG)) {
> > -           /* Receive Timeout Interrupt */
> > -           while (!(readl(port->membase + CDNS_UART_SR_OFFSET) &
> > -                                   CDNS_UART_SR_RXEMPTY)) {
> > -                   data = readl(port->membase +
> CDNS_UART_FIFO_OFFSET);
> > +   while ((readl(port->membase + CDNS_UART_SR_OFFSET) &
> > +           CDNS_UART_SR_RXEMPTY) != CDNS_UART_SR_RXEMPTY) {
> > +           data = readl(port->membase + CDNS_UART_FIFO_OFFSET);
> > +           port->icount.rx++;
> > +           /*
> > +            * There is no hardware break detection, so we interpret
> > +            * framing error with all-zeros data as a break sequence.
> > +            * Most of the time, there's another non-zero byte at the
> > +            * end of the sequence.
> > +            */
> > +           if (isrstatus & CDNS_UART_IXR_FRAMING) {
> > +                   if (!data) {
> > +                           port->read_status_mask |=
> CDNS_UART_IXR_BRK;
> > +                           framerrprocessed = 1;
> > +                           continue;
> > +                   }
> > +           }
> > +           isrstatus &= port->read_status_mask;
> > +           isrstatus &= ~port->ignore_status_mask;
> >
> > -                   /* Non-NULL byte after BREAK is garbage (99%) */
> > -                   if (data && (port->read_status_mask &
> > -                                           CDNS_UART_IXR_BRK)) {
> > +           if ((isrstatus & CDNS_UART_IXR_TOUT) ||
> > +               (isrstatus & CDNS_UART_IXR_RXTRIG)) {
> > +                   if (data &&
> > +                       (port->read_status_mask & CDNS_UART_IXR_BRK)) {
> >                             port->read_status_mask &=
> ~CDNS_UART_IXR_BRK;
> >                             port->icount.brk++;
> >                             if (uart_handle_break(port))
> > @@ -249,67 +274,56 @@ static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
> >                             spin_lock(&port->lock);
> >                     }
> >  #endif
> > -
> > -                   port->icount.rx++;
> > -
> >                     if (isrstatus & CDNS_UART_IXR_PARITY) {
> >                             port->icount.parity++;
> >                             status = TTY_PARITY;
> > -                   } else if (isrstatus & CDNS_UART_IXR_FRAMING) {
> > +                   }
> > +                   if ((isrstatus & CDNS_UART_IXR_FRAMING) &&
> > +                       !framerrprocessed) {
> >                             port->icount.frame++;
> >                             status = TTY_FRAME;
> > -                   } else if (isrstatus & CDNS_UART_IXR_OVERRUN) {
> > +                   }
> > +                   if (isrstatus & CDNS_UART_IXR_OVERRUN) {
> >                             port->icount.overrun++;
> > +                           tty_insert_flip_char(&port->state->port, 0,
> > +                                                TTY_OVERRUN);
> >                     }
> > -
> > -                   uart_insert_char(port, isrstatus,
> CDNS_UART_IXR_OVERRUN,
> > -                                   data, status);
> > +                   tty_insert_flip_char(&port->state->port, data, status);
> >             }
> > -           spin_unlock(&port->lock);
> > -           tty_flip_buffer_push(&port->state->port);
> > -           spin_lock(&port->lock);
> >     }
> > +   spin_unlock(&port->lock);
> > +   tty_flip_buffer_push(&port->state->port);
> > +   spin_lock(&port->lock);
> > +}
> >
> > -   /* Dispatch an appropriate handler */
> > -   if ((isrstatus & CDNS_UART_IXR_TXEMPTY) ==
> CDNS_UART_IXR_TXEMPTY) {
> > -           if (uart_circ_empty(&port->state->xmit)) {
> > -                   writel(CDNS_UART_IXR_TXEMPTY,
> > -                                   port->membase +
> CDNS_UART_IDR_OFFSET);
> > -           } else {
> > -                   numbytes = port->fifosize;
> > -                   /* Break if no more data available in the UART buffer */
> > -                   while (numbytes--) {
> > -                           if (uart_circ_empty(&port->state->xmit))
> > -                                   break;
> > -                           /* Get the data from the UART circular buffer
> > -                            * and write it to the cdns_uart's TX_FIFO
> > -                            * register.
> > -                            */
> > -                           writel(port->state->xmit.buf[
> > -                                           port->state->xmit.tail],
> > -                                   port->membase +
> CDNS_UART_FIFO_OFFSET);
> > -
> > -                           port->icount.tx++;
> > -
> > -                           /* Adjust the tail of the UART buffer and wrap
> > -                            * the buffer if it reaches limit.
> > -                            */
> > -                           port->state->xmit.tail =
> > -                                   (port->state->xmit.tail + 1) &
> > -                                           (UART_XMIT_SIZE - 1);
> > -                   }
> > +/**
> > + * cdns_uart_isr - Interrupt handler
> > + * @irq: Irq number
> > + * @dev_id: Id of the port
> > + *
> > + * Return: IRQHANDLED
> > + */
> > +static irqreturn_t cdns_uart_isr(int irq, void *dev_id) {
> > +   struct uart_port *port = (struct uart_port *)dev_id;
> > +   unsigned int isrstatus;
> >
> > -                   if (uart_circ_chars_pending(
> > -                                   &port->state->xmit) < WAKEUP_CHARS)
> > -                           uart_write_wakeup(port);
> > -           }
> > -   }
> > +   spin_lock(&port->lock);
> >
> > +   /* Read the interrupt status register to determine which
> > +    * interrupt(s) is/are active and clear them.
> > +    */
> > +   isrstatus = readl(port->membase + CDNS_UART_ISR_OFFSET);
> >     writel(isrstatus, port->membase + CDNS_UART_ISR_OFFSET);
> >
> > -   /* be sure to release the lock and tty before leaving */
> > -   spin_unlock_irqrestore(&port->lock, flags);
> > +   if (isrstatus & CDNS_UART_IXR_TXEMPTY) {
> > +           cdns_uart_handle_tx(dev_id);
> > +           isrstatus &= ~CDNS_UART_IXR_TXEMPTY;
> > +   }
> > +   if (isrstatus & CDNS_UART_IXR_MASK)
> > +           cdns_uart_handle_rx(dev_id, isrstatus);
> >
> > +   spin_unlock(&port->lock);
> >     return IRQ_HANDLED;
> >  }
> >
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under IGNPAR option
  2015-08-17 15:58       ` Anirudha Sarangi
  (?)
@ 2015-08-17 16:19         ` Peter Hurley
  -1 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 16:19 UTC (permalink / raw)
  To: Anirudha Sarangi, Michal Simek
  Cc: linux-kernel, monstr, Soren Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

On 08/17/2015 11:58 AM, Anirudha Sarangi wrote:
> Hi,
> 
>> -----Original Message-----
>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
>> Sent: Monday, August 17, 2015 9:20 PM
>> To: Michal Simek
>> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Anirudha Sarangi; Soren
>> Brinkmann; Jiri Slaby; linux-serial@vger.kernel.org; Greg Kroah-Hartman; linux-
>> arm-kernel@lists.infradead.org
>> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
>> IGNPAR option
>>
>> On 08/17/2015 03:22 AM, Michal Simek wrote:
>>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
>>>
>>> The existing implementation includes overrun errors under IGNPAR
>>> option. This patch fixes it by including only parity and framing error
>>> under IGNPAR option.
>>
>> The convention adopted by Linux serial drivers is to ignore overrun errors if both
>> IGNPAR and IGNBRK are set.
>>
> I just followed the set_termios documentation, which says that IGNPAR is for parity and framing.
> The current controller does not support break detection reliably.
> That is probably why we don’t have IGNBRK.

My point is about how a user-space process tells the serial driver to ignore
overrun errors, as well, and not specifically about break handling.

> 
> Regards
> Anirudha
> 
>> Regards,
>> Peter Hurley
>>
>>> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
>>> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
>>> ---
>>>
>>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/tty/serial/xilinx_uartps.c
>>> b/drivers/tty/serial/xilinx_uartps.c
>>> index a3020344ac9d..c4437e8929ff 100644
>>> --- a/drivers/tty/serial/xilinx_uartps.c
>>> +++ b/drivers/tty/serial/xilinx_uartps.c
>>> @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct uart_port
>>> *port,
>>>
>>>     if (termios->c_iflag & IGNPAR)
>>>             port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
>>> -                   CDNS_UART_IXR_FRAMING |
>> CDNS_UART_IXR_OVERRUN;
>>> +                                       CDNS_UART_IXR_FRAMING;
>>>
>>>     /* ignore all characters if CREAD is not set */
>>>     if ((termios->c_cflag & CREAD) == 0)
>>>
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 


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

* Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under IGNPAR option
@ 2015-08-17 16:19         ` Peter Hurley
  0 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 16:19 UTC (permalink / raw)
  To: Anirudha Sarangi, Michal Simek
  Cc: linux-kernel, monstr, Soren Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

On 08/17/2015 11:58 AM, Anirudha Sarangi wrote:
> Hi,
> 
>> -----Original Message-----
>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
>> Sent: Monday, August 17, 2015 9:20 PM
>> To: Michal Simek
>> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Anirudha Sarangi; Soren
>> Brinkmann; Jiri Slaby; linux-serial@vger.kernel.org; Greg Kroah-Hartman; linux-
>> arm-kernel@lists.infradead.org
>> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
>> IGNPAR option
>>
>> On 08/17/2015 03:22 AM, Michal Simek wrote:
>>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
>>>
>>> The existing implementation includes overrun errors under IGNPAR
>>> option. This patch fixes it by including only parity and framing error
>>> under IGNPAR option.
>>
>> The convention adopted by Linux serial drivers is to ignore overrun errors if both
>> IGNPAR and IGNBRK are set.
>>
> I just followed the set_termios documentation, which says that IGNPAR is for parity and framing.
> The current controller does not support break detection reliably.
> That is probably why we don’t have IGNBRK.

My point is about how a user-space process tells the serial driver to ignore
overrun errors, as well, and not specifically about break handling.

> 
> Regards
> Anirudha
> 
>> Regards,
>> Peter Hurley
>>
>>> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
>>> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
>>> ---
>>>
>>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/tty/serial/xilinx_uartps.c
>>> b/drivers/tty/serial/xilinx_uartps.c
>>> index a3020344ac9d..c4437e8929ff 100644
>>> --- a/drivers/tty/serial/xilinx_uartps.c
>>> +++ b/drivers/tty/serial/xilinx_uartps.c
>>> @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct uart_port
>>> *port,
>>>
>>>     if (termios->c_iflag & IGNPAR)
>>>             port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
>>> -                   CDNS_UART_IXR_FRAMING |
>> CDNS_UART_IXR_OVERRUN;
>>> +                                       CDNS_UART_IXR_FRAMING;
>>>
>>>     /* ignore all characters if CREAD is not set */
>>>     if ((termios->c_cflag & CREAD) == 0)
>>>
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 

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

* [PATCH 2/4] serial: xuartps: Do not handle overrun errors under IGNPAR option
@ 2015-08-17 16:19         ` Peter Hurley
  0 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 16:19 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/17/2015 11:58 AM, Anirudha Sarangi wrote:
> Hi,
> 
>> -----Original Message-----
>> From: Peter Hurley [mailto:peter at hurleysoftware.com]
>> Sent: Monday, August 17, 2015 9:20 PM
>> To: Michal Simek
>> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Anirudha Sarangi; Soren
>> Brinkmann; Jiri Slaby; linux-serial at vger.kernel.org; Greg Kroah-Hartman; linux-
>> arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
>> IGNPAR option
>>
>> On 08/17/2015 03:22 AM, Michal Simek wrote:
>>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
>>>
>>> The existing implementation includes overrun errors under IGNPAR
>>> option. This patch fixes it by including only parity and framing error
>>> under IGNPAR option.
>>
>> The convention adopted by Linux serial drivers is to ignore overrun errors if both
>> IGNPAR and IGNBRK are set.
>>
> I just followed the set_termios documentation, which says that IGNPAR is for parity and framing.
> The current controller does not support break detection reliably.
> That is probably why we don?t have IGNBRK.

My point is about how a user-space process tells the serial driver to ignore
overrun errors, as well, and not specifically about break handling.

> 
> Regards
> Anirudha
> 
>> Regards,
>> Peter Hurley
>>
>>> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
>>> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
>>> ---
>>>
>>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/tty/serial/xilinx_uartps.c
>>> b/drivers/tty/serial/xilinx_uartps.c
>>> index a3020344ac9d..c4437e8929ff 100644
>>> --- a/drivers/tty/serial/xilinx_uartps.c
>>> +++ b/drivers/tty/serial/xilinx_uartps.c
>>> @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct uart_port
>>> *port,
>>>
>>>     if (termios->c_iflag & IGNPAR)
>>>             port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
>>> -                   CDNS_UART_IXR_FRAMING |
>> CDNS_UART_IXR_OVERRUN;
>>> +                                       CDNS_UART_IXR_FRAMING;
>>>
>>>     /* ignore all characters if CREAD is not set */
>>>     if ((termios->c_cflag & CREAD) == 0)
>>>
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 

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

* Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
  2015-08-17 15:55     ` Anirudha Sarangi
  (?)
@ 2015-08-17 16:24       ` Peter Hurley
  -1 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 16:24 UTC (permalink / raw)
  To: Anirudha Sarangi, Michal Simek
  Cc: linux-kernel, monstr, Soren Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

On 08/17/2015 11:55 AM, Anirudha Sarangi wrote:
> Hi,
> 
>> -----Original Message-----
>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
>> Sent: Monday, August 17, 2015 9:09 PM
>> To: Michal Simek
>> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Anirudha Sarangi; Soren
>> Brinkmann; Jiri Slaby; linux-serial@vger.kernel.org; Greg Kroah-Hartman; linux-
>> arm-kernel@lists.infradead.org
>> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
>>
>> On 08/17/2015 03:22 AM, Michal Simek wrote:
>>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
>>>
>>> Existing set_termios does not handle the option for enabling odd
>>> parity. This patch fixes it.
>>
>> NAK. PARODD does not enable parity generation or detection.
>>
> What if someone is trying to change from even to odd parity?

If userspace wants odd parity, then c_cflag must have both
PARENB and PARODD set.

Just PARODD does nothing.

>From SUS v4, General Terminal Interface, 11.2.4 Control Modes;

"If PARENB is set, parity generation and detection shall be enabled
and a parity bit is added to each byte. If parity is enabled, PARODD
shall specify odd parity if set; otherwise, even parity shall be used."



> In this conditional case, we setup some register bit for the same.
> Is the above use case not a valid one?
> 
> Regards
> Anirudha
> 
>> Regards,
>> Peter Hurley
>>
>>> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
>>> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
>>> ---
>>>
>>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/tty/serial/xilinx_uartps.c
>>> b/drivers/tty/serial/xilinx_uartps.c
>>> index 009e0dbc12d2..a3020344ac9d 100644
>>> --- a/drivers/tty/serial/xilinx_uartps.c
>>> +++ b/drivers/tty/serial/xilinx_uartps.c
>>> @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port
>> *port,
>>>     else
>>>             cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
>>>
>>> -   if (termios->c_cflag & PARENB) {
>>> +   if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
>>>             /* Mark or Space parity */
>>>             if (termios->c_cflag & CMSPAR) {
>>>                     if (termios->c_cflag & PARODD)
>>>
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 


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

* Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
@ 2015-08-17 16:24       ` Peter Hurley
  0 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 16:24 UTC (permalink / raw)
  To: Anirudha Sarangi, Michal Simek
  Cc: linux-kernel, monstr, Soren Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

On 08/17/2015 11:55 AM, Anirudha Sarangi wrote:
> Hi,
> 
>> -----Original Message-----
>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
>> Sent: Monday, August 17, 2015 9:09 PM
>> To: Michal Simek
>> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Anirudha Sarangi; Soren
>> Brinkmann; Jiri Slaby; linux-serial@vger.kernel.org; Greg Kroah-Hartman; linux-
>> arm-kernel@lists.infradead.org
>> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
>>
>> On 08/17/2015 03:22 AM, Michal Simek wrote:
>>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
>>>
>>> Existing set_termios does not handle the option for enabling odd
>>> parity. This patch fixes it.
>>
>> NAK. PARODD does not enable parity generation or detection.
>>
> What if someone is trying to change from even to odd parity?

If userspace wants odd parity, then c_cflag must have both
PARENB and PARODD set.

Just PARODD does nothing.

>From SUS v4, General Terminal Interface, 11.2.4 Control Modes;

"If PARENB is set, parity generation and detection shall be enabled
and a parity bit is added to each byte. If parity is enabled, PARODD
shall specify odd parity if set; otherwise, even parity shall be used."



> In this conditional case, we setup some register bit for the same.
> Is the above use case not a valid one?
> 
> Regards
> Anirudha
> 
>> Regards,
>> Peter Hurley
>>
>>> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
>>> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
>>> ---
>>>
>>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/tty/serial/xilinx_uartps.c
>>> b/drivers/tty/serial/xilinx_uartps.c
>>> index 009e0dbc12d2..a3020344ac9d 100644
>>> --- a/drivers/tty/serial/xilinx_uartps.c
>>> +++ b/drivers/tty/serial/xilinx_uartps.c
>>> @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port
>> *port,
>>>     else
>>>             cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
>>>
>>> -   if (termios->c_cflag & PARENB) {
>>> +   if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
>>>             /* Mark or Space parity */
>>>             if (termios->c_cflag & CMSPAR) {
>>>                     if (termios->c_cflag & PARODD)
>>>
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 

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

* [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
@ 2015-08-17 16:24       ` Peter Hurley
  0 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 16:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/17/2015 11:55 AM, Anirudha Sarangi wrote:
> Hi,
> 
>> -----Original Message-----
>> From: Peter Hurley [mailto:peter at hurleysoftware.com]
>> Sent: Monday, August 17, 2015 9:09 PM
>> To: Michal Simek
>> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Anirudha Sarangi; Soren
>> Brinkmann; Jiri Slaby; linux-serial at vger.kernel.org; Greg Kroah-Hartman; linux-
>> arm-kernel at lists.infradead.org
>> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
>>
>> On 08/17/2015 03:22 AM, Michal Simek wrote:
>>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
>>>
>>> Existing set_termios does not handle the option for enabling odd
>>> parity. This patch fixes it.
>>
>> NAK. PARODD does not enable parity generation or detection.
>>
> What if someone is trying to change from even to odd parity?

If userspace wants odd parity, then c_cflag must have both
PARENB and PARODD set.

Just PARODD does nothing.

>From SUS v4, General Terminal Interface, 11.2.4 Control Modes;

"If PARENB is set, parity generation and detection shall be enabled
and a parity bit is added to each byte. If parity is enabled, PARODD
shall specify odd parity if set; otherwise, even parity shall be used."



> In this conditional case, we setup some register bit for the same.
> Is the above use case not a valid one?
> 
> Regards
> Anirudha
> 
>> Regards,
>> Peter Hurley
>>
>>> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
>>> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
>>> ---
>>>
>>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/tty/serial/xilinx_uartps.c
>>> b/drivers/tty/serial/xilinx_uartps.c
>>> index 009e0dbc12d2..a3020344ac9d 100644
>>> --- a/drivers/tty/serial/xilinx_uartps.c
>>> +++ b/drivers/tty/serial/xilinx_uartps.c
>>> @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct uart_port
>> *port,
>>>     else
>>>             cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
>>>
>>> -   if (termios->c_cflag & PARENB) {
>>> +   if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD)) {
>>>             /* Mark or Space parity */
>>>             if (termios->c_cflag & CMSPAR) {
>>>                     if (termios->c_cflag & PARODD)
>>>
> 
> 
> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 

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

* RE: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
  2015-08-17 16:24       ` Peter Hurley
  (?)
@ 2015-08-17 18:06         ` Anirudha Sarangi
  -1 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 18:06 UTC (permalink / raw)
  To: Peter Hurley, Michal Simek
  Cc: linux-kernel, monstr, Soren Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 3825 bytes --]

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:54 PM
> To: Anirudha Sarangi; Michal Simek
> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Soren Brinkmann; Jiri
> Slaby; linux-serial@vger.kernel.org; Greg Kroah-Hartman; linux-arm-
> kernel@lists.infradead.org
> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
>
> On 08/17/2015 11:55 AM, Anirudha Sarangi wrote:
> > Hi,
> >
> >> -----Original Message-----
> >> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> >> Sent: Monday, August 17, 2015 9:09 PM
> >> To: Michal Simek
> >> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Anirudha Sarangi;
> >> Soren Brinkmann; Jiri Slaby; linux-serial@vger.kernel.org; Greg
> >> Kroah-Hartman; linux- arm-kernel@lists.infradead.org
> >> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for
> >> enabling odd parity
> >>
> >> On 08/17/2015 03:22 AM, Michal Simek wrote:
> >>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >>>
> >>> Existing set_termios does not handle the option for enabling odd
> >>> parity. This patch fixes it.
> >>
> >> NAK. PARODD does not enable parity generation or detection.
> >>
> > What if someone is trying to change from even to odd parity?
>
> If userspace wants odd parity, then c_cflag must have both PARENB and PARODD
> set.
>
> Just PARODD does nothing.
>
> From SUS v4, General Terminal Interface, 11.2.4 Control Modes;
>
> "If PARENB is set, parity generation and detection shall be enabled and a parity
> bit is added to each byte. If parity is enabled, PARODD shall specify odd parity if
> set; otherwise, even parity shall be used."
>
>
Thanks a lot. I will incorporate the changes.
>
> > In this conditional case, we setup some register bit for the same.
> > Is the above use case not a valid one?
> >
> > Regards
> > Anirudha
> >
> >> Regards,
> >> Peter Hurley
> >>
> >>> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> >>> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> >>> ---
> >>>
> >>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >>>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/tty/serial/xilinx_uartps.c
> >>> b/drivers/tty/serial/xilinx_uartps.c
> >>> index 009e0dbc12d2..a3020344ac9d 100644
> >>> --- a/drivers/tty/serial/xilinx_uartps.c
> >>> +++ b/drivers/tty/serial/xilinx_uartps.c
> >>> @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct
> >>> uart_port
> >> *port,
> >>>     else
> >>>             cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
> >>>
> >>> -   if (termios->c_cflag & PARENB) {
> >>> +   if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD))
> >>> + {
> >>>             /* Mark or Space parity */
> >>>             if (termios->c_cflag & CMSPAR) {
> >>>                     if (termios->c_cflag & PARODD)
> >>>
> >
> >
> >
> > This email and any attachments are intended for the sole use of the named
> recipient(s) and contain(s) confidential information that may be proprietary,
> privileged or copyrighted under applicable law. If you are not the intended
> recipient, do not read, copy, or forward this email message or any attachments.
> Delete this email message and any attachments immediately.
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* RE: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
@ 2015-08-17 18:06         ` Anirudha Sarangi
  0 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 18:06 UTC (permalink / raw)
  To: Peter Hurley, Michal Simek
  Cc: linux-kernel, monstr, Soren Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:54 PM
> To: Anirudha Sarangi; Michal Simek
> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Soren Brinkmann; Jiri
> Slaby; linux-serial@vger.kernel.org; Greg Kroah-Hartman; linux-arm-
> kernel@lists.infradead.org
> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
>
> On 08/17/2015 11:55 AM, Anirudha Sarangi wrote:
> > Hi,
> >
> >> -----Original Message-----
> >> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> >> Sent: Monday, August 17, 2015 9:09 PM
> >> To: Michal Simek
> >> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Anirudha Sarangi;
> >> Soren Brinkmann; Jiri Slaby; linux-serial@vger.kernel.org; Greg
> >> Kroah-Hartman; linux- arm-kernel@lists.infradead.org
> >> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for
> >> enabling odd parity
> >>
> >> On 08/17/2015 03:22 AM, Michal Simek wrote:
> >>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >>>
> >>> Existing set_termios does not handle the option for enabling odd
> >>> parity. This patch fixes it.
> >>
> >> NAK. PARODD does not enable parity generation or detection.
> >>
> > What if someone is trying to change from even to odd parity?
>
> If userspace wants odd parity, then c_cflag must have both PARENB and PARODD
> set.
>
> Just PARODD does nothing.
>
> From SUS v4, General Terminal Interface, 11.2.4 Control Modes;
>
> "If PARENB is set, parity generation and detection shall be enabled and a parity
> bit is added to each byte. If parity is enabled, PARODD shall specify odd parity if
> set; otherwise, even parity shall be used."
>
>
Thanks a lot. I will incorporate the changes.
>
> > In this conditional case, we setup some register bit for the same.
> > Is the above use case not a valid one?
> >
> > Regards
> > Anirudha
> >
> >> Regards,
> >> Peter Hurley
> >>
> >>> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> >>> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> >>> ---
> >>>
> >>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >>>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/tty/serial/xilinx_uartps.c
> >>> b/drivers/tty/serial/xilinx_uartps.c
> >>> index 009e0dbc12d2..a3020344ac9d 100644
> >>> --- a/drivers/tty/serial/xilinx_uartps.c
> >>> +++ b/drivers/tty/serial/xilinx_uartps.c
> >>> @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct
> >>> uart_port
> >> *port,
> >>>     else
> >>>             cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
> >>>
> >>> -   if (termios->c_cflag & PARENB) {
> >>> +   if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD))
> >>> + {
> >>>             /* Mark or Space parity */
> >>>             if (termios->c_cflag & CMSPAR) {
> >>>                     if (termios->c_cflag & PARODD)
> >>>
> >
> >
> >
> > This email and any attachments are intended for the sole use of the named
> recipient(s) and contain(s) confidential information that may be proprietary,
> privileged or copyrighted under applicable law. If you are not the intended
> recipient, do not read, copy, or forward this email message or any attachments.
> Delete this email message and any attachments immediately.
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


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

* [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
@ 2015-08-17 18:06         ` Anirudha Sarangi
  0 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 18:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:54 PM
> To: Anirudha Sarangi; Michal Simek
> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Soren Brinkmann; Jiri
> Slaby; linux-serial at vger.kernel.org; Greg Kroah-Hartman; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity
>
> On 08/17/2015 11:55 AM, Anirudha Sarangi wrote:
> > Hi,
> >
> >> -----Original Message-----
> >> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> >> Sent: Monday, August 17, 2015 9:09 PM
> >> To: Michal Simek
> >> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Anirudha Sarangi;
> >> Soren Brinkmann; Jiri Slaby; linux-serial at vger.kernel.org; Greg
> >> Kroah-Hartman; linux- arm-kernel at lists.infradead.org
> >> Subject: Re: [PATCH 1/4] serial: xuartps: Fix termios issue for
> >> enabling odd parity
> >>
> >> On 08/17/2015 03:22 AM, Michal Simek wrote:
> >>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >>>
> >>> Existing set_termios does not handle the option for enabling odd
> >>> parity. This patch fixes it.
> >>
> >> NAK. PARODD does not enable parity generation or detection.
> >>
> > What if someone is trying to change from even to odd parity?
>
> If userspace wants odd parity, then c_cflag must have both PARENB and PARODD
> set.
>
> Just PARODD does nothing.
>
> From SUS v4, General Terminal Interface, 11.2.4 Control Modes;
>
> "If PARENB is set, parity generation and detection shall be enabled and a parity
> bit is added to each byte. If parity is enabled, PARODD shall specify odd parity if
> set; otherwise, even parity shall be used."
>
>
Thanks a lot. I will incorporate the changes.
>
> > In this conditional case, we setup some register bit for the same.
> > Is the above use case not a valid one?
> >
> > Regards
> > Anirudha
> >
> >> Regards,
> >> Peter Hurley
> >>
> >>> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> >>> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> >>> ---
> >>>
> >>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >>>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/tty/serial/xilinx_uartps.c
> >>> b/drivers/tty/serial/xilinx_uartps.c
> >>> index 009e0dbc12d2..a3020344ac9d 100644
> >>> --- a/drivers/tty/serial/xilinx_uartps.c
> >>> +++ b/drivers/tty/serial/xilinx_uartps.c
> >>> @@ -723,7 +723,7 @@ static void cdns_uart_set_termios(struct
> >>> uart_port
> >> *port,
> >>>     else
> >>>             cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
> >>>
> >>> -   if (termios->c_cflag & PARENB) {
> >>> +   if ((termios->c_cflag & PARENB) || (termios->c_cflag & PARODD))
> >>> + {
> >>>             /* Mark or Space parity */
> >>>             if (termios->c_cflag & CMSPAR) {
> >>>                     if (termios->c_cflag & PARODD)
> >>>
> >
> >
> >
> > This email and any attachments are intended for the sole use of the named
> recipient(s) and contain(s) confidential information that may be proprietary,
> privileged or copyrighted under applicable law. If you are not the intended
> recipient, do not read, copy, or forward this email message or any attachments.
> Delete this email message and any attachments immediately.
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* RE: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under IGNPAR option
  2015-08-17 16:19         ` Peter Hurley
  (?)
@ 2015-08-17 18:07           ` Anirudha Sarangi
  -1 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 18:07 UTC (permalink / raw)
  To: Peter Hurley, Michal Simek
  Cc: linux-kernel, monstr, Soren Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 3826 bytes --]

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:50 PM
> To: Anirudha Sarangi; Michal Simek
> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Soren Brinkmann; Jiri
> Slaby; linux-serial@vger.kernel.org; Greg Kroah-Hartman; linux-arm-
> kernel@lists.infradead.org
> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
> IGNPAR option
>
> On 08/17/2015 11:58 AM, Anirudha Sarangi wrote:
> > Hi,
> >
> >> -----Original Message-----
> >> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> >> Sent: Monday, August 17, 2015 9:20 PM
> >> To: Michal Simek
> >> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Anirudha Sarangi;
> >> Soren Brinkmann; Jiri Slaby; linux-serial@vger.kernel.org; Greg
> >> Kroah-Hartman; linux- arm-kernel@lists.infradead.org
> >> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun
> >> errors under IGNPAR option
> >>
> >> On 08/17/2015 03:22 AM, Michal Simek wrote:
> >>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >>>
> >>> The existing implementation includes overrun errors under IGNPAR
> >>> option. This patch fixes it by including only parity and framing
> >>> error under IGNPAR option.
> >>
> >> The convention adopted by Linux serial drivers is to ignore overrun
> >> errors if both IGNPAR and IGNBRK are set.
> >>
> > I just followed the set_termios documentation, which says that IGNPAR is for
> parity and framing.
> > The current controller does not support break detection reliably.
> > That is probably why we don’t have IGNBRK.
>
> My point is about how a user-space process tells the serial driver to ignore
> overrun errors, as well, and not specifically about break handling.
>
I understand and this particular change is not very important in the patch set.
I can happily remove it.

Regards
Anirudha
> >
> > Regards
> > Anirudha
> >
> >> Regards,
> >> Peter Hurley
> >>
> >>> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> >>> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> >>> ---
> >>>
> >>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >>>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/tty/serial/xilinx_uartps.c
> >>> b/drivers/tty/serial/xilinx_uartps.c
> >>> index a3020344ac9d..c4437e8929ff 100644
> >>> --- a/drivers/tty/serial/xilinx_uartps.c
> >>> +++ b/drivers/tty/serial/xilinx_uartps.c
> >>> @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct
> >>> uart_port *port,
> >>>
> >>>     if (termios->c_iflag & IGNPAR)
> >>>             port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
> >>> -                   CDNS_UART_IXR_FRAMING |
> >> CDNS_UART_IXR_OVERRUN;
> >>> +                                       CDNS_UART_IXR_FRAMING;
> >>>
> >>>     /* ignore all characters if CREAD is not set */
> >>>     if ((termios->c_cflag & CREAD) == 0)
> >>>
> >
> >
> >
> > This email and any attachments are intended for the sole use of the named
> recipient(s) and contain(s) confidential information that may be proprietary,
> privileged or copyrighted under applicable law. If you are not the intended
> recipient, do not read, copy, or forward this email message or any attachments.
> Delete this email message and any attachments immediately.
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* RE: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under IGNPAR option
@ 2015-08-17 18:07           ` Anirudha Sarangi
  0 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 18:07 UTC (permalink / raw)
  To: Peter Hurley, Michal Simek
  Cc: linux-kernel, monstr, Soren Brinkmann, Jiri Slaby, linux-serial,
	Greg Kroah-Hartman, linux-arm-kernel

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:50 PM
> To: Anirudha Sarangi; Michal Simek
> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Soren Brinkmann; Jiri
> Slaby; linux-serial@vger.kernel.org; Greg Kroah-Hartman; linux-arm-
> kernel@lists.infradead.org
> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
> IGNPAR option
>
> On 08/17/2015 11:58 AM, Anirudha Sarangi wrote:
> > Hi,
> >
> >> -----Original Message-----
> >> From: Peter Hurley [mailto:peter@hurleysoftware.com]
> >> Sent: Monday, August 17, 2015 9:20 PM
> >> To: Michal Simek
> >> Cc: linux-kernel@vger.kernel.org; monstr@monstr.eu; Anirudha Sarangi;
> >> Soren Brinkmann; Jiri Slaby; linux-serial@vger.kernel.org; Greg
> >> Kroah-Hartman; linux- arm-kernel@lists.infradead.org
> >> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun
> >> errors under IGNPAR option
> >>
> >> On 08/17/2015 03:22 AM, Michal Simek wrote:
> >>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >>>
> >>> The existing implementation includes overrun errors under IGNPAR
> >>> option. This patch fixes it by including only parity and framing
> >>> error under IGNPAR option.
> >>
> >> The convention adopted by Linux serial drivers is to ignore overrun
> >> errors if both IGNPAR and IGNBRK are set.
> >>
> > I just followed the set_termios documentation, which says that IGNPAR is for
> parity and framing.
> > The current controller does not support break detection reliably.
> > That is probably why we don’t have IGNBRK.
>
> My point is about how a user-space process tells the serial driver to ignore
> overrun errors, as well, and not specifically about break handling.
>
I understand and this particular change is not very important in the patch set.
I can happily remove it.

Regards
Anirudha
> >
> > Regards
> > Anirudha
> >
> >> Regards,
> >> Peter Hurley
> >>
> >>> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> >>> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> >>> ---
> >>>
> >>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >>>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/tty/serial/xilinx_uartps.c
> >>> b/drivers/tty/serial/xilinx_uartps.c
> >>> index a3020344ac9d..c4437e8929ff 100644
> >>> --- a/drivers/tty/serial/xilinx_uartps.c
> >>> +++ b/drivers/tty/serial/xilinx_uartps.c
> >>> @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct
> >>> uart_port *port,
> >>>
> >>>     if (termios->c_iflag & IGNPAR)
> >>>             port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
> >>> -                   CDNS_UART_IXR_FRAMING |
> >> CDNS_UART_IXR_OVERRUN;
> >>> +                                       CDNS_UART_IXR_FRAMING;
> >>>
> >>>     /* ignore all characters if CREAD is not set */
> >>>     if ((termios->c_cflag & CREAD) == 0)
> >>>
> >
> >
> >
> > This email and any attachments are intended for the sole use of the named
> recipient(s) and contain(s) confidential information that may be proprietary,
> privileged or copyrighted under applicable law. If you are not the intended
> recipient, do not read, copy, or forward this email message or any attachments.
> Delete this email message and any attachments immediately.
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


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

* [PATCH 2/4] serial: xuartps: Do not handle overrun errors under IGNPAR option
@ 2015-08-17 18:07           ` Anirudha Sarangi
  0 siblings, 0 replies; 39+ messages in thread
From: Anirudha Sarangi @ 2015-08-17 18:07 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

> -----Original Message-----
> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> Sent: Monday, August 17, 2015 9:50 PM
> To: Anirudha Sarangi; Michal Simek
> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Soren Brinkmann; Jiri
> Slaby; linux-serial at vger.kernel.org; Greg Kroah-Hartman; linux-arm-
> kernel at lists.infradead.org
> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun errors under
> IGNPAR option
>
> On 08/17/2015 11:58 AM, Anirudha Sarangi wrote:
> > Hi,
> >
> >> -----Original Message-----
> >> From: Peter Hurley [mailto:peter at hurleysoftware.com]
> >> Sent: Monday, August 17, 2015 9:20 PM
> >> To: Michal Simek
> >> Cc: linux-kernel at vger.kernel.org; monstr at monstr.eu; Anirudha Sarangi;
> >> Soren Brinkmann; Jiri Slaby; linux-serial at vger.kernel.org; Greg
> >> Kroah-Hartman; linux- arm-kernel at lists.infradead.org
> >> Subject: Re: [PATCH 2/4] serial: xuartps: Do not handle overrun
> >> errors under IGNPAR option
> >>
> >> On 08/17/2015 03:22 AM, Michal Simek wrote:
> >>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
> >>>
> >>> The existing implementation includes overrun errors under IGNPAR
> >>> option. This patch fixes it by including only parity and framing
> >>> error under IGNPAR option.
> >>
> >> The convention adopted by Linux serial drivers is to ignore overrun
> >> errors if both IGNPAR and IGNBRK are set.
> >>
> > I just followed the set_termios documentation, which says that IGNPAR is for
> parity and framing.
> > The current controller does not support break detection reliably.
> > That is probably why we don?t have IGNBRK.
>
> My point is about how a user-space process tells the serial driver to ignore
> overrun errors, as well, and not specifically about break handling.
>
I understand and this particular change is not very important in the patch set.
I can happily remove it.

Regards
Anirudha
> >
> > Regards
> > Anirudha
> >
> >> Regards,
> >> Peter Hurley
> >>
> >>> Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
> >>> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
> >>> ---
> >>>
> >>>  drivers/tty/serial/xilinx_uartps.c | 2 +-
> >>>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>>
> >>> diff --git a/drivers/tty/serial/xilinx_uartps.c
> >>> b/drivers/tty/serial/xilinx_uartps.c
> >>> index a3020344ac9d..c4437e8929ff 100644
> >>> --- a/drivers/tty/serial/xilinx_uartps.c
> >>> +++ b/drivers/tty/serial/xilinx_uartps.c
> >>> @@ -691,7 +691,7 @@ static void cdns_uart_set_termios(struct
> >>> uart_port *port,
> >>>
> >>>     if (termios->c_iflag & IGNPAR)
> >>>             port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
> >>> -                   CDNS_UART_IXR_FRAMING |
> >> CDNS_UART_IXR_OVERRUN;
> >>> +                                       CDNS_UART_IXR_FRAMING;
> >>>
> >>>     /* ignore all characters if CREAD is not set */
> >>>     if ((termios->c_cflag & CREAD) == 0)
> >>>
> >
> >
> >
> > This email and any attachments are intended for the sole use of the named
> recipient(s) and contain(s) confidential information that may be proprietary,
> privileged or copyrighted under applicable law. If you are not the intended
> recipient, do not read, copy, or forward this email message or any attachments.
> Delete this email message and any attachments immediately.
> >



This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.

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

* Re: [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
  2015-08-17 16:00       ` Anirudha Sarangi
  (?)
@ 2015-08-17 18:46         ` Peter Hurley
  -1 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 18:46 UTC (permalink / raw)
  To: Anirudha Sarangi
  Cc: Michal Simek, linux-kernel, monstr, Soren Brinkmann, Jiri Slaby,
	linux-serial, Greg Kroah-Hartman, linux-arm-kernel

On 08/17/2015 12:00 PM, Anirudha Sarangi wrote:
>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
>> On 08/17/2015 03:22 AM, Michal Simek wrote:
>>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
>>>
>>> The existing interrupt handling logic has followins issues.
>>> - Upon a parity error with default configuration, the control
>>>   never comes out of the ISR thereby hanging Linux.
>>> - The error handling logic around framing and parity error are buggy.
>>>   There are chances that the errors will never be captured.
>>> - The existing ISR is just too long.
>>> This patch fixes all these concerns.
>>
>> This patch is unreviewable. Please break this down into multiple patches.
>>
> Thanks. Let me give a shot. It is just breaking the single big ISR that has both Rx and Tx in a single function into smaller ones.
> Not sure how I will create smaller patches, but I will try and get back.

I would start with a refactor patch that splits up the ISR but
makes no other functional changes. Then add the bug fix patches.

Regards,
Peter Hurley

ps - The email signature below is not appropriate for lkml.

> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 


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

* Re: [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
@ 2015-08-17 18:46         ` Peter Hurley
  0 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 18:46 UTC (permalink / raw)
  To: Anirudha Sarangi
  Cc: Michal Simek, linux-kernel, monstr, Soren Brinkmann, Jiri Slaby,
	linux-serial, Greg Kroah-Hartman, linux-arm-kernel

On 08/17/2015 12:00 PM, Anirudha Sarangi wrote:
>> From: Peter Hurley [mailto:peter@hurleysoftware.com]
>> On 08/17/2015 03:22 AM, Michal Simek wrote:
>>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
>>>
>>> The existing interrupt handling logic has followins issues.
>>> - Upon a parity error with default configuration, the control
>>>   never comes out of the ISR thereby hanging Linux.
>>> - The error handling logic around framing and parity error are buggy.
>>>   There are chances that the errors will never be captured.
>>> - The existing ISR is just too long.
>>> This patch fixes all these concerns.
>>
>> This patch is unreviewable. Please break this down into multiple patches.
>>
> Thanks. Let me give a shot. It is just breaking the single big ISR that has both Rx and Tx in a single function into smaller ones.
> Not sure how I will create smaller patches, but I will try and get back.

I would start with a refactor patch that splits up the ISR but
makes no other functional changes. Then add the bug fix patches.

Regards,
Peter Hurley

ps - The email signature below is not appropriate for lkml.

> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 

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

* [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic
@ 2015-08-17 18:46         ` Peter Hurley
  0 siblings, 0 replies; 39+ messages in thread
From: Peter Hurley @ 2015-08-17 18:46 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/17/2015 12:00 PM, Anirudha Sarangi wrote:
>> From: Peter Hurley [mailto:peter at hurleysoftware.com]
>> On 08/17/2015 03:22 AM, Michal Simek wrote:
>>> From: Anirudha Sarangi <anirudha.sarangi@xilinx.com>
>>>
>>> The existing interrupt handling logic has followins issues.
>>> - Upon a parity error with default configuration, the control
>>>   never comes out of the ISR thereby hanging Linux.
>>> - The error handling logic around framing and parity error are buggy.
>>>   There are chances that the errors will never be captured.
>>> - The existing ISR is just too long.
>>> This patch fixes all these concerns.
>>
>> This patch is unreviewable. Please break this down into multiple patches.
>>
> Thanks. Let me give a shot. It is just breaking the single big ISR that has both Rx and Tx in a single function into smaller ones.
> Not sure how I will create smaller patches, but I will try and get back.

I would start with a refactor patch that splits up the ISR but
makes no other functional changes. Then add the bug fix patches.

Regards,
Peter Hurley

ps - The email signature below is not appropriate for lkml.

> 
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
> 

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

end of thread, other threads:[~2015-08-17 18:46 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-17  7:22 [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity Michal Simek
2015-08-17  7:22 ` Michal Simek
2015-08-17  7:22 ` Michal Simek
2015-08-17  7:22 ` [PATCH 2/4] serial: xuartps: Do not handle overrun errors under IGNPAR option Michal Simek
2015-08-17  7:22   ` Michal Simek
2015-08-17 15:49   ` Peter Hurley
2015-08-17 15:49     ` Peter Hurley
2015-08-17 15:58     ` Anirudha Sarangi
2015-08-17 15:58       ` Anirudha Sarangi
2015-08-17 15:58       ` Anirudha Sarangi
2015-08-17 16:19       ` Peter Hurley
2015-08-17 16:19         ` Peter Hurley
2015-08-17 16:19         ` Peter Hurley
2015-08-17 18:07         ` Anirudha Sarangi
2015-08-17 18:07           ` Anirudha Sarangi
2015-08-17 18:07           ` Anirudha Sarangi
2015-08-17  7:22 ` [PATCH 3/4] serial: xuartps: Do not enable parity error interrupt Michal Simek
2015-08-17  7:22   ` Michal Simek
2015-08-17  7:22 ` [PATCH 4/4] serial: xuartps: Rewrite the interrupt handling logic Michal Simek
2015-08-17  7:22   ` Michal Simek
2015-08-17 15:55   ` Peter Hurley
2015-08-17 15:55     ` Peter Hurley
2015-08-17 16:00     ` Anirudha Sarangi
2015-08-17 16:00       ` Anirudha Sarangi
2015-08-17 16:00       ` Anirudha Sarangi
2015-08-17 18:46       ` Peter Hurley
2015-08-17 18:46         ` Peter Hurley
2015-08-17 18:46         ` Peter Hurley
2015-08-17 15:39 ` [PATCH 1/4] serial: xuartps: Fix termios issue for enabling odd parity Peter Hurley
2015-08-17 15:39   ` Peter Hurley
2015-08-17 15:55   ` Anirudha Sarangi
2015-08-17 15:55     ` Anirudha Sarangi
2015-08-17 15:55     ` Anirudha Sarangi
2015-08-17 16:24     ` Peter Hurley
2015-08-17 16:24       ` Peter Hurley
2015-08-17 16:24       ` Peter Hurley
2015-08-17 18:06       ` Anirudha Sarangi
2015-08-17 18:06         ` Anirudha Sarangi
2015-08-17 18:06         ` Anirudha Sarangi

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.