Skip to contentSkip to conversation

OMAP2+: UART: Runtime adaptation + cleanup

PATCH New Govindraj.R 5 participants 22 messages Nov 11, 2011 – Dec 14, 2011

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

v8 cover OMAP2+: UART: Runtime adaptation + cleanup

Converting uart driver to adapt to pm runtime API's. Code re-org + cleanup.
Moving some functionality from serial.c to omap-serial.c

Changes involves:
================
1.) Cleaning up certain uart calls from sram_idle func.
2.) Removed all types of uart clock handling code from serial.c 3.) Using hwmod_mux API enable wakeup capability for uart pad during
hwmod_idle state i.e., when uart clocks are disabled we can enable io-pad wakeup capability for uart if mux_data is available for given uart. Also during during resume from idle call to uart we need to enable clocks back conditionally and this can be done only when io-pad wakeup event bit is set for uart_rx pad. So we need a hwmod API which can probe the uart pad and let us know whether a uart wakeup happened. So omap_hmwod_pad_wakeup_status API is added to meet this requirement.
3.) Adapted omap-serial driver to use runtime API's.
4.) Modify serial_init calls to accept uart parameters from board file.
Like dma_usage, rx_timeout, dma_rx_pollrate, auto_suspend_timeout etc.
5.) Use the omap_prm driver with irq_chaining to wake up uart after clocks are
cut.

Patch series is based on 3.2-rc1.

Patch series depends on *Tero's v9 Irq_chaining patches*. Dependent irq_chaining patches are as below.

89ac62b omap3+: add omap prm driver initialization 170431f OMAP3: pm: do not enable PRCM MPU interrupts manually 9aba1b0 omap3: pm: use prcm chain handler
435481f OMAP2+: mux: add support for PAD wakeup interrupts 5b2d361 mfd: omap-prm: added suspend prepare and complete callbacks aa55c41 mfd: omap-prm: added chain interrupt handler d1db904 mfd: omap-prm: add driver skeleton
31d056c TEMP: OMAP4xxx: hwmod data: add PRM hwmod 19ec3bc TEMP: OMAP3xxx: hwmod data: add PRM hwmod 9a89688 OMAP2+: hwmod: Add API to check IO PAD wakeup status 78e8b65 OMAP2+: hwmod: Add API to enable IO ring wakeup.

Same combination is hosted at:
git://gitorious.org/runtime_3-0/runtime_3-0.git 3.2-rc1_uart_runtime

Ensure CONFIG_OMAP_PRM is set while testing irq_chaining with uart. And for pm_qos usage ensure CONFIG_CPU_IDLE is selected other wise console might be sluggish.

Changes from v7:
---------------
http://www.mail-archive.com/linux-omap at vger.kernel.org/msg57804.html
http://www.mail-archive.com/linux-omap at vger.kernel.org/msg58209.html
http://www.spinics.net/lists/linux-omap/msg59978.html
http://www.spinics.net/lists/linux-serial/msg04772.html

Testing updates:
----------------
OMAP2420/2430SDP: Boot tested.

OMAP3430SDP:
retention, off_mode, system_wide suspend is tested. (earlyprintk & no_console_suspend checked)

OMAP3630 - Zoom3:
pm-retention checked with quart/omap-uart3
[Also tested with uart3 as console uart and pm-ret checked]

BeagleBoard XM Rev C(3630):
retention, off_mode, system_wide suspend is tested.

Deepak K (1):
OMAP2+: UART: Allow UART parameters to be configured from board file.

Govindraj.R (18):
OMAP2+: UART: cleanup + remove uart pm specific API OMAP2+: UART: cleanup 8250 console driver support
OMAP2+: UART: Cleanup part of clock gating mechanism for uart OMAP2+: UART: Add default mux for all uarts.
OMAP2+: UART: Remove mapbase/membase fields from pdata. OMAP2+: UART: Add runtime pm support for omap-serial driver OMAP2+: UART: Remove context_save and move context restore to driver OMAP2+: UART: Ensure all reg values configured are available from
port structure
OMAP2+: UART: Remove uart reset function.
OMAP2+: UART: Get context loss count to context restore OMAP2+: UART: Move errata handling from serial.c to omap-serial OMAP2+: UART: Add wakeup mechanism for omap-uarts
OMAP2+: UART: Remove old and unused clocks handling funcs OMAP2+: UART: remove temporary variable used to count uart instance OMAP2+: UART: Use custom activate func for console uart. OMAP2+: UART: Avoid uart idling on suspend for no_console_suspend
usecase
OMAP2+: UART: Do not gate uart clocks if used for debug_prints OMAP2+: UART: Remove omap_uart_can_sleep and add pm_qos

Jon Hunter (1):
OMAP2+: UART: Make the RX_TIMEOUT for DMA configurable for each UART

 arch/arm/mach-omap2/board-3430sdp.c           |  100 +---
 arch/arm/mach-omap2/board-4430sdp.c           |   68 +--
 arch/arm/mach-omap2/board-n8x0.c              |    6 +-
 arch/arm/mach-omap2/board-omap4panda.c        |   68 +--
 arch/arm/mach-omap2/cpuidle34xx.c             |    5 -
 arch/arm/mach-omap2/pm24xx.c                  |   20 -
 arch/arm/mach-omap2/pm34xx.c                  |   42 --
 arch/arm/mach-omap2/serial.c                  |  926 +++++++------------------
 arch/arm/plat-omap/include/plat/omap-serial.h |   36 +-
 arch/arm/plat-omap/include/plat/serial.h      |   10 +-
 drivers/tty/serial/omap-serial.c              |  341 ++++++++--
 11 files changed, 607 insertions(+), 1015 deletions(-)
Signature · 1 line
1.7.4.1
#1 lore raw

PATCH v8 1/20 OMAP2+: UART: cleanup + remove uart pm specific API

In preparation to UART runtime conversion remove uart specific calls from pm24xx/34xx files and their definition from serial.c These func calls will no more be used with upcoming uart runtime design.

1.) omap_uart_prepare_suspend :- can be taken care with driver suspend hooks. 2.) omap_uart_enable_irqs :- Used to enable/disable uart irq's in suspend
path from PM code, this is removed as same is handled by uart_suspend_port/uart_resume_port in omap-serial driver which will do an port_shutdown on suspend freeing irq and port_startup on resume enabling back irq.
3.) Remove prepare_idle/resume_idle calls used to gate uart clocks.
UART clocks can be gated within driver using runtime funcs and be woken up using irq_chaining from omap_prm driver.
4.) Remove console_locking from idle path as clock gating is done withing
driver itself with runtime API. Remove is_suspending check used to acquire console_lock.

---
 arch/arm/mach-omap2/pm24xx.c             |   18 --------
 arch/arm/mach-omap2/pm34xx.c             |   32 ---------------
 arch/arm/mach-omap2/serial.c             |   65 ------------------------------
 arch/arm/plat-omap/include/plat/serial.h |    4 --
 4 files changed, 0 insertions(+), 119 deletions(-)
arch/arm/mach-omap2/pm24xx.c +0 -18
index cf0c216..5ec2b43 100644
@@ -30,7 +30,6 @@
 #include <linux/irq.h>
 #include <linux/time.h>
 #include <linux/gpio.h>
-#include <linux/console.h>
 
 #include <asm/mach/time.h>
 #include <asm/mach/irq.h>
@@ -126,27 +125,11 @@ static void omap2_enter_full_retention(void)
 	if (omap_irq_pending())
 		goto no_sleep;
 
-	/* Block console output in case it is on one of the OMAP UARTs */
-	if (!is_suspending())
-		if (!console_trylock())
-			goto no_sleep;
-
-	omap_uart_prepare_idle(0);
-	omap_uart_prepare_idle(1);
-	omap_uart_prepare_idle(2);
-
 	/* Jump to SRAM suspend code */
 	omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL),
 			   OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL),
 			   OMAP_SDRC_REGADDR(SDRC_POWER));
 
-	omap_uart_resume_idle(2);
-	omap_uart_resume_idle(1);
-	omap_uart_resume_idle(0);
-
-	if (!is_suspending())
-		console_unlock();
-
 no_sleep:
 	omap2_gpio_resume_after_idle();
 
@@ -290,7 +273,6 @@ static int omap2_pm_suspend(void)
 	mir1 = omap_readl(0x480fe0a4);
 	omap_writel(1 << 5, 0x480fe0ac);
 
-	omap_uart_prepare_suspend();
 	omap2_enter_full_retention();
 
 	omap_writel(mir1, 0x480fe0a4);
arch/arm/mach-omap2/pm34xx.c +0 -32
index 9517203..2eb3215 100644
@@ -28,7 +28,6 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/console.h>
 #include <linux/mfd/omap-prm.h>
 #include <trace/events/power.h>
 
@@ -54,15 +53,6 @@
 
 #ifdef CONFIG_SUSPEND
 static suspend_state_t suspend_state = PM_SUSPEND_ON;
-static inline bool is_suspending(void)
-{
-	return (suspend_state != PM_SUSPEND_ON) && console_suspend_enabled;
-}
-#else
-static inline bool is_suspending(void)
-{
-	return false;
-}
 #endif
 
 /* pm34xx errata defined in pm.h */
@@ -337,20 +327,11 @@ void omap_sram_idle(void)
 			omap3_enable_io_chain();
 	}
 
