Skip to contentSkip to conversation

UART: OMAP: Updates

PATCH New Shubhrajyoti D 3 participants 14 messages Apr 16, 2012 – Apr 20, 2012

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover UART: OMAP: Updates

The patch series collects few previously posted patches and adds some clock fixes to the series.

The patch series does following.
- Makes the context_loss_cnt signed to make error handling possible.
- The clock cutting is missed in the error cases, fix it.
- Make the serial_omap_console_ports depend on the macro OMAP_MAX_HSUART_PORTS.
- use devinit and devexit for the probe and remove functions.
- Fixes to the software flow control.

The following changes since commit e816b57a337ea3b755de72bec38c10c864f23015:

Linux 3.4-rc3 (2012-04-15 18:28:29 -0700)

are available in the git repository at:
git://gitorious.org/linus-tree/linus-tree.git uart-omap-next

Shubhrajyoti D (6):
ARM: OMAP: UART: Make context_loss_cnt signed
UART: OMAP: Cut the clock in the error cases
UART: OMAP: Remove the default setting of special character
UART: OMAP: Prevent cutting of clocks if put_sync immediately follows
UART: OMAP: Remove the hardcode serial_omap_console_ports array.
UART: OMAP: Trivial optimisation of the probe and remove

Vikram Pandita (1):
UART: OMAP: fix software flow control

 arch/arm/plat-omap/include/plat/omap-serial.h |    6 ++--
 drivers/tty/serial/omap-serial.c              |   47 ++++++++++++++-----------
 2 files changed, 29 insertions(+), 24 deletions(-)
#1 lore raw

PATCH 1/7 ARM: OMAP: UART: Make context_loss_cnt signed

get_context_loss_count returns an int however it is stored in unsigned integer context_loss_cnt . This patch tries to make context_loss_cnt int. So that in case of errors(which may be negative) the value is not interpreted wrongly.

In serial_omap_runtime_resume in case of errors returned by get_context_loss_count print a warning and do a restore.

---
 arch/arm/plat-omap/include/plat/omap-serial.h |    2 +-
 drivers/tty/serial/omap-serial.c              |   10 ++++++++--
 2 files changed, 9 insertions(+), 3 deletions(-)
arch/arm/plat-omap/include/plat/omap-serial.h +1 -1
index 9ff4444..b7fb6dc 100644
@@ -128,7 +128,7 @@ struct uart_omap_port {
 	unsigned char		msr_saved_flags;
 	char			name[20];
 	unsigned long		port_activity;
-	u32			context_loss_cnt;
+	int			context_loss_cnt;
 	u32			errata;
 	u8			wakeups_enabled;
 
drivers/tty/serial/omap-serial.c +8 -2
index d00b38e..fe099bb 100644
@@ -1612,10 +1612,16 @@ static int serial_omap_runtime_resume(struct device *dev)
 
 	if (up && pdata) {
 		if (pdata->get_context_loss_count) {
-			u32 loss_cnt = pdata->get_context_loss_count(dev);
+			int loss_cnt = pdata->get_context_loss_count(dev);
 
-			if (up->context_loss_cnt != loss_cnt)
+			if (loss_cnt < 0) {
+				dev_err(dev,
+					"get_context_loss_count failed : %d\n",
+					loss_cnt);
 				serial_omap_restore_context(up);
+			} else if (up->context_loss_cnt != loss_cnt) {
+				serial_omap_restore_context(up);
+			}
 		}
 
 		/* Errata i291 */
Signature · 1 line
1.7.4.1
#2 lore raw

PATCH 2/7 UART: OMAP: Cut the clock in the error cases

In reply to Shubhrajyoti D

In the error cases the clock cut is missed. This patch intends to fix the same.

Cc stable at vger.kernel.org
Cc Govindraj.R <[email protected]>
---
 drivers/tty/serial/omap-serial.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)
drivers/tty/serial/omap-serial.c +5 -1
index fe099bb..10e80bb 100644
@@ -319,6 +319,8 @@ static void serial_omap_start_tx(struct uart_port *port)
 
 		if (ret < 0) {
 			serial_omap_enable_ier_thri(up);
+			pm_runtime_mark_last_busy(&up->pdev->dev);
+			pm_runtime_put_autosuspend(&up->pdev->dev);
 			return;
 		}
 	}
@@ -1029,8 +1031,10 @@ static int serial_omap_poll_get_char(struct uart_port *port)
 
 	pm_runtime_get_sync(&up->pdev->dev);
 	status = serial_in(up, UART_LSR);
