[PATCH 2/7] OMAP2+: mux: Enable wakeup for wakeup enable requested pads

Kevin Hilman khilman at ti.com
Tue Mar 8 20:14:46 EST 2011


Govindraj <govindraj.ti at gmail.com> writes:

> Module level wakeup doesn't seem to work and only
> way it seem to wakeup is through using resume_idle
> from sram_idle.

Have you verified if the module wakeups themselves are not working, or
just that the wakeup is not propagating to a device IRQ?

As a quick test, I did a suspend-only test shows that module-level
wakeups (at least from PER UART) are working.

On 3530/Beagle, which has console on UART3 (in PER), I successfully
tested module level wakeups from suspend.

First, I added a simple debug printk[1] to show the wakeup source.
Then, I ensure CORE stays 'ON' during suspend.  If CORE stays on, the IO
ring is never armed, so only module wakeups can happen:

   # echo 3 > /debug/pm_debug/core_pwrdm/suspend 

then I suspend

   # echo mem > /sys/power/state 

and type a key on the console to wakeup, and I see:

   PRCM IRQ: mod 0x800: WKST=0x00000800

Which shows PER wakeup from UART3.  If you do the same without setting
CORE to ON, you'll see that the first wakeup is in the WKUP powerdomain
from the IO ring.

So module-level wakeups are indeed working.

The problem is actually not that module wakeups are working, but rather
that the module does not generate an interrupt upon wakeup if it is
idle.  The resume_from_idle hack works because as soon as clocks are
enabled, the module generates the interrupt (special thanks to Paul
Walmsley for helping me understand this.)

>
> One simple way to reproduce the problem with
> existing code base also is adding this patch which
> will enable module level wakeup always.
>
> https://patchwork.kernel.org/patch/501211/
>
> and with below change.
>
> govindraj at Linux-BSP-Server:~/clones/linux-omap-2.6$ gd
> diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
> index 47eef48..6343773 100644
> --- a/arch/arm/mach-omap2/serial.c
> +++ b/arch/arm/mach-omap2/serial.c
> @@ -380,6 +380,7 @@ static void omap_uart_allow_sleep(struct
> omap_uart_state *uart)
>         omap_uart_smart_idle_enable(uart, 1);
>         uart->can_sleep = 1;
>         del_timer(&uart->timer);
> +       omap_uart_disable_clocks(uart);
>  }
>
> We can see module level wakeup doesn't wakeup the uart.
> once we set sleep_timeout for uart and timer starts.

The above change alone can never work.  I'm pretty sure you wouldn't see
IO-ring wakeups will not happen with this change either because the
kernel will probably hang.

If you disable the clocks here, then any console usage between the
timeout and the idle path will hang the kernel.  You can't do this
without taking the console lock.  Doing that will be much easier in your
new driver.

Kevin


[1]
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 6e2bd38..677a235 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -219,6 +219,8 @@ static int prcm_clear_mod_irqs(s16 module, u8 regs)
 		iclk = omap2_cm_read_mod_reg(module, iclk_off);
 		fclk = omap2_cm_read_mod_reg(module, fclk_off);
 		while (wkst) {
+			printk("PRCM IRQ: mod 0x%x: WKST=0x%08x\n",
+			       module, wkst);
 			clken = wkst;
 			omap2_cm_set_mod_reg_bits(clken, module, iclk_off);
 			/*




More information about the linux-arm-kernel mailing list