Skip to contentSkip to conversation

gpio-omap: wakeup mask

DISCUSSION Pascal Huerst 2 participants 8 messages Jul 2, 2014 – Jul 15, 2014 GPIO

lore
Share & tools
lore
#0 lore raw

Hi everyone,

we have a device with an am335x and are using some gpios on bank0 to wake up the device from suspend to ram.

We have some user buttons which are configured in the devicetree as gpio-keys and one power-key which should wake up the device:

&buttons {
        power {
                label = "Power";
                gpios = <&gpio0 6 1>;
                linux,code = <116>;
                gpio-key,wakeup;
        };

        one {
                label = "One";
                gpios = <&gpio0 11 1>;
                linux,code = <2>;
        };

        : : :
}

The problem is, that the device wakes up on any trigger on bank 0. No matter which button was pressed. "gpio-key,wakeup" seems not to have any influence.

Now, if I comment the following lines out in drivers/gpio/gpio-omap.c :
set_gpio_trigger(...).

321
322 if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
323 _gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0);
324 bank->context.wake_en =
325 readl_relaxed(bank->base + bank->regs->wkup_en);
326 }
327

Everything works as expected. But I don't really understand why? Is this a bug, or does this break something else I have not discovered yet?

Thanks,
Pascal

#1 lore raw
Quoted 40 lines · Pascal Huerst

Hi everyone,

we have a device with an am335x and are using some gpios on bank0 to wake up the device from suspend to ram.

We have some user buttons which are configured in the devicetree as gpio-keys and one power-key which should wake up the device:

&buttons {
        power {
                label = "Power";
                gpios = <&gpio0 6 1>;
                linux,code = <116>;
                gpio-key,wakeup;
        };

        one {
                label = "One";
                gpios = <&gpio0 11 1>;
                linux,code = <2>;
        };

        : : :
}

The problem is, that the device wakes up on any trigger on bank 0. No matter which button was pressed. "gpio-key,wakeup" seems not to have any influence.

Now, if I comment the following lines out in drivers/gpio/gpio-omap.c :
set_gpio_trigger(...).

321
322 if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
323 _gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0);
324 bank->context.wake_en =
325 readl_relaxed(bank->base + bank->regs->wkup_en);
326 }
327

Quoted 2 lines

Everything works as expected. But I don't really understand why? Is this a bug, or does this break something else I have not discovered yet?

The GPIO wake-up events are working from off-idle for omap3 the last time I checked, so sounds like this is some am335x related issue.

What does your bank->context.wake_en mask get set to with this code?

Regards,

Tony

#2 lore raw

Hey Tony, all

Quoted 41 lines · Tony Lindgren
Quoted 40 lines · Pascal Huerst

Hi everyone,

we have a device with an am335x and are using some gpios on bank0 to wake up the device from suspend to ram.

We have some user buttons which are configured in the devicetree as gpio-keys and one power-key which should wake up the device:

&buttons {
        power {
                label = "Power";
                gpios = <&gpio0 6 1>;
                linux,code = <116>;
                gpio-key,wakeup;
        };

        one {
                label = "One";
                gpios = <&gpio0 11 1>;
                linux,code = <2>;
        };

        : : :
}

The problem is, that the device wakes up on any trigger on bank 0. No matter which button was pressed. "gpio-key,wakeup" seems not to have any influence.

Now, if I comment the following lines out in drivers/gpio/gpio-omap.c :
set_gpio_trigger(...).

321
322 if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
323 _gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0);
324 bank->context.wake_en =
325 readl_relaxed(bank->base + bank->regs->wkup_en);
326 }
327

Quoted 6 lines
Quoted 2 lines

Everything works as expected. But I don't really understand why? Is this a bug, or does this break something else I have not discovered yet?

The GPIO wake-up events are working from off-idle for omap3 the last time I checked, so sounds like this is some am335x related issue.

Ok, that sounds reasonable.

Quoted 1 line

What does your bank->context.wake_en mask get set to with this code?