-	/* Block console output in case it is on one of the OMAP UARTs */
-	if (!is_suspending())
-		if (per_next_state < PWRDM_POWER_ON ||
-		    core_next_state < PWRDM_POWER_ON)
-			if (!console_trylock())
-				goto console_still_active;
-
 	pwrdm_pre_transition();
 
 	/* PER */
 	if (per_next_state < PWRDM_POWER_ON) {
 		per_going_off = (per_next_state == PWRDM_POWER_OFF) ? 1 : 0;
-		omap_uart_prepare_idle(2);
-		omap_uart_prepare_idle(3);
 		omap2_gpio_prepare_for_idle(per_going_off);
 		if (per_next_state == PWRDM_POWER_OFF)
 				omap3_per_save_context();
@@ -358,8 +339,6 @@ void omap_sram_idle(void)
 
 	/* CORE */
 	if (core_next_state < PWRDM_POWER_ON) {
-		omap_uart_prepare_idle(0);
-		omap_uart_prepare_idle(1);
 		if (core_next_state == PWRDM_POWER_OFF) {
 			omap3_core_save_context();
 			omap3_cm_save_context();
@@ -408,8 +387,6 @@ void omap_sram_idle(void)
 			omap3_sram_restore_context();
 			omap2_sms_restore_context();
 		}
-		omap_uart_resume_idle(0);
-		omap_uart_resume_idle(1);
 		if (core_next_state == PWRDM_POWER_OFF)
 			omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
 					       OMAP3430_GR_MOD,
@@ -425,14 +402,8 @@ void omap_sram_idle(void)
 		omap2_gpio_resume_after_idle();
 		if (per_prev_state == PWRDM_POWER_OFF)
 			omap3_per_restore_context();
-		omap_uart_resume_idle(2);
-		omap_uart_resume_idle(3);
 	}
 
-	if (!is_suspending())
-		console_unlock();
-
-console_still_active:
 	/* Disable IO-PAD and IO-CHAIN wakeup */
 	if (omap3_has_io_wakeup() &&
 	    (per_next_state < PWRDM_POWER_ON ||
@@ -494,7 +465,6 @@ static int omap3_pm_suspend(void)
 			goto restore;
 	}
 
-	omap_uart_prepare_suspend();
 	omap3_intc_suspend();
 
 	omap_sram_idle();
@@ -541,14 +511,12 @@ static int omap3_pm_begin(suspend_state_t state)
 {
 	disable_hlt();
 	suspend_state = state;
-	omap_uart_enable_irqs(0);
 	return 0;
 }
 
 static void omap3_pm_end(void)
 {
 	suspend_state = PM_SUSPEND_ON;
-	omap_uart_enable_irqs(1);
 	enable_hlt();
 	return;
 }
arch/arm/mach-omap2/serial.c +0 -65

77 lines not on this page · raw message

arch/arm/plat-omap/include/plat/serial.h +0 -4
index 1ab9fd6..73dd022 100644
@@ -111,10 +111,6 @@ extern void omap_serial_init(void);
 extern void omap_serial_init_port(struct omap_board_data *bdata);
 extern int omap_uart_can_sleep(void);
 extern void omap_uart_check_wakeup(void);
-extern void omap_uart_prepare_suspend(void);
-extern void omap_uart_prepare_idle(int num);
-extern void omap_uart_resume_idle(int num);
-extern void omap_uart_enable_irqs(int enable);
 #endif
 
 #endif
Signature · 1 line
1.7.4.1
#2 lore raw

PATCH v8 2/20 OMAP2+: UART: cleanup 8250 console driver support

In reply to Govindraj.R

We had been using traditional 8250 driver as uart console driver prior to omap-serial driver. Since we have omap-serial driver in mainline kernel for some time now it has been used as default uart console driver on omap2+ platforms. Remove 8250 support for omap-uarts.

Serial_in and serial_out override for 8250 serial driver is also removed. Empty fifo read fix is already taken care with omap-serial driver with data ready bit check from LSR reg before reading RX fifo. Also waiting for THRE(transmit hold reg empty) is done with wait_for_xmitr in omap-serial driver.

Serial_in/out overrides are not neceesary for omap-serial driver and things that are taken with omap-serial driver are removed here.

Remove headers that were necessary to support 8250 support and remove all config bindings done to keep 8250 backward compatibility while adding omap-serial driver. Remove omap_uart_reset needed for 8250 autoconf.

---
 arch/arm/mach-omap2/serial.c |   97 ------------------------------------------
 1 files changed, 0 insertions(+), 97 deletions(-)
arch/arm/mach-omap2/serial.c +0 -97
index 8254067..8499f06 100644
@@ -19,23 +19,17 @@
  */
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/serial_reg.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/serial_8250.h>
 #include <linux/pm_runtime.h>
 #include <linux/console.h>
 
-#ifdef CONFIG_SERIAL_OMAP
 #include <plat/omap-serial.h>
-#endif
-
 #include <plat/common.h>
 #include <plat/board.h>
-#include <plat/clock.h>
 #include <plat/dma.h>
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
@@ -47,10 +41,8 @@
 #include "control.h"
 #include "mux.h"
 
-#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV	0x52
 #define UART_OMAP_WER		0x17	/* Wake-up enable register */
 
-#define UART_ERRATA_FIFO_FULL_ABORT	(0x1 << 0)
 #define UART_ERRATA_i202_MDR1_ACCESS	(0x1 << 1)
 
 /*
@@ -533,41 +525,6 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart)
 #define DEV_CREATE_FILE(dev, attr)
 #endif /* CONFIG_PM */
 
-#ifndef CONFIG_SERIAL_OMAP
-/*
- * Override the default 8250 read handler: mem_serial_in()
- * Empty RX fifo read causes an abort on omap3630 and omap4
- * This function makes sure that an empty rx fifo is not read on these silicons
- * (OMAP1/2/3430 are not affected)
- */
-static unsigned int serial_in_override(struct uart_port *up, int offset)
-{
-	if (UART_RX == offset) {
-		unsigned int lsr;
-		lsr = __serial_read_reg(up, UART_LSR);
-		if (!(lsr & UART_LSR_DR))
-			return -EPERM;
-	}
-
-	return __serial_read_reg(up, offset);
-}
-
-static void serial_out_override(struct uart_port *up, int offset, int value)
-{
-	unsigned int status, tmout = 10000;
-
-	status = __serial_read_reg(up, UART_LSR);
-	while (!(status & UART_LSR_THRE)) {
-		/* Wait up to 10ms for the character(s) to be sent. */
-		if (--tmout == 0)
-			break;
-		udelay(1);
-		status = __serial_read_reg(up, UART_LSR);
-	}
-	__serial_write_reg(up, offset, value);
-}
-#endif
-
 static int __init omap_serial_early_init(void)
 {
 	int i = 0;
@@ -628,15 +585,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 	void *pdata = NULL;
 	u32 pdata_size = 0;
 	char *name;
-#ifndef CONFIG_SERIAL_OMAP
-	struct plat_serial8250_port ports[2] = {
-		{},
-		{.flags = 0},
-	};
-	struct plat_serial8250_port *p = &ports[0];
-#else
 	struct omap_uart_port_info omap_up;
-#endif
 
 	if (WARN_ON(!bdata))
 		return;
@@ -651,51 +600,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 
 	oh = uart->oh;
 	uart->dma_enabled = 0;
-#ifndef CONFIG_SERIAL_OMAP
-	name = "serial8250";
-
-	/*
-	 * !! 8250 driver does not use standard IORESOURCE* It
-	 * has it's own custom pdata that can be taken from
-	 * the hwmod resource data.  But, this needs to be
-	 * done after the build.
-	 *
-	 * ?? does it have to be done before the register ??
-	 * YES, because platform_device_data_add() copies
-	 * pdata, it does not use a pointer.
-	 */
-	p->flags = UPF_BOOT_AUTOCONF;
-	p->iotype = UPIO_MEM;
-	p->regshift = 2;
-	p->uartclk = OMAP24XX_BASE_BAUD * 16;
-	p->irq = oh->mpu_irqs[0].irq;
-	p->mapbase = oh->slaves[0]->addr->pa_start;
-	p->membase = omap_hwmod_get_mpu_rt_va(oh);
-	p->irqflags = IRQF_SHARED;
-	p->private_data = uart;
-
-	/*
-	 * omap44xx, ti816x: Never read empty UART fifo
-	 * omap3xxx: Never read empty UART fifo on UARTs
-	 * with IP rev >=0x52
-	 */
-	uart->regshift = p->regshift;
-	uart->membase = p->membase;
-	if (cpu_is_omap44xx() || cpu_is_ti816x())
-		uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
-	else if ((serial_read_reg(uart, UART_OMAP_MVER) & 0xFF)
-			>= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV)
-		uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
-
-	if (uart->errata & UART_ERRATA_FIFO_FULL_ABORT) {
-		p->serial_in = serial_in_override;
-		p->serial_out = serial_out_override;
-	}
-
-	pdata = &ports[0];
-	pdata_size = 2 * sizeof(struct plat_serial8250_port);
-#else
-
 	name = DRIVER_NAME;
 
 	omap_up.dma_enabled = uart->dma_enabled;
@@ -707,7 +611,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 
 	pdata = &omap_up;
 	pdata_size = sizeof(struct omap_uart_port_info);
-#endif
 
 	if (WARN_ON(!oh))
 		return;
Signature · 1 line
1.7.4.1
#3 lore raw

PATCH v8 3/20 OMAP2+: UART: Cleanup part of clock gating mechanism for uart

In reply to Govindraj.R

Currently we use a shared irq handler to identify uart activity and then trigger a timer. By default the timeout value is zero and can be set or modified from sysfs. If there was no uart activity for the period set through sysfs, the timer will expire and call timer handler this will set a flag can_sleep using which decision to gate uart clocks can be taken.

Since the clock gating mechanism is outside the uart driver, we currently use this mechanism. In preparation to runtime implementation for omap-serial driver we can cleanup this mechanism and use runtime API's to gate uart clocks.

Removes the following:
* timer related info from local uart_state struct
* the code used to set timeout value from sysfs.
* irqflags used to set shared irq handler.
* un-used function omap_uart_check_wakeup.

---
 arch/arm/mach-omap2/serial.c                  |  118 +------------------------
 arch/arm/plat-omap/include/plat/omap-serial.h |    1 -
 arch/arm/plat-omap/include/plat/serial.h      |    1 -
 drivers/tty/serial/omap-serial.c              |    1 -
 4 files changed, 2 insertions(+), 119 deletions(-)
arch/arm/mach-omap2/serial.c +2 -116
index 8499f06..f6adb49 100644
@@ -58,8 +58,6 @@
 struct omap_uart_state {
 	int num;
 	int can_sleep;
-	struct timer_list timer;
-	u32 timeout;
 
 	void __iomem *wk_st;
 	void __iomem *wk_en;
@@ -67,13 +65,9 @@ struct omap_uart_state {
 	u32 padconf;
 	u32 dma_enabled;
 
-	struct clk *ick;
-	struct clk *fck;
 	int clocked;
 
-	int irq;
 	int regshift;
-	int irqflags;
 	void __iomem *membase;
 	resource_size_t mapbase;
 
@@ -331,32 +325,6 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart)
 
 	omap_uart_smart_idle_enable(uart, 0);
 	uart->can_sleep = 0;
-	if (uart->timeout)
-		mod_timer(&uart->timer, jiffies + uart->timeout);
-	else
-		del_timer(&uart->timer);
-}
-
-static void omap_uart_allow_sleep(struct omap_uart_state *uart)
-{
-	if (device_may_wakeup(&uart->pdev->dev))
-		omap_uart_enable_wakeup(uart);
-	else
-		omap_uart_disable_wakeup(uart);
-
-	if (!uart->clocked)
-		return;
-
-	omap_uart_smart_idle_enable(uart, 1);
-	uart->can_sleep = 1;
-	del_timer(&uart->timer);
-}
-
-static void omap_uart_idle_timer(unsigned long data)
-{
-	struct omap_uart_state *uart = (struct omap_uart_state *)data;
-
-	omap_uart_allow_sleep(uart);
 }
 
 int omap_uart_can_sleep(void)
@@ -380,35 +348,11 @@ int omap_uart_can_sleep(void)
 	return can_sleep;
 }
 
-/**
- * omap_uart_interrupt()
- *
- * This handler is used only to detect that *any* UART interrupt has
- * occurred.  It does _nothing_ to handle the interrupt.  Rather,
- * any UART interrupt will trigger the inactivity timer so the
- * UART will not idle or sleep for its timeout period.
- *
- **/
-/* static int first_interrupt; */
-static irqreturn_t omap_uart_interrupt(int irq, void *dev_id)
-{
-	struct omap_uart_state *uart = dev_id;
-
-	omap_uart_block_sleep(uart);
-
-	return IRQ_NONE;
-}
-
 static void omap_uart_idle_init(struct omap_uart_state *uart)
 {
 	int ret;
 
 	uart->can_sleep = 0;
-	uart->timeout = DEFAULT_TIMEOUT;
-	setup_timer(&uart->timer, omap_uart_idle_timer,
-		    (unsigned long) uart);
-	if (uart->timeout)
-		mod_timer(&uart->timer, jiffies + uart->timeout);
 	omap_uart_smart_idle_enable(uart, 0);
 
 	if (cpu_is_omap34xx() && !cpu_is_ti816x()) {
@@ -470,51 +414,8 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
 		uart->wk_mask = 0;
 		uart->padconf = 0;
 	}
-
-	uart->irqflags |= IRQF_SHARED;
-	ret = request_threaded_irq(uart->irq, NULL, omap_uart_interrupt,
-				   IRQF_SHARED, "serial idle", (void *)uart);
-	WARN_ON(ret);
-}
-
-static ssize_t sleep_timeout_show(struct device *dev,
-				  struct device_attribute *attr,
-				  char *buf)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct omap_device *odev = to_omap_device(pdev);
-	struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
-
-	return sprintf(buf, "%u\n", uart->timeout / HZ);
 }
 
-static ssize_t sleep_timeout_store(struct device *dev,
-				   struct device_attribute *attr,
-				   const char *buf, size_t n)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct omap_device *odev = to_omap_device(pdev);
-	struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
-	unsigned int value;
-
-	if (sscanf(buf, "%u", &value) != 1) {
-		dev_err(dev, "sleep_timeout_store: Invalid value\n");
-		return -EINVAL;
-	}
-
-	uart->timeout = value * HZ;
-	if (uart->timeout)
-		mod_timer(&uart->timer, jiffies + uart->timeout);
-	else
-		/* A zero value means disable timeout feature */
-		omap_uart_block_sleep(uart);
-
-	return n;
-}
-
-static DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show,
-		sleep_timeout_store);
-#define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr))
 #else
 static inline void omap_uart_idle_init(struct omap_uart_state *uart) {}
 static void omap_uart_block_sleep(struct omap_uart_state *uart)