-	if (!(status & UART_LSR_DR))
+	if (!(status & UART_LSR_DR)) {
+		pm_runtime_put(&up->pdev->dev);
 		return NO_POLL_CHAR;
+	}
 
 	status = serial_in(up, UART_RX);
 	pm_runtime_put(&up->pdev->dev);
Signature · 1 line
1.7.4.1
#3 lore raw

PATCH 2/7 UART: OMAP: Cut the clock in the error cases

Quoted 2 lines · Shubhrajyoti D

In the error cases the clock cut is missed. This patch intends to fix the same.

Please change the references to 'cut clocks' in subject/changelog here
(and in other patches) to use runtime suspend instead. First, runtime PM
calls do more than cut clocks, but they only do so when usecounting/autosuspend timeouts permit.

Quoted 1 line
Cc stable at vger.kernel.org

Please hold off on Cc'ing stable until your patches are reviewed and accepted.

Quoted 11 lines
---
 drivers/tty/serial/omap-serial.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)
drivers/tty/serial/omap-serial.c +0 -0
index fe099bb..10e80bb 100644

drivers/tty/serial/omap-serial.c static void serial_omap_start_tx(struct uart_port *port) · line 323

Quoted 5 lines
drivers/tty/serial/omap-serial.c +2 -0
@@ -319,6 +319,8 @@ static void serial_omap_start_tx(struct uart_port *port)
 
 		if (ret < 0) {
 			serial_omap_enable_ier_thri(up);
+			pm_runtime_mark_last_busy(&up->pdev->dev);
+			pm_runtime_put_autosuspend(&up->pdev->dev);

Why the autosuspend version here?

Kevin

Quoted 15 lines
drivers/tty/serial/omap-serial.c +3 -1
 			return;
 		}
 	}
@@ -1029,8 +1031,10 @@ static int serial_omap_poll_get_char(struct uart_port *port)
 
 	pm_runtime_get_sync(&up->pdev->dev);
 	status = serial_in(up, UART_LSR);
-	if (!(status & UART_LSR_DR))
+	if (!(status & UART_LSR_DR)) {
+		pm_runtime_put(&up->pdev->dev);
 		return NO_POLL_CHAR;
+	}
 
 	status = serial_in(up, UART_RX);
 	pm_runtime_put(&up->pdev->dev);
#4 lore raw

PATCH 2/7 UART: OMAP: Cut the clock in the error cases

Hi Kevin,
Thanks for the review.

Quoted 8 lines · Kevin Hilman
Quoted 2 lines · Shubhrajyoti D

In the error cases the clock cut is missed. This patch intends to fix the same.

Please change the references to 'cut clocks' in subject/changelog here
(and in other patches) to use runtime suspend instead. First, runtime PM
calls do more than cut clocks, but they only do so when usecounting/autosuspend timeouts permit.

Yes thanks will fix it.

Quoted 4 lines
Quoted 3 lines
Cc stable at vger.kernel.org

Please hold off on Cc'ing stable until your patches are reviewed and accepted.

OK

Quoted 12 lines
Quoted 12 lines
---
 drivers/tty/serial/omap-serial.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)
drivers/tty/serial/omap-serial.c +0 -0
index fe099bb..10e80bb 100644
@@ -319,6 +319,8 @@ static void serial_omap_start_tx(struct uart_port *port)
 
Quoted 9 lines

drivers/tty/serial/omap-serial.c static void serial_omap_start_tx(struct uart_port *port) · line 323

Quoted 4 lines
drivers/tty/serial/omap-serial.c +2 -0
 		if (ret < 0) {
 			serial_omap_enable_ier_thri(up);
+			pm_runtime_mark_last_busy(&up->pdev->dev);
+			pm_runtime_put_autosuspend(&up->pdev->dev);

Why the autosuspend version here?

Kevin

In case the request_dma fails we enable the thri( effectively like intr mode) so
I thought of using the autosuspend version here .

Do you prefer put version instead ?

With Regards,
Shubhro

#5 lore raw

PATCH 2/7 UART: OMAP: Cut the clock in the error cases

Quoted 36 lines · Shubhrajyoti

Hi Kevin,
Thanks for the review.

Quoted 8 lines · Kevin Hilman
Quoted 2 lines · Shubhrajyoti D

In the error cases the clock cut is missed. This patch intends to fix the same.

Please change the references to 'cut clocks' in subject/changelog here
(and in other patches) to use runtime suspend instead. First, runtime PM
calls do more than cut clocks, but they only do so when usecounting/autosuspend timeouts permit.

Yes thanks will fix it.

Quoted 4 lines
Quoted 3 lines
Cc stable at vger.kernel.org

Please hold off on Cc'ing stable until your patches are reviewed and accepted.

OK

Quoted 18 lines
Quoted 11 lines
---
 drivers/tty/serial/omap-serial.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)