by calling 'echo mem > /sys/power/state' followed by a wakeup, I get the following:

[   28.738416] PM: Syncing filesystems ... done.
[   28.779153] Freezing user space processes ... (elapsed 0.003 seconds)
done.
[   28.790236] Freezing remaining freezable tasks ... (elapsed 0.002
seconds) done.
[   28.801386] PM: Sending message for entering DeepSleep mode
[   28.935412] bank->context->wake_en = 00080840
[   28.945935] PM: suspend of devices complete after 133.156 msecs
[   28.961008] PM: late suspend of devices complete after 8.834 msecs
[   28.978874] omap_hwmod: cpgmac0: _wait_target_disable failed
[   28.985940] PM: noirq suspend of devices complete after 18.324 msecs
[   28.992697] PM: GFX domain entered low power state
[   28.992697] PM: Could not transition all powerdomains to target state
[   28.992697] PM: Wakeup source GPIO0
[   28.992866] bank->context->wake_en = 00080040
[   29.020974] PM: noirq resume of devices complete after 22.439 msecs
[   29.028257] bank->context->wake_en = 00080040
[   29.032840] bank->context->wake_en = 00080840
[   29.039207] bank->context->wake_en = 00080840
[   29.043961] bank->context->wake_en = 0000F200
[   29.048534] bank->context->wake_en = 0000F200
[   29.053093] bank->context->wake_en = 0000F200
[   29.057704] bank->context->wake_en = 0000F200
[   29.062266] bank->context->wake_en = 0000F200
[   29.066992] bank->context->wake_en = 00060000
[   29.071554] bank->context->wake_en = 00060000
[   29.082499] PM: early resume of devices complete after 6.136 msecs
[   29.091048] net eth0: initializing cpsw version 1.12 (0)
[   29.173888] net eth0: phy found : id is : 0x4dd076
[   29.229388] mmc0: error -110 during resume (card was removed?)
[   29.235609] dpm_run_callback(): mmc_bus_resume+0x0/0x74 returns -110
[   29.242272] PM: Device mmc0:0001 failed to resume: error -110
[   29.293992] PM: resume of devices complete after 204.891 msecs
[   29.306801] PM: Sending message for resetting M3 state machine
[   29.313693] Restarting tasks ... done.

Thanks
Pascal

#3 lore raw
Quoted 53 lines · Pascal Huerst

Hey Tony, all

Quoted 41 lines · Tony Lindgren
Quoted 40 lines · Pascal Huerst

Hi everyone,

we have a device with an am335x and are using some gpios on bank0 to wake up the device from suspend to ram.

We have some user buttons which are configured in the devicetree as gpio-keys and one power-key which should wake up the device:

&buttons {
        power {
                label = "Power";
                gpios = <&gpio0 6 1>;
                linux,code = <116>;
                gpio-key,wakeup;
        };

        one {
                label = "One";
                gpios = <&gpio0 11 1>;
                linux,code = <2>;
        };

        : : :
}

The problem is, that the device wakes up on any trigger on bank 0. No matter which button was pressed. "gpio-key,wakeup" seems not to have any influence.

Now, if I comment the following lines out in drivers/gpio/gpio-omap.c :
set_gpio_trigger(...).

321
322 if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
323 _gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0);
324 bank->context.wake_en =
325 readl_relaxed(bank->base + bank->regs->wkup_en);
326 }
327

Quoted 6 lines
Quoted 2 lines

Everything works as expected. But I don't really understand why? Is this a bug, or does this break something else I have not discovered yet?

The GPIO wake-up events are working from off-idle for omap3 the last time I checked, so sounds like this is some am335x related issue.

Ok, that sounds reasonable.

Quoted 7 lines
Quoted 1 line

What does your bank->context.wake_en mask get set to with this code?

by calling 'echo mem > /sys/power/state' followed by a wakeup, I get the following:

[   28.992866] bank->context->wake_en = 00080040
[   29.020974] PM: noirq resume of devices complete after 22.439 msecs