@@ -522,7 +423,6 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart)
 	/* Needed to enable UART clocks when built without CONFIG_PM */
 	omap_uart_enable_clocks(uart);
 }
-#define DEV_CREATE_FILE(dev, attr)
 #endif /* CONFIG_PM */
 
 static int __init omap_serial_early_init(void)
@@ -606,8 +506,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 	omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
 	omap_up.mapbase = oh->slaves[0]->addr->pa_start;
 	omap_up.membase = omap_hwmod_get_mpu_rt_va(oh);
-	omap_up.irqflags = IRQF_SHARED;
-	omap_up.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+	omap_up.flags = UPF_BOOT_AUTOCONF;
 
 	pdata = &omap_up;
 	pdata_size = sizeof(struct omap_uart_port_info);
@@ -623,7 +522,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 	omap_device_disable_idle_on_suspend(pdev);
 	oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
 
-	uart->irq = oh->mpu_irqs[0].irq;
 	uart->regshift = 2;
 	uart->mapbase = oh->slaves[0]->addr->pa_start;
 	uart->membase = omap_hwmod_get_mpu_rt_va(oh);
@@ -646,24 +544,12 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 	omap_hwmod_enable_wakeup(uart->oh);
 	omap_device_idle(uart->pdev);
 
-	/*
-	 * Need to block sleep long enough for interrupt driven
-	 * driver to start.  Console driver is in polling mode
-	 * so device needs to be kept enabled while polling driver
-	 * is in use.
-	 */
-	if (uart->timeout)
-		uart->timeout = (30 * HZ);
 	omap_uart_block_sleep(uart);
-	uart->timeout = DEFAULT_TIMEOUT;
-
 	console_unlock();
 
 	if ((cpu_is_omap34xx() && uart->padconf) ||
-	    (uart->wk_en && uart->wk_mask)) {
+	    (uart->wk_en && uart->wk_mask))
 		device_init_wakeup(&pdev->dev, true);
-		DEV_CREATE_FILE(&pdev->dev, &dev_attr_sleep_timeout);
-	}
 
 	/* Enable the MDR1 errata for OMAP3 */
 	if (cpu_is_omap34xx() && !cpu_is_ti816x())
arch/arm/plat-omap/include/plat/omap-serial.h +0 -1
index 2682043..307cd6f 100644
@@ -61,7 +61,6 @@ struct omap_uart_port_info {
 	unsigned int		uartclk;	/* UART clock rate */
 	void __iomem		*membase;	/* ioremap cookie or NULL */
 	resource_size_t		mapbase;	/* resource base */
-	unsigned long		irqflags;	/* request_irq flags */
 	upf_t			flags;		/* UPF_* flags */
 };
 
arch/arm/plat-omap/include/plat/serial.h +0 -1
index 73dd022..eb3f514 100644
@@ -110,7 +110,6 @@ struct omap_board_data;
 extern void omap_serial_init(void);
 extern void omap_serial_init_port(struct omap_board_data *bdata);
 extern int omap_uart_can_sleep(void);
-extern void omap_uart_check_wakeup(void);
 #endif
 
 #endif
drivers/tty/serial/omap-serial.c +0 -1
index 5e713d3..be368cf7 100644
@@ -1278,7 +1278,6 @@ static int serial_omap_probe(struct platform_device *pdev)
 	up->port.membase = omap_up_info->membase;
 	up->port.mapbase = omap_up_info->mapbase;
 	up->port.flags = omap_up_info->flags;
-	up->port.irqflags = omap_up_info->irqflags;
 	up->port.uartclk = omap_up_info->uartclk;
 	up->uart_dma.uart_base = mem->start;
 
Signature · 1 line
1.7.4.1
#4 lore raw

PATCH v8 4/20 OMAP2+: UART: Add default mux for all uarts.

In reply to Govindraj.R

Padconf wakeup is used to wakeup uart after uart fclks/iclks are gated. Rx-Pad wakeup was done by writing to rx-pad offset value populated in serial.c idle_init. Remove the direct reading and writing into rx pad. Remove the padconf field part of omap_uart_state struct and pad offsets populated.

Now with mux framework support we can use mux_utilities
along with hmwod framework to handle io-pad configuration and enable rx-pad wake-up mechanism.

To avoid breaking any board support add default mux data for all uart's if mux info is not passed from board file.
With the default pads populated in serial.c wakeup capability for rx pads is set, this can be used to enable uart_rx io-pad wakeup from hwmod framework. The pad values in 3430sdp/4430sdp/omap4panda board file are same as the default pad values populated in serial.c. Remove pad values from 3430sdp/4430sdp/omap4panda board file and use the default pads from serial.c file.

---
 arch/arm/mach-omap2/board-3430sdp.c    |  100 +--------------------
 arch/arm/mach-omap2/board-4430sdp.c    |   68 +--------------
 arch/arm/mach-omap2/board-omap4panda.c |   68 +--------------
 arch/arm/mach-omap2/serial.c           |  155 ++++++++++++++++++++++++++-----
 4 files changed, 133 insertions(+), 258 deletions(-)
arch/arm/mach-omap2/board-3430sdp.c +1 -99
index 77142c1..b80108b 100644
@@ -475,106 +475,8 @@ static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
 static struct omap_board_mux board_mux[] __initdata = {
 	{ .reg_offset = OMAP_MUX_TERMINATOR },
 };
-
-static struct omap_device_pad serial1_pads[] __initdata = {
-	/*
-	 * Note that off output enable is an active low
-	 * signal. So setting this means pin is a
-	 * input enabled in off mode
-	 */
-	OMAP_MUX_STATIC("uart1_cts.uart1_cts",
-			 OMAP_PIN_INPUT |
-			 OMAP_PIN_OFF_INPUT_PULLDOWN |
-			 OMAP_OFFOUT_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart1_rts.uart1_rts",
-			 OMAP_PIN_OUTPUT |
-			 OMAP_OFF_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart1_rx.uart1_rx",
-			 OMAP_PIN_INPUT |
-			 OMAP_PIN_OFF_INPUT_PULLDOWN |
-			 OMAP_OFFOUT_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart1_tx.uart1_tx",
-			 OMAP_PIN_OUTPUT |
-			 OMAP_OFF_EN |
-			 OMAP_MUX_MODE0),
-};
-
-static struct omap_device_pad serial2_pads[] __initdata = {
-	OMAP_MUX_STATIC("uart2_cts.uart2_cts",
-			 OMAP_PIN_INPUT_PULLUP |
-			 OMAP_PIN_OFF_INPUT_PULLDOWN |
-			 OMAP_OFFOUT_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart2_rts.uart2_rts",
-			 OMAP_PIN_OUTPUT |
-			 OMAP_OFF_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart2_rx.uart2_rx",
-			 OMAP_PIN_INPUT |
-			 OMAP_PIN_OFF_INPUT_PULLDOWN |
-			 OMAP_OFFOUT_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart2_tx.uart2_tx",
-			 OMAP_PIN_OUTPUT |
-			 OMAP_OFF_EN |
-			 OMAP_MUX_MODE0),
-};
-
-static struct omap_device_pad serial3_pads[] __initdata = {
-	OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx",
-			 OMAP_PIN_INPUT_PULLDOWN |
-			 OMAP_PIN_OFF_INPUT_PULLDOWN |
-			 OMAP_OFFOUT_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd",
-			 OMAP_PIN_OUTPUT |
-			 OMAP_OFF_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx",
-			 OMAP_PIN_INPUT |
-			 OMAP_PIN_OFF_INPUT_PULLDOWN |
-			 OMAP_OFFOUT_EN |
-			 OMAP_MUX_MODE0),
-	OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx",
-			 OMAP_PIN_OUTPUT |
-			 OMAP_OFF_EN |
-			 OMAP_MUX_MODE0),
-};
-
-static struct omap_board_data serial1_data __initdata = {
-	.id		= 0,
-	.pads		= serial1_pads,
-	.pads_cnt	= ARRAY_SIZE(serial1_pads),
-};
-
-static struct omap_board_data serial2_data __initdata = {
-	.id		= 1,
-	.pads		= serial2_pads,
-	.pads_cnt	= ARRAY_SIZE(serial2_pads),
-};
-
-static struct omap_board_data serial3_data __initdata = {
-	.id		= 2,
-	.pads		= serial3_pads,
-	.pads_cnt	= ARRAY_SIZE(serial3_pads),
-};
-
-static inline void board_serial_init(void)
-{
-	omap_serial_init_port(&serial1_data);
-	omap_serial_init_port(&serial2_data);
-	omap_serial_init_port(&serial3_data);
-}
 #else
 #define board_mux	NULL