drivers/tty/serial/omap-serial.c +0 -0
index fe099bb..10e80bb 100644

drivers/tty/serial/omap-serial.c static void serial_omap_start_tx(struct uart_port *port) · line 323

Quoted 5 lines
drivers/tty/serial/omap-serial.c +2 -0
@@ -319,6 +319,8 @@ static void serial_omap_start_tx(struct uart_port *port)
 
 		if (ret < 0) {
 			serial_omap_enable_ier_thri(up);
+			pm_runtime_mark_last_busy(&up->pdev->dev);
+			pm_runtime_put_autosuspend(&up->pdev->dev);

Why the autosuspend version here?

Quoted 8 lines
Quoted 3 lines

Kevin

In case the request_dma fails we enable the thri( effectively like intr mode) so
I thought of using the autosuspend version here .

Do you prefer put version instead ?

Not necessarily, it should just be well described in the changelog.

Kevin

#6 lore raw

PATCH 2/7 UART: OMAP: Cut the clock in the error cases

Quoted 9 lines · Kevin Hilman
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 4 lines

drivers/tty/serial/omap-serial.c static void serial_omap_start_tx(struct uart_port *port) · line 323

Quoted 4 lines
drivers/tty/serial/omap-serial.c +2 -0
 		if (ret < 0) {
 			serial_omap_enable_ier_thri(up);
+			pm_runtime_mark_last_busy(&up->pdev->dev);
+			pm_runtime_put_autosuspend(&up->pdev->dev);

Why the autosuspend version here?

Kevin

Quoted 8 lines
Quoted 5 lines
Quoted 5 lines

In case the request_dma fails we enable the thri( effectively like intr mode) so
I thought of using the autosuspend version here .

Do you prefer put version instead ?

Not necessarily, it should just be well described in the changelog.

Kevin

Yes agree completely. Will describe that in the changelog.

#7 lore raw

PATCH 2/7 UART: OMAP: Cut the clock in the error cases

Quoted 4 lines · Shubhrajyoti
Quoted 2 lines

Kevin

Yes agree completely. Will describe that in the changelog. --

Does the following changelog look ok?

Quoted 1 line

From 37fdc2d40c9b2b19b8c5a9a4b8f7dd547d420f55 Mon Sep 17 00:00:00 2001

From: Shubhrajyoti D <[email protected]>
Date: Wed, 4 Apr 2012 16:32:37 +0530
Subject: [PATCH] UART: OMAP: call pm_runtime_put/autosuspend in the error cases

In the error cases the runtime_put call is missed. This patch intends to fix the same. In case dma request fails, we fall back to the nondma mode so after enabling the threshold call put_autosuspend.

---
 drivers/tty/serial/omap-serial.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)
drivers/tty/serial/omap-serial.c +2 -0
index fe099bb..10e80bb 100644
@@ -319,6 +319,8 @@ static void serial_omap_start_tx(struct uart_port *port)
 
 		if (ret < 0) {
 			serial_omap_enable_ier_thri(up);
+			pm_runtime_mark_last_busy(&up->pdev->dev);
+			pm_runtime_put_autosuspend(&up->pdev->dev);
 			return;
 		}
 	}
@@ -1029,8 +1031,10 @@ static int serial_omap_poll_get_char(struct

uart_port *port)

pm_runtime_get_sync(&up->pdev->dev);
status = serial_in(up, UART_LSR);
- if (!(status & UART_LSR_DR))
+ if (!(status & UART_LSR_DR)) {
+ pm_runtime_put(&up->pdev->dev);
return NO_POLL_CHAR;
+ }

status = serial_in(up, UART_RX);
pm_runtime_put(&up->pdev->dev);

Signature · 1 line
1.7.5.4
#8 lore raw

PATCH 2/7 UART: OMAP: Cut the clock in the error cases

Quoted 6 lines · Shubhrajyoti Datta
Quoted 4 lines · Shubhrajyoti
Quoted 2 lines

Kevin

Yes agree completely. Will describe that in the changelog. --

Does the following changelog look ok?

A little better, but still doesn't explain things so that someone who is not intimately familar with the driver can understand the auto-suspend version is needed in the one case.