I guess that's for gpio bank 0 with no bit 11 as your dts has it configured. If you just comment out the _gpio_rmw part above do things work as expected?

Then if that works as expected, maybe write only some unused bits into wkup_en register and see if it still wakes to all events while it should not?

It might be worth comparing the GPIO registers between am37xx and am335x for the wkup_en register.

Regards,

Tony

#4 lore raw
Quoted 56 lines · Tony Lindgren
Quoted 55 lines · Pascal Huerst

Hey Tony, all

Quoted 41 lines · Tony Lindgren
Quoted 40 lines · Pascal Huerst

Hi everyone,

we have a device with an am335x and are using some gpios on bank0 to wake up the device from suspend to ram.

We have some user buttons which are configured in the devicetree as gpio-keys and one power-key which should wake up the device:

&buttons {
        power {
                label = "Power";
                gpios = <&gpio0 6 1>;
                linux,code = <116>;
                gpio-key,wakeup;
        };

        one {
                label = "One";
                gpios = <&gpio0 11 1>;
                linux,code = <2>;
        };

        : : :
}

The problem is, that the device wakes up on any trigger on bank 0. No matter which button was pressed. "gpio-key,wakeup" seems not to have any influence.

Now, if I comment the following lines out in drivers/gpio/gpio-omap.c :
set_gpio_trigger(...).

321
322 if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
323 _gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0);
324 bank->context.wake_en =
325 readl_relaxed(bank->base + bank->regs->wkup_en);
326 }
327

Quoted 6 lines
Quoted 2 lines

Everything works as expected. But I don't really understand why? Is this a bug, or does this break something else I have not discovered yet?

The GPIO wake-up events are working from off-idle for omap3 the last time I checked, so sounds like this is some am335x related issue.

Ok, that sounds reasonable.

Quoted 1 line

What does your bank->context.wake_en mask get set to with this code?

Quoted 8 lines
Quoted 5 lines

by calling 'echo mem > /sys/power/state' followed by a wakeup, I get the following:

[   28.992866] bank->context->wake_en = 00080040
[   29.020974] PM: noirq resume of devices complete after 22.439 msecs

I guess that's for gpio bank 0 with no bit 11 as your dts has it configured.

Yes that's right. I forgot to print the context, too. If I do so, it's:

[   31.034972] bank->base = F9E07000 gpio = 6 bank->context->wake_en =

00080040

respectively:

[   31.846992] bank->base = F9E07000 gpio = 11 bank->context->wake_en =

00080040

Quoted 2 lines

If you just comment out the _gpio_rmw part above do things work as expected?

Yes. It only wakes up on gpio 6 not on gpio 11 anymore.

Quoted 3 lines

Then if that works as expected, maybe write only some unused bits into wkup_en register and see if it still wakes to all events while it should not?

If I use the following testcode, everything works as expected:

//WARN(true, "WARN: bank->base = %08X\n", bank->base);

if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
//_gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0); writel(0xABC00000, base + bank->regs->wkup_en);

bank->context.wake_en = readl_relaxed(bank->base +

    bank->regs->wkup_en);
  printk("bank->base = %08X gpio = %i bank->context->wake_en = %08X\n",
    bank->base, gpio, bank->context.wake_en);
}

This produces the following output:

[   35.319228] PM: Syncing filesystems ... done.
[   35.358702] Freezing user space processes ... (elapsed 0.003 seconds)
done.
[   35.369754] Freezing remaining freezable tasks ... (elapsed 0.002
seconds) done.
[   35.380734] PM: Sending message for entering DeepSleep mode
[   35.515932] bank->base = F9E07000 gpio = 19 bank->context->wake_en =
ABC00000
[   35.529319] PM: suspend of devices complete after 137.218 msecs
[   35.544410] PM: late suspend of devices complete after 8.715 msecs
[   35.562247] omap_hwmod: cpgmac0: _wait_target_disable failed
[   35.569325] PM: noirq suspend of devices complete after 18.289 msecs
[   35.576156] PM: GFX domain entered low power state
[   35.576156] PM: Could not transition all powerdomains to target state
[   35.576156] PM: Wakeup source GPIO0
[   35.576156] PM Wakeup source extra: 00000840
[   35.576329] bank->base = F9E07000 gpio = 6 bank->context->wake_en =
ABC00000
[   35.583710] bank->base = F9E07000 gpio = 11 bank->context->wake_en =
ABC00000
[   35.614846] PM: noirq resume of devices complete after 22.582 msecs
[   35.622009] bank->base = F9E07000 gpio = 6 bank->context->wake_en =
ABC00000
[   35.631798] bank->base = F9E07000 gpio = 11 bank->context->wake_en =
ABC00000
[   35.639511] bank->base = F9E07000 gpio = 19 bank->context->wake_en =
ABC00000
[   35.647116] bank->base = FA04C000 gpio = 9 bank->context->wake_en =
ABC00000
[   35.654547] bank->base = FA04C000 gpio = 12 bank->context->wake_en =
ABC00000
[   35.662015] bank->base = FA04C000 gpio = 13 bank->context->wake_en =
ABC00000
[   35.669526] bank->base = FA04C000 gpio = 14 bank->context->wake_en =
ABC00000
[   35.677039] bank->base = FA04C000 gpio = 15 bank->context->wake_en =
ABC00000
[   35.685035] bank->base = FA1AC000 gpio = 17 bank->context->wake_en =
ABC00000
[   35.692507] bank->base = FA1AC000 gpio = 18 bank->context->wake_en =
ABC00000
[   35.706466] PM: early resume of devices complete after 6.235 msecs
[   35.715010] net eth0: initializing cpsw version 1.12 (0)
[   35.794388] net eth0: phy found : id is : 0x4dd076
[   35.849941] mmc0: error -110 during resume (card was removed?)
[   35.856164] dpm_run_callback(): mmc_bus_resume+0x0/0x74 returns -110
[   35.862828] PM: Device mmc0:0001 failed to resume: error -110
[   35.914573] PM: resume of devices complete after 201.604 msecs
[   35.927336] PM: Sending message for resetting M3 state machine
[   35.934236] Restarting tasks ... done.
Quoted 2 lines

It might be worth comparing the GPIO registers between am37xx and am335x for the wkup_en register.

I had a quick look, but did not find anything. May be I will have to look into that again.

Thanks
Pascal

#5 lore raw
Quoted 19 lines · Pascal Huerst
Quoted 2 lines · Tony Lindgren

If you just comment out the _gpio_rmw part above do things work as expected?

Yes. It only wakes up on gpio 6 not on gpio 11 anymore.

Quoted 3 lines

Then if that works as expected, maybe write only some unused bits into wkup_en register and see if it still wakes to all events while it should not?

If I use the following testcode, everything works as expected:

//WARN(true, "WARN: bank->base = %08X\n", bank->base);

if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
//_gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0); writel(0xABC00000, base + bank->regs->wkup_en);

Quoted 5 lines

bank->context.wake_en = readl_relaxed(bank->base +

    bank->regs->wkup_en);
  printk("bank->base = %08X gpio = %i bank->context->wake_en = %08X\n",
    bank->base, gpio, bank->context.wake_en);
}

Hmm weird. It sounds like something like the following is happening:

1. The first GPIO bank is always powered, and does not need to set wake-up events

2. When setting the GPIO wake-up events it seems that enabling any wake-up event for the first (16?) bits wakes up the system

You might want to check this with some spare GPIOs not in the first bank and see if you need the wake-up events and if enabling some bits enables more than one GPIO for wake-up events.

Regards,

Tony

#6 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 25 lines · Tony Lindgren
Quoted 15 lines · Pascal Huerst
Quoted 2 lines · Tony Lindgren

If you just comment out the _gpio_rmw part above do things work as expected?

