Re: [PATCH 1/1] Added sleep support to UART
* Tony Lindgren [EMAIL PROTECTED] [080609 22:11]: Hi, Sorry for the delay on looking at this, it's looking pretty good in general. Few more mostly cosmetic comments below. Here's one more comment: --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c if (omap2_pm_debug) { unsigned long long tmp; - u32 resume_time; + s64 resume_time; + struct timespec t; - resume_time = omap2_read_32k_sync_counter(); + getnstimeofday(t); + resume_time = timespec_to_ns(t); tmp = resume_time - sleep_time; - tmp *= 100; - omap2_pm_dump(0, 1, tmp / 32768); + omap2_pm_dump(0, 1, tmp / 1000); } You should make all these calculations using timespec_sub(): struct timespec ts1, ts2, ts_delta; getnstimeofday(ts1); getnstimeofday(ts2); ts_delta = timespec_sub(ts2, ts1); Regards, Tony -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 1/1] Added sleep support to UART
Hi, I'll resend the patch in the following email. Comments below what has been changed. -Original Message- From: ext Tony Lindgren [mailto:[EMAIL PROTECTED] Sent: 10 June, 2008 09:06 To: Kristo Tero (Nokia-D/Tampere) Cc: linux-omap@vger.kernel.org Subject: Re: [PATCH 1/1] Added sleep support to UART * Tony Lindgren [EMAIL PROTECTED] [080609 22:11]: Hi, Sorry for the delay on looking at this, it's looking pretty good in general. Few more mostly cosmetic comments below. Here's one more comment: --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c if (omap2_pm_debug) { unsigned long long tmp; - u32 resume_time; + s64 resume_time; + struct timespec t; - resume_time = omap2_read_32k_sync_counter(); + getnstimeofday(t); + resume_time = timespec_to_ns(t); tmp = resume_time - sleep_time; - tmp *= 100; - omap2_pm_dump(0, 1, tmp / 32768); + omap2_pm_dump(0, 1, tmp / 1000); } You should make all these calculations using timespec_sub(): struct timespec ts1, ts2, ts_delta; getnstimeofday(ts1); getnstimeofday(ts2); ts_delta = timespec_sub(ts2, ts1); Fixed this in several places now to use timespec_sub, timespec_add and timespec_compare. copy-paste from another email +#if defined(CONFIG_ARCH_OMAP2) +static const u32 omap_uart_fclk_mask[OMAP_MAX_NR_PORTS] = { +OMAP24XX_EN_UART1, OMAP24XX_EN_UART2, OMAP24XX_EN_UART3 }; #endif + +#if defined(CONFIG_ARCH_OMAP3) +static const u32 omap_uart_fclk_mask[OMAP_MAX_NR_PORTS] = { +OMAP3430_EN_UART1, OMAP3430_EN_UART2, OMAP3430_EN_UART3 }; The above should be omap24xx_uart_fclk_mask and omap34xx_uart_fclk_mask. Otherwise we cannot compile in both 24xx and 34xx into the same kernel. Changed. Added omap_uart_fclk_mask to point to these structures though, initialized at boot time. Also removed those #ifdef:s from the code. +/* UART padconfig registers, these may differ if non-default padconfig + is used */ +#define CONTROL_PADCONF_UART1_RX 0x48002182 #define +CONTROL_PADCONF_UART2_RX 0x4800217A #define CONTROL_PADCONF_UART3_RX +0x4800219E #define PADCONF_WAKEUP_ST 0x8000 + +static const u32 omap_uart_padconf[OMAP_MAX_NR_PORTS] = { +CONTROL_PADCONF_UART1_RX, CONTROL_PADCONF_UART2_RX, +CONTROL_PADCONF_UART3_RX }; #endif This should be omap34xx_uart_padconf is only used for 34xx. Also, it's currently not defined for 24xx and breaks build. Changed. +void omap_serial_check_wakeup(void) +{ +int i; + +if (cpu_is_omap34xx()) +for (i = 0; i OMAP_MAX_NR_PORTS; i++) { +if (!uart_ick[i]) +continue; +if (omap_readw(omap_uart_padconf[i]) PADCONF_WAKEUP_ST) +omap_serial_kick(); +return; +} The formatting for return above looks one tab too much to the right? This is actually a hidden bug, that return should be part of that if statement. Luckily enough the code worked if you had only one UART enabled in configs. Added braces around that stuff now. +if (cpu_is_omap24xx()) { +u32 l; + +for (i = 0; i OMAP_MAX_NR_PORTS; i++) { +if (!uart_ick[i]) +continue; +l = prm_read_mod_reg(CORE_MOD, omap2_uart_wk_st[i]); +if (l omap2_uart_wk_bit[i]) +omap_serial_kick(); +return; +} +} +} Here too. Similar bug. + +if (cpu_is_omap24xx()) +prm_set_mod_reg_bits(omap2_uart_wk_bit[i], CORE_MOD, +omap2_uart_wk_en[i]); } How about run the patch through checkpatch.pl, this line looks too long? Ok, split the code lines that caused warnings now to be multiline statements. -Tero -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/1] Added sleep support to UART
Hi, Sorry for the delay on looking at this, it's looking pretty good in general. Few more mostly cosmetic comments below. * Tero Kristo [EMAIL PROTECTED] [080603 01:53]: UART usage (e.g. serial console) now denies sleep for 5 seconds. This makes it possible to use serial console when dynamic idle is enabled. Also moved code from pm-debug.c to serial.c, and made pm24xx.c use this new implementation. Signed-off-by: Tero Kristo [EMAIL PROTECTED] --- arch/arm/mach-omap2/pm-debug.c | 132 arch/arm/mach-omap2/pm.h |8 -- arch/arm/mach-omap2/pm24xx.c | 53 ++- arch/arm/mach-omap2/pm34xx.c |5 ++ arch/arm/mach-omap2/serial.c | 118 include/asm-arm/arch-omap/common.h |3 + 6 files changed, 162 insertions(+), 157 deletions(-) snip diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index b0fa582..65571f9 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -23,8 +23,47 @@ #include asm/arch/common.h #include asm/arch/board.h +#include prm.h +#include pm.h + +#define SERIAL_AWAKE_TIME 5 + static struct clk *uart_ick[OMAP_MAX_NR_PORTS]; static struct clk *uart_fck[OMAP_MAX_NR_PORTS]; +static s64 omap_serial_next_sleep; + +static const u32 omap2_uart_wk_st[OMAP_MAX_NR_PORTS] = { + PM_WKST1, PM_WKST1, OMAP24XX_PM_WKST2 +}; +static const u32 omap2_uart_wk_en[OMAP_MAX_NR_PORTS] = { + PM_WKEN1, PM_WKEN1, OMAP24XX_PM_WKEN2 +}; +const u32 omap2_uart_wk_bit[OMAP_MAX_NR_PORTS] = { + OMAP24XX_ST_UART1, OMAP24XX_ST_UART2, OMAP24XX_ST_UART3 +}; + +#if defined(CONFIG_ARCH_OMAP2) +static const u32 omap_uart_fclk_mask[OMAP_MAX_NR_PORTS] = { + OMAP24XX_EN_UART1, OMAP24XX_EN_UART2, OMAP24XX_EN_UART3 +}; +#endif + +#if defined(CONFIG_ARCH_OMAP3) +static const u32 omap_uart_fclk_mask[OMAP_MAX_NR_PORTS] = { + OMAP3430_EN_UART1, OMAP3430_EN_UART2, OMAP3430_EN_UART3 +}; The above should be omap24xx_uart_fclk_mask and omap34xx_uart_fclk_mask. Otherwise we cannot compile in both 24xx and 34xx into the same kernel. +/* UART padconfig registers, these may differ if non-default padconfig + is used */ +#define CONTROL_PADCONF_UART1_RX 0x48002182 +#define CONTROL_PADCONF_UART2_RX 0x4800217A +#define CONTROL_PADCONF_UART3_RX 0x4800219E +#define PADCONF_WAKEUP_ST 0x8000 + +static const u32 omap_uart_padconf[OMAP_MAX_NR_PORTS] = { + CONTROL_PADCONF_UART1_RX, CONTROL_PADCONF_UART2_RX, CONTROL_PADCONF_UART3_RX +}; +#endif This should be omap34xx_uart_padconf is only used for 34xx. Also, it's currently not defined for 24xx and breaks build. static struct plat_serial8250_port serial_platform_data[] = { { @@ -83,6 +122,15 @@ static inline void __init omap_serial_reset(struct plat_serial8250_port *p) serial_write_reg(p, UART_OMAP_SYSC, (0x02 3) | (1 2) | (1 0)); } +static void omap_serial_kick(void) +{ + struct timespec t; + + getnstimeofday(t); + omap_serial_next_sleep = timespec_to_ns(t) + + (s64)SERIAL_AWAKE_TIME * (s64)10; +} + void omap_serial_enable_clocks(int enable) { int i; @@ -99,6 +147,71 @@ void omap_serial_enable_clocks(int enable) } } +void omap_serial_fclk_mask(u32 *f1, u32 *f2) +{ + if (uart_ick[0]) + *f1 = ~omap_uart_fclk_mask[0]; + if (uart_ick[1]) + *f1 = ~omap_uart_fclk_mask[1]; + if (uart_ick[2]) + *f2 = ~omap_uart_fclk_mask[2]; +} + +void omap_serial_check_wakeup(void) +{ + int i; + + if (cpu_is_omap34xx()) + for (i = 0; i OMAP_MAX_NR_PORTS; i++) { + if (!uart_ick[i]) + continue; + if (omap_readw(omap_uart_padconf[i]) PADCONF_WAKEUP_ST) + omap_serial_kick(); + return; + } The formatting for return above looks one tab too much to the right? + if (cpu_is_omap24xx()) { + u32 l; + + for (i = 0; i OMAP_MAX_NR_PORTS; i++) { + if (!uart_ick[i]) + continue; + l = prm_read_mod_reg(CORE_MOD, omap2_uart_wk_st[i]); + if (l omap2_uart_wk_bit[i]) + omap_serial_kick(); + return; + } + } +} Here too. +int omap_serial_can_sleep(void) +{ + s64 cnt; + int i; + struct timespec t; + + struct plat_serial8250_port *p = serial_platform_data; + + getnstimeofday(t); + cnt = timespec_to_ns(t); + + for (i = 0; i OMAP_MAX_NR_PORTS; i++) { + if (!uart_ick[i]) + continue; + /* Check if we have data in the transmit buffer */ + if ((serial_read_reg(p + i,
RE: [PATCH 1/1] Added sleep support to UART
Hi, This patch currently depends on at least one of the PM workaround patches from Jouni Hogander. Namely this one: [PATCH 07/10] 34XX: PM: Workaround to check whether any fck is active before entering sleep Sorry I think I forgot to mention this in the patch note. Should we change the patch in order to make this one apply cleanly (I could make a separate patch for the UART fclk hack which depends on the above?) -Tero -Original Message- From: ext Tony Lindgren [mailto:[EMAIL PROTECTED] Sent: 31 May, 2008 02:02 To: Kristo Tero (Nokia-D/Tampere) Cc: linux-omap@vger.kernel.org Subject: Re: [PATCH 1/1] Added sleep support to UART Hi, * Tero Kristo [EMAIL PROTECTED] [080529 06:07]: UART usage (e.g. serial console) now denies sleep for 5 seconds. This makes it possible to use serial console when dynamic idle is enabled. Also moved code from pm-debug.c to serial.c, and made pm24xx.c use this new implementation. The changes for pm34xx.c don't currently apply, can you please refresh this patch? Thanks, Tony Signed-off-by: Tero Kristo [EMAIL PROTECTED] --- arch/arm/mach-omap2/pm-debug.c | 132 arch/arm/mach-omap2/pm.h |8 -- arch/arm/mach-omap2/pm24xx.c | 53 ++- arch/arm/mach-omap2/pm34xx.c |8 ++- arch/arm/mach-omap2/serial.c | 118 include/asm-arm/arch-omap/common.h |3 + 6 files changed, 163 insertions(+), 159 deletions(-) diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 8a9f3c4..c20fa3b 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -34,138 +34,6 @@ #ifdef CONFIG_PM_DEBUG int omap2_pm_debug = 0; -static int serial_console_clock_disabled; -static int serial_console_uart; -static unsigned int serial_console_next_disable; - -static struct clk *console_iclk, *console_fclk; - -static void serial_console_kick(void) -{ -serial_console_next_disable = omap2_read_32k_sync_counter(); -/* Keep the clocks on for 4 secs */ -serial_console_next_disable += 4 * 32768; -} - -static void serial_wait_tx(void) -{ -static const unsigned long uart_bases[3] = { -0x4806a000, 0x4806c000, 0x4806e000 -}; -unsigned long lsr_reg; -int looped = 0; - -/* Wait for TX FIFO and THR to get empty */ -lsr_reg = IO_ADDRESS(uart_bases[serial_console_uart - 1] + (5 2)); -while ((__raw_readb(lsr_reg) 0x60) != 0x60) -looped = 1; -if (looped) -serial_console_kick(); -} - -u32 omap2_read_32k_sync_counter(void) -{ -return omap_readl(OMAP2_32KSYNCT_BASE + 0x0010); -} - -void serial_console_fclk_mask(u32 *f1, u32 *f2) -{ -switch (serial_console_uart) { -case 1: -*f1 = ~(1 21); -break; -case 2: -*f1 = ~(1 22); -break; -case 3: -*f2 = ~(1 2); -break; -} -} - -void serial_console_sleep(int enable) -{ -if (console_iclk == NULL || console_fclk == NULL) -return; - -if (enable) { -BUG_ON(serial_console_clock_disabled); -if (clk_get_usecount(console_fclk) == 0) -return; -if ((int) serial_console_next_disable - (int) omap2_read_32k_sync_counter() = 0) -return; -serial_wait_tx(); -clk_disable(console_iclk); -clk_disable(console_fclk); -serial_console_clock_disabled = 1; -} else { -int serial_wakeup = 0; -u32 l; - -switch (serial_console_uart) { -case 1: -l = prm_read_mod_reg(CORE_MOD, PM_WKST1); -if (l OMAP24XX_ST_UART1) -serial_wakeup = 1; -break; -case 2: -l = prm_read_mod_reg(CORE_MOD, PM_WKST1); -if (l OMAP24XX_ST_UART2) -serial_wakeup = 1; -break; -case 3: -l = prm_read_mod_reg(CORE_MOD, OMAP24XX_PM_WKST2); -if (l OMAP24XX_ST_UART3) -serial_wakeup = 1; -break; -} -if (serial_wakeup) -serial_console_kick(); -if (!serial_console_clock_disabled) -return; -clk_enable(console_iclk); -clk_enable(console_fclk); -serial_console_clock_disabled = 0; -} -} - -void pm_init_serial_console(void) -{ -const struct omap_serial_console_config *conf; -char name[16]; - -conf = omap_get_config(OMAP_TAG_SERIAL_CONSOLE, - struct omap_serial_console_config); -if (conf == NULL) -return; -if (conf
Re: [PATCH 1/1] Added sleep support to UART
* [EMAIL PROTECTED] [EMAIL PROTECTED] [080602 01:09]: Hi, This patch currently depends on at least one of the PM workaround patches from Jouni Hogander. Namely this one: [PATCH 07/10] 34XX: PM: Workaround to check whether any fck is active before entering sleep Sorry I think I forgot to mention this in the patch note. Should we change the patch in order to make this one apply cleanly (I could make a separate patch for the UART fclk hack which depends on the above?) Yeah that would be great. Tony -Tero -Original Message- From: ext Tony Lindgren [mailto:[EMAIL PROTECTED] Sent: 31 May, 2008 02:02 To: Kristo Tero (Nokia-D/Tampere) Cc: linux-omap@vger.kernel.org Subject: Re: [PATCH 1/1] Added sleep support to UART Hi, * Tero Kristo [EMAIL PROTECTED] [080529 06:07]: UART usage (e.g. serial console) now denies sleep for 5 seconds. This makes it possible to use serial console when dynamic idle is enabled. Also moved code from pm-debug.c to serial.c, and made pm24xx.c use this new implementation. The changes for pm34xx.c don't currently apply, can you please refresh this patch? Thanks, Tony Signed-off-by: Tero Kristo [EMAIL PROTECTED] --- arch/arm/mach-omap2/pm-debug.c | 132 arch/arm/mach-omap2/pm.h |8 -- arch/arm/mach-omap2/pm24xx.c | 53 ++- arch/arm/mach-omap2/pm34xx.c |8 ++- arch/arm/mach-omap2/serial.c | 118 include/asm-arm/arch-omap/common.h |3 + 6 files changed, 163 insertions(+), 159 deletions(-) diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 8a9f3c4..c20fa3b 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -34,138 +34,6 @@ #ifdef CONFIG_PM_DEBUG int omap2_pm_debug = 0; -static int serial_console_clock_disabled; -static int serial_console_uart; -static unsigned int serial_console_next_disable; - -static struct clk *console_iclk, *console_fclk; - -static void serial_console_kick(void) -{ - serial_console_next_disable = omap2_read_32k_sync_counter(); - /* Keep the clocks on for 4 secs */ - serial_console_next_disable += 4 * 32768; -} - -static void serial_wait_tx(void) -{ - static const unsigned long uart_bases[3] = { - 0x4806a000, 0x4806c000, 0x4806e000 - }; - unsigned long lsr_reg; - int looped = 0; - - /* Wait for TX FIFO and THR to get empty */ - lsr_reg = IO_ADDRESS(uart_bases[serial_console_uart - 1] + (5 2)); - while ((__raw_readb(lsr_reg) 0x60) != 0x60) - looped = 1; - if (looped) - serial_console_kick(); -} - -u32 omap2_read_32k_sync_counter(void) -{ -return omap_readl(OMAP2_32KSYNCT_BASE + 0x0010); -} - -void serial_console_fclk_mask(u32 *f1, u32 *f2) -{ - switch (serial_console_uart) { - case 1: - *f1 = ~(1 21); - break; - case 2: - *f1 = ~(1 22); - break; - case 3: - *f2 = ~(1 2); - break; - } -} - -void serial_console_sleep(int enable) -{ - if (console_iclk == NULL || console_fclk == NULL) - return; - - if (enable) { - BUG_ON(serial_console_clock_disabled); - if (clk_get_usecount(console_fclk) == 0) - return; - if ((int) serial_console_next_disable - (int) omap2_read_32k_sync_counter() = 0) - return; - serial_wait_tx(); - clk_disable(console_iclk); - clk_disable(console_fclk); - serial_console_clock_disabled = 1; - } else { - int serial_wakeup = 0; - u32 l; - - switch (serial_console_uart) { - case 1: - l = prm_read_mod_reg(CORE_MOD, PM_WKST1); - if (l OMAP24XX_ST_UART1) - serial_wakeup = 1; - break; - case 2: - l = prm_read_mod_reg(CORE_MOD, PM_WKST1); - if (l OMAP24XX_ST_UART2) - serial_wakeup = 1; - break; - case 3: - l = prm_read_mod_reg(CORE_MOD, OMAP24XX_PM_WKST2); - if (l OMAP24XX_ST_UART3) - serial_wakeup = 1; - break; - } - if (serial_wakeup) - serial_console_kick(); - if (!serial_console_clock_disabled) - return; - clk_enable(console_iclk); - clk_enable(console_fclk); - serial_console_clock_disabled = 0; - } -} - -void pm_init_serial_console(void) -{ - const struct omap_serial_console_config *conf; - char name[16]; - - conf = omap_get_config(OMAP_TAG_SERIAL_CONSOLE
Re: [PATCH 1/1] Added sleep support to UART
Hi, * Tero Kristo [EMAIL PROTECTED] [080529 06:07]: UART usage (e.g. serial console) now denies sleep for 5 seconds. This makes it possible to use serial console when dynamic idle is enabled. Also moved code from pm-debug.c to serial.c, and made pm24xx.c use this new implementation. The changes for pm34xx.c don't currently apply, can you please refresh this patch? Thanks, Tony Signed-off-by: Tero Kristo [EMAIL PROTECTED] --- arch/arm/mach-omap2/pm-debug.c | 132 arch/arm/mach-omap2/pm.h |8 -- arch/arm/mach-omap2/pm24xx.c | 53 ++- arch/arm/mach-omap2/pm34xx.c |8 ++- arch/arm/mach-omap2/serial.c | 118 include/asm-arm/arch-omap/common.h |3 + 6 files changed, 163 insertions(+), 159 deletions(-) diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 8a9f3c4..c20fa3b 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -34,138 +34,6 @@ #ifdef CONFIG_PM_DEBUG int omap2_pm_debug = 0; -static int serial_console_clock_disabled; -static int serial_console_uart; -static unsigned int serial_console_next_disable; - -static struct clk *console_iclk, *console_fclk; - -static void serial_console_kick(void) -{ - serial_console_next_disable = omap2_read_32k_sync_counter(); - /* Keep the clocks on for 4 secs */ - serial_console_next_disable += 4 * 32768; -} - -static void serial_wait_tx(void) -{ - static const unsigned long uart_bases[3] = { - 0x4806a000, 0x4806c000, 0x4806e000 - }; - unsigned long lsr_reg; - int looped = 0; - - /* Wait for TX FIFO and THR to get empty */ - lsr_reg = IO_ADDRESS(uart_bases[serial_console_uart - 1] + (5 2)); - while ((__raw_readb(lsr_reg) 0x60) != 0x60) - looped = 1; - if (looped) - serial_console_kick(); -} - -u32 omap2_read_32k_sync_counter(void) -{ -return omap_readl(OMAP2_32KSYNCT_BASE + 0x0010); -} - -void serial_console_fclk_mask(u32 *f1, u32 *f2) -{ - switch (serial_console_uart) { - case 1: - *f1 = ~(1 21); - break; - case 2: - *f1 = ~(1 22); - break; - case 3: - *f2 = ~(1 2); - break; - } -} - -void serial_console_sleep(int enable) -{ - if (console_iclk == NULL || console_fclk == NULL) - return; - - if (enable) { - BUG_ON(serial_console_clock_disabled); - if (clk_get_usecount(console_fclk) == 0) - return; - if ((int) serial_console_next_disable - (int) omap2_read_32k_sync_counter() = 0) - return; - serial_wait_tx(); - clk_disable(console_iclk); - clk_disable(console_fclk); - serial_console_clock_disabled = 1; - } else { - int serial_wakeup = 0; - u32 l; - - switch (serial_console_uart) { - case 1: - l = prm_read_mod_reg(CORE_MOD, PM_WKST1); - if (l OMAP24XX_ST_UART1) - serial_wakeup = 1; - break; - case 2: - l = prm_read_mod_reg(CORE_MOD, PM_WKST1); - if (l OMAP24XX_ST_UART2) - serial_wakeup = 1; - break; - case 3: - l = prm_read_mod_reg(CORE_MOD, OMAP24XX_PM_WKST2); - if (l OMAP24XX_ST_UART3) - serial_wakeup = 1; - break; - } - if (serial_wakeup) - serial_console_kick(); - if (!serial_console_clock_disabled) - return; - clk_enable(console_iclk); - clk_enable(console_fclk); - serial_console_clock_disabled = 0; - } -} - -void pm_init_serial_console(void) -{ - const struct omap_serial_console_config *conf; - char name[16]; - - conf = omap_get_config(OMAP_TAG_SERIAL_CONSOLE, -struct omap_serial_console_config); - if (conf == NULL) - return; - if (conf-console_uart 3 || conf-console_uart 1) - return; - serial_console_uart = conf-console_uart; - sprintf(name, uart%d_fck, conf-console_uart); - console_fclk = clk_get(NULL, name); - if (IS_ERR(console_fclk)) - console_fclk = NULL; - name[6] = 'i'; - console_iclk = clk_get(NULL, name); - if (IS_ERR(console_fclk)) - console_iclk = NULL; - if (console_fclk == NULL || console_iclk == NULL) { - serial_console_uart = 0; - return; - } - switch (serial_console_uart) {
[PATCH 1/1] Added sleep support to UART
UART usage (e.g. serial console) now denies sleep for 5 seconds. This makes it possible to use serial console when dynamic idle is enabled. Also moved code from pm-debug.c to serial.c, and made pm24xx.c use this new implementation. Signed-off-by: Tero Kristo [EMAIL PROTECTED] --- arch/arm/mach-omap2/pm-debug.c | 132 arch/arm/mach-omap2/pm.h |8 -- arch/arm/mach-omap2/pm24xx.c | 53 ++- arch/arm/mach-omap2/pm34xx.c |8 ++- arch/arm/mach-omap2/serial.c | 118 include/asm-arm/arch-omap/common.h |3 + 6 files changed, 163 insertions(+), 159 deletions(-) diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 8a9f3c4..c20fa3b 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -34,138 +34,6 @@ #ifdef CONFIG_PM_DEBUG int omap2_pm_debug = 0; -static int serial_console_clock_disabled; -static int serial_console_uart; -static unsigned int serial_console_next_disable; - -static struct clk *console_iclk, *console_fclk; - -static void serial_console_kick(void) -{ - serial_console_next_disable = omap2_read_32k_sync_counter(); - /* Keep the clocks on for 4 secs */ - serial_console_next_disable += 4 * 32768; -} - -static void serial_wait_tx(void) -{ - static const unsigned long uart_bases[3] = { - 0x4806a000, 0x4806c000, 0x4806e000 - }; - unsigned long lsr_reg; - int looped = 0; - - /* Wait for TX FIFO and THR to get empty */ - lsr_reg = IO_ADDRESS(uart_bases[serial_console_uart - 1] + (5 2)); - while ((__raw_readb(lsr_reg) 0x60) != 0x60) - looped = 1; - if (looped) - serial_console_kick(); -} - -u32 omap2_read_32k_sync_counter(void) -{ -return omap_readl(OMAP2_32KSYNCT_BASE + 0x0010); -} - -void serial_console_fclk_mask(u32 *f1, u32 *f2) -{ - switch (serial_console_uart) { - case 1: - *f1 = ~(1 21); - break; - case 2: - *f1 = ~(1 22); - break; - case 3: - *f2 = ~(1 2); - break; - } -} - -void serial_console_sleep(int enable) -{ - if (console_iclk == NULL || console_fclk == NULL) - return; - - if (enable) { - BUG_ON(serial_console_clock_disabled); - if (clk_get_usecount(console_fclk) == 0) - return; - if ((int) serial_console_next_disable - (int) omap2_read_32k_sync_counter() = 0) - return; - serial_wait_tx(); - clk_disable(console_iclk); - clk_disable(console_fclk); - serial_console_clock_disabled = 1; - } else { - int serial_wakeup = 0; - u32 l; - - switch (serial_console_uart) { - case 1: - l = prm_read_mod_reg(CORE_MOD, PM_WKST1); - if (l OMAP24XX_ST_UART1) - serial_wakeup = 1; - break; - case 2: - l = prm_read_mod_reg(CORE_MOD, PM_WKST1); - if (l OMAP24XX_ST_UART2) - serial_wakeup = 1; - break; - case 3: - l = prm_read_mod_reg(CORE_MOD, OMAP24XX_PM_WKST2); - if (l OMAP24XX_ST_UART3) - serial_wakeup = 1; - break; - } - if (serial_wakeup) - serial_console_kick(); - if (!serial_console_clock_disabled) - return; - clk_enable(console_iclk); - clk_enable(console_fclk); - serial_console_clock_disabled = 0; - } -} - -void pm_init_serial_console(void) -{ - const struct omap_serial_console_config *conf; - char name[16]; - - conf = omap_get_config(OMAP_TAG_SERIAL_CONSOLE, - struct omap_serial_console_config); - if (conf == NULL) - return; - if (conf-console_uart 3 || conf-console_uart 1) - return; - serial_console_uart = conf-console_uart; - sprintf(name, uart%d_fck, conf-console_uart); - console_fclk = clk_get(NULL, name); - if (IS_ERR(console_fclk)) - console_fclk = NULL; - name[6] = 'i'; - console_iclk = clk_get(NULL, name); - if (IS_ERR(console_fclk)) - console_iclk = NULL; - if (console_fclk == NULL || console_iclk == NULL) { - serial_console_uart = 0; - return; - } - switch (serial_console_uart) { - case 1: - prm_set_mod_reg_bits(OMAP24XX_ST_UART1, CORE_MOD, PM_WKEN1); - break; -