Possibly explaining in more detail what would happen if the normal put is used here instead of the autosuspend version might help.

Kevin

Quoted 41 lines

From 37fdc2d40c9b2b19b8c5a9a4b8f7dd547d420f55 Mon Sep 17 00:00:00 2001
From: Shubhrajyoti D <[email protected]>
Date: Wed, 4 Apr 2012 16:32:37 +0530
Subject: [PATCH] UART: OMAP: call pm_runtime_put/autosuspend in the error cases

In the error cases the runtime_put call is missed. This patch intends to fix the same. In case dma request fails, we fall back to the nondma mode so after enabling the threshold call put_autosuspend.

---
 drivers/tty/serial/omap-serial.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)
drivers/tty/serial/omap-serial.c +5 -1
index fe099bb..10e80bb 100644
@@ -319,6 +319,8 @@ static void serial_omap_start_tx(struct uart_port *port)
 
 		if (ret < 0) {
 			serial_omap_enable_ier_thri(up);
+			pm_runtime_mark_last_busy(&up->pdev->dev);
+			pm_runtime_put_autosuspend(&up->pdev->dev);
 			return;
 		}
 	}
@@ -1029,8 +1031,10 @@ static int serial_omap_poll_get_char(struct
 uart_port *port)
 
 	pm_runtime_get_sync(&up->pdev->dev);
 	status = serial_in(up, UART_LSR);
-	if (!(status & UART_LSR_DR))
+	if (!(status & UART_LSR_DR)) {
+		pm_runtime_put(&up->pdev->dev);
 		return NO_POLL_CHAR;
+	}
 
 	status = serial_in(up, UART_RX);

pm_runtime_put(&up->pdev->dev);

#9 lore raw

PATCH 3/7 UART: OMAP: fix software flow control

In reply to Shubhrajyoti D

From: Vikram Pandita <[email protected]>

Software flow control register bits were not defined correctly.

Also clarify the IXON and IXOFF logic to reflect what userspace wants.

Cc stable at vger.kernel.org
Cc Govindraj.R <[email protected]>
---
 arch/arm/plat-omap/include/plat/omap-serial.h |    4 ++--
 drivers/tty/serial/omap-serial.c              |   12 ++++++------
 2 files changed, 8 insertions(+), 8 deletions(-)
arch/arm/plat-omap/include/plat/omap-serial.h +2 -2
index b7fb6dc..6edc30a 100644
@@ -42,10 +42,10 @@
 #define OMAP_UART_WER_MOD_WKUP	0X7F
 
 /* Enable XON/XOFF flow control on output */
-#define OMAP_UART_SW_TX		0x04
+#define OMAP_UART_SW_TX		0x8
 
 /* Enable XON/XOFF flow control on input */
-#define OMAP_UART_SW_RX		0x04
+#define OMAP_UART_SW_RX		0x2
 
 #define OMAP_UART_SYSC_RESET	0X07
 #define OMAP_UART_TCR_TRIG	0X0F
drivers/tty/serial/omap-serial.c +6 -6
index 10e80bb..887d578 100644
@@ -651,19 +651,19 @@ serial_omap_configure_xonxoff
 
 	/*
 	 * IXON Flag:
-	 * Enable XON/XOFF flow control on output.
-	 * Transmit XON1, XOFF1
+	 * Flow control for OMAP.TX
+	 * OMAP.RX should listen for XON/XOFF
 	 */
 	if (termios->c_iflag & IXON)
-		up->efr |= OMAP_UART_SW_TX;
+		up->efr |= OMAP_UART_SW_RX;
 
 	/*
 	 * IXOFF Flag:
-	 * Enable XON/XOFF flow control on input.
-	 * Receiver compares XON1, XOFF1.
+	 * Flow control for OMAP.RX
+	 * OMAP.TX should send XON/XOFF
 	 */
 	if (termios->c_iflag & IXOFF)
-		up->efr |= OMAP_UART_SW_RX;
+		up->efr |= OMAP_UART_SW_TX;
 
 	serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
Signature · 1 line
1.7.4.1
#10 lore raw

PATCH 4/7 UART: OMAP: Remove the default setting of special character

In reply to Shubhrajyoti D

Special character detect enable if enabled by default.Received data comparison with XOFF2 data happens by default.

tty provides only XOFF1 no X0FF2 is provided so no need to enable check for XOFF2.

Keeping this enabled might give some slow transfers due to dummy xoff2 comparison with xoff2 reset value.