Yes. It only wakes up on gpio 6 not on gpio 11 anymore.

Quoted 3 lines

Then if that works as expected, maybe write only some unused bits into wkup_en register and see if it still wakes to all events while it should not?

If I use the following testcode, everything works as expected:

//WARN(true, "WARN: bank->base = %08X\n", bank->base);

Quoted 8 lines

if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { //_gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0); writel(0xABC00000, base + bank->regs->wkup_en);

bank->context.wake_en = readl_relaxed(bank->base + bank->regs->wkup_en); printk("bank->base = %08X gpio = %i bank->context->wake_en = %08X\n", bank->base, gpio, bank->context.wake_en); }

Quoted 5 lines

Hmm weird. It sounds like something like the following is happening:

1. The first GPIO bank is always powered, and does not need to set wake-up events

I dont think so. If I apply my hack (commenting the _gpio_rmw() call) and don't have a wakeup source in the dt, I have to reboot the system, sonce im not able to wake it up anymore. Or did I miss something?

Quoted 6 lines

2. When setting the GPIO wake-up events it seems that enabling any wake-up event for the first (16?) bits wakes up the system

You might want to check this with some spare GPIOs not in the first bank and see if you need the wake-up events and if enabling some bits enables more than one GPIO for wake-up events.

Im not sure if this makes sense, since only the first gpio bank can act as a wakeup source. So it should not be possible.

thanks!
pascal
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iEYEARECAAYFAlPFLEYACgkQo7eFcXQQ8U1NcACbBzQiKoU5MO/MLSdrjeg5CaAc YJcAn3bSthD4ByFOQ31jjOFI1F/HP4Lr
=o4r2
-----END PGP SIGNATURE-----

#7 lore raw
Quoted 31 lines · Pascal Huerst
Quoted 28 lines · Tony Lindgren
Quoted 15 lines · Pascal Huerst
Quoted 2 lines · Tony Lindgren

If you just comment out the _gpio_rmw part above do things work as expected?

Yes. It only wakes up on gpio 6 not on gpio 11 anymore.

Quoted 3 lines

Then if that works as expected, maybe write only some unused bits into wkup_en register and see if it still wakes to all events while it should not?

If I use the following testcode, everything works as expected:

//WARN(true, "WARN: bank->base = %08X\n", bank->base);

Quoted 8 lines

if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { //_gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0); writel(0xABC00000, base + bank->regs->wkup_en);

bank->context.wake_en = readl_relaxed(bank->base + bank->regs->wkup_en); printk("bank->base = %08X gpio = %i bank->context->wake_en = %08X\n", bank->base, gpio, bank->context.wake_en); }

Hmm weird. It sounds like something like the following is happening:

Quoted 6 lines
Quoted 2 lines

1. The first GPIO bank is always powered, and does not need to set wake-up events

I dont think so. If I apply my hack (commenting the _gpio_rmw() call) and don't have a wakeup source in the dt, I have to reboot the system, sonce im not able to wake it up anymore. Or did I miss something?

Well this just from my head without looking at the code, so please check..

When you comment out the _gpio_rmw() call you are not configuring any GPIO bank wake-up events.

And the .dts entry just manages the keypad wake-up event for suspend and resume and does not affect the GPIO bank after you commented out the _gpio_rmw().

Quoted 9 lines
Quoted 6 lines

2. When setting the GPIO wake-up events it seems that enabling any wake-up event for the first (16?) bits wakes up the system

You might want to check this with some spare GPIOs not in the first bank and see if you need the wake-up events and if enabling some bits enables more than one GPIO for wake-up events.

Im not sure if this makes sense, since only the first gpio bank can act as a wakeup source. So it should not be possible.

Usually on omaps the first GPIO bank is always powered but also the other banks can provide wake-up events for most GPIOs via the IO chain path. I think on am335x, there is no IO chain path, maybe because of the support for dual voltage IO? So yeah it could be that only the first GPIO bank can wake up the system on am335x.

Regards,

Tony