From: Kevin Hilman <khilman@deeprootsystems.com>
To: linux-omap@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 3/3] OMAP: UART: use atomic idle notifiers
Date: Wed, 20 Oct 2010 16:31:23 -0700 [thread overview]
Message-ID: <1287617483-24170-3-git-send-email-khilman@deeprootsystems.com> (raw)
In-Reply-To: <1287617483-24170-1-git-send-email-khilman@deeprootsystems.com>
Convert UART idle management routines from custom hooks in the core
idle path to use new idle notifiers.
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
arch/arm/mach-omap2/pm24xx.c | 9 +---
arch/arm/mach-omap2/pm34xx.c | 8 ---
arch/arm/mach-omap2/serial.c | 71 +++++++++++++++++++----------
arch/arm/plat-omap/include/plat/serial.h | 2 -
4 files changed, 47 insertions(+), 43 deletions(-)
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index cb1b333..47644d2 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -40,6 +40,7 @@
#include <plat/sram.h>
#include <plat/dma.h>
#include <plat/board.h>
+#include <plat/common.h>
#include "prm.h"
#include "prm-regbits-24xx.h"
@@ -120,19 +121,11 @@ static void omap2_enter_full_retention(void)
if (omap_irq_pending())
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);
-
no_sleep:
if (omap2_pm_debug) {
unsigned long long tmp;
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 4674748..eaed95d 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -390,8 +390,6 @@ void omap_sram_idle(void)
/* PER */
if (per_next_state < PWRDM_POWER_ON) {
- omap_uart_prepare_idle(2);
- omap_uart_prepare_idle(3);
omap2_gpio_prepare_for_idle(per_next_state);
if (per_next_state == PWRDM_POWER_OFF)
omap3_per_save_context();
@@ -399,8 +397,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_prcm_save_context();
@@ -445,8 +441,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)
prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK,
OMAP3430_GR_MOD,
@@ -459,8 +453,6 @@ 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);
}
/* Disable IO-PAD and IO-CHAIN wakeup */
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index becf0e3..8a619ff 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -73,6 +73,7 @@ struct omap_uart_state {
u32 padconf;
u32 dma_enabled;
+ struct powerdomain *pwrdm;
struct clk *ick;
struct clk *fck;
int clocked;
@@ -389,39 +390,31 @@ static void omap_uart_idle_timer(unsigned long data)
omap_uart_allow_sleep(uart);
}
-void omap_uart_prepare_idle(int num)
+static void omap_uart_prepare_idle(struct omap_uart_state *uart)
{
- 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;
- }
- }
+ if (uart->can_sleep &&
+ pwrdm_read_next_pwrst(uart->pwrdm) < PWRDM_POWER_ON)
+ omap_uart_disable_clocks(uart);
}
-void omap_uart_resume_idle(int num)
+static void omap_uart_resume_idle(struct omap_uart_state *uart)
{
- struct omap_uart_state *uart;
+ if (uart->can_sleep &&
+ pwrdm_read_next_pwrst(uart->pwrdm) < PWRDM_POWER_ON) {
+ omap_uart_enable_clocks(uart);
- list_for_each_entry(uart, &uart_list, node) {
- if (num == uart->num) {
- 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 IO pad wakeup */
+ if (cpu_is_omap34xx() && uart->padconf) {
+ u16 p = omap_ctrl_readw(uart->padconf);
- /* Check for normal UART wakeup */
- if (__raw_readl(uart->wk_st) & uart->wk_mask)
+ if (p & OMAP3_PADCONF_WAKEUPEVENT0)
omap_uart_block_sleep(uart);
- return;
}
+
+ /* Check for normal UART wakeup */
+ if (__raw_readl(uart->wk_st) & uart->wk_mask)
+ omap_uart_block_sleep(uart);
+ return;
}
}
@@ -474,6 +467,27 @@ static irqreturn_t omap_uart_interrupt(int irq, void *dev_id)
return IRQ_NONE;
}
+static int omap_uart_idle_notifier(struct notifier_block *n,
+ unsigned long val,
+ void *p)
+{
+ struct omap_uart_state *uart;
+
+ if (val == OMAP_IDLE_START)
+ list_for_each_entry(uart, &uart_list, node)
+ omap_uart_prepare_idle(uart);
+ else
+ list_for_each_entry(uart, &uart_list, node)
+ omap_uart_resume_idle(uart);
+
+ return 0;
+}
+
+static bool omap_uart_notifier_enabled;
+static struct notifier_block omap_uart_notifier = {
+ .notifier_call = omap_uart_idle_notifier,
+};
+
static void omap_uart_idle_init(struct omap_uart_state *uart)
{
int ret;
@@ -549,6 +563,11 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
ret = request_threaded_irq(uart->irq, NULL, omap_uart_interrupt,
IRQF_SHARED, "serial idle", (void *)uart);
WARN_ON(ret);
+
+ if (!omap_uart_notifier_enabled) {
+ omap_idle_notifier_register(&omap_uart_notifier);
+ omap_uart_notifier_enabled = true;
+ }
}
void omap_uart_enable_irqs(int enable)
@@ -731,6 +750,8 @@ void __init omap_serial_init_port(int port)
break;
oh = uart->oh;
+ uart->pwrdm = omap_hwmod_get_pwrdm(oh);
+ WARN_ON(!uart->pwrdm);
uart->dma_enabled = 0;
#ifndef CONFIG_SERIAL_OMAP
name = "serial8250";
diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
index 19145f5..d3ee47b 100644
--- a/arch/arm/plat-omap/include/plat/serial.h
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -99,8 +99,6 @@ extern void omap_serial_init_port(int port);
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
--
1.7.2.1
next prev parent reply other threads:[~2010-10-20 23:31 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-20 23:31 [PATCH 1/3] OMAP: PM: formalize idle notifications Kevin Hilman
2010-10-20 23:31 ` [PATCH 2/3] OMAP: INTC: use idle notifier for autoidle management Kevin Hilman
2010-10-20 23:31 ` Kevin Hilman [this message]
2010-10-22 12:54 ` [PATCH 3/3] OMAP: UART: use atomic idle notifiers Govindraj
2010-10-22 16:11 ` Kevin Hilman
2010-10-22 18:05 ` [PATCH 1/3] OMAP: PM: formalize idle notifications Tony Lindgren
2010-10-22 22:00 ` Kevin Hilman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1287617483-24170-3-git-send-email-khilman@deeprootsystems.com \
--to=khilman@deeprootsystems.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-omap@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox