Hi,
I am using imx53 custom board with linux-2.6.35 .
Trying to achieve power management in this platform.
PMIC used is ltc3589.
Currently trying to wakeup the system from "mem"(Sleep mode) using UART and gpios connected to buttons.
System is able to wake up using RTC alarm, but not able to wake up using UART and gpios.
GPIOs are generating interrupt on pressing the buttons in normal mode. GPIO voltage level is changing when button is pressed in low power mode.
Also noticed that there is no entry for "echo enabled > /sys/devices/gpio/<gpio_no>/power/wakeup".
For UART added following lines in drivers/serial/mxc_uart.c mxcuart_suspend function.
if (device_may_wakeup(&pdev->dev)) { |
/* UART RTS signal is used as wakeup source */ | |
writel(MXC_UARTUCR1_RTSDEN, umxc->port.membase + MXC_UARTUCR1); | |
} |
But the above condition is not becoming true when mxcuart_suspend() is called.
Please, help me to configure GPIO and UART as wake up source.
I haven't used 2.6.35 in a long time, but I know that wakeup from UART and from GPIO is functional on 3.17 kernel on mx53 qsb board.
Hi Jith,
These are the steps:
1. Allow uart0 to be source of wakeup:
echo enabled > /sys/class/tty/ttymxc0/power/wakeup |
2. Put the system in low power mode
echo mem > /sys/power/state
3. Then type any key in the console and the system wakes up.
It would be better to upgrade the kernel, but if you can't do that, then you need to add this support.
I added it sometime ago with this commmit:
Hi Fabio,
I have tested the suggested patches and found not-waking behavior with UART.
We made some more experiment and got some clarification.
A.Going to Low power mode by following below commands.
echo enabled > /sys/class/tty/ttymxc0/power/wakeup
echo 1 > /sys/devices/platform/mxc_dvfs_core.0/enable
echo 1 > /sys/devices/platform/busfreq.0/enable
B.Followed below mentioned steps in suspend function (mxcuart_suspend)
1.Clear WAKE status bit.
2.Clear AWAKE status bit.
3.Enable WAKE interrupt.
4.Enable AWAKE interrupt.
C.Dumping Configuration register and Status Register while suspending got below information.
UCR4 0x8080 => WAKE interrupt is enabled.
UCR3 0x310 => AWAKE interrupt is enabled.
UCR2 0x1
UCR1 0x0 => IR mode disabled.
USR1 0x2040 => AWAKE interrupt status is cleared.
USR2 0x1 => WAKE interrupt status is cleared.
D.Pressing Keys in debug console to wake the system from Low power mode.But not able to wake the system using UART.
Probing RXD pin to check falling edge signal occurrence while trying to wake the system by giving keypress in debug console.
We found falling edge signal in RXD pin and attaching image for your reference.
E.Resuming the system using GPIO key press(Since we are not ale to wake the system using UART,used GPIO Keys)
F.Dumping Configuration register and Status Register while resuming to normal mode and got below information
UCR4 0x80 => WAKE interrupt is in enabled state only
UCR3 0x414 => AWAKE interrupt is in enabled state only
UCR2 0x502F
UCR1 0x201 => IR mode is disabled in state only
USR1 0x2040 => No falling edge was detected on the RXD Serial pin.
USR2 0x502F => Start bit is not detected.
By analyzing status registers,we can see that, the falling edge signal was not detected.
I would like to know that whether the above mentioned behavior is causing the wake up issue with UART or not.
It would make things easier if you could at least use kernel 3.17 for debugging purpose, since uart wakeup works fine there.
Porting to 3.17 means you only need to add a very minimal device tree file (dts) for your board.
Can u please share 3.17 Kernel link for imx53? We try the same.
Is it possible to dump Configuration register and Status Register while suspend and resuming the system at your side in parallel?
It will be a real help to us.
Hi Fabio,
We have done some experiment on UART as wakeup source in mxc_uart.c.Then we found that the mxcuart_suspend function [ drivers/serial/mxc_uart.c] is not calling uart_suspend_port function[drivers/serial/serial_core.c].
That is the reason for the waking up issue.
The mxcuart_suspend function is checking umxc->port.flags for ASYNC_INITIALIZED. But the umxc->port.flags is not maintaining the port flags information from the serial_core driver.
We have analyzed the serial_core driver and found that struct tty_port *port is used to maintain the flags information.[port->flags]
if we are checking tty_port flags in mxcuart_suspend function[in mxc_uart.c ], then the uart_suspend_port function will be get called and the problem can be solved.
These are the changes we have done in mxc_uart.c suspend function,
+ struct uart_state *state = mxc_reg.state + umxc->port.line; /* This we have taken from serial_core.c */
+ struct tty_port *port = &state->port;
- if (umxc && umxc->port.flags & ASYNC_INITIALIZED)
- uart_suspend_port(&mxc_reg, &umxc->port);
- if (umxc && umxc->port.flags & ASYNC_SUSPENDED)
- umxc->port.state->port.tty->hw_stopped = 1;
+ if (umxc && port->flags & ASYNC_INITIALIZED)
+ uart_suspend_port(&mxc_reg, &umxc->port);
+ if (umxc && port->flags & ASYNC_SUSPENDED)
+ port->tty->hw_stopped = 1;
Please let me know your comments.