ONOFF button doesn't interrupt

cancel
Showing results for 
Search instead for 
Did you mean: 

ONOFF button doesn't interrupt

Jump to solution
5,946 Views
andreygelman
Contributor III

I try to hook ONOFF button interrupt.

Long press on ONOFF button turns the SoC off - as expected.

I have configured all the interrupt handling in Linux kernel, but what happens is the interrupt arrives only once.

Upon 1-st press, the interrupt is sent.

Any additional press leads to nothing.

Do I have to re-enable ONOFF interrupt (IRQ 36) somehow ?

Thanks in advance.

Labels (4)
1 Solution
442 Views
RobinGong
NXP Employee
NXP Employee

Did you clear the interrupt status of SNVS? you can read the register 0x020cc04c and then write the value which you read before in you ISR. No need re-enable ONOFF interrupt.

View solution in original post

0 Kudos
19 Replies
442 Views
PaulDeMetrotion
Senior Contributor I

I am also working on a custom board with a Linux-3.0.35 kernel. I can put the device into suspend mode but can never wake it up by pressing the power button. This sounds like it could also be my problem.

After reviewing the code in rtc-snvs.c, it appears that the ISR already clears the register 0x020cc04c. Am I missing something in my kernel configuration? Does the IRQ 36 have to be enabled and configured? I assume it is already enabled. Andrey, what do you mean by "I have configured all the interrupt handling in Linux kernel"? Thanks.

0 Kudos
442 Views
andreygelman
Contributor III

1. request_irq 36 ... clearing the register each time the interrupt is handled

2. register IRQ 36 as wake source (enable_irq_wake()) when your device goes to sleep - you can even hook up rtc-snvs.c

3. as waking up is not an interrupt, you have to clear the register on the resume path

0 Kudos
442 Views
PaulDeMetrotion
Senior Contributor I

Thanks for the assistance. I plan to enable IRQ36 as a wake up source in my custom suspend_enter function. I also plan to clear the SNVS_LPSR register in my custom suspend_exit function. Remaining question is where do I request IRQ36? Did you create a custom handler? Can I attach the IRQ to my pm device? Here is a snippet of my code:

static void sbc35_c398_suspend_enter(void)
{
      // suspend preparation
      // register irq36 as a wake-up source

}

static void sbc35_c398_suspend_exit(void)
{

      // resume restore
      // clear the irq register

}

static const struct pm_platform_data mx6q_sbc35_c398_pm_data __initconst = {

      .name = "imx_pm",
      .suspend_enter = sbc35_c398_suspend_enter,
      .suspend_exit = sbc35_c398_suspend_exit,

};

Later in the code:

imx6q_add_pm_imx(0, &mx6q_sbc35_c398_pm_data);

Can I just request the irq within my board initialization routine like below? Also need some assistance on two variables.

request_irq( 36,

                    ???,     // irq handler

                    IRQF_NO_SUSPEND.

                    mx6q_sbc35_c398_pm_data.name,

                    ???)    // device

0 Kudos
442 Views
andreygelman
Contributor III

Yes, request the IRQ in your board initialization routine.

You might need to play with the flags - it should be rising edge triggered ...

My observation is that the SNVS_LPSR register should be cleared by a deferred worker rather than the IRQ handler. When it is cleared by the IRQ handler it just occasionally fails to be cleared  --  may be Yibin Gong would like to comment on this ?

When you wake your device up with the power button press, the IRQ handler routine will not be called, so the register will not be cleared - in your custom suspend_exit() add the register clearing and, possibly, additional actions you plan to take upon IRQ 36.

0 Kudos
442 Views
RobinGong
NXP Employee
NXP Employee

hi Andrey and Paul,

Please check the attached patch. At the last minute ,we give up the patch because ONOFF key can only trigger interrupt after key up which means it can meet with Android’s software requirement(long press to launch power-off menu ,short press to suspend/resume system). Then, we use another GPIO to connect with the ONOFF key. Please check our reference design MX6Q-SABRESD board, and below code in arch/arm/mach-mx6/board-mx6q_sabresd.c:

static struct gpio_keys_button imx6q_buttons[] = {

GPIO_BUTTON(SABRESD_VOLUME_UP, KEY_VOLUMEUP, 1, "volume-up", 0, 1),

GPIO_BUTTON(SABRESD_VOLUME_DN, KEY_VOLUMEDOWN, 1, "volume-down", 0, 1),

GPIO_BUTTON(SABRESD_POWER_OFF, KEY_POWER, 1, "power", 1, 1),

};

0 Kudos
442 Views
ningli
Contributor III

Hi,

i can't understand this code

GPIO_BUTTON(SABRESD_VOLUME_UP, KEY_VOLUMEUP, 1, "volume-up", 0),
-GPIO_BUTTON(SABRESD_VOLUME_DN, KEY_VOLUMEDOWN, 1, "volume-down", 1),
+GPIO_BUTTON(SABRESD_VOLUME_DN, KEY_POWER, 1, "volume-down", 1),
GPIO_BUTTON(SABRESD_POWER_OFF, KEY_POWER, 1, "power", 1),

any one can explain for me? thanks!!

or show  me the hardware design?

0 Kudos
442 Views
EricNelson
Senior Contributor II

Thanks Yibin,

This is also roughly what I just implemented.

0 Kudos
442 Views
PaulDeMetrotion
Senior Contributor I

Thanks!!! Great help. My system now wakes up when the power button is hit. In our implementation the power switch is hooked directly to the ONOFF pin. There is no GPIO used.

There is still a problem because the system does not return to a usable state. The video locks up with my wallpaper and a white block. The keyboard and mouse are unresponsive. The serial console is usable so the system is alive.

Here is the dmesg output from suspend to wake up. Do you see anything that looks suspicious? Right after wake up I do get the following console message: mxc_hdmi mxc_hdmi: PHY PLL not locked

init: anacron main process (5258) killed by TERM signal

PM: Syncing filesystems ... done.

PM: Preparing system for mem sleep

Freezing user space processes ... (elapsed 0.01 seconds) done.

Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.

PM: Entering mem sleep

Suspending console(s) (use no_console_suspend to debug)

ehci_fsl_bus_suspend begins, Host 1

ehci_fsl_bus_suspend ends, Host 1

USB Host suspend begins

ehci_fsl_drv_suspend, pm event

host suspend ends

udc suspend begins

USB Host suspend begins

ehci_fsl_drv_suspend, pm event

host suspend ends

add wake up source irq 36

add wake up source irq 51

PM: suspend of devices complete after 48.710 msecs

PM: late suspend of devices complete after 0.645 msecs

Disabling non-boot CPUs ...

CPU1: shutdown

CPU2: shutdown

CPU3: shutdown

Enabling non-boot CPUs ...

CPU1: Booted secondary processor

Calibrating delay loop (skipped) already calibrated this CPU

i.MXC CPU frequency driver

CPU1 is up

CPU2: Booted secondary processor

Calibrating delay loop (skipped) already calibrated this CPU

i.MXC CPU frequency driver

CPU2 is up

CPU3: Booted secondary processor

Calibrating delay loop (skipped) already calibrated this CPU

i.MXC CPU frequency driver

CPU3 is up

PM: early resume of devices complete after 0.485 msecs

=======snvs_pwrkey_interrupt()lpstatus 0x40040000, lp_cr 0x21

set snvs as DUMP PMIC MODE

imx-ipuv3 imx-ipuv3.0: IPU DMFC DP HIGH RESOLUTION: 1(0,1), 5B(2~5), 5F(6,7)

imx-ipuv3 imx-ipuv3.1: IPU DMFC DP HIGH RESOLUTION: 1(0,1), 5B(2~5), 5F(6,7)

mxc_hdmi mxc_hdmi: PHY PLL not locked