-
-static inline void board_serial_init(void)
-{
-	omap_serial_init();
-}
 #endif
 
 /*
@@ -711,7 +613,7 @@ static void __init omap_3430sdp_init(void)
 	else
 		gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1;
 	omap_ads7846_init(1, gpio_pendown, 310, NULL);
-	board_serial_init();
+	omap_serial_init();
 	omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL);
 	usb_musb_init(NULL);
 	board_smc91x_init();
arch/arm/mach-omap2/board-4430sdp.c +1 -67

82 lines not on this page · raw message

arch/arm/mach-omap2/board-omap4panda.c +1 -67

82 lines not on this page · raw message

arch/arm/mach-omap2/serial.c +130 -25

225 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#5 lore raw

PATCH v8 5/20 OMAP2+: UART: Remove mapbase/membase fields from pdata.

In reply to Govindraj.R

The mapbase (start_address), membase(io_remap cookie) part of pdata struct omap_uart_port_info are removed as this should be derived within driver.

---
 arch/arm/mach-omap2/serial.c                  |    2 --
 arch/arm/plat-omap/include/plat/omap-serial.h |    2 --
 drivers/tty/serial/omap-serial.c              |   10 ++++++++--
 3 files changed, 8 insertions(+), 6 deletions(-)
arch/arm/mach-omap2/serial.c +0 -2
index 0de1a56..beb46e8 100644
@@ -605,8 +605,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 
 	omap_up.dma_enabled = uart->dma_enabled;
 	omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
-	omap_up.mapbase = oh->slaves[0]->addr->pa_start;
-	omap_up.membase = omap_hwmod_get_mpu_rt_va(oh);
 	omap_up.flags = UPF_BOOT_AUTOCONF;
 
 	pdata = &omap_up;
arch/arm/plat-omap/include/plat/omap-serial.h +0 -2
index 307cd6f..db9bda9 100644
@@ -59,8 +59,6 @@
 struct omap_uart_port_info {
 	bool			dma_enabled;	/* To specify DMA Mode */
 	unsigned int		uartclk;	/* UART clock rate */
-	void __iomem		*membase;	/* ioremap cookie or NULL */
-	resource_size_t		mapbase;	/* resource base */
 	upf_t			flags;		/* UPF_* flags */
 };
 
drivers/tty/serial/omap-serial.c +8 -2
index be368cf7..31f0cbf 100644
@@ -1275,8 +1275,14 @@ static int serial_omap_probe(struct platform_device *pdev)
 	up->port.ops = &serial_omap_pops;
 	up->port.line = pdev->id;
 
-	up->port.membase = omap_up_info->membase;
-	up->port.mapbase = omap_up_info->mapbase;
+	up->port.mapbase = mem->start;
+	up->port.membase = ioremap(mem->start, resource_size(mem));
+	if (!up->port.membase) {
+		dev_err(&pdev->dev, "can't ioremap UART\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
 	up->port.flags = omap_up_info->flags;
 	up->port.uartclk = omap_up_info->uartclk;
 	up->uart_dma.uart_base = mem->start;
Signature · 1 line
1.7.4.1
#6 lore raw

PATCH v8 6/20 OMAP2+: UART: Add runtime pm support for omap-serial driver

In reply to Govindraj.R

Adapts omap-serial driver to use pm_runtime API's.
Use runtime runtime API's to handle uart clocks and obtain device_usage statics. Set runtime API's usage to irq_safe so that we can use get_sync from irq context. Auto-suspend for port specific activities and put for reg access. Moving suspend/resume hooks to dev_pm_ops structure and bing with config_suspend to avoid any compilation warning if config_suspend is disabled.

By default uart autosuspend delay is set to -1 to avoid character loss if uart's are autoidled and woken up on rx pin.

After boot up UART's can be autoidled by setting autosuspend delay from sysfs.

echo 3000 > /sys/devices/platform/omap/omap_uart.X/power/autosuspend_delay_ms X=0,1,2,3 for UART1/2/3/4. Number of uarts available may vary across omap_soc.

Also if uart is not wakeup capable we can prevent runtime autosuspend by forbiding runtime.

---
 drivers/tty/serial/omap-serial.c |  122 ++++++++++++++++++++++++++++++++++----
 1 files changed, 109 insertions(+), 13 deletions(-)
drivers/tty/serial/omap-serial.c +109 -13
index 31f0cbf..f16ef4b9 100644
@@ -37,11 +37,14 @@
 #include <linux/clk.h>
 #include <linux/serial_core.h>
 #include <linux/irq.h>
+#include <linux/pm_runtime.h>
 
 #include <plat/dma.h>
 #include <plat/dmtimer.h>
 #include <plat/omap-serial.h>
 
+#define OMAP_UART_AUTOSUSPEND_DELAY -1
+
 static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
 
 /* Forward declaration of functions */
@@ -102,6 +105,8 @@ static void serial_omap_stop_rxdma(struct uart_omap_port *up)
 		omap_free_dma(up->uart_dma.rx_dma_channel);
 		up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE;
 		up->uart_dma.rx_dma_used = false;
+		pm_runtime_mark_last_busy(&up->pdev->dev);
+		pm_runtime_put_autosuspend(&up->pdev->dev);
 	}
 }
 
@@ -110,8 +115,11 @@ static void serial_omap_enable_ms(struct uart_port *port)
 	struct uart_omap_port *up = (struct uart_omap_port *)port;
 
 	dev_dbg(up->port.dev, "serial_omap_enable_ms+%d\n", up->pdev->id);
+
+	pm_runtime_get_sync(&up->pdev->dev);
 	up->ier |= UART_IER_MSI;
 	serial_out(up, UART_IER, up->ier);
+	pm_runtime_put(&up->pdev->dev);
 }
 
 static void serial_omap_stop_tx(struct uart_port *port)
@@ -129,23 +137,32 @@ 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);
 	}
 
+	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);
 	}
+
+	pm_runtime_mark_last_busy(&up->pdev->dev);
+	pm_runtime_put_autosuspend(&up->pdev->dev);
 }
 
 static void serial_omap_stop_rx(struct uart_port *port)
 {
 	struct uart_omap_port *up = (struct uart_omap_port *)port;
 
+	pm_runtime_get_sync(&up->pdev->dev);
 	if (up->use_dma)
 		serial_omap_stop_rxdma(up);
 	up->ier &= ~UART_IER_RLSI;
 	up->port.read_status_mask &= ~UART_LSR_DR;
 	serial_out(up, UART_IER, up->ier);
+	pm_runtime_mark_last_busy(&up->pdev->dev);
+	pm_runtime_put_autosuspend(&up->pdev->dev);
 }
 
 static inline void receive_chars(struct uart_omap_port *up, int *status)
@@ -262,7 +279,10 @@ static void serial_omap_start_tx(struct uart_port *port)
 	int ret = 0;
 
 	if (!up->use_dma) {
+		pm_runtime_get_sync(&up->pdev->dev);
 		serial_omap_enable_ier_thri(up);
+		pm_runtime_mark_last_busy(&up->pdev->dev);
+		pm_runtime_put_autosuspend(&up->pdev->dev);
 		return;
 	}
 
@@ -272,6 +292,7 @@ static void serial_omap_start_tx(struct uart_port *port)
 	xmit = &up->port.state->xmit;
 
 	if (up->uart_dma.tx_dma_channel == OMAP_UART_DMA_CH_FREE) {
+		pm_runtime_get_sync(&up->pdev->dev);
 		ret = omap_request_dma(up->uart_dma.uart_dma_tx,
 				"UART Tx DMA",
 				(void *)uart_tx_dma_callback, up,
@@ -354,9 +375,13 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
 	unsigned int iir, lsr;
 	unsigned long flags;
 
+	pm_runtime_get_sync(&up->pdev->dev);
 	iir = serial_in(up, UART_IIR);
-	if (iir & UART_IIR_NO_INT)
+	if (iir & UART_IIR_NO_INT) {
+		pm_runtime_mark_last_busy(&up->pdev->dev);
+		pm_runtime_put_autosuspend(&up->pdev->dev);
 		return IRQ_NONE;
+	}
 
 	spin_lock_irqsave(&up->port.lock, flags);
 	lsr = serial_in(up, UART_LSR);
@@ -378,6 +403,9 @@ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id)
 		transmit_chars(up);
 
 	spin_unlock_irqrestore(&up->port.lock, flags);
+	pm_runtime_mark_last_busy(&up->pdev->dev);
+	pm_runtime_put_autosuspend(&up->pdev->dev);
+
 	up->port_activity = jiffies;
 	return IRQ_HANDLED;
 }
@@ -388,11 +416,12 @@ static unsigned int serial_omap_tx_empty(struct uart_port *port)
 	unsigned long flags = 0;
 	unsigned int ret = 0;
 
+	pm_runtime_get_sync(&up->pdev->dev);
 	dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->pdev->id);
 	spin_lock_irqsave(&up->port.lock, flags);
 	ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
 	spin_unlock_irqrestore(&up->port.lock, flags);
-
+	pm_runtime_put(&up->pdev->dev);
 	return ret;
 }
 
@@ -402,7 +431,10 @@ static unsigned int serial_omap_get_mctrl(struct uart_port *port)
 	unsigned char status;
 	unsigned int ret = 0;
 
+	pm_runtime_get_sync(&up->pdev->dev);
 	status = check_modem_status(up);
+	pm_runtime_put(&up->pdev->dev);
+
 	dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->pdev->id);
 
 	if (status & UART_MSR_DCD)
@@ -433,8 +465,10 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl)
 	if (mctrl & TIOCM_LOOP)
 		mcr |= UART_MCR_LOOP;
 
+	pm_runtime_get_sync(&up->pdev->dev);
 	mcr |= up->mcr;
 	serial_out(up, UART_MCR, mcr);
+	pm_runtime_put(&up->pdev->dev);
 }
 
 static void serial_omap_break_ctl(struct uart_port *port, int break_state)
@@ -443,6 +477,7 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state)
 	unsigned long flags = 0;
 
 	dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->pdev->id);
+	pm_runtime_get_sync(&up->pdev->dev);
 	spin_lock_irqsave(&up->port.lock, flags);
 	if (break_state == -1)
 		up->lcr |= UART_LCR_SBC;
@@ -450,6 +485,7 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state)
 		up->lcr &= ~UART_LCR_SBC;
 	serial_out(up, UART_LCR, up->lcr);
 	spin_unlock_irqrestore(&up->port.lock, flags);
+	pm_runtime_put(&up->pdev->dev);
 }
 
 static int serial_omap_startup(struct uart_port *port)
@@ -468,6 +504,7 @@ static int serial_omap_startup(struct uart_port *port)
 
 	dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->pdev->id);
 
+	pm_runtime_get_sync(&up->pdev->dev);
 	/*
 	 * Clear the FIFO buffers and disable them.
 	 * (they will be reenabled in set_termios())
@@ -523,6 +560,8 @@ static int serial_omap_startup(struct uart_port *port)
 	/* Enable module level wake up */
 	serial_out(up, UART_OMAP_WER, OMAP_UART_WER_MOD_WKUP);
 
+	pm_runtime_mark_last_busy(&up->pdev->dev);
+	pm_runtime_put_autosuspend(&up->pdev->dev);
 	up->port_activity = jiffies;
 	return 0;
 }
@@ -533,6 +572,8 @@ static void serial_omap_shutdown(struct uart_port *port)
 	unsigned long flags = 0;
 
 	dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->pdev->id);
+
+	pm_runtime_get_sync(&up->pdev->dev);
 	/*
 	 * Disable interrupts from this port
 	 */
@@ -566,6 +607,8 @@ static void serial_omap_shutdown(struct uart_port *port)
 			up->uart_dma.rx_buf_dma_phys);
 		up->uart_dma.rx_buf = NULL;
 	}
+
+	pm_runtime_put(&up->pdev->dev);
 	free_irq(up->port.irq, up);
 }
 
@@ -680,6 +723,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 	 * Ok, we're now changing the port state. Do it with
 	 * interrupts disabled.
 	 */
