From 1e6cb146c39cdef1ffc340c13637fce2ba5575be Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Tue, 13 Dec 2011 10:46:43 -0800 Subject: ARM: OMAP: am33xx: Update common OMAP machine specific sources This patch updates the common machine specific source files for support for AM33XX/AM335x with cpu type, macros for identification of AM33XX/AM335X device. Signed-off-by: Afzal Mohammed Signed-off-by: Vaibhav Hiremath Reviewed-by: Kevin Hilman Tested-by: Kevin Hilman [tony@atomide.com: updated for map_io and common.h changes, dropped CK_AM33XX] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/serial.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 42c326732a29..9770c7624aa0 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -464,7 +464,7 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) mod_timer(&uart->timer, jiffies + uart->timeout); omap_uart_smart_idle_enable(uart, 0); - if (cpu_is_omap34xx() && !cpu_is_ti816x()) { + if (cpu_is_omap34xx() && !(cpu_is_ti816x() || cpu_is_am33xx())) { u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD; u32 wk_mask = 0; u32 padconf = 0; @@ -828,7 +828,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) } /* Enable the MDR1 errata for OMAP3 */ - if (cpu_is_omap34xx() && !cpu_is_ti816x()) + if (cpu_is_omap34xx() && !(cpu_is_ti816x() || cpu_is_am33xx())) uart->errata |= UART_ERRATA_i202_MDR1_ACCESS; } -- cgit v1.2.3 From a920360f038e976e7a86b002e209402da20e9147 Mon Sep 17 00:00:00 2001 From: Hemant Pedanekar Date: Tue, 13 Dec 2011 10:46:44 -0800 Subject: ARM: OMAP: TI81XX: Prepare for addition of TI814X support This patch updates existing macros, functions used for TI816X, to enable addition of other SoCs belonging to TI81XX family (e.g., TI814X). The approach taken is to use TI81XX/ti81xx for code/data going to be common across all TI81XX devices. cpu_is_ti81xx() is introduced to handle code common across TI81XX devices. In addition, ti8168_evm_map_io() is now replaced with ti81xx_map_io() and moved in mach-omap2/common.c as same will be used for TI814X and is not board specific. Signed-off-by: Hemant Pedanekar Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Kconfig | 6 +++--- arch/arm/mach-omap2/board-ti8168evm.c | 11 +++------- arch/arm/mach-omap2/clock3xxx_data.c | 2 +- arch/arm/mach-omap2/common.c | 29 +++++++++++++++----------- arch/arm/mach-omap2/common.h | 13 ++++++------ arch/arm/mach-omap2/control.h | 8 +++---- arch/arm/mach-omap2/id.c | 8 +++---- arch/arm/mach-omap2/include/mach/debug-macro.S | 12 +++++------ arch/arm/mach-omap2/io.c | 14 ++++++------- arch/arm/mach-omap2/irq.c | 2 +- arch/arm/mach-omap2/serial.c | 6 +++--- arch/arm/plat-omap/include/plat/cpu.h | 13 ++++++++++++ arch/arm/plat-omap/include/plat/hardware.h | 2 +- arch/arm/plat-omap/include/plat/serial.h | 14 ++++++------- arch/arm/plat-omap/include/plat/ti816x.h | 27 ------------------------ arch/arm/plat-omap/include/plat/ti81xx.h | 27 ++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/uncompress.h | 8 +++---- 17 files changed, 108 insertions(+), 94 deletions(-) delete mode 100644 arch/arm/plat-omap/include/plat/ti816x.h create mode 100644 arch/arm/plat-omap/include/plat/ti81xx.h (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index ccdd442ca124..f475954c3b98 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -76,8 +76,8 @@ config SOC_OMAP3430 default y select ARCH_OMAP_OTG -config SOC_OMAPTI816X - bool "TI816X support" +config SOC_OMAPTI81XX + bool "TI81XX support" depends on ARCH_OMAP3 default y @@ -319,7 +319,7 @@ config MACH_OMAP_3630SDP config MACH_TI8168EVM bool "TI8168 Evaluation Module" - depends on SOC_OMAPTI816X + depends on SOC_OMAPTI81XX default y config MACH_OMAP_4430SDP diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c index 8402b39b2840..b236fcc023ac 100644 --- a/arch/arm/mach-omap2/board-ti8168evm.c +++ b/arch/arm/mach-omap2/board-ti8168evm.c @@ -35,17 +35,12 @@ static void __init ti8168_evm_init(void) omap_board_config_size = ARRAY_SIZE(ti8168_evm_config); } -static void __init ti8168_evm_map_io(void) -{ - omapti816x_map_common_io(); -} - MACHINE_START(TI8168EVM, "ti8168evm") /* Maintainer: Texas Instruments */ .atag_offset = 0x100, - .map_io = ti8168_evm_map_io, - .init_early = ti816x_init_early, - .init_irq = ti816x_init_irq, + .map_io = ti81xx_map_io, + .init_early = ti81xx_init_early, + .init_irq = ti81xx_init_irq, .timer = &omap3_timer, .init_machine = ti8168_evm_init, MACHINE_END diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index 3d56d8a2b86e..be0fa34e5506 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -3602,7 +3602,7 @@ int __init omap3xxx_clk_init(void) * Lock DPLL5 -- here only until other device init code can * handle this */ - if (!cpu_is_ti816x() && (omap_rev() >= OMAP3430_REV_ES2_0)) + if (!cpu_is_ti81xx() && (omap_rev() >= OMAP3430_REV_ES2_0)) omap3_clk_lock_dpll5(); /* Avoid sleeping during omap3_core_dpll_m2_set_rate() */ diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c index c900dcb6f1fd..aaf421178c91 100644 --- a/arch/arm/mach-omap2/common.c +++ b/arch/arm/mach-omap2/common.c @@ -110,27 +110,32 @@ void __init omap3_map_io(void) /* * Adjust TAP register base such that omap3_check_revision accesses the correct - * TI816X register for checking device ID (it adds 0x204 to tap base while - * TI816X DEVICE ID register is at offset 0x600 from control base). + * TI81XX register for checking device ID (it adds 0x204 to tap base while + * TI81XX DEVICE ID register is at offset 0x600 from control base). */ -#define TI816X_TAP_BASE (TI816X_CTRL_BASE + \ - TI816X_CONTROL_DEVICE_ID - 0x204) +#define TI81XX_TAP_BASE (TI81XX_CTRL_BASE + \ + TI81XX_CONTROL_DEVICE_ID - 0x204) -static struct omap_globals ti816x_globals = { +static struct omap_globals ti81xx_globals = { .class = OMAP343X_CLASS, - .tap = OMAP2_L4_IO_ADDRESS(TI816X_TAP_BASE), - .ctrl = OMAP2_L4_IO_ADDRESS(TI816X_CTRL_BASE), - .prm = OMAP2_L4_IO_ADDRESS(TI816X_PRCM_BASE), - .cm = OMAP2_L4_IO_ADDRESS(TI816X_PRCM_BASE), + .tap = OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE), + .ctrl = OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE), + .prm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), + .cm = OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), }; -void __init omap2_set_globals_ti816x(void) +void __init omap2_set_globals_ti81xx(void) { - __omap2_set_globals(&ti816x_globals); + __omap2_set_globals(&ti81xx_globals); +} + +void __init ti81xx_map_io(void) +{ + omapti81xx_map_common_io(); } #define AM33XX_TAP_BASE (AM33XX_CTRL_BASE + \ - TI816X_CONTROL_DEVICE_ID - 0x204) + TI81XX_CONTROL_DEVICE_ID - 0x204) static struct omap_globals am33xx_globals = { .class = AM335X_CLASS, diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 9b733e343bf5..4b2b416fafe1 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -52,10 +52,10 @@ static inline void omap34xx_map_common_io(void) } #endif -#ifdef CONFIG_SOC_OMAPTI816X -extern void omapti816x_map_common_io(void); +#ifdef CONFIG_SOC_OMAPTI81XX +extern void omapti81xx_map_common_io(void); #else -static inline void omapti816x_map_common_io(void) +static inline void omapti81xx_map_common_io(void) { } #endif @@ -90,7 +90,7 @@ void omap35xx_init_early(void); void omap3630_init_early(void); void omap3_init_early(void); /* Do not use this one */ void am35xx_init_early(void); -void ti816x_init_early(void); +void ti81xx_init_early(void); void omap4430_init_early(void); /* @@ -114,7 +114,7 @@ void omap2_set_globals_242x(void); void omap2_set_globals_243x(void); void omap2_set_globals_3xxx(void); void omap2_set_globals_443x(void); -void omap2_set_globals_ti816x(void); +void omap2_set_globals_ti81xx(void); void omap2_set_globals_am33xx(void); /* These get called from omap2_set_globals_xxxx(), do not call these */ @@ -128,6 +128,7 @@ void omap243x_map_io(void); void omap3_map_io(void); void am33xx_map_io(void); void omap4_map_io(void); +void ti81xx_map_io(void); /** * omap_test_timeout - busy-loop, testing a condition @@ -156,7 +157,7 @@ extern struct device *omap4_get_dsp_device(void); void omap2_init_irq(void); void omap3_init_irq(void); -void ti816x_init_irq(void); +void ti81xx_init_irq(void); extern int omap_irq_pending(void); void omap_intc_save_context(void); void omap_intc_restore_context(void); diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index d4ef75d5a382..0ba68d3764bc 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h @@ -52,8 +52,8 @@ #define OMAP343X_CONTROL_PADCONFS_WKUP 0xa00 #define OMAP343X_CONTROL_GENERAL_WKUP 0xa60 -/* TI816X spefic control submodules */ -#define TI816X_CONTROL_DEVCONF 0x600 +/* TI81XX spefic control submodules */ +#define TI81XX_CONTROL_DEVCONF 0x600 /* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */ @@ -244,8 +244,8 @@ #define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250 #define OMAP3_PADCONF_SAD2D_IDLEACK 0x254 -/* TI816X CONTROL_DEVCONF register offsets */ -#define TI816X_CONTROL_DEVICE_ID (TI816X_CONTROL_DEVCONF + 0x000) +/* TI81XX CONTROL_DEVCONF register offsets */ +#define TI81XX_CONTROL_DEVICE_ID (TI81XX_CONTROL_DEVCONF + 0x000) /* * REVISIT: This list of registers is not comprehensive - there are more diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 439afe7acdca..1dc68e64d7e2 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -226,7 +226,7 @@ static void __init omap4_check_features(void) } } -static void __init ti816x_check_features(void) +static void __init ti81xx_check_features(void) { omap_features = OMAP3_HAS_NEON; } @@ -489,11 +489,11 @@ void __init omap2_check_revision(void) } else if (cpu_is_omap34xx()) { omap3_check_revision(&cpu_rev); - /* TI816X doesn't have feature register */ - if (!cpu_is_ti816x()) + /* TI81XX doesn't have feature register */ + if (!cpu_is_ti81xx()) omap3_check_features(); else - ti816x_check_features(); + ti81xx_check_features(); omap3_cpuinfo(cpu_rev); return; diff --git a/arch/arm/mach-omap2/include/mach/debug-macro.S b/arch/arm/mach-omap2/include/mach/debug-macro.S index 13f98e59cfef..cdfc2a1f0e75 100644 --- a/arch/arm/mach-omap2/include/mach/debug-macro.S +++ b/arch/arm/mach-omap2/include/mach/debug-macro.S @@ -66,11 +66,11 @@ omap_uart_lsr: .word 0 beq 34f @ configure OMAP3UART4 cmp \rp, #OMAP4UART4 @ only on 44xx beq 44f @ configure OMAP4UART4 - cmp \rp, #TI816XUART1 @ ti816x UART offsets different + cmp \rp, #TI81XXUART1 @ ti81Xx UART offsets different beq 81f @ configure UART1 - cmp \rp, #TI816XUART2 @ ti816x UART offsets different + cmp \rp, #TI81XXUART2 @ ti81Xx UART offsets different beq 82f @ configure UART2 - cmp \rp, #TI816XUART3 @ ti816x UART offsets different + cmp \rp, #TI81XXUART3 @ ti81Xx UART offsets different beq 83f @ configure UART3 cmp \rp, #ZOOM_UART @ only on zoom2/3 beq 95f @ configure ZOOM_UART @@ -94,11 +94,11 @@ omap_uart_lsr: .word 0 b 98f 44: mov \rp, #UART_OFFSET(OMAP4_UART4_BASE) b 98f -81: mov \rp, #UART_OFFSET(TI816X_UART1_BASE) +81: mov \rp, #UART_OFFSET(TI81XX_UART1_BASE) b 98f -82: mov \rp, #UART_OFFSET(TI816X_UART2_BASE) +82: mov \rp, #UART_OFFSET(TI81XX_UART2_BASE) b 98f -83: mov \rp, #UART_OFFSET(TI816X_UART3_BASE) +83: mov \rp, #UART_OFFSET(TI81XX_UART3_BASE) b 98f 95: ldr \rp, =ZOOM_UART_BASE diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 088d2ba60eff..73d617f0dc4a 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -176,8 +176,8 @@ static struct map_desc omap34xx_io_desc[] __initdata = { }; #endif -#ifdef CONFIG_SOC_OMAPTI816X -static struct map_desc omapti816x_io_desc[] __initdata = { +#ifdef CONFIG_SOC_OMAPTI81XX +static struct map_desc omapti81xx_io_desc[] __initdata = { { .virtual = L4_34XX_VIRT, .pfn = __phys_to_pfn(L4_34XX_PHYS), @@ -280,10 +280,10 @@ void __init omap34xx_map_common_io(void) } #endif -#ifdef CONFIG_SOC_OMAPTI816X -void __init omapti816x_map_common_io(void) +#ifdef CONFIG_SOC_OMAPTI81XX +void __init omapti81xx_map_common_io(void) { - iotable_init(omapti816x_io_desc, ARRAY_SIZE(omapti816x_io_desc)); + iotable_init(omapti81xx_io_desc, ARRAY_SIZE(omapti81xx_io_desc)); } #endif @@ -442,9 +442,9 @@ void __init am35xx_init_early(void) omap3_init_early(); } -void __init ti816x_init_early(void) +void __init ti81xx_init_early(void) { - omap2_set_globals_ti816x(); + omap2_set_globals_ti81xx(); omap_common_init_early(); omap3xxx_voltagedomains_init(); omap3xxx_powerdomains_init(); diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 42b1d6591912..1fef061f7927 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -193,7 +193,7 @@ void __init omap3_init_irq(void) omap_init_irq(OMAP34XX_IC_BASE, 96); } -void __init ti816x_init_irq(void) +void __init ti81xx_init_irq(void) { omap_init_irq(OMAP34XX_IC_BASE, 128); } diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 9770c7624aa0..d0f009cbfb50 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -464,7 +464,7 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) mod_timer(&uart->timer, jiffies + uart->timeout); omap_uart_smart_idle_enable(uart, 0); - if (cpu_is_omap34xx() && !(cpu_is_ti816x() || cpu_is_am33xx())) { + if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx())) { u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD; u32 wk_mask = 0; u32 padconf = 0; @@ -746,7 +746,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) */ uart->regshift = p->regshift; uart->membase = p->membase; - if (cpu_is_omap44xx() || cpu_is_ti816x()) + if (cpu_is_omap44xx() || cpu_is_ti81xx()) 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) @@ -828,7 +828,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) } /* Enable the MDR1 errata for OMAP3 */ - if (cpu_is_omap34xx() && !(cpu_is_ti816x() || cpu_is_am33xx())) + if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx())) uart->errata |= UART_ERRATA_i202_MDR1_ACCESS; } diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 34fc9136b1a0..5f7aa4981daf 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -87,6 +87,14 @@ static inline int is_am ##class (void) \ return (GET_AM_CLASS == (id)) ? 1 : 0; \ } +#define GET_TI_CLASS ((omap_rev() >> 24) & 0xff) + +#define IS_TI_CLASS(class, id) \ +static inline int is_ti ##class (void) \ +{ \ + return (GET_TI_CLASS == (id)) ? 1 : 0; \ +} + #define GET_OMAP_SUBCLASS ((omap_rev() >> 20) & 0x0fff) #define IS_OMAP_SUBCLASS(subclass, id) \ @@ -115,6 +123,8 @@ IS_OMAP_CLASS(34xx, 0x34) IS_OMAP_CLASS(44xx, 0x44) IS_AM_CLASS(33xx, 0x33) +IS_TI_CLASS(81xx, 0x81) + IS_OMAP_SUBCLASS(242x, 0x242) IS_OMAP_SUBCLASS(243x, 0x243) IS_OMAP_SUBCLASS(343x, 0x343) @@ -134,6 +144,7 @@ IS_AM_SUBCLASS(335x, 0x335) #define cpu_is_omap243x() 0 #define cpu_is_omap34xx() 0 #define cpu_is_omap343x() 0 +#define cpu_is_ti81xx() 0 #define cpu_is_ti816x() 0 #define cpu_is_am33xx() 0 #define cpu_is_am335x() 0 @@ -343,6 +354,7 @@ IS_OMAP_TYPE(3517, 0x3517) # undef cpu_is_omap3530 # undef cpu_is_omap3505 # undef cpu_is_omap3517 +# undef cpu_is_ti81xx # undef cpu_is_ti816x # undef cpu_is_am33xx # undef cpu_is_am335x @@ -362,6 +374,7 @@ IS_OMAP_TYPE(3517, 0x3517) !omap3_has_sgx()) # undef cpu_is_omap3630 # define cpu_is_omap3630() is_omap363x() +# define cpu_is_ti81xx() is_ti81xx() # define cpu_is_ti816x() is_ti816x() # define cpu_is_am33xx() is_am33xx() # define cpu_is_am335x() is_am335x() diff --git a/arch/arm/plat-omap/include/plat/hardware.h b/arch/arm/plat-omap/include/plat/hardware.h index e6521e120d9f..e897978371c2 100644 --- a/arch/arm/plat-omap/include/plat/hardware.h +++ b/arch/arm/plat-omap/include/plat/hardware.h @@ -286,7 +286,7 @@ #include #include #include -#include +#include #include #endif /* __ASM_ARCH_OMAP_HARDWARE_H */ diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index 1ab9fd6abe6d..6975ee3f5217 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -51,10 +51,10 @@ #define OMAP4_UART3_BASE 0x48020000 #define OMAP4_UART4_BASE 0x4806e000 -/* TI816X serial ports */ -#define TI816X_UART1_BASE 0x48020000 -#define TI816X_UART2_BASE 0x48022000 -#define TI816X_UART3_BASE 0x48024000 +/* TI81XX serial ports */ +#define TI81XX_UART1_BASE 0x48020000 +#define TI81XX_UART2_BASE 0x48022000 +#define TI81XX_UART3_BASE 0x48024000 /* AM3505/3517 UART4 */ #define AM35XX_UART4_BASE 0x4809E000 /* Only on AM3505/3517 */ @@ -89,9 +89,9 @@ #define OMAP4UART2 OMAP2UART2 #define OMAP4UART3 43 #define OMAP4UART4 44 -#define TI816XUART1 81 -#define TI816XUART2 82 -#define TI816XUART3 83 +#define TI81XXUART1 81 +#define TI81XXUART2 82 +#define TI81XXUART3 83 #define ZOOM_UART 95 /* Only on zoom2/3 */ /* This is only used by 8250.c for omap1510 */ diff --git a/arch/arm/plat-omap/include/plat/ti816x.h b/arch/arm/plat-omap/include/plat/ti816x.h deleted file mode 100644 index 50510f5dda1e..000000000000 --- a/arch/arm/plat-omap/include/plat/ti816x.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file contains the address data for various TI816X modules. - * - * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __ASM_ARCH_TI816X_H -#define __ASM_ARCH_TI816X_H - -#define L4_SLOW_TI816X_BASE 0x48000000 - -#define TI816X_SCM_BASE 0x48140000 -#define TI816X_CTRL_BASE TI816X_SCM_BASE -#define TI816X_PRCM_BASE 0x48180000 - -#define TI816X_ARM_INTC_BASE 0x48200000 - -#endif /* __ASM_ARCH_TI816X_H */ diff --git a/arch/arm/plat-omap/include/plat/ti81xx.h b/arch/arm/plat-omap/include/plat/ti81xx.h new file mode 100644 index 000000000000..8f9843f78422 --- /dev/null +++ b/arch/arm/plat-omap/include/plat/ti81xx.h @@ -0,0 +1,27 @@ +/* + * This file contains the address data for various TI81XX modules. + * + * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARCH_TI81XX_H +#define __ASM_ARCH_TI81XX_H + +#define L4_SLOW_TI81XX_BASE 0x48000000 + +#define TI81XX_SCM_BASE 0x48140000 +#define TI81XX_CTRL_BASE TI81XX_SCM_BASE +#define TI81XX_PRCM_BASE 0x48180000 + +#define TI81XX_ARM_INTC_BASE 0x48200000 + +#endif /* __ASM_ARCH_TI81XX_H */ diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h index 2f472e989ec6..7fbc361946b5 100644 --- a/arch/arm/plat-omap/include/plat/uncompress.h +++ b/arch/arm/plat-omap/include/plat/uncompress.h @@ -99,9 +99,9 @@ static inline void flush(void) #define DEBUG_LL_ZOOM(mach) \ _DEBUG_LL_ENTRY(mach, ZOOM_UART_BASE, ZOOM_PORT_SHIFT, ZOOM_UART) -#define DEBUG_LL_TI816X(p, mach) \ - _DEBUG_LL_ENTRY(mach, TI816X_UART##p##_BASE, OMAP_PORT_SHIFT, \ - TI816XUART##p) +#define DEBUG_LL_TI81XX(p, mach) \ + _DEBUG_LL_ENTRY(mach, TI81XX_UART##p##_BASE, OMAP_PORT_SHIFT, \ + TI81XXUART##p) static inline void __arch_decomp_setup(unsigned long arch_id) { @@ -177,7 +177,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id) DEBUG_LL_ZOOM(omap_zoom3); /* TI8168 base boards using UART3 */ - DEBUG_LL_TI816X(3, ti8168evm); + DEBUG_LL_TI81XX(3, ti8168evm); } while (0); } -- cgit v1.2.3 From 8384c9749f8c31c6e1e64a63c8d50af7863ce657 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Wed, 9 Nov 2011 17:22:30 +0530 Subject: ARM: 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. Signed-off-by: Govindraj.R Signed-off-by: Kevin Hilman --- 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, 119 deletions(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index ef8595c80296..22af2f2fdbf9 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -127,27 +126,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(); @@ -291,7 +274,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); diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index fa637dfdda53..4feee45ef069 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -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 */ @@ -376,20 +366,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(); @@ -397,8 +378,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(); @@ -447,8 +426,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, @@ -464,14 +441,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 || @@ -533,7 +504,6 @@ static int omap3_pm_suspend(void) goto restore; } - omap_uart_prepare_suspend(); omap3_intc_suspend(); omap_sram_idle(); @@ -580,14 +550,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; } diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index d0f009cbfb50..6378a2a5d6b1 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -367,51 +367,6 @@ static void omap_uart_idle_timer(unsigned long data) omap_uart_allow_sleep(uart); } -void omap_uart_prepare_idle(int num) -{ - struct omap_uart_state *uart; - - list_for_each_entry(uart, &uart_list, node) { - if (num == uart->num && uart->can_sleep) { - omap_uart_disable_clocks(uart); - return; - } - } -} - -void omap_uart_resume_idle(int num) -{ - struct omap_uart_state *uart; - - list_for_each_entry(uart, &uart_list, node) { - if (num == uart->num && uart->can_sleep) { - omap_uart_enable_clocks(uart); - - /* Check for IO pad wakeup */ - if (cpu_is_omap34xx() && uart->padconf) { - u16 p = omap_ctrl_readw(uart->padconf); - - if (p & OMAP3_PADCONF_WAKEUPEVENT0) - omap_uart_block_sleep(uart); - } - - /* Check for normal UART wakeup */ - if (__raw_readl(uart->wk_st) & uart->wk_mask) - omap_uart_block_sleep(uart); - return; - } - } -} - -void omap_uart_prepare_suspend(void) -{ - struct omap_uart_state *uart; - - list_for_each_entry(uart, &uart_list, node) { - omap_uart_allow_sleep(uart); - } -} - int omap_uart_can_sleep(void) { struct omap_uart_state *uart; @@ -530,26 +485,6 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) WARN_ON(ret); } -void omap_uart_enable_irqs(int enable) -{ - int ret; - struct omap_uart_state *uart; - - list_for_each_entry(uart, &uart_list, node) { - if (enable) { - pm_runtime_put_sync(&uart->pdev->dev); - ret = request_threaded_irq(uart->irq, NULL, - omap_uart_interrupt, - IRQF_SHARED, - "serial idle", - (void *)uart); - } else { - pm_runtime_get_noresume(&uart->pdev->dev); - free_irq(uart->irq, (void *)uart); - } - } -} - static ssize_t sleep_timeout_show(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index 6975ee3f5217..73d990780da3 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -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 -- cgit v1.2.3 From 8a60585159067f110075ef8ffda13abd94826daf Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Tue, 13 Sep 2011 13:32:32 +0530 Subject: ARM: 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. Signed-off-by: Govindraj.R Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 97 -------------------------------------------- 1 file changed, 97 deletions(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 6378a2a5d6b1..e027bc99251c 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -19,23 +19,17 @@ */ #include #include -#include #include #include #include #include #include -#include #include #include -#ifdef CONFIG_SERIAL_OMAP #include -#endif - #include "common.h" #include -#include #include #include #include @@ -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_ti81xx()) - 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; -- cgit v1.2.3 From 273558b3a0399e368d99da5b3daf1c0e11b93e06 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Tue, 13 Sep 2011 14:01:01 +0530 Subject: ARM: OMAP2+: UART: Cleanup part of clock gating mechanism for uart 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. Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- 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(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index e027bc99251c..5bdbc42e42a6 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -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_ti81xx() || cpu_is_am33xx())) { @@ -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_ti81xx() || cpu_is_am33xx())) diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 2682043f5a5b..307cd6f15822 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -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 */ }; diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index 73d990780da3..152500b558a2 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -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 diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 5e713d3ef1f4..be368cf70f3c 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -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; -- cgit v1.2.3 From 7496ba309f2adbce74d917fbb8bd3da26222d49f Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Mon, 7 Nov 2011 18:55:05 +0530 Subject: ARM: OMAP2+: UART: Add default mux for all uarts. 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. Signed-off-by: Govindraj.R Signed-off-by: Kevin Hilman --- 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(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c index 83126368ed99..109b434159f5 100644 --- a/arch/arm/mach-omap2/board-3430sdp.c +++ b/arch/arm/mach-omap2/board-3430sdp.c @@ -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(); diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index ef2bbc09428a..5f264fad69bc 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -837,74 +837,8 @@ static struct omap_board_mux board_mux[] __initdata = { { .reg_offset = OMAP_MUX_TERMINATOR }, }; -static struct omap_device_pad serial2_pads[] __initdata = { - OMAP_MUX_STATIC("uart2_cts.uart2_cts", - OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), - OMAP_MUX_STATIC("uart2_rts.uart2_rts", - OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), - OMAP_MUX_STATIC("uart2_rx.uart2_rx", - OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), - OMAP_MUX_STATIC("uart2_tx.uart2_tx", - OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), -}; - -static struct omap_device_pad serial3_pads[] __initdata = { - OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx", - OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), - OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd", - OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), - OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx", - OMAP_PIN_INPUT | OMAP_MUX_MODE0), - OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx", - OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), -}; - -static struct omap_device_pad serial4_pads[] __initdata = { - OMAP_MUX_STATIC("uart4_rx.uart4_rx", - OMAP_PIN_INPUT | OMAP_MUX_MODE0), - OMAP_MUX_STATIC("uart4_tx.uart4_tx", - OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), -}; - -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 struct omap_board_data serial4_data __initdata = { - .id = 3, - .pads = serial4_pads, - .pads_cnt = ARRAY_SIZE(serial4_pads), -}; - -static inline void board_serial_init(void) -{ - struct omap_board_data bdata; - bdata.flags = 0; - bdata.pads = NULL; - bdata.pads_cnt = 0; - bdata.id = 0; - /* pass dummy data for UART1 */ - omap_serial_init_port(&bdata); - - omap_serial_init_port(&serial2_data); - omap_serial_init_port(&serial3_data); - omap_serial_init_port(&serial4_data); -} #else #define board_mux NULL - -static inline void board_serial_init(void) -{ - omap_serial_init(); -} #endif static void omap4_sdp4430_wifi_mux_init(void) @@ -954,7 +888,7 @@ static void __init omap_4430sdp_init(void) omap4_i2c_init(); omap_sfh7741prox_init(); platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); - board_serial_init(); + omap_serial_init(); omap_sdrc_init(NULL, NULL); omap4_sdp4430_wifi_init(); omap4_twl6030_hsmmc_init(mmc); diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index b6f114436dbc..ea45f5835103 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -364,74 +364,8 @@ static struct omap_board_mux board_mux[] __initdata = { { .reg_offset = OMAP_MUX_TERMINATOR }, }; -static struct omap_device_pad serial2_pads[] __initdata = { - OMAP_MUX_STATIC("uart2_cts.uart2_cts", - OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), - OMAP_MUX_STATIC("uart2_rts.uart2_rts", - OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), - OMAP_MUX_STATIC("uart2_rx.uart2_rx", - OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), - OMAP_MUX_STATIC("uart2_tx.uart2_tx", - OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), -}; - -static struct omap_device_pad serial3_pads[] __initdata = { - OMAP_MUX_STATIC("uart3_cts_rctx.uart3_cts_rctx", - OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0), - OMAP_MUX_STATIC("uart3_rts_sd.uart3_rts_sd", - OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), - OMAP_MUX_STATIC("uart3_rx_irrx.uart3_rx_irrx", - OMAP_PIN_INPUT | OMAP_MUX_MODE0), - OMAP_MUX_STATIC("uart3_tx_irtx.uart3_tx_irtx", - OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), -}; - -static struct omap_device_pad serial4_pads[] __initdata = { - OMAP_MUX_STATIC("uart4_rx.uart4_rx", - OMAP_PIN_INPUT | OMAP_MUX_MODE0), - OMAP_MUX_STATIC("uart4_tx.uart4_tx", - OMAP_PIN_OUTPUT | OMAP_MUX_MODE0), -}; - -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 struct omap_board_data serial4_data __initdata = { - .id = 3, - .pads = serial4_pads, - .pads_cnt = ARRAY_SIZE(serial4_pads), -}; - -static inline void board_serial_init(void) -{ - struct omap_board_data bdata; - bdata.flags = 0; - bdata.pads = NULL; - bdata.pads_cnt = 0; - bdata.id = 0; - /* pass dummy data for UART1 */ - omap_serial_init_port(&bdata); - - omap_serial_init_port(&serial2_data); - omap_serial_init_port(&serial3_data); - omap_serial_init_port(&serial4_data); -} #else #define board_mux NULL - -static inline void board_serial_init(void) -{ - omap_serial_init(); -} #endif /* Display DVI */ @@ -562,7 +496,7 @@ static void __init omap4_panda_init(void) omap4_panda_i2c_init(); platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices)); platform_device_register(&omap_vwlan_device); - board_serial_init(); + omap_serial_init(); omap_sdrc_init(NULL, NULL); omap4_twl6030_hsmmc_init(mmc); omap4_ehci_init(); diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 5bdbc42e42a6..77feaab78059 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -62,7 +62,6 @@ struct omap_uart_state { void __iomem *wk_st; void __iomem *wk_en; u32 wk_mask; - u32 padconf; u32 dma_enabled; int clocked; @@ -272,13 +271,6 @@ static void omap_uart_enable_wakeup(struct omap_uart_state *uart) v |= uart->wk_mask; __raw_writel(v, uart->wk_en); } - - /* Ensure IOPAD wake-enables are set */ - if (cpu_is_omap34xx() && uart->padconf) { - u16 v = omap_ctrl_readw(uart->padconf); - v |= OMAP3_PADCONF_WAKEUPENABLE0; - omap_ctrl_writew(v, uart->padconf); - } } static void omap_uart_disable_wakeup(struct omap_uart_state *uart) @@ -289,13 +281,6 @@ static void omap_uart_disable_wakeup(struct omap_uart_state *uart) v &= ~uart->wk_mask; __raw_writel(v, uart->wk_en); } - - /* Ensure IOPAD wake-enables are cleared */ - if (cpu_is_omap34xx() && uart->padconf) { - u16 v = omap_ctrl_readw(uart->padconf); - v &= ~OMAP3_PADCONF_WAKEUPENABLE0; - omap_ctrl_writew(v, uart->padconf); - } } static void omap_uart_smart_idle_enable(struct omap_uart_state *uart, @@ -358,7 +343,6 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx())) { u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD; u32 wk_mask = 0; - u32 padconf = 0; /* XXX These PRM accesses do not belong here */ uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1); @@ -366,23 +350,18 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) switch (uart->num) { case 0: wk_mask = OMAP3430_ST_UART1_MASK; - padconf = 0x182; break; case 1: wk_mask = OMAP3430_ST_UART2_MASK; - padconf = 0x17a; break; case 2: wk_mask = OMAP3430_ST_UART3_MASK; - padconf = 0x19e; break; case 3: wk_mask = OMAP3630_ST_UART4_MASK; - padconf = 0x0d2; break; } uart->wk_mask = wk_mask; - uart->padconf = padconf; } else if (cpu_is_omap24xx()) { u32 wk_mask = 0; u32 wk_en = PM_WKEN1, wk_st = PM_WKST1; @@ -412,12 +391,10 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) uart->wk_en = NULL; uart->wk_st = NULL; uart->wk_mask = 0; - uart->padconf = 0; } } #else -static inline void omap_uart_idle_init(struct omap_uart_state *uart) {} static void omap_uart_block_sleep(struct omap_uart_state *uart) { /* Needed to enable UART clocks when built without CONFIG_PM */ @@ -425,6 +402,130 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart) } #endif /* CONFIG_PM */ +#ifdef CONFIG_OMAP_MUX +static struct omap_device_pad default_uart1_pads[] __initdata = { + { + .name = "uart1_cts.uart1_cts", + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, + { + .name = "uart1_rts.uart1_rts", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart1_tx.uart1_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart1_rx.uart1_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, +}; + +static struct omap_device_pad default_uart2_pads[] __initdata = { + { + .name = "uart2_cts.uart2_cts", + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, + { + .name = "uart2_rts.uart2_rts", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart2_tx.uart2_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart2_rx.uart2_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, +}; + +static struct omap_device_pad default_uart3_pads[] __initdata = { + { + .name = "uart3_cts_rctx.uart3_cts_rctx", + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, + { + .name = "uart3_rts_sd.uart3_rts_sd", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart3_tx_irtx.uart3_tx_irtx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart3_rx_irrx.uart3_rx_irrx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + }, +}; + +static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = { + { + .name = "gpmc_wait2.uart4_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "gpmc_wait3.uart4_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE2, + .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE2, + }, +}; + +static struct omap_device_pad default_omap4_uart4_pads[] __initdata = { + { + .name = "uart4_tx.uart4_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart4_rx.uart4_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + }, +}; + +static void omap_serial_fill_default_pads(struct omap_board_data *bdata) +{ + switch (bdata->id) { + case 0: + bdata->pads = default_uart1_pads; + bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads); + break; + case 1: + bdata->pads = default_uart2_pads; + bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads); + break; + case 2: + bdata->pads = default_uart3_pads; + bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads); + break; + case 3: + if (cpu_is_omap44xx()) { + bdata->pads = default_omap4_uart4_pads; + bdata->pads_cnt = + ARRAY_SIZE(default_omap4_uart4_pads); + } else if (cpu_is_omap3630()) { + bdata->pads = default_omap36xx_uart4_pads; + bdata->pads_cnt = + ARRAY_SIZE(default_omap36xx_uart4_pads); + } + break; + default: + break; + } +} +#else +static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {} +#endif + static int __init omap_serial_early_init(void) { int i = 0; @@ -547,8 +648,8 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) omap_uart_block_sleep(uart); console_unlock(); - if ((cpu_is_omap34xx() && uart->padconf) || - (uart->wk_en && uart->wk_mask)) + if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) || + (pdata->wk_en && pdata->wk_mask)) device_init_wakeup(&pdev->dev, true); /* Enable the MDR1 errata for OMAP3 */ @@ -573,6 +674,10 @@ void __init omap_serial_init(void) bdata.flags = 0; bdata.pads = NULL; bdata.pads_cnt = 0; + + if (cpu_is_omap44xx() || cpu_is_omap34xx()) + omap_serial_fill_default_pads(&bdata); + omap_serial_init_port(&bdata); } -- cgit v1.2.3 From edd70ad757e9b336116433e6e62de79ae1dfef54 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Tue, 11 Oct 2011 14:55:41 +0530 Subject: ARM: OMAP2+: UART: Remove mapbase/membase fields from pdata. 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. Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- 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(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 77feaab78059..2456cfdad78c 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -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; diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 307cd6f15822..db9bda978767 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -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 */ }; diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index be368cf70f3c..31f0cbf73c18 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -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; -- cgit v1.2.3 From 9f9ac1e84a24670eea1430040e0aef278b4daffa Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Mon, 7 Nov 2011 18:56:12 +0530 Subject: ARM: OMAP2+: UART: Remove context_save and move context restore to driver 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. Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 118 --------------------------------------- drivers/tty/serial/omap-serial.c | 24 ++++++++ 2 files changed, 24 insertions(+), 118 deletions(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 2456cfdad78c..64b0d11ddc49 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -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; diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index f16ef4b9363d..a834e913a6e4 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -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 -- cgit v1.2.3 From 32212897eeb8c2b2b3c74dbd44d842963084d808 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Mon, 7 Nov 2011 18:58:55 +0530 Subject: ARM: OMAP2+: UART: Remove uart reset function. Remove the uart reset function which is configuring the TX empty irq which can now be handled within omap-serial driver. Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- 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(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 64b0d11ddc49..b3f3284bf6ba 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -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); diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 70e7738dd3a0..5b913c71cd7f 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -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 */ diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 5327ff0b008e..f5a5ed676825 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -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 */ -- cgit v1.2.3 From ec3bebc6ec64aac23500e6b8ef5c0aaaeda735cf Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Tue, 11 Oct 2011 19:11:27 +0530 Subject: ARM: OMAP2+: UART: Get context loss count to context restore Avoid unconditional context restore every time we gate uart clocks. Check whether context loss happened based on which we can context restore uart regs from uart_port structure. Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 2 ++ arch/arm/plat-omap/include/plat/omap-serial.h | 3 +++ drivers/tty/serial/omap-serial.c | 20 ++++++++++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index b3f3284bf6ba..78ca7e8fc10b 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "prm2xxx_3xxx.h" #include "pm.h" @@ -478,6 +479,7 @@ 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.flags = UPF_BOOT_AUTOCONF; + omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; pdata = &omap_up; pdata_size = sizeof(struct omap_uart_port_info); diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 5b913c71cd7f..348c9ead6edb 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -62,6 +62,8 @@ struct omap_uart_port_info { bool dma_enabled; /* To specify DMA Mode */ unsigned int uartclk; /* UART clock rate */ upf_t flags; /* UPF_* flags */ + + int (*get_context_loss_count)(struct device *); }; struct uart_omap_dma { @@ -114,6 +116,7 @@ struct uart_omap_port { unsigned char msr_saved_flags; char name[20]; unsigned long port_activity; + u32 context_loss_cnt; }; #endif /* __OMAP_SERIAL_H__ */ diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index f5a5ed676825..ea4c24aa8c87 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1440,15 +1440,31 @@ static void serial_omap_restore_context(struct uart_omap_port *up) #ifdef CONFIG_PM_RUNTIME static int serial_omap_runtime_suspend(struct device *dev) { + struct uart_omap_port *up = dev_get_drvdata(dev); + struct omap_uart_port_info *pdata = dev->platform_data; + + if (!up) + return -EINVAL; + + if (pdata->get_context_loss_count) + up->context_loss_cnt = pdata->get_context_loss_count(dev); + return 0; } static int serial_omap_runtime_resume(struct device *dev) { struct uart_omap_port *up = dev_get_drvdata(dev); + struct omap_uart_port_info *pdata = dev->platform_data; - if (up) - serial_omap_restore_context(up); + if (up) { + if (pdata->get_context_loss_count) { + u32 loss_cnt = pdata->get_context_loss_count(dev); + + if (up->context_loss_cnt != loss_cnt) + serial_omap_restore_context(up); + } + } return 0; } -- cgit v1.2.3 From 94734749af794c080f6af6ac3ce8c1c13ee2dbbd Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Mon, 7 Nov 2011 19:00:33 +0530 Subject: ARM: OMAP2+: UART: Move errata handling from serial.c to omap-serial Move the errata handling mechanism from serial.c to omap-serial file and utilise the same func in driver file. Errata i202, i291 are moved to be handled with omap-serial Moving the errata macro from serial.c file to driver header file as from on errata will be handled in driver file itself. Corrected errata id from chapter reference 2.15 to errata id i291. Removed errata and dma_enabled fields from omap_uart_state struct as they are no more needed with errata handling done within omap-serial. Signed-off-by: Govindraj.R Acked-by: Alan Cox Acked-by: Greg Kroah-Hartman Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 101 ++++++++------------------ arch/arm/plat-omap/include/plat/omap-serial.h | 7 ++ drivers/tty/serial/omap-serial.c | 68 ++++++++++++++++- 3 files changed, 102 insertions(+), 74 deletions(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 78ca7e8fc10b..77a25cb1dcca 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -42,8 +42,6 @@ #include "control.h" #include "mux.h" -#define UART_ERRATA_i202_MDR1_ACCESS (0x1 << 1) - /* * NOTE: By default the serial timeout is disabled as it causes lost characters * over the serial ports. This means that the UART clocks will stay on until @@ -61,59 +59,17 @@ struct omap_uart_state { void __iomem *wk_st; void __iomem *wk_en; u32 wk_mask; - u32 dma_enabled; int clocked; struct list_head node; struct omap_hwmod *oh; struct platform_device *pdev; - - u32 errata; }; static LIST_HEAD(uart_list); static u8 num_uarts; -#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) - -/* - * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6) - * The access to uart register after MDR1 Access - * causes UART to corrupt data. - * - * Need a delay = - * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS) - * give 10 times as much - */ -static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val, - u8 fcr_val) -{ - u8 timeout = 255; - - serial_write_reg(uart, UART_OMAP_MDR1, mdr1_val); - udelay(2); - serial_write_reg(uart, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT | - UART_FCR_CLEAR_RCVR); - /* - * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and - * TX_FIFO_E bit is 1. - */ - while (UART_LSR_THRE != (serial_read_reg(uart, UART_LSR) & - (UART_LSR_THRE | UART_LSR_DR))) { - timeout--; - if (!timeout) { - /* Should *never* happen. we warn and carry on */ - dev_crit(&uart->pdev->dev, "Errata i202: timedout %x\n", - serial_read_reg(uart, UART_LSR)); - break; - } - udelay(1); - } -} - -#endif /* CONFIG_PM && CONFIG_ARCH_OMAP3 */ - static inline void omap_uart_enable_clocks(struct omap_uart_state *uart) { if (uart->clocked) @@ -156,27 +112,6 @@ static void omap_uart_disable_wakeup(struct omap_uart_state *uart) } } -static void omap_uart_smart_idle_enable(struct omap_uart_state *uart, - int enable) -{ - u8 idlemode; - - if (enable) { - /** - * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests - * in Smartidle Mode When Configured for DMA Operations. - */ - if (uart->dma_enabled) - idlemode = HWMOD_IDLEMODE_FORCE; - else - idlemode = HWMOD_IDLEMODE_SMART; - } else { - idlemode = HWMOD_IDLEMODE_NO; - } - - omap_hwmod_set_slave_idlemode(uart->oh, idlemode); -} - static void omap_uart_block_sleep(struct omap_uart_state *uart) { omap_uart_enable_clocks(uart); @@ -267,7 +202,28 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) } } +/* + * Errata i291: [UART]:Cannot Acknowledge Idle Requests + * in Smartidle Mode When Configured for DMA Operations. + * WA: configure uart in force idle mode. + */ +static void omap_uart_set_noidle(struct platform_device *pdev) +{ + struct omap_device *od = to_omap_device(pdev); + + omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO); +} + +static void omap_uart_set_forceidle(struct platform_device *pdev) +{ + struct omap_device *od = to_omap_device(pdev); + + omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_FORCE); +} + #else +static void omap_uart_set_noidle(struct platform_device *pdev) {} +static void omap_uart_set_forceidle(struct platform_device *pdev) {} static void omap_uart_block_sleep(struct omap_uart_state *uart) { /* Needed to enable UART clocks when built without CONFIG_PM */ @@ -473,13 +429,22 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) break; oh = uart->oh; - uart->dma_enabled = 0; name = DRIVER_NAME; omap_up.dma_enabled = uart->dma_enabled; omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; omap_up.flags = UPF_BOOT_AUTOCONF; omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; + omap_up.set_forceidle = omap_uart_set_forceidle; + omap_up.set_noidle = omap_uart_set_noidle; + + /* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */ + if (!cpu_is_omap2420() && !cpu_is_ti816x()) + omap_up.errata |= UART_ERRATA_i202_MDR1_ACCESS; + + /* Enable DMA Mode Force Idle Errata i291 for omap34xx/3630 */ + if (cpu_is_omap34xx() || cpu_is_omap3630()) + omap_up.errata |= UART_ERRATA_i291_DMA_FORCEIDLE; pdata = &omap_up; pdata_size = sizeof(struct omap_uart_port_info); @@ -519,10 +484,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) || (pdata->wk_en && pdata->wk_mask)) device_init_wakeup(&pdev->dev, true); - - /* Enable the MDR1 errata for OMAP3 */ - if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx())) - uart->errata |= UART_ERRATA_i202_MDR1_ACCESS; } /** diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 348c9ead6edb..842b429cfeaa 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -58,12 +58,18 @@ #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA +#define UART_ERRATA_i202_MDR1_ACCESS BIT(0) +#define UART_ERRATA_i291_DMA_FORCEIDLE BIT(1) + struct omap_uart_port_info { bool dma_enabled; /* To specify DMA Mode */ unsigned int uartclk; /* UART clock rate */ upf_t flags; /* UPF_* flags */ + u32 errata; int (*get_context_loss_count)(struct device *); + void (*set_forceidle)(struct platform_device *); + void (*set_noidle)(struct platform_device *); }; struct uart_omap_dma { @@ -117,6 +123,7 @@ struct uart_omap_port { char name[20]; unsigned long port_activity; u32 context_loss_cnt; + u32 errata; }; #endif /* __OMAP_SERIAL_H__ */ diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index ea4c24aa8c87..764ac7795694 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -51,6 +51,7 @@ static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; static void uart_tx_dma_callback(int lch, u16 ch_status, void *data); static void serial_omap_rx_timeout(unsigned long uart_no); static int serial_omap_start_rxdma(struct uart_omap_port *up); +static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1); static inline unsigned int serial_in(struct uart_omap_port *up, int offset) { @@ -808,7 +809,11 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, /* Protocol, Baud Rate, and Interrupt Settings */ - serial_out(up, UART_OMAP_MDR1, up->mdr1); + if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) + serial_omap_mdr1_errataset(up, up->mdr1); + else + serial_out(up, UART_OMAP_MDR1, up->mdr1); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR); @@ -833,7 +838,10 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, else up->mdr1 = UART_OMAP_MDR1_16X_MODE; - serial_out(up, UART_OMAP_MDR1, up->mdr1); + if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) + serial_omap_mdr1_errataset(up, up->mdr1); + else + serial_out(up, UART_OMAP_MDR1, up->mdr1); /* Hardware Flow Control Configuration */ @@ -1362,6 +1370,7 @@ static int serial_omap_probe(struct platform_device *pdev) up->port.flags = omap_up_info->flags; up->port.uartclk = omap_up_info->uartclk; up->uart_dma.uart_base = mem->start; + up->errata = omap_up_info->errata; if (omap_up_info->dma_enabled) { up->uart_dma.uart_dma_tx = dma_tx->start; @@ -1415,9 +1424,47 @@ static int serial_omap_remove(struct platform_device *dev) return 0; } +/* + * Work Around for Errata i202 (2430, 3430, 3630, 4430 and 4460) + * The access to uart register after MDR1 Access + * causes UART to corrupt data. + * + * Need a delay = + * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS) + * give 10 times as much + */ +static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1) +{ + u8 timeout = 255; + + serial_out(up, UART_OMAP_MDR1, mdr1); + udelay(2); + serial_out(up, UART_FCR, up->fcr | UART_FCR_CLEAR_XMIT | + UART_FCR_CLEAR_RCVR); + /* + * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and + * TX_FIFO_E bit is 1. + */ + while (UART_LSR_THRE != (serial_in(up, UART_LSR) & + (UART_LSR_THRE | UART_LSR_DR))) { + timeout--; + if (!timeout) { + /* Should *never* happen. we warn and carry on */ + dev_crit(&up->pdev->dev, "Errata i202: timedout %x\n", + serial_in(up, UART_LSR)); + break; + } + udelay(1); + } +} + static void serial_omap_restore_context(struct uart_omap_port *up) { - serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); + if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) + serial_omap_mdr1_errataset(up, UART_OMAP_MDR1_DISABLE); + else + 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 */ @@ -1434,7 +1481,10 @@ static void serial_omap_restore_context(struct uart_omap_port *up) serial_out(up, UART_OMAP_SCR, up->scr); serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, up->lcr); - serial_out(up, UART_OMAP_MDR1, up->mdr1); + if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) + serial_omap_mdr1_errataset(up, up->mdr1); + else + serial_out(up, UART_OMAP_MDR1, up->mdr1); } #ifdef CONFIG_PM_RUNTIME @@ -1449,6 +1499,11 @@ static int serial_omap_runtime_suspend(struct device *dev) if (pdata->get_context_loss_count) up->context_loss_cnt = pdata->get_context_loss_count(dev); + /* Errata i291 */ + if (up->use_dma && pdata->set_forceidle && + (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) + pdata->set_forceidle(up->pdev); + return 0; } @@ -1464,6 +1519,11 @@ static int serial_omap_runtime_resume(struct device *dev) if (up->context_loss_cnt != loss_cnt) serial_omap_restore_context(up); } + + /* Errata i291 */ + if (up->use_dma && pdata->set_noidle && + (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) + pdata->set_noidle(up->pdev); } return 0; -- cgit v1.2.3 From 62f3ec5fbd5fddce62b7a71adc04723a5eb903da Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Thu, 13 Oct 2011 14:11:09 +0530 Subject: ARM: OMAP2+: UART: Add wakeup mechanism for omap-uarts From the runtime callbacks enable hwmod wakeups for uart which will internally enable io-pad wakeups for uarts if they have rx-pad pins set as wakeup capabale. Use the io-ring wakeup mechanism after uart clock gating and leave the PM_WKST set for uart to default reset values cleanup the code in serial.c which was handling PM_WKST reg. Irq_chaing(PRM_DRIVER) is used to wakeup uart after uart clocks are gated using pad wakeup mechanism. Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 96 ++++----------------------- arch/arm/plat-omap/include/plat/omap-serial.h | 2 + drivers/tty/serial/omap-serial.c | 15 +++++ 3 files changed, 29 insertions(+), 84 deletions(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 77a25cb1dcca..aa6f7f05a1e3 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -56,10 +56,6 @@ struct omap_uart_state { int num; int can_sleep; - void __iomem *wk_st; - void __iomem *wk_en; - u32 wk_mask; - int clocked; struct list_head node; @@ -92,26 +88,6 @@ static inline void omap_uart_disable_clocks(struct omap_uart_state *uart) omap_device_idle(uart->pdev); } -static void omap_uart_enable_wakeup(struct omap_uart_state *uart) -{ - /* Set wake-enable bit */ - if (uart->wk_en && uart->wk_mask) { - u32 v = __raw_readl(uart->wk_en); - v |= uart->wk_mask; - __raw_writel(v, uart->wk_en); - } -} - -static void omap_uart_disable_wakeup(struct omap_uart_state *uart) -{ - /* Clear wake-enable bit */ - if (uart->wk_en && uart->wk_mask) { - u32 v = __raw_readl(uart->wk_en); - v &= ~uart->wk_mask; - __raw_writel(v, uart->wk_en); - } -} - static void omap_uart_block_sleep(struct omap_uart_state *uart) { omap_uart_enable_clocks(uart); @@ -141,65 +117,17 @@ int omap_uart_can_sleep(void) return can_sleep; } -static void omap_uart_idle_init(struct omap_uart_state *uart) +static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable) { - int ret; - - uart->can_sleep = 0; - omap_uart_smart_idle_enable(uart, 0); + struct omap_device *od = to_omap_device(pdev); - if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx())) { - u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD; - u32 wk_mask = 0; + if (!od) + return; - /* XXX These PRM accesses do not belong here */ - uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1); - uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1); - switch (uart->num) { - case 0: - wk_mask = OMAP3430_ST_UART1_MASK; - break; - case 1: - wk_mask = OMAP3430_ST_UART2_MASK; - break; - case 2: - wk_mask = OMAP3430_ST_UART3_MASK; - break; - case 3: - wk_mask = OMAP3630_ST_UART4_MASK; - break; - } - uart->wk_mask = wk_mask; - } else if (cpu_is_omap24xx()) { - u32 wk_mask = 0; - u32 wk_en = PM_WKEN1, wk_st = PM_WKST1; - - switch (uart->num) { - case 0: - wk_mask = OMAP24XX_ST_UART1_MASK; - break; - case 1: - wk_mask = OMAP24XX_ST_UART2_MASK; - break; - case 2: - wk_en = OMAP24XX_PM_WKEN2; - wk_st = OMAP24XX_PM_WKST2; - wk_mask = OMAP24XX_ST_UART3_MASK; - break; - } - uart->wk_mask = wk_mask; - if (cpu_is_omap2430()) { - uart->wk_en = OMAP2430_PRM_REGADDR(CORE_MOD, wk_en); - uart->wk_st = OMAP2430_PRM_REGADDR(CORE_MOD, wk_st); - } else if (cpu_is_omap2420()) { - uart->wk_en = OMAP2420_PRM_REGADDR(CORE_MOD, wk_en); - uart->wk_st = OMAP2420_PRM_REGADDR(CORE_MOD, wk_st); - } - } else { - uart->wk_en = NULL; - uart->wk_st = NULL; - uart->wk_mask = 0; - } + if (enable) + omap_hwmod_enable_wakeup(od->hwmods[0]); + else + omap_hwmod_disable_wakeup(od->hwmods[0]); } /* @@ -222,6 +150,8 @@ static void omap_uart_set_forceidle(struct platform_device *pdev) } #else +static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable) +{} static void omap_uart_set_noidle(struct platform_device *pdev) {} static void omap_uart_set_forceidle(struct platform_device *pdev) {} static void omap_uart_block_sleep(struct omap_uart_state *uart) @@ -437,6 +367,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; omap_up.set_forceidle = omap_uart_set_forceidle; omap_up.set_noidle = omap_uart_set_noidle; + omap_up.enable_wakeup = omap_uart_enable_wakeup; /* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */ if (!cpu_is_omap2420() && !cpu_is_ti816x()) @@ -474,15 +405,12 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) omap_hwmod_idle(uart->oh); omap_device_enable(uart->pdev); - omap_uart_idle_init(uart); - omap_hwmod_enable_wakeup(uart->oh); omap_device_idle(uart->pdev); omap_uart_block_sleep(uart); console_unlock(); - if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) || - (pdata->wk_en && pdata->wk_mask)) + if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) device_init_wakeup(&pdev->dev, true); } diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 842b429cfeaa..39709ecfd58f 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -70,6 +70,7 @@ struct omap_uart_port_info { int (*get_context_loss_count)(struct device *); void (*set_forceidle)(struct platform_device *); void (*set_noidle)(struct platform_device *); + void (*enable_wakeup)(struct platform_device *, bool); }; struct uart_omap_dma { @@ -124,6 +125,7 @@ struct uart_omap_port { unsigned long port_activity; u32 context_loss_cnt; u32 errata; + u8 wakeups_enabled; }; #endif /* __OMAP_SERIAL_H__ */ diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 764ac7795694..45a25a01c44d 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1496,9 +1496,24 @@ static int serial_omap_runtime_suspend(struct device *dev) if (!up) return -EINVAL; + if (!pdata->enable_wakeup) + return 0; + if (pdata->get_context_loss_count) up->context_loss_cnt = pdata->get_context_loss_count(dev); + if (device_may_wakeup(dev)) { + if (!up->wakeups_enabled) { + pdata->enable_wakeup(up->pdev, true); + up->wakeups_enabled = true; + } + } else { + if (up->wakeups_enabled) { + pdata->enable_wakeup(up->pdev, false); + up->wakeups_enabled = false; + } + } + /* Errata i291 */ if (up->use_dma && pdata->set_forceidle && (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) -- cgit v1.2.3 From 634bd6e4817cd6a7109be8d2eee5c578a283d1ee Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Mon, 7 Nov 2011 19:01:24 +0530 Subject: ARM: OMAP2+: UART: Remove old and unused clocks handling funcs With runtime adaptation done remove clock_enable/disbale API's Signed-off-by: Govindraj.R Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index aa6f7f05a1e3..f94394fe5b16 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -56,8 +56,6 @@ struct omap_uart_state { int num; int can_sleep; - int clocked; - struct list_head node; struct omap_hwmod *oh; struct platform_device *pdev; @@ -66,36 +64,8 @@ struct omap_uart_state { static LIST_HEAD(uart_list); static u8 num_uarts; -static inline void omap_uart_enable_clocks(struct omap_uart_state *uart) -{ - if (uart->clocked) - return; - - omap_device_enable(uart->pdev); - uart->clocked = 1; - omap_uart_restore_context(uart); -} - #ifdef CONFIG_PM -static inline void omap_uart_disable_clocks(struct omap_uart_state *uart) -{ - if (!uart->clocked) - return; - - omap_uart_save_context(uart); - uart->clocked = 0; - omap_device_idle(uart->pdev); -} - -static void omap_uart_block_sleep(struct omap_uart_state *uart) -{ - omap_uart_enable_clocks(uart); - - omap_uart_smart_idle_enable(uart, 0); - uart->can_sleep = 0; -} - int omap_uart_can_sleep(void) { struct omap_uart_state *uart; @@ -154,11 +124,6 @@ static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable) {} static void omap_uart_set_noidle(struct platform_device *pdev) {} static void omap_uart_set_forceidle(struct platform_device *pdev) {} -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); -} #endif /* CONFIG_PM */ #ifdef CONFIG_OMAP_MUX @@ -407,7 +372,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) omap_device_enable(uart->pdev); omap_device_idle(uart->pdev); - omap_uart_block_sleep(uart); console_unlock(); if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) -- cgit v1.2.3 From c86845db77ce220f77e6645b18800744684946ac Mon Sep 17 00:00:00 2001 From: Deepak K Date: Wed, 9 Nov 2011 17:33:38 +0530 Subject: ARM: OMAP2+: UART: Allow UART parameters to be configured from board file. The following UART parameters are defined within the UART driver: 1). Whether the UART uses DMA (dma_enabled), by default set to 0 2). The size of dma buffer (set to 4096 bytes) 3). The time after which the dma should stop if no more data is received. 4). The auto suspend delay that will be passed for pm_runtime_autosuspend where uart will be disabled after timeout Different UARTs may be used for different purpose such as the console, for interfacing bluetooth chip, for interfacing to a modem chip, etc. Therefore, it is necessary to be able to customize the above settings for a given board on a per UART basis. This change allows these parameters to be configured from the board file and allows the parameters to be configured for each UART independently. If a board does not define its own custom parameters for the UARTs, then use the default parameters in the structure "omap_serial_default_info". The default parameters are defined to be the same as the current settings in the UART driver to avoid breaking the UART for any cuurnelty supported boards. By default, make all boards use the default UART parameters. Signed-off-by: Deepak K Signed-off-by: Jon Hunter Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/board-n8x0.c | 6 +-- arch/arm/mach-omap2/serial.c | 56 +++++++++++++++++++++------ arch/arm/plat-omap/include/plat/omap-serial.h | 7 +++- arch/arm/plat-omap/include/plat/serial.h | 5 ++- drivers/tty/serial/omap-serial.c | 8 ++-- 5 files changed, 60 insertions(+), 22 deletions(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index bebd3d84365e..118f38c4b37d 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -644,15 +644,15 @@ static inline void board_serial_init(void) bdata.pads_cnt = 0; bdata.id = 0; - omap_serial_init_port(&bdata); + omap_serial_init_port(&bdata, NULL); bdata.id = 1; - omap_serial_init_port(&bdata); + omap_serial_init_port(&bdata, NULL); bdata.id = 2; bdata.pads = serial2_pads; bdata.pads_cnt = ARRAY_SIZE(serial2_pads); - omap_serial_init_port(&bdata); + omap_serial_init_port(&bdata, NULL); } #else diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index f94394fe5b16..5b1b36a45e9c 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -43,12 +43,12 @@ #include "mux.h" /* - * NOTE: By default the serial timeout is disabled as it causes lost characters - * over the serial ports. This means that the UART clocks will stay on until - * disabled via sysfs. This also causes that any deeper omap sleep states are - * blocked. + * NOTE: By default the serial auto_suspend timeout is disabled as it causes + * lost characters over the serial ports. This means that the UART clocks will + * stay on until power/autosuspend_delay is set for the uart from sysfs. + * This also causes that any deeper omap sleep states are blocked. */ -#define DEFAULT_TIMEOUT 0 +#define DEFAULT_AUTOSUSPEND_DELAY -1 #define MAX_UART_HWMOD_NAME_LEN 16 @@ -64,6 +64,18 @@ struct omap_uart_state { static LIST_HEAD(uart_list); static u8 num_uarts; +#define DEFAULT_RXDMA_TIMEOUT 1 /* RX DMA polling rate (us) */ +#define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */ + +static struct omap_uart_port_info omap_serial_default_info[] __initdata = { + { + .dma_enabled = false, + .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, + .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, + .autosuspend_timeout = DEFAULT_AUTOSUSPEND_DELAY, + }, +}; + #ifdef CONFIG_PM int omap_uart_can_sleep(void) @@ -294,6 +306,7 @@ core_initcall(omap_serial_early_init); /** * omap_serial_init_port() - initialize single serial port * @bdata: port specific board data pointer + * @info: platform specific data pointer * * This function initialies serial driver for given port only. * Platforms can call this function instead of omap_serial_init() @@ -302,7 +315,8 @@ core_initcall(omap_serial_early_init); * Don't mix calls to omap_serial_init_port() and omap_serial_init(), * use only one of the two. */ -void __init omap_serial_init_port(struct omap_board_data *bdata) +void __init omap_serial_init_port(struct omap_board_data *bdata, + struct omap_uart_port_info *info) { struct omap_uart_state *uart; struct omap_hwmod *oh; @@ -322,17 +336,22 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) list_for_each_entry(uart, &uart_list, node) if (bdata->id == uart->num) break; + if (!info) + info = omap_serial_default_info; oh = uart->oh; name = DRIVER_NAME; - omap_up.dma_enabled = uart->dma_enabled; + omap_up.dma_enabled = info->dma_enabled; omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; omap_up.flags = UPF_BOOT_AUTOCONF; omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; omap_up.set_forceidle = omap_uart_set_forceidle; omap_up.set_noidle = omap_uart_set_noidle; omap_up.enable_wakeup = omap_uart_enable_wakeup; + omap_up.dma_rx_buf_size = info->dma_rx_buf_size; + omap_up.dma_rx_timeout = info->dma_rx_timeout; + omap_up.autosuspend_timeout = info->autosuspend_timeout; /* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */ if (!cpu_is_omap2420() && !cpu_is_ti816x()) @@ -379,13 +398,14 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) } /** - * omap_serial_init() - initialize all supported serial ports + * omap_serial_board_init() - initialize all supported serial ports + * @info: platform specific data pointer * * Initializes all available UARTs as serial ports. Platforms * can call this function when they want to have default behaviour * for serial ports (e.g initialize them all as serial ports). */ -void __init omap_serial_init(void) +void __init omap_serial_board_init(struct omap_uart_port_info *info) { struct omap_uart_state *uart; struct omap_board_data bdata; @@ -399,7 +419,21 @@ void __init omap_serial_init(void) if (cpu_is_omap44xx() || cpu_is_omap34xx()) omap_serial_fill_default_pads(&bdata); - omap_serial_init_port(&bdata); - + if (!info) + omap_serial_init_port(&bdata, NULL); + else + omap_serial_init_port(&bdata, &info[uart->num]); } } + +/** + * omap_serial_init() - initialize all supported serial ports + * + * Initializes all available UARTs. + * Platforms can call this function when they want to have default behaviour + * for serial ports (e.g initialize them all as serial ports). + */ +void __init omap_serial_init(void) +{ + omap_serial_board_init(NULL); +} diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index 39709ecfd58f..a740a6c0e104 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -66,6 +66,9 @@ struct omap_uart_port_info { unsigned int uartclk; /* UART clock rate */ upf_t flags; /* UPF_* flags */ u32 errata; + unsigned int dma_rx_buf_size; + unsigned int dma_rx_timeout; + unsigned int autosuspend_timeout; int (*get_context_loss_count)(struct device *); void (*set_forceidle)(struct platform_device *); @@ -94,8 +97,8 @@ struct uart_omap_dma { spinlock_t rx_lock; /* timer to poll activity on rx dma */ struct timer_list rx_timer; - int rx_buf_size; - int rx_timeout; + unsigned int rx_buf_size; + unsigned int rx_timeout; }; struct uart_omap_port { diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index 152500b558a2..38b3e38df2a0 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -106,10 +106,13 @@ #ifndef __ASSEMBLER__ struct omap_board_data; +struct omap_uart_port_info; 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_serial_board_init(struct omap_uart_port_info *platform_data); +extern void omap_serial_init_port(struct omap_board_data *bdata, + struct omap_uart_port_info *platform_data); #endif #endif diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 45a25a01c44d..d60e001cf60f 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -43,8 +43,6 @@ #include #include -#define OMAP_UART_AUTOSUSPEND_DELAY -1 - static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; /* Forward declaration of functions */ @@ -1376,8 +1374,8 @@ static int serial_omap_probe(struct platform_device *pdev) up->uart_dma.uart_dma_tx = dma_tx->start; up->uart_dma.uart_dma_rx = dma_rx->start; up->use_dma = 1; - up->uart_dma.rx_buf_size = 4096; - up->uart_dma.rx_timeout = 2; + up->uart_dma.rx_buf_size = omap_up_info->dma_rx_buf_size; + up->uart_dma.rx_timeout = omap_up_info->dma_rx_timeout; spin_lock_init(&(up->uart_dma.tx_lock)); spin_lock_init(&(up->uart_dma.rx_lock)); up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; @@ -1386,7 +1384,7 @@ static int serial_omap_probe(struct platform_device *pdev) pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, - OMAP_UART_AUTOSUSPEND_DELAY); + omap_up_info->autosuspend_timeout); pm_runtime_irq_safe(&pdev->dev); pm_runtime_enable(&pdev->dev); -- cgit v1.2.3 From a9e210e0b7a344c0e44aa6bf6888176bbc635c42 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Wed, 9 Nov 2011 17:34:49 +0530 Subject: ARM: OMAP2+: UART: Make the RX_TIMEOUT for DMA configurable for each UART When using DMA there are two timeouts defined. The first timeout, rx_timeout, is really a polling rate in which software polls the DMA status to see if the DMA has finished. This is necessary for the RX side because we do not know how much data we will receive. The secound timeout, RX_TIMEOUT, is a timeout after which the DMA will be stopped if no more data is received. To make this clearer, rename rx_timeout as rx_poll_rate and rename the function serial_omap_rx_timeout() to serial_omap_rxdma_poll(). The OMAP-Serial driver defines an RX_TIMEOUT of 3 seconds that is used to indicate when the DMA for UART can be stopped if no more data is received. The value is a global definition that is applied to all instances of the UART. Each UART may be used for a different purpose and so the timeout required may differ. Make this value configurable for each UART so that this value can be optimised for power savings. Signed-off-by: Jon Hunter Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 5 ++++- arch/arm/plat-omap/include/plat/omap-serial.h | 3 ++- drivers/tty/serial/omap-serial.c | 15 ++++++++------- 3 files changed, 14 insertions(+), 9 deletions(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 5b1b36a45e9c..5dd928945033 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -64,13 +64,15 @@ struct omap_uart_state { static LIST_HEAD(uart_list); static u8 num_uarts; -#define DEFAULT_RXDMA_TIMEOUT 1 /* RX DMA polling rate (us) */ +#define DEFAULT_RXDMA_POLLRATE 1 /* RX DMA polling rate (us) */ #define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */ +#define DEFAULT_RXDMA_TIMEOUT (3 * HZ)/* RX DMA timeout (jiffies) */ static struct omap_uart_port_info omap_serial_default_info[] __initdata = { { .dma_enabled = false, .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, + .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE, .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, .autosuspend_timeout = DEFAULT_AUTOSUSPEND_DELAY, }, @@ -351,6 +353,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, omap_up.enable_wakeup = omap_uart_enable_wakeup; omap_up.dma_rx_buf_size = info->dma_rx_buf_size; omap_up.dma_rx_timeout = info->dma_rx_timeout; + omap_up.dma_rx_poll_rate = info->dma_rx_poll_rate; omap_up.autosuspend_timeout = info->autosuspend_timeout; /* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */ diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index a740a6c0e104..ea63b2bc761c 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -53,7 +53,6 @@ #define OMAP_UART_DMA_CH_FREE -1 -#define RX_TIMEOUT (3 * HZ) #define OMAP_MAX_HSUART_PORTS 4 #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA @@ -69,6 +68,7 @@ struct omap_uart_port_info { unsigned int dma_rx_buf_size; unsigned int dma_rx_timeout; unsigned int autosuspend_timeout; + unsigned int dma_rx_poll_rate; int (*get_context_loss_count)(struct device *); void (*set_forceidle)(struct platform_device *); @@ -98,6 +98,7 @@ struct uart_omap_dma { /* timer to poll activity on rx dma */ struct timer_list rx_timer; unsigned int rx_buf_size; + unsigned int rx_poll_rate; unsigned int rx_timeout; }; diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index d60e001cf60f..e1eaa66c047b 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -47,7 +47,7 @@ static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; /* Forward declaration of functions */ static void uart_tx_dma_callback(int lch, u16 ch_status, void *data); -static void serial_omap_rx_timeout(unsigned long uart_no); +static void serial_omap_rxdma_poll(unsigned long uart_no); static int serial_omap_start_rxdma(struct uart_omap_port *up); static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1); @@ -542,7 +542,7 @@ static int serial_omap_startup(struct uart_port *port) (dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys), 0); init_timer(&(up->uart_dma.rx_timer)); - up->uart_dma.rx_timer.function = serial_omap_rx_timeout; + up->uart_dma.rx_timer.function = serial_omap_rxdma_poll; up->uart_dma.rx_timer.data = up->pdev->id; /* Currently the buffer size is 4KB. Can increase it */ up->uart_dma.rx_buf = dma_alloc_coherent(NULL, @@ -1160,7 +1160,7 @@ static int serial_omap_resume(struct device *dev) } #endif -static void serial_omap_rx_timeout(unsigned long uart_no) +static void serial_omap_rxdma_poll(unsigned long uart_no) { struct uart_omap_port *up = ui[uart_no]; unsigned int curr_dma_pos, curr_transmitted_size; @@ -1170,9 +1170,9 @@ static void serial_omap_rx_timeout(unsigned long uart_no) if ((curr_dma_pos == up->uart_dma.prev_rx_dma_pos) || (curr_dma_pos == 0)) { if (jiffies_to_msecs(jiffies - up->port_activity) < - RX_TIMEOUT) { + up->uart_dma.rx_timeout) { mod_timer(&up->uart_dma.rx_timer, jiffies + - usecs_to_jiffies(up->uart_dma.rx_timeout)); + usecs_to_jiffies(up->uart_dma.rx_poll_rate)); } else { serial_omap_stop_rxdma(up); up->ier |= (UART_IER_RDI | UART_IER_RLSI); @@ -1201,7 +1201,7 @@ static void serial_omap_rx_timeout(unsigned long uart_no) } } else { mod_timer(&up->uart_dma.rx_timer, jiffies + - usecs_to_jiffies(up->uart_dma.rx_timeout)); + usecs_to_jiffies(up->uart_dma.rx_poll_rate)); } up->port_activity = jiffies; } @@ -1240,7 +1240,7 @@ static int serial_omap_start_rxdma(struct uart_omap_port *up) /* FIXME: Cache maintenance needed here? */ omap_start_dma(up->uart_dma.rx_dma_channel); mod_timer(&up->uart_dma.rx_timer, jiffies + - usecs_to_jiffies(up->uart_dma.rx_timeout)); + usecs_to_jiffies(up->uart_dma.rx_poll_rate)); up->uart_dma.rx_dma_used = true; return ret; } @@ -1376,6 +1376,7 @@ static int serial_omap_probe(struct platform_device *pdev) up->use_dma = 1; up->uart_dma.rx_buf_size = omap_up_info->dma_rx_buf_size; up->uart_dma.rx_timeout = omap_up_info->dma_rx_timeout; + up->uart_dma.rx_poll_rate = omap_up_info->dma_rx_poll_rate; spin_lock_init(&(up->uart_dma.tx_lock)); spin_lock_init(&(up->uart_dma.rx_lock)); up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; -- cgit v1.2.3 From 969996a57fd2345a1141280dddcf9e10fa5f6690 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Tue, 18 Oct 2011 16:32:14 +0530 Subject: ARM: OMAP2+: UART: remove temporary variable used to count uart instance Reuse the num_uarts variable itself to count number of uarts. Signed-off-by: Govindraj.R Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 5dd928945033..8e0d0062cb15 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -266,15 +266,13 @@ static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {} static int __init omap_serial_early_init(void) { - int i = 0; - do { char oh_name[MAX_UART_HWMOD_NAME_LEN]; struct omap_hwmod *oh; struct omap_uart_state *uart; snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN, - "uart%d", i + 1); + "uart%d", num_uarts + 1); oh = omap_hwmod_lookup(oh_name); if (!oh) break; @@ -284,9 +282,8 @@ static int __init omap_serial_early_init(void) return -ENODEV; uart->oh = oh; - uart->num = i++; + uart->num = num_uarts++; list_add_tail(&uart->node, &uart_list); - num_uarts++; /* * NOTE: omap_hwmod_setup*() has not yet been called, -- cgit v1.2.3 From 8612bd22f30369745d0fda0d540aca39ab591cc5 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Mon, 7 Nov 2011 19:05:44 +0530 Subject: ARM: OMAP2+: UART: Avoid console uart idling during bootup Omap-uart can be used as console uart to print early boot messages using earlyprintk so for console uart prevent hwmod reset or idling during bootup. Identify omap-uart used as console and avoid idling rather than preventing all omap-uarts from idling during bootup. Update the comments for the same. Remove the uart idling and enabling back using hwmod_idle/omap_device_enable for all uarts that where left enabled from boot to set the hwmod framework state machine right. This need not be taken care any more serial.c rather can be handled within the hwmod framework. Reference: http://www.spinics.net/lists/linux-omap/msg60300.html Signed-off-by: Govindraj.R Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 51 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 26 deletions(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 8e0d0062cb15..85516c946ef0 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -63,6 +63,7 @@ struct omap_uart_state { static LIST_HEAD(uart_list); static u8 num_uarts; +static u8 console_uart_id = -1; #define DEFAULT_RXDMA_POLLRATE 1 /* RX DMA polling rate (us) */ #define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */ @@ -264,12 +265,20 @@ static void omap_serial_fill_default_pads(struct omap_board_data *bdata) static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {} #endif +char *cmdline_find_option(char *str) +{ + extern char *saved_command_line; + + return strstr(saved_command_line, str); +} + static int __init omap_serial_early_init(void) { do { char oh_name[MAX_UART_HWMOD_NAME_LEN]; struct omap_hwmod *oh; struct omap_uart_state *uart; + char uart_name[MAX_UART_HWMOD_NAME_LEN]; snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN, "uart%d", num_uarts + 1); @@ -284,18 +293,22 @@ static int __init omap_serial_early_init(void) uart->oh = oh; uart->num = num_uarts++; list_add_tail(&uart->node, &uart_list); - - /* - * NOTE: omap_hwmod_setup*() has not yet been called, - * so no hwmod functions will work yet. - */ - - /* - * During UART early init, device need to be probed - * to determine SoC specific init before omap_device - * is ready. Therefore, don't allow idle here - */ - uart->oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET; + snprintf(uart_name, MAX_UART_HWMOD_NAME_LEN, + "%s%d", OMAP_SERIAL_NAME, uart->num); + + if (cmdline_find_option(uart_name)) { + console_uart_id = uart->num; + /* + * omap-uart can be used for earlyprintk logs + * So if omap-uart is used as console then prevent + * uart reset and idle to get logs from omap-uart + * until uart console driver is available to take + * care for console messages. + * Idling or resetting omap-uart while printing logs + * early boot logs can stall the boot-up. + */ + oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET; + } } while (1); return 0; @@ -379,20 +392,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, oh->dev_attr = uart; - console_lock(); /* in case the earlycon is on the UART */ - - /* - * Because of early UART probing, UART did not get idled - * on init. Now that omap_device is ready, ensure full idle - * before doing omap_device_enable(). - */ - omap_hwmod_idle(uart->oh); - - omap_device_enable(uart->pdev); - omap_device_idle(uart->pdev); - - console_unlock(); - if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) device_init_wakeup(&pdev->dev, true); } -- cgit v1.2.3 From 08f86b3eab9807e6d36de7e00025abad893ff557 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Tue, 18 Oct 2011 17:09:10 +0530 Subject: ARM: OMAP2+: UART: Avoid uart idling on suspend for no_console_suspend usecase If no_console_suspend is used we have prevent uart idling during suspend to provide debug prints. Power domain hooks can idle uarts if left enabled during system wide suspend so re-use the omap_device_disable_idle_on_suspend API's to ensure console_uart is not idled during suspend. omap_device_disable_idle_on_suspend API was used on all uarts since the uart driver was not runtime adapted, now with runtime adaptation we can re-use this API only for no_console_suspend use cases. Signed-off-by: Govindraj.R Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 85516c946ef0..6c8135a9d35d 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -64,6 +64,7 @@ struct omap_uart_state { static LIST_HEAD(uart_list); static u8 num_uarts; static u8 console_uart_id = -1; +static u8 no_console_suspend; #define DEFAULT_RXDMA_POLLRATE 1 /* RX DMA polling rate (us) */ #define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */ @@ -298,6 +299,10 @@ static int __init omap_serial_early_init(void) if (cmdline_find_option(uart_name)) { console_uart_id = uart->num; + + if (cmdline_find_option("no_console_suspend")) + no_console_suspend = true; + /* * omap-uart can be used for earlyprintk logs * So if omap-uart is used as console then prevent @@ -385,7 +390,9 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n", name, oh->name); - omap_device_disable_idle_on_suspend(pdev); + if ((console_uart_id == bdata->id) && no_console_suspend) + omap_device_disable_idle_on_suspend(pdev); + oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); uart->pdev = pdev; -- cgit v1.2.3 From 36fc2d15b120ef85be74c68b5ad74ac04fbefa8a Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Wed, 21 Sep 2011 16:54:12 +0530 Subject: ARM: OMAP2+: UART: Do not gate uart clocks if used for debug_prints If OMAP UART is used as console uart and debug is enabled, avoid gating of uart clocks to print all debug prints. If uart clocks are gated then the debug prints from omap_device framework or hwmod framework can cause uart to enter recursive pm_runtime calls, which can cause a deadlock over power lock usage. For example: Say, uart clocks are cut and we get a print from omap_device_disable stating disabling uart clocks. This print calls omap_uart driver console_write which will call runtime API get_sync which means we enter from runtime API put context to runtime API get context. --> runtime put (take power lock) --> print disabling uart clocks --> call uart console write --> call get_sync (try to take power lock) Also any clock enable API call from uart driver should not call any uart operation until clocks are enabled back. Like get_sync having debug print calling uart console write even before clocks are enabled. So to avoid these scenarios, identify from bootargs if OMAP_UART(ttyO) is used in debug mode. If so, do not set device_may_wakeup. This will prevent pm_runtime_enable in uart driver and will avoid uart clock gating. Debug is enabled either by adding debug word in bootarg or by setting loglevel=10 Signed-off-by: Govindraj.R Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/serial.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 6c8135a9d35d..c909770eacd1 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -65,6 +65,7 @@ static LIST_HEAD(uart_list); static u8 num_uarts; static u8 console_uart_id = -1; static u8 no_console_suspend; +static u8 uart_debug; #define DEFAULT_RXDMA_POLLRATE 1 /* RX DMA polling rate (us) */ #define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */ @@ -300,6 +301,13 @@ static int __init omap_serial_early_init(void) if (cmdline_find_option(uart_name)) { console_uart_id = uart->num; + if (console_loglevel >= 10) { + uart_debug = true; + pr_info("%s used as console in debug mode" + " uart%d clocks will not be" + " gated", uart_name, uart->num); + } + if (cmdline_find_option("no_console_suspend")) no_console_suspend = true; @@ -399,7 +407,8 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, oh->dev_attr = uart; - if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) + if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) + && !uart_debug) device_init_wakeup(&pdev->dev, true); } -- cgit v1.2.3 From 2fd149645eb46d26130d7070c6de037dddf34880 Mon Sep 17 00:00:00 2001 From: "Govindraj.R" Date: Wed, 9 Nov 2011 17:41:21 +0530 Subject: ARM: OMAP2+: UART: Remove omap_uart_can_sleep and add pm_qos Omap_uart_can_sleep function blocks system wide low power state until uart is active remove this func and add qos requests to prevent MPU from transitioning. Keep qos request to default value which will allow MPU to transition and while uart baud rate is available calculate the latency value from the baudrate and use the same to hold constraint while uart clocks are enabled, and if uart is auto-idled the constraint is updated with default constraint value allowing MPU to transition. Qos requests are blocking notifier calls so put these requests to work queue, also the driver uses irq_safe version of runtime API's and callbacks can be called in interrupt disabled context. So to avoid warn on slow path warning while using qos update API's from runtime callbacks use the qos_work_queue. During bootup the runtime_resume call backs might not be called and runtime callback gets called only after uart is idled by setting the autosuspend timeout. So qos_request from runtime resume callback might not activated during boot if uart baudrate is calculated during bootup for console uart, so schedule the qos_work queue once we calc_latency while configuring the uart port. Flush and complete any pending qos jobs in work queue while suspending. Signed-off-by: Govindraj.R Acked-by: Greg Kroah-Hartman (for drivers/tty changes) Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/cpuidle34xx.c | 6 ----- arch/arm/mach-omap2/pm24xx.c | 2 -- arch/arm/mach-omap2/pm34xx.c | 11 -------- arch/arm/mach-omap2/serial.c | 22 ---------------- arch/arm/plat-omap/include/plat/omap-serial.h | 6 +++++ drivers/tty/serial/omap-serial.c | 36 ++++++++++++++++++++++++++- 6 files changed, 41 insertions(+), 42 deletions(-) (limited to 'arch/arm/mach-omap2/serial.c') diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index e20332f4abdc..3a9d2b883b34 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -30,7 +30,6 @@ #include #include "powerdomain.h" #include "clockdomain.h" -#include #include "pm.h" #include "control.h" @@ -245,11 +244,6 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, struct omap3_idle_statedata *cx; int ret; - if (!omap3_can_sleep()) { - new_state_idx = drv->safe_state_index; - goto select_state; - } - /* * Prevent idle completely if CAM is active. * CAM does not have wakeup capability in OMAP3. diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 22af2f2fdbf9..b8822f8b2891 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -222,8 +222,6 @@ static int omap2_can_sleep(void) { if (omap2_fclks_active()) return 0; - if (!omap_uart_can_sleep()) - return 0; if (osc_ck->usecount > 1) return 0; if (omap_dma_running()) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 4feee45ef069..4ee5f4eb04e4 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -35,7 +35,6 @@ #include #include "clockdomain.h" #include "powerdomain.h" -#include #include #include #include @@ -456,21 +455,11 @@ void omap_sram_idle(void) clkdm_allow_idle(mpu_pwrdm->pwrdm_clkdms[0]); } -int omap3_can_sleep(void) -{ - if (!omap_uart_can_sleep()) - return 0; - return 1; -} - static void omap3_pm_idle(void) { local_irq_disable(); local_fiq_disable(); - if (!omap3_can_sleep()) - goto out; - if (omap_irq_pending() || need_resched()) goto out; diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index c909770eacd1..247d89478f24 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -82,28 +82,6 @@ static struct omap_uart_port_info omap_serial_default_info[] __initdata = { }; #ifdef CONFIG_PM - -int omap_uart_can_sleep(void) -{ - struct omap_uart_state *uart; - int can_sleep = 1; - - list_for_each_entry(uart, &uart_list, node) { - if (!uart->clocked) - continue; - - if (!uart->can_sleep) { - can_sleep = 0; - continue; - } - - /* This UART can now safely sleep. */ - omap_uart_allow_sleep(uart); - } - - return can_sleep; -} - static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable) { struct omap_device *od = to_omap_device(pdev); diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h index ea63b2bc761c..9ff444469f3d 100644 --- a/arch/arm/plat-omap/include/plat/omap-serial.h +++ b/arch/arm/plat-omap/include/plat/omap-serial.h @@ -19,6 +19,7 @@ #include #include +#include #include @@ -130,6 +131,11 @@ struct uart_omap_port { u32 context_loss_cnt; u32 errata; u8 wakeups_enabled; + + struct pm_qos_request pm_qos_request; + u32 latency; + u32 calc_latency; + struct work_struct qos_work; }; #endif /* __OMAP_SERIAL_H__ */ diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index e1eaa66c047b..f3ff0ca377c5 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -51,6 +51,8 @@ static void serial_omap_rxdma_poll(unsigned long uart_no); static int serial_omap_start_rxdma(struct uart_omap_port *up); static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1); +static struct workqueue_struct *serial_omap_uart_wq; + static inline unsigned int serial_in(struct uart_omap_port *up, int offset) { offset <<= up->port.regshift; @@ -671,6 +673,14 @@ serial_omap_configure_xonxoff serial_out(up, UART_LCR, up->lcr); } +static void serial_omap_uart_qos_work(struct work_struct *work) +{ + struct uart_omap_port *up = container_of(work, struct uart_omap_port, + qos_work); + + pm_qos_update_request(&up->pm_qos_request, up->latency); +} + static void serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) @@ -711,6 +721,12 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/13); quot = serial_omap_get_divisor(port, baud); + /* calculate wakeup latency constraint */ + up->calc_latency = (1000000 * up->port.fifosize) / + (1000 * baud / 8); + up->latency = up->calc_latency; + schedule_work(&up->qos_work); + up->dll = quot & 0xff; up->dlh = quot >> 8; up->mdr1 = UART_OMAP_MDR1_DISABLE; @@ -1145,8 +1161,11 @@ static int serial_omap_suspend(struct device *dev) { struct uart_omap_port *up = dev_get_drvdata(dev); - if (up) + if (up) { uart_suspend_port(&serial_omap_reg, &up->port); + flush_work_sync(&up->qos_work); + } + return 0; } @@ -1383,6 +1402,13 @@ static int serial_omap_probe(struct platform_device *pdev) up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; } + up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; + up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; + pm_qos_add_request(&up->pm_qos_request, + PM_QOS_CPU_DMA_LATENCY, up->latency); + serial_omap_uart_wq = create_singlethread_workqueue(up->name); + INIT_WORK(&up->qos_work, serial_omap_uart_qos_work); + pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, omap_up_info->autosuspend_timeout); @@ -1416,6 +1442,8 @@ static int serial_omap_remove(struct platform_device *dev) if (up) { pm_runtime_disable(&up->pdev->dev); uart_remove_one_port(&serial_omap_reg, &up->port); + pm_qos_remove_request(&up->pm_qos_request); + kfree(up); } @@ -1518,6 +1546,9 @@ static int serial_omap_runtime_suspend(struct device *dev) (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) pdata->set_forceidle(up->pdev); + up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; + schedule_work(&up->qos_work); + return 0; } @@ -1538,6 +1569,9 @@ static int serial_omap_runtime_resume(struct device *dev) if (up->use_dma && pdata->set_noidle && (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) pdata->set_noidle(up->pdev); + + up->latency = up->calc_latency; + schedule_work(&up->qos_work); } return 0; -- cgit v1.2.3