mxc_hdmi mxc_hdmi: PHY PLL not locked

remove wake up source irq 51

remove wake up source irq 36

ehci fsl drv resume begins: DR

ehci_fsl_drv_resume,pm event, wait for wakeup irq if needed

USB Gadget resume begins

fsl_udc_resume, Wait for wakeup thread finishes

ehci_fsl_bus_resume begins, DR

ehci fsl drv resume begins: Host 1

ehci_fsl_drv_resume,pm event, wait for wakeup irq if needed

ehci_fsl_bus_resume begins, Host 1

ehci_fsl_bus_resume ends, Host 1

PM: resume of devices complete after 1398.805 msecs

PM: Finishing wakeup.

Restarting tasks ... done.

eth0: Freescale FEC PHY driver [Micrel KSZ9031 Gigabit PHY] (mii_bus:phy_addr=1:07, irq=-1)

ADDRCONF(NETDEV_UP): eth0: link is not ready

PHY: 1:07 - Link is Up - 1000/Full

ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready

0 Kudos
442 Views
PaulDeMetrotion
Senior Contributor I

UPDATE: I added the switch no_console_suspend to my command line and the system now wakes up fine. Is this typical behavior? Any idea why this specific switch works?

0 Kudos
442 Views
RobinGong
NXP Employee
NXP Employee

It’s not a typical behavior, no_console_suspend shouldn’t have so big impact . Without no_console_suspend, the log printed during system suspend will be postponed to resume back. ‘mxc_hdmi: PHY PLL not locked’ is still here when you add no_console_suspend in command line?

0 Kudos
442 Views
PaulDeMetrotion
Senior Contributor I

Yes, the HDMI message is displayed with the no_console_suspend selected.

0 Kudos
442 Views
RobinGong
NXP Employee
NXP Employee

Kernel seems ok since console is usable after resume back, I doubt there is something wrong about input event notification . Because ONOFF key only trigger interrupt after key up, the code in the patch will report another pseudo ‘down’ event before every ‘up’ event. I’m not sure this is harmless for your system(or need add some delay between two events?), what’s your system ? The patch has been validated on Android .

0 Kudos
442 Views
PaulDeMetrotion
Senior Contributor I

We have our own custom system based on the i.MX6Q. I reviewed the code and the functions uart_suspend_port and uart_resume_port are the only places the variable console_suspend_enable is used. This variable is set based on the no_console_suspend setting. Both functions are in drivers/tty/serial/serial_core.c.

Is there something within the suspend or resume code of the console that needs to be customized based on my hardware? We use serial port 1 (ttymxc0) as the console.

0 Kudos
442 Views
RobinGong
NXP Employee
NXP Employee

console_suspend_enable is a common debug option to see the log timely, no need any specific low level code support.

0 Kudos
442 Views
andreygelman
Contributor III

You make me cry !

Only yesterday :smileyalert: I have implemented almost identical driver myself.

Thank you again !

0 Kudos
442 Views
RobinGong
NXP Employee
NXP Employee

You need enable IRQ36 firstly , the code in rtc-snvs.c will not handle this.

0 Kudos
443 Views
RobinGong
NXP Employee
NXP Employee

Did you clear the interrupt status of SNVS? you can read the register 0x020cc04c and then write the value which you read before in you ISR. No need re-enable ONOFF interrupt.

View solution in original post

0 Kudos
442 Views
andreygelman
Contributor III

Thank you !

Indeed writing 0x00040000 to register 0x020cc04c effectively re-enables ONOFF interrupt.

But why don't I see this information in i.MX6 reference manual ?

I see some code dealing with this register in the kernel, under rtc-snvs, but it all private (i.e. data structures defined inside .c file) ...

0 Kudos
442 Views
RobinGong
NXP Employee
NXP Employee

Yes, you can’t find more information in any document you can get. Sorry, the document I got only for internal share.

0 Kudos