+	pm_runtime_get_sync(&up->pdev->dev);
 	spin_lock_irqsave(&up->port.lock, flags);
 
 	/*
@@ -809,6 +853,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 	serial_omap_configure_xonxoff(up, termios);
 
 	spin_unlock_irqrestore(&up->port.lock, flags);
+	pm_runtime_put(&up->pdev->dev);
 	dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->pdev->id);
 }
 
@@ -820,6 +865,8 @@ serial_omap_pm(struct uart_port *port, unsigned int state,
 	unsigned char efr;
 
 	dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->pdev->id);
+
+	pm_runtime_get_sync(&up->pdev->dev);
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 	efr = serial_in(up, UART_EFR);
 	serial_out(up, UART_EFR, efr | UART_EFR_ECB);
@@ -829,6 +876,15 @@ serial_omap_pm(struct uart_port *port, unsigned int state,
 	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
 	serial_out(up, UART_EFR, efr);
 	serial_out(up, UART_LCR, 0);
+
+	if (!device_may_wakeup(&up->pdev->dev)) {
+		if (!state)
+			pm_runtime_forbid(&up->pdev->dev);
+		else
+			pm_runtime_allow(&up->pdev->dev);
+	}
+
+	pm_runtime_put(&up->pdev->dev);
 }
 
 static void serial_omap_release_port(struct uart_port *port)
@@ -906,19 +962,26 @@ static inline void wait_for_xmitr(struct uart_omap_port *up)
 static void serial_omap_poll_put_char(struct uart_port *port, unsigned char ch)
 {
 	struct uart_omap_port *up = (struct uart_omap_port *)port;
+
+	pm_runtime_get_sync(&up->pdev->dev);
 	wait_for_xmitr(up);
 	serial_out(up, UART_TX, ch);
+	pm_runtime_put(&up->pdev->dev);
 }
 
 static int serial_omap_poll_get_char(struct uart_port *port)
 {
 	struct uart_omap_port *up = (struct uart_omap_port *)port;
-	unsigned int status = serial_in(up, UART_LSR);
+	unsigned int status;
 
+	pm_runtime_get_sync(&up->pdev->dev);
+	status = serial_in(up, UART_LSR);
 	if (!(status & UART_LSR_DR))
 		return NO_POLL_CHAR;
 
-	return serial_in(up, UART_RX);
+	status = serial_in(up, UART_RX);
+	pm_runtime_put(&up->pdev->dev);
+	return status;
 }
 
 #endif /* CONFIG_CONSOLE_POLL */