Since not all want the XOFF2 support lets not enable it by default.

---
 drivers/tty/serial/omap-serial.c |    6 +-----
 1 files changed, 1 insertions(+), 5 deletions(-)
drivers/tty/serial/omap-serial.c +1 -5
index 887d578..7c69b21 100644
@@ -682,11 +682,7 @@ serial_omap_configure_xonxoff
 	serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 	serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG);
-	/* Enable special char function UARTi.EFR_REG[5] and
-	 * load the new software flow control mode IXON or IXOFF
-	 * and restore the UARTi.EFR_REG[4] ENHANCED_EN value.
-	 */
-	serial_out(up, UART_EFR, up->efr | UART_EFR_SCD);
+
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
 
 	serial_out(up, UART_MCR, up->mcr & ~UART_MCR_TCRTLR);
Signature · 1 line
1.7.4.1
#11 lore raw

PATCH 5/7 UART: OMAP: Prevent cutting of clocks if put_sync immediately follows

In reply to Shubhrajyoti D

In serial_omap_stop_tx in the dma case. We do a autosuspend and immediately a put_sync. Prevent the call of auto suspend. The else case is left as is.

---
 drivers/tty/serial/omap-serial.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)
drivers/tty/serial/omap-serial.c +2 -3
index 7c69b21..1593986 100644
@@ -149,11 +149,10 @@ static void serial_omap_stop_tx(struct uart_port *port)
 		omap_stop_dma(up->uart_dma.tx_dma_channel);
 		omap_free_dma(up->uart_dma.tx_dma_channel);
 		up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE;
-		pm_runtime_mark_last_busy(&up->pdev->dev);
-		pm_runtime_put_autosuspend(&up->pdev->dev);
+	} else {
+		pm_runtime_get_sync(&up->pdev->dev);
 	}
 
-	pm_runtime_get_sync(&up->pdev->dev);
 	if (up->ier & UART_IER_THRI) {
 		up->ier &= ~UART_IER_THRI;
 		serial_out(up, UART_IER, up->ier);
Signature · 1 line
1.7.4.1
#12 lore raw

PATCH 6/7 UART: OMAP: Remove the hardcode serial_omap_console_ports array.

In reply to Shubhrajyoti D

Currently the array serial_omap_console_ports is hard coded to 4. Make it depend on the maximum uart count.
Also fixes OMAP5 which has 6 instances of uart.

---
 drivers/tty/serial/omap-serial.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/tty/serial/omap-serial.c +1 -1
index 1593986..cbc9d64 100644
@@ -1040,7 +1040,7 @@ static int serial_omap_poll_get_char(struct uart_port *port)
 
 #ifdef CONFIG_SERIAL_OMAP_CONSOLE
 
-static struct uart_omap_port *serial_omap_console_ports[4];
+static struct uart_omap_port *serial_omap_console_ports[OMAP_MAX_HSUART_PORTS];
 
 static struct uart_driver serial_omap_reg;
 
Signature · 1 line
1.7.4.1
#13 lore raw

PATCH 7/7 UART: OMAP: Trivial optimisation of the probe and remove

In reply to Shubhrajyoti D

The probe and remove may not be needed after initialisation and remove the code could be be put in the devint and devexit section.

---
 drivers/tty/serial/omap-serial.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/tty/serial/omap-serial.c +3 -3
index cbc9d64..42ad500 100644
@@ -1358,7 +1358,7 @@ static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev)
 	return omap_up_info;
 }
 
-static int serial_omap_probe(struct platform_device *pdev)
+static int __devinit serial_omap_probe(struct platform_device *pdev)
 {
 	struct uart_omap_port	*up;
 	struct resource		*mem, *irq, *dma_tx, *dma_rx;
@@ -1489,7 +1489,7 @@ err_port_line:
 	return ret;
 }
 
-static int serial_omap_remove(struct platform_device *dev)
+static int __devexit serial_omap_remove(struct platform_device *dev)
 {
 	struct uart_omap_port *up = platform_get_drvdata(dev);
 
@@ -1654,7 +1654,7 @@ MODULE_DEVICE_TABLE(of, omap_serial_of_match);
 
 static struct platform_driver serial_omap_driver = {
 	.probe          = serial_omap_probe,
-	.remove         = serial_omap_remove,
+	.remove         = __devexit_p(serial_omap_remove),
 	.driver		= {
 		.name	= DRIVER_NAME,
 		.pm	= &serial_omap_dev_pm_ops,
Signature · 1 line
1.7.4.1