@@ -946,6 +1009,8 @@ serial_omap_console_write(struct console *co, const char *s,
 	unsigned int ier;
 	int locked = 1;
 
+	pm_runtime_get_sync(&up->pdev->dev);
+
 	local_irq_save(flags);
 	if (up->port.sysrq)
 		locked = 0;
@@ -978,6 +1043,8 @@ serial_omap_console_write(struct console *co, const char *s,
 	if (up->msr_saved_flags)
 		check_modem_status(up);
 
+	pm_runtime_mark_last_busy(&up->pdev->dev);
+	pm_runtime_put_autosuspend(&up->pdev->dev);
 	if (locked)
 		spin_unlock(&up->port.lock);
 	local_irq_restore(flags);
@@ -1060,24 +1127,25 @@ static struct uart_driver serial_omap_reg = {
 	.cons		= OMAP_CONSOLE,
 };
 
-static int
-serial_omap_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_SUSPEND
+static int serial_omap_suspend(struct device *dev)
 {
-	struct uart_omap_port *up = platform_get_drvdata(pdev);
+	struct uart_omap_port *up = dev_get_drvdata(dev);
 
 	if (up)
 		uart_suspend_port(&serial_omap_reg, &up->port);
 	return 0;
 }
 
-static int serial_omap_resume(struct platform_device *dev)
+static int serial_omap_resume(struct device *dev)
 {
-	struct uart_omap_port *up = platform_get_drvdata(dev);
+	struct uart_omap_port *up = dev_get_drvdata(dev);
 
 	if (up)
 		uart_resume_port(&serial_omap_reg, &up->port);
 	return 0;
 }
+#endif
 
 static void serial_omap_rx_timeout(unsigned long uart_no)
 {
@@ -1135,6 +1203,7 @@ static int serial_omap_start_rxdma(struct uart_omap_port *up)
 	int ret = 0;
 
 	if (up->uart_dma.rx_dma_channel == -1) {
+		pm_runtime_get_sync(&up->pdev->dev);
 		ret = omap_request_dma(up->uart_dma.uart_dma_rx,
 				"UART Rx DMA",
 				(void *)uart_rx_dma_callback, up,
@@ -1299,6 +1368,14 @@ static int serial_omap_probe(struct platform_device *pdev)
 		up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE;
 	}
 
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev,
+			OMAP_UART_AUTOSUSPEND_DELAY);
+
+	pm_runtime_irq_safe(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get_sync(&pdev->dev);
+
 	ui[pdev->id] = up;
 	serial_omap_add_console_port(up);
 
@@ -1306,6 +1383,7 @@ static int serial_omap_probe(struct platform_device *pdev)
 	if (ret != 0)
 		goto do_release_region;
 
+	pm_runtime_put(&pdev->dev);
 	platform_set_drvdata(pdev, up);
 	return 0;
 err:
@@ -1320,22 +1398,40 @@ static int serial_omap_remove(struct platform_device *dev)
 {
 	struct uart_omap_port *up = platform_get_drvdata(dev);
 
-	platform_set_drvdata(dev, NULL);
 	if (up) {
+		pm_runtime_disable(&up->pdev->dev);
 		uart_remove_one_port(&serial_omap_reg, &up->port);
 		kfree(up);
 	}
+
+	platform_set_drvdata(dev, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM_RUNTIME
+static int serial_omap_runtime_suspend(struct device *dev)
+{
 	return 0;
 }
 
+static int serial_omap_runtime_resume(struct device *dev)
+{
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops serial_omap_dev_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(serial_omap_suspend, serial_omap_resume)
+	SET_RUNTIME_PM_OPS(serial_omap_runtime_suspend,
+				serial_omap_runtime_resume, NULL)
+};
+
 static struct platform_driver serial_omap_driver = {
 	.probe          = serial_omap_probe,
 	.remove         = serial_omap_remove,
-
-	.suspend	= serial_omap_suspend,
-	.resume		= serial_omap_resume,
 	.driver		= {
 		.name	= DRIVER_NAME,
+		.pm	= &serial_omap_dev_pm_ops,
 	},
 };
 
Signature · 1 line
1.7.4.1
#7 lore raw

PATCH v8 7/20 OMAP2+: UART: Remove context_save and move context restore to driver

In reply to Govindraj.R

Remove context save function from serial.c and move context restore function to omap-serial. Remove all regs stored in omap_uart_state for contex_save/restore, reg read write funcs used in context_save/restore, io_addresses populated for read/write funcs.

Clock gating mechanism was done in serial.c and had no info on uart state thus we needed context save and restore in serial.c
With runtime conversion and clock gating done within uart driver context restore can be done from regs value available from uart_omap_port structure.

---
 arch/arm/mach-omap2/serial.c     |  118 --------------------------------------
 drivers/tty/serial/omap-serial.c |   24 ++++++++
 2 files changed, 24 insertions(+), 118 deletions(-)
arch/arm/mach-omap2/serial.c +0 -118
index beb46e8..3d5df9a 100644
@@ -41,8 +41,6 @@
 #include "control.h"
 #include "mux.h"
 
-#define UART_OMAP_WER		0x17	/* Wake-up enable register */
-
 #define UART_ERRATA_i202_MDR1_ACCESS	(0x1 << 1)
 
 /*
@@ -66,60 +64,16 @@ struct omap_uart_state {
 
 	int clocked;
 
-	int regshift;
-	void __iomem *membase;
-	resource_size_t mapbase;
-
 	struct list_head node;
 	struct omap_hwmod *oh;
 	struct platform_device *pdev;
 
 	u32 errata;
-#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
-	int context_valid;
-
-	/* Registers to be saved/restored for OFF-mode */
-	u16 dll;
-	u16 dlh;
-	u16 ier;
-	u16 sysc;
-	u16 scr;
-	u16 wer;
-	u16 mcr;
-#endif
 };
 
 static LIST_HEAD(uart_list);
 static u8 num_uarts;
 
-static inline unsigned int __serial_read_reg(struct uart_port *up,
-					     int offset)
-{
-	offset <<= up->regshift;
-	return (unsigned int)__raw_readb(up->membase + offset);
-}
-
-static inline unsigned int serial_read_reg(struct omap_uart_state *uart,
-					   int offset)
-{
-	offset <<= uart->regshift;
-	return (unsigned int)__raw_readb(uart->membase + offset);
-}
-
-static inline void __serial_write_reg(struct uart_port *up, int offset,
-		int value)
-{
-	offset <<= up->regshift;
-	__raw_writeb(value, up->membase + offset);
-}
-
-static inline void serial_write_reg(struct omap_uart_state *uart, int offset,
-				    int value)
-{
-	offset <<= uart->regshift;
-	__raw_writeb(value, uart->membase + offset);
-}
-
 /*
  * Internal UARTs need to be initialized for the 8250 autoconfig to work
  * properly. Note that the TX watermark initialization may not be needed
@@ -170,75 +124,6 @@ static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val,
 	}
 }
 
-static void omap_uart_save_context(struct omap_uart_state *uart)
-{
-	u16 lcr = 0;
-
-	if (!enable_off_mode)
-		return;
-
-	lcr = serial_read_reg(uart, UART_LCR);
-	serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
-	uart->dll = serial_read_reg(uart, UART_DLL);
-	uart->dlh = serial_read_reg(uart, UART_DLM);
-	serial_write_reg(uart, UART_LCR, lcr);
-	uart->ier = serial_read_reg(uart, UART_IER);
-	uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC);
-	uart->scr = serial_read_reg(uart, UART_OMAP_SCR);
-	uart->wer = serial_read_reg(uart, UART_OMAP_WER);
-	serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
-	uart->mcr = serial_read_reg(uart, UART_MCR);
-	serial_write_reg(uart, UART_LCR, lcr);
-
-	uart->context_valid = 1;
-}
-
-static void omap_uart_restore_context(struct omap_uart_state *uart)
-{
-	u16 efr = 0;
-
-	if (!enable_off_mode)
-		return;
-
-	if (!uart->context_valid)
-		return;
-
-	uart->context_valid = 0;
-
-	if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
-		omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_DISABLE, 0xA0);
-	else
-		serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
-
-	serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
-	efr = serial_read_reg(uart, UART_EFR);
-	serial_write_reg(uart, UART_EFR, UART_EFR_ECB);
-	serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
-	serial_write_reg(uart, UART_IER, 0x0);
-	serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
-	serial_write_reg(uart, UART_DLL, uart->dll);
-	serial_write_reg(uart, UART_DLM, uart->dlh);
-	serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
-	serial_write_reg(uart, UART_IER, uart->ier);
-	serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
-	serial_write_reg(uart, UART_MCR, uart->mcr);
-	serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
-	serial_write_reg(uart, UART_EFR, efr);
-	serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8);
-	serial_write_reg(uart, UART_OMAP_SCR, uart->scr);
-	serial_write_reg(uart, UART_OMAP_WER, uart->wer);
-	serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc);
-
-	if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
-		omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_16X_MODE, 0xA1);
-	else
-		/* UART 16x mode */
-		serial_write_reg(uart, UART_OMAP_MDR1,
-				UART_OMAP_MDR1_16X_MODE);
-}
-#else
-static inline void omap_uart_save_context(struct omap_uart_state *uart) {}
-static inline void omap_uart_restore_context(struct omap_uart_state *uart) {}
 #endif /* CONFIG_PM && CONFIG_ARCH_OMAP3 */
 
 static inline void omap_uart_enable_clocks(struct omap_uart_state *uart)
@@ -621,9 +506,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 	omap_device_disable_idle_on_suspend(pdev);
 	oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
 
-	uart->regshift = 2;
-	uart->mapbase = oh->slaves[0]->addr->pa_start;
-	uart->membase = omap_hwmod_get_mpu_rt_va(oh);
 	uart->pdev = pdev;
 
 	oh->dev_attr = uart;
drivers/tty/serial/omap-serial.c +24 -0
index f16ef4b9..a834e91 100644
@@ -1408,6 +1408,25 @@ static int serial_omap_remove(struct platform_device *dev)
 	return 0;
 }
 
+static void serial_omap_restore_context(struct uart_omap_port *up)
+{
+	serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
+	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */
+	serial_out(up, UART_EFR, UART_EFR_ECB);
+	serial_out(up, UART_LCR, 0x0); /* Operational mode */
+	serial_out(up, UART_IER, 0x0);
+	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */
+	serial_out(up, UART_LCR, 0x0); /* Operational mode */
+	serial_out(up, UART_IER, up->ier);
+	serial_out(up, UART_FCR, up->fcr);
+	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
+	serial_out(up, UART_MCR, up->mcr);
+	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */
+	serial_out(up, UART_EFR, up->efr);
+	serial_out(up, UART_LCR, up->lcr);
+	serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
+}
+
 #ifdef CONFIG_PM_RUNTIME
 static int serial_omap_runtime_suspend(struct device *dev)
 {
@@ -1416,6 +1435,11 @@ static int serial_omap_runtime_suspend(struct device *dev)
 
 static int serial_omap_runtime_resume(struct device *dev)
 {
+	struct uart_omap_port *up = dev_get_drvdata(dev);
+
+	if (up)
+		serial_omap_restore_context(up);
+
 	return 0;
 }
 #endif
Signature · 1 line
1.7.4.1
#8 lore raw

PATCH v8 8/20 OMAP2+: UART: Ensure all reg values configured are available from port structure

In reply to Govindraj.R

Add missing uart regs to uart_port structure which can be used in context restore. Store dll, dlh, mdr1, scr, efr, lcr, mcr reg values into uart_port structure while configuring individual port in termios function.

---
 arch/arm/plat-omap/include/plat/omap-serial.h |    4 ++
 drivers/tty/serial/omap-serial.c              |   43 +++++++++++++++----------
 2 files changed, 30 insertions(+), 17 deletions(-)
arch/arm/plat-omap/include/plat/omap-serial.h +4 -0
index db9bda9..70e7738 100644
@@ -97,6 +97,10 @@ struct uart_omap_port {
 	unsigned char		mcr;
 	unsigned char		fcr;
 	unsigned char		efr;
+	unsigned char		dll;
+	unsigned char		dlh;
+	unsigned char		mdr1;
+	unsigned char		scr;
 
 	int			use_dma;
 	/*
drivers/tty/serial/omap-serial.c +26 -17

132 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#9 lore raw

PATCH v8 9/20 OMAP2+: UART: Remove uart reset function.

In reply to Govindraj.R

Remove the uart reset function which is configuring the TX empty irq which can now be handled within omap-serial driver.

---
 arch/arm/mach-omap2/serial.c                  |   14 --------------
 arch/arm/plat-omap/include/plat/omap-serial.h |    2 ++
 drivers/tty/serial/omap-serial.c              |    1 +
 3 files changed, 3 insertions(+), 14 deletions(-)
arch/arm/mach-omap2/serial.c +0 -14
index 3d5df9a..06887d3 100644
@@ -74,19 +74,6 @@ struct omap_uart_state {
 static LIST_HEAD(uart_list);
 static u8 num_uarts;
 
-/*
- * Internal UARTs need to be initialized for the 8250 autoconfig to work
- * properly. Note that the TX watermark initialization may not be needed
- * once the 8250.c watermark handling code is merged.
- */
-
-static inline void __init omap_uart_reset(struct omap_uart_state *uart)
-{
-	serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
-	serial_write_reg(uart, UART_OMAP_SCR, 0x08);
-	serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
-}
-
 #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
 
 /*
@@ -521,7 +508,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 
 	omap_device_enable(uart->pdev);
 	omap_uart_idle_init(uart);
-	omap_uart_reset(uart);
 	omap_hwmod_enable_wakeup(uart->oh);
 	omap_device_idle(uart->pdev);
 
arch/arm/plat-omap/include/plat/omap-serial.h +2 -0
index 70e7738..5b913c7 100644
@@ -33,6 +33,8 @@
 
 #define OMAP_MODE13X_SPEED	230400
 
+#define OMAP_UART_SCR_TX_EMPTY	0x08
+
 /* WER = 0x7F
  * Enable module level wakeup in WER reg
  */
drivers/tty/serial/omap-serial.c +1 -0
index 5327ff0..f5a5ed6 100644
@@ -770,6 +770,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
 	serial_out(up, UART_IER, up->ier);
 	serial_out(up, UART_LCR, cval);		/* reset DLAB */
 	up->lcr = cval;
+	up->scr = OMAP_UART_SCR_TX_EMPTY;
 
 	/* FIFOs and DMA Settings */
 
Signature · 1 line
1.7.4.1
#10 lore raw

v8 cover OMAP2+: UART: Runtime adaptation + cleanup

In reply to Govindraj.R
Quoted 3 lines · Govindraj.R

Converting uart driver to adapt to pm runtime API's. Code re-org + cleanup.
Moving some functionality from serial.c to omap-serial.c

Alan, can you confirm your Ack's are still valid on the drivers/tty parts of this series? It has gone through quite a few changes since your original ack.

Greg, are you ok with this series merging via the OMAP tree since it is changing arch/arm/mach-omap2/* code as well as the driver, and should go together. If so, with your ack (on the drivers/tty/* parts), I'll handle this series through the OMAP tree.

Thanks,

Kevin

#11 lore raw

v8 cover OMAP2+: UART: Runtime adaptation + cleanup

Quoted 9 lines · On Tue, 06 Dec 2011 16:21:20 -0800 Kevin Hilman <[email protected]> wrote:
Quoted 3 lines · Govindraj.R

Converting uart driver to adapt to pm runtime API's. Code re-org + cleanup.
Moving some functionality from serial.c to omap-serial.c

Alan, can you confirm your Ack's are still valid on the drivers/tty parts of this series? It has gone through quite a few changes since your original ack.

Yes

#12 lore raw

v8 cover OMAP2+: UART: Runtime adaptation + cleanup

In reply to Kevin Hilman

Hi Kevin,

Quoted 6 lines · Kevin Hilman
Quoted 3 lines · Govindraj.R

Converting uart driver to adapt to pm runtime API's. Code re-org + cleanup.
Moving some functionality from serial.c to omap-serial.c

Quoted 8 lines

Alan, can you confirm your Ack's are still valid on the drivers/tty parts of this series? It has gone through quite a few changes since your original ack.

Greg, are you ok with this series merging via the OMAP tree since it is changing arch/arm/mach-omap2/* code as well as the driver, and should go together. If so, with your ack (on the drivers/tty/* parts), I'll handle this series through the OMAP tree.

I had a series to add DT support for omap-serial, which I did on top of the runtime series from Govindraj. Its already acked by Rob Herring for the DT parts. Would you be able to pick those up as well if its fine with Greg?

regards,
Rajendra

Quoted 9 lines

Thanks,

Kevin

#13 lore raw

v8 cover OMAP2+: UART: Runtime adaptation + cleanup

Quoted 18 lines · Rajendra Nayak

Hi Kevin,

Quoted 6 lines · Kevin Hilman
Quoted 3 lines · Govindraj.R

Converting uart driver to adapt to pm runtime API's. Code re-org + cleanup.
Moving some functionality from serial.c to omap-serial.c

Quoted 8 lines

Alan, can you confirm your Ack's are still valid on the drivers/tty parts of this series? It has gone through quite a few changes since your original ack.

Greg, are you ok with this series merging via the OMAP tree since it is changing arch/arm/mach-omap2/* code as well as the driver, and should go together. If so, with your ack (on the drivers/tty/* parts), I'll handle this series through the OMAP tree.

Quoted 4 lines

I had a series to add DT support for omap-serial, which I did on top of the runtime series from Govindraj. Its already acked by Rob Herring for the DT parts. Would you be able to pick those up as well if its fine with Greg?

Yes, those should go on top of Govindraj's series.

I'm OK with taking them, but I'd like to see them rebased on Govidraj's latest and see several Tested-by reports from various people since it is pretty late in the merge cycle.

Kevin

#14 lore raw

v8 cover OMAP2+: UART: Runtime adaptation + cleanup

In reply to Govindraj.R

Hi Tony/kevin,

Quoted 40 lines · Govindraj.R

Converting uart driver to adapt to pm runtime API's. Code re-org + cleanup.
Moving some functionality from serial.c to omap-serial.c

Changes involves:
================
1.) Cleaning up certain uart calls from sram_idle func.
2.) Removed all types of uart clock handling code from serial.c 3.) Using hwmod_mux API enable wakeup capability for uart pad during ? hwmod_idle state i.e., when uart clocks are disabled we can enable ? io-pad wakeup capability for uart if mux_data is available for ? given uart. Also during during resume from idle call to uart we need ? to enable clocks back conditionally and this can be done only when io-pad ? wakeup event bit is set for uart_rx pad. So we need a hwmod API ? which can probe the uart pad and let us know whether a uart wakeup ? happened. So omap_hmwod_pad_wakeup_status API is added to meet this ? requirement.
3.) Adapted omap-serial driver to use runtime API's.
4.) Modify serial_init calls to accept uart parameters from board file. ? ?Like dma_usage, rx_timeout, dma_rx_pollrate, auto_suspend_timeout etc. 5.) Use the omap_prm driver with irq_chaining to wake up uart after clocks are ? ?cut.

Patch series is based on 3.2-rc1.

Patch series depends on *Tero's v9 Irq_chaining patches*. Dependent irq_chaining patches are as below.

89ac62b omap3+: add omap prm driver initialization 170431f OMAP3: pm: do not enable PRCM MPU interrupts manually 9aba1b0 omap3: pm: use prcm chain handler
435481f OMAP2+: mux: add support for PAD wakeup interrupts 5b2d361 mfd: omap-prm: added suspend prepare and complete callbacks aa55c41 mfd: omap-prm: added chain interrupt handler d1db904 mfd: omap-prm: add driver skeleton
31d056c TEMP: OMAP4xxx: hwmod data: add PRM hwmod 19ec3bc TEMP: OMAP3xxx: hwmod data: add PRM hwmod 9a89688 OMAP2+: hwmod: Add API to check IO PAD wakeup status 78e8b65 OMAP2+: hwmod: Add API to enable IO ring wakeup.

Quoted 7 lines

Same combination is hosted at:
git://gitorious.org/runtime_3-0/runtime_3-0.git 3.2-rc1_uart_runtime

Ensure CONFIG_OMAP_PRM is set while testing irq_chaining with uart. And for pm_qos usage ensure CONFIG_CPU_IDLE is selected other wise console might be sluggish.

I have re-based this patch series against LO master commit id: deee6d5359969a0ce4e2760cfd7b9f379bd5698a

Same is available here [1]

I have tested this patch series along with:

1.) Tero's V11 irq chaining series
http://www.spinics.net/lists/linux-omap/msg61445.html
(This patch series is used for uart wakeup handling using
prcm_irq chaining)

2.) Rajendra's hwmod change
http://www.spinics.net/lists/arm-kernel/msg148632.html
(This patch handles init_no_idle flag setting
without this patch there will be boot warning however all pm features will work after boot up.)

3.) Vishwa's io daisy chain changes.
http://permalink.gmane.org/gmane.linux.ports.arm.omap/65500
(tested with and without this patch series pm features works).

Same combination of patches based on above commit id used for testing is available here [2].

--
Thanks,
Govindraj.R

[1]:
git://gitorious.org/runtime_3-0/runtime_3-0.git
for_3_3/lo_rc4_uartruntime

[2]:
git://gitorious.org/runtime_3-0/runtime_3-0.git
for_3_3/tmp_rc4_uart_pm_intg

Quoted 70 lines

Changes from v7:
---------------
http://www.mail-archive.com/linux-omap at vger.kernel.org/msg57804.html
http://www.mail-archive.com/linux-omap at vger.kernel.org/msg58209.html
http://www.spinics.net/lists/linux-omap/msg59978.html
http://www.spinics.net/lists/linux-serial/msg04772.html

Testing updates:
----------------
OMAP2420/2430SDP: Boot tested.

OMAP3430SDP:
retention, off_mode, system_wide suspend is tested. (earlyprintk & no_console_suspend checked)

OMAP3630 - Zoom3:
pm-retention checked with quart/omap-uart3
[Also tested with uart3 as console uart and pm-ret checked]

BeagleBoard XM Rev C(3630):
retention, off_mode, system_wide suspend is tested.

Deepak K (1):
?OMAP2+: UART: Allow UART parameters to be configured from board file.

Govindraj.R (18):
?OMAP2+: UART: cleanup + remove uart pm specific API ?OMAP2+: UART: cleanup 8250 console driver support ?OMAP2+: UART: Cleanup part of clock gating mechanism for uart ?OMAP2+: UART: Add default mux for all uarts.
?OMAP2+: UART: Remove mapbase/membase fields from pdata. ?OMAP2+: UART: Add runtime pm support for omap-serial driver ?OMAP2+: UART: Remove context_save and move context restore to driver ?OMAP2+: UART: Ensure all reg values configured are available from ? ?port structure
?OMAP2+: UART: Remove uart reset function.
?OMAP2+: UART: Get context loss count to context restore ?OMAP2+: UART: Move errata handling from serial.c to omap-serial ?OMAP2+: UART: Add wakeup mechanism for omap-uarts ?OMAP2+: UART: Remove old and unused clocks handling funcs ?OMAP2+: UART: remove temporary variable used to count uart instance ?OMAP2+: UART: Use custom activate func for console uart. ?OMAP2+: UART: Avoid uart idling on suspend for no_console_suspend ? ?usecase
?OMAP2+: UART: Do not gate uart clocks if used for debug_prints ?OMAP2+: UART: Remove omap_uart_can_sleep and add pm_qos

Jon Hunter (1):
?OMAP2+: UART: Make the RX_TIMEOUT for DMA configurable for each UART

?arch/arm/mach-omap2/board-3430sdp.c ? ? ? ? ? | ?100 +---
?arch/arm/mach-omap2/board-4430sdp.c ? ? ? ? ? | ? 68 +--
?arch/arm/mach-omap2/board-n8x0.c ? ? ? ? ? ? ?| ? ?6 +-
?arch/arm/mach-omap2/board-omap4panda.c ? ? ? ?| ? 68 +--
?arch/arm/mach-omap2/cpuidle34xx.c ? ? ? ? ? ? | ? ?5 -
?arch/arm/mach-omap2/pm24xx.c ? ? ? ? ? ? ? ? ?| ? 20 -
?arch/arm/mach-omap2/pm34xx.c ? ? ? ? ? ? ? ? ?| ? 42 --
?arch/arm/mach-omap2/serial.c ? ? ? ? ? ? ? ? ?| ?926 +++++++------------------
?arch/arm/plat-omap/include/plat/omap-serial.h | ? 36 +-
?arch/arm/plat-omap/include/plat/serial.h ? ? ?| ? 10 +-
?drivers/tty/serial/omap-serial.c ? ? ? ? ? ? ?| ?341 ++++++++--

?11 files changed, 607 insertions(+), 1015 deletions(-)

--
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo at vger.kernel.org
More majordomo info at ?http://vger.kernel.org/majordomo-info.html

#15 lore raw

v8 cover OMAP2+: UART: Runtime adaptation + cleanup

Govindraj <[email protected]> writes:

[...]

Quoted 18 lines

I have re-based this patch series against LO master commit id: deee6d5359969a0ce4e2760cfd7b9f379bd5698a

Same is available here [1]

I have tested this patch series along with:

1.) Tero's V11 irq chaining series
http://www.spinics.net/lists/linux-omap/msg61445.html
(This patch series is used for uart wakeup handling using
prcm_irq chaining)

2.) Rajendra's hwmod change
http://www.spinics.net/lists/arm-kernel/msg148632.html
(This patch handles init_no_idle flag setting
without this patch there will be boot warning however all pm features will work after boot up.)

Quoted 6 lines

3.) Vishwa's io daisy chain changes.
http://permalink.gmane.org/gmane.linux.ports.arm.omap/65500
(tested with and without this patch series pm features works).

Same combination of patches based on above commit id used for testing is available here [2].

Please have a closer look at your branch.

The second commit[1] commits the .rej file from a failed patch apply, so obviously doesn't do what was intended.

Kevin

[1]

Quoted 1 line

From ae5d13382a5784f35f5bfe05413fbec4632e58f0 Mon Sep 17 00:00:00 2001

From: "Govindraj.R" <[email protected]>
Date: Tue, 13 Sep 2011 13:32:32 +0530
Subject: [PATCH] OMAP2+: UART: cleanup 8250 console driver support

We had been using traditional 8250 driver as uart console driver prior to omap-serial driver. Since we have omap-serial driver in mainline kernel for some time now it has been used as default uart console driver on omap2+ platforms. Remove 8250 support for omap-uarts.

Serial_in and serial_out override for 8250 serial driver is also removed. Empty fifo read fix is already taken care with omap-serial driver with data ready bit check from LSR reg before reading RX fifo. Also waiting for THRE(transmit hold reg empty) is done with wait_for_xmitr in omap-serial driver.

Serial_in/out overrides are not neceesary for omap-serial driver and things that are taken with omap-serial driver are removed here.

Remove headers that were necessary to support 8250 support and remove all config bindings done to keep 8250 backward compatibility while adding omap-serial driver. Remove omap_uart_reset needed for 8250 autoconf.

---
 arch/arm/mach-omap2/serial.c.rej |   26 ++++++++++++++++++++++++++
 1 files changed, 26 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-omap2/serial.c.rej
arch/arm/mach-omap2/serial.c.rej new file +26 -0
new file mode 100644
index 0000000..2325897
@@ -0,0 +1,26 @@
+--- arch/arm/mach-omap2/serial.c
++++ arch/arm/mach-omap2/serial.c
+@@ -19,23 +19,17 @@
+  */
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+-#include <linux/serial_reg.h>
+ #include <linux/clk.h>
+ #include <linux/io.h>
+ #include <linux/delay.h>
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
+-#include <linux/serial_8250.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/console.h>
+ 
+-#ifdef CONFIG_SERIAL_OMAP
+ #include <plat/omap-serial.h>
+-#endif
+-
+ #include <plat/common.h>
+ #include <plat/board.h>
+-#include <plat/clock.h>
+ #include <plat/dma.h>
+ #include <plat/omap_hwmod.h>
+ #include <plat/omap_device.h>
Signature · 1 line
1.7.6
#16 lore raw

v8 cover OMAP2+: UART: Runtime adaptation + cleanup

Quoted 26 lines · Kevin Hilman

Govindraj <[email protected]> writes:

[...]

Quoted 22 lines

I have re-based this patch series against LO master commit id: deee6d5359969a0ce4e2760cfd7b9f379bd5698a

Same is available here [1]

I have tested this patch series along with:

1.) Tero's V11 irq chaining series
? ? ?http://www.spinics.net/lists/linux-omap/msg61445.html ? ? (This patch series is used for uart wakeup handling using ? ? ? prcm_irq chaining)

2.) Rajendra's hwmod change
? ? ?http://www.spinics.net/lists/arm-kernel/msg148632.html ? ? ?(This patch handles init_no_idle flag setting ? ? ? without this patch there will be boot warning however ? ? ? all pm features will work after boot up.)

3.) Vishwa's io daisy chain changes.
? ? ?http://permalink.gmane.org/gmane.linux.ports.arm.omap/65500 ? ? ?(tested with and without this patch series pm features works).

Quoted 8 lines
Quoted 2 lines

Same combination of patches based on above commit id used for testing is available here [2].

Please have a closer look at your branch.

The second commit[1] commits the .rej file from a failed patch apply, so obviously doesn't do what was intended.

Sorry my bad I have refreshed the uart runtime branch [1] & test branch [2].

stat for uart patches for the both the branches as here [3]

--
Thanks,
Govindraj.R

[1]:
git://gitorious.org/runtime_3-0/runtime_3-0.git
for_3_3/lo_rc4_uartruntime

[2]:
git://gitorious.org/runtime_3-0/runtime_3-0.git
for_3_3/tmp_rc4_uart_pm_intg

[3]:
<<uart runtime branch>>

ubnuser at ula0131859:~/clones/runtime_3-0$ git diff --stat deee6d5

 arch/arm/mach-omap2/board-3430sdp.c           |  100 +---
 arch/arm/mach-omap2/board-4430sdp.c           |   68 +--
 arch/arm/mach-omap2/board-n8x0.c              |    6 +-
 arch/arm/mach-omap2/board-omap4panda.c        |   68 +--
 arch/arm/mach-omap2/cpuidle34xx.c             |    6 -
 arch/arm/mach-omap2/pm24xx.c                  |   20 -
 arch/arm/mach-omap2/pm34xx.c                  |   43 --
 arch/arm/mach-omap2/serial.c                  |  907 +++++++------------------
 arch/arm/plat-omap/include/plat/omap-serial.h |   37 +-
 arch/arm/plat-omap/include/plat/serial.h      |   10 +-
 drivers/tty/serial/omap-serial.c              |  343 ++++++++--
 11 files changed, 584 insertions(+), 1024 deletions(-)

<<tmp_intg_test branch>>

ubnuser at ula0131859:~/clones/runtime_3-0$ git diff --stat deee6d5..aad8423

 arch/arm/mach-omap2/board-3430sdp.c           |  100 +---
 arch/arm/mach-omap2/board-4430sdp.c           |   68 +--
 arch/arm/mach-omap2/board-n8x0.c              |    6 +-
 arch/arm/mach-omap2/board-omap4panda.c        |   68 +--
 arch/arm/mach-omap2/cpuidle34xx.c             |    6 -
 arch/arm/mach-omap2/pm24xx.c                  |   20 -
 arch/arm/mach-omap2/pm34xx.c                  |   43 --
 arch/arm/mach-omap2/serial.c                  |  907 +++++++------------------
 arch/arm/plat-omap/include/plat/omap-serial.h |   37 +-
 arch/arm/plat-omap/include/plat/serial.h      |   10 +-
 drivers/tty/serial/omap-serial.c              |  343 ++++++++--
 11 files changed, 584 insertions(+), 1024 deletions(-)
#17 lore raw

v8 cover OMAP2+: UART: Runtime adaptation + cleanup

Quoted 30 lines · Govindraj
Quoted 29 lines · Kevin Hilman

Govindraj <[email protected]> writes:

[...]

Quoted 24 lines

I have re-based this patch series against LO master commit id: deee6d5359969a0ce4e2760cfd7b9f379bd5698a

Same is available here [1]

I have tested this patch series along with:

1.) Tero's V11 irq chaining series
? ? ?http://www.spinics.net/lists/linux-omap/msg61445.html ? ? (This patch series is used for uart wakeup handling using ? ? ? prcm_irq chaining)

2.) Rajendra's hwmod change
? ? ?http://www.spinics.net/lists/arm-kernel/msg148632.html ? ? ?(This patch handles init_no_idle flag setting ? ? ? without this patch there will be boot warning however ? ? ? all pm features will work after boot up.)

3.) Vishwa's io daisy chain changes.
? ? ?http://permalink.gmane.org/gmane.linux.ports.arm.omap/65500 ? ? ?(tested with and without this patch series pm features works).

Same combination of patches based on above commit id used for testing is available here [2].

Quoted 8 lines
Quoted 5 lines

Please have a closer look at your branch.

The second commit[1] commits the .rej file from a failed patch apply, so obviously doesn't do what was intended.

Sorry my bad I have refreshed the uart runtime branch [1] & test branch [2].

Can you add another patch which fixes these compiler warnings:

/work/kernel/omap/pm/drivers/tty/serial/omap-serial.c: In function 'serial_omap_irq':
/work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:228:29: warning: 'ch' may be used uninitialized in this function [-Wuninitialized] /work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:176:16: note: 'ch' was declared here /work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:228:29: warning: 'ch' may be used uninitialized in this function [-Wuninitialized] /work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:176:16: note: 'ch' was declared here

Kevin

#18 lore raw

v8 cover OMAP2+: UART: Runtime adaptation + cleanup

Quoted 41 lines · Kevin Hilman
Quoted 30 lines · Govindraj
Quoted 29 lines · Kevin Hilman

Govindraj <[email protected]> writes:

[...]

Quoted 24 lines

I have re-based this patch series against LO master commit id: deee6d5359969a0ce4e2760cfd7b9f379bd5698a

Same is available here [1]

I have tested this patch series along with:

1.) Tero's V11 irq chaining series
? ? ?http://www.spinics.net/lists/linux-omap/msg61445.html ? ? (This patch series is used for uart wakeup handling using ? ? ? prcm_irq chaining)

2.) Rajendra's hwmod change
? ? ?http://www.spinics.net/lists/arm-kernel/msg148632.html ? ? ?(This patch handles init_no_idle flag setting ? ? ? without this patch there will be boot warning however ? ? ? all pm features will work after boot up.)

3.) Vishwa's io daisy chain changes.
? ? ?http://permalink.gmane.org/gmane.linux.ports.arm.omap/65500 ? ? ?(tested with and without this patch series pm features works).

Same combination of patches based on above commit id used for testing is available here [2].

Quoted 8 lines
Quoted 5 lines

Please have a closer look at your branch.

The second commit[1] commits the .rej file from a failed patch apply, so obviously doesn't do what was intended.

Sorry my bad I have refreshed the uart runtime branch [1] & test branch [2].

Quoted 8 lines

Can you add another patch which fixes these compiler warnings:

/work/kernel/omap/pm/drivers/tty/serial/omap-serial.c: In function 'serial_omap_irq':
/work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:228:29: warning: 'ch' may be used uninitialized in this function [-Wuninitialized] /work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:176:16: note: 'ch' was declared here /work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:228:29: warning: 'ch' may be used uninitialized in this function [-Wuninitialized] /work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:176:16: note: 'ch' was declared here

Here is the patch [1] and pushed to
git://gitorious.org/runtime_3-0/runtime_3-0.git for_3_3/lo_rc4_uartruntime

--
Thanks,
Govindraj.R

[1]:

Quoted 1 line

From 3a40f4e1a4c6db40d06cc6c5536ec06e9e5daf3d Mon Sep 17 00:00:00 2001

From: "Govindraj.R" <[email protected]>
Date: Wed, 14 Dec 2011 21:24:11 +0530
Subject: [PATCH] OMAP2+: UART: Fix compilation/sparse warnings

Fixes below compilation warning.

drivers/tty/serial/omap-serial.c: In function 'serial_omap_irq':
drivers/tty/serial/omap-serial.c:228:29: warning: 'ch' may be used uninitialized in this function [-Wuninitialized]

Fix below sparse warning.

drivers/tty/serial/omap-serial.c:392:52: warning: incorrect type in argument 2 (different signedness)
drivers/tty/serial/omap-serial.c:392:52: expected int *status
drivers/tty/serial/omap-serial.c:392:52: got unsigned int *<noident>

---
 drivers/tty/serial/omap-serial.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)
drivers/tty/serial/omap-serial.c +4 -3
index f3ff0ca..7b0303d 100644
@@ -166,11 +166,12 @@ static void serial_omap_stop_rx(struct uart_port *port)
 	pm_runtime_put_autosuspend(&up->pdev->dev);
 }
 
-static inline void receive_chars(struct uart_omap_port *up, int *status)
+static inline void receive_chars(struct uart_omap_port *up,
+		unsigned int *status)
 {
 	struct tty_struct *tty = up->port.state->port.tty;
-	unsigned int flag;
-	unsigned char ch, lsr = *status;
+	unsigned int flag, lsr = *status;
+	unsigned char ch = 0;
 	int max_count = 256;
 
 	do {
Signature · 1 line
1.7.5.4
#19 lore raw

v8 cover OMAP2+: UART: Runtime adaptation + cleanup

Quoted 51 lines · Govindraj
Quoted 41 lines · Kevin Hilman
Quoted 30 lines · Govindraj
Quoted 29 lines · Kevin Hilman

Govindraj <[email protected]> writes:

[...]

Quoted 24 lines

I have re-based this patch series against LO master commit id: deee6d5359969a0ce4e2760cfd7b9f379bd5698a

Same is available here [1]

I have tested this patch series along with:

1.) Tero's V11 irq chaining series
? ? ?http://www.spinics.net/lists/linux-omap/msg61445.html ? ? (This patch series is used for uart wakeup handling using ? ? ? prcm_irq chaining)

2.) Rajendra's hwmod change
? ? ?http://www.spinics.net/lists/arm-kernel/msg148632.html ? ? ?(This patch handles init_no_idle flag setting ? ? ? without this patch there will be boot warning however ? ? ? all pm features will work after boot up.)

3.) Vishwa's io daisy chain changes.
? ? ?http://permalink.gmane.org/gmane.linux.ports.arm.omap/65500 ? ? ?(tested with and without this patch series pm features works).

Same combination of patches based on above commit id used for testing is available here [2].

Quoted 8 lines
Quoted 5 lines

Please have a closer look at your branch.

The second commit[1] commits the .rej file from a failed patch apply, so obviously doesn't do what was intended.

Sorry my bad I have refreshed the uart runtime branch [1] & test branch [2].

Quoted 8 lines

Can you add another patch which fixes these compiler warnings:

/work/kernel/omap/pm/drivers/tty/serial/omap-serial.c: In function 'serial_omap_irq':
/work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:228:29: warning: 'ch' may be used uninitialized in this function [-Wuninitialized] /work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:176:16: note: 'ch' was declared here /work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:228:29: warning: 'ch' may be used uninitialized in this function [-Wuninitialized] /work/kernel/omap/pm/drivers/tty/serial/omap-serial.c:176:16: note: 'ch' was declared here

Quoted 2 lines

Here is the patch [1] and pushed to
git://gitorious.org/runtime_3-0/runtime_3-0.git for_3_3/lo_rc4_uartruntime

Thanks!

Kevin

#20 lore raw

v8 cover OMAP2+: UART: Runtime adaptation + cleanup

In reply to Govindraj

Govindraj <[email protected]> writes:

[...]

Quoted 12 lines

I have re-based this patch series against LO master commit id: deee6d5359969a0ce4e2760cfd7b9f379bd5698a

Same is available here [1]

I have tested this patch series along with:

1.) Tero's V11 irq chaining series
http://www.spinics.net/lists/linux-omap/msg61445.html
(This patch series is used for uart wakeup handling using
prcm_irq chaining)

Quoted 5 lines

2.) Rajendra's hwmod change
http://www.spinics.net/lists/arm-kernel/msg148632.html
(This patch handles init_no_idle flag setting
without this patch there will be boot warning however all pm features will work after boot up.)

Actually, without Rajendra's patch all features do not work. I don't get UART console wakeups from idle (with runtime PM autosuspend enabled) on 3430/n900 or 3530/Overo without Rajendra's patch.

Kevin

#21 lore raw

v8 cover OMAP2+: UART: Runtime adaptation + cleanup

Quoted 22 lines · Kevin Hilman

Govindraj <[email protected]> writes:

[...]

Quoted 12 lines

I have re-based this patch series against LO master commit id: deee6d5359969a0ce4e2760cfd7b9f379bd5698a

Same is available here [1]

I have tested this patch series along with:

1.) Tero's V11 irq chaining series
? ? ?http://www.spinics.net/lists/linux-omap/msg61445.html ? ? (This patch series is used for uart wakeup handling using ? ? ? prcm_irq chaining)

Quoted 5 lines

2.) Rajendra's hwmod change
? ? ?http://www.spinics.net/lists/arm-kernel/msg148632.html ? ? ?(This patch handles init_no_idle flag setting ? ? ? without this patch there will be boot warning however ? ? ? all pm features will work after boot up.)

Quoted 3 lines

Actually, without Rajendra's patch all features do not work. ?I don't get UART console wakeups from idle (with runtime PM autosuspend enabled) on 3430/n900 or 3530/Overo without Rajendra's patch.

okay, I forgot last time when I tested without rajendra's patch was with a custom activate func.
and now we have removed it.
Yes you are correct Rajendra's patch + Tero's v11 series is a needed for proper uart_runtime_pm functioning.

--
Thanks,
Govindraj.R