Does FSL kernel support sdio irq wake up?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Does FSL kernel support sdio irq wake up?

Jump to solution
3,216 Views
raymondwang
Senior Contributor I

my board design is based on SabreSD, and my kernel is 3.0.35, android release is android_jb_4.2.2_1.1.0.

   My issue is Marvell based wlan trying to wake up AP while system entered suspend state. From it's driver, I know that it

use sdio DAT1 line to wake up host. I don't know where to find the patch for that since FSL kernel seems no ready yet to

support this feature.

   From Re: Power State Wakeup accepted interrupts and wakeup times for IMX6 SoloLite?,  I found following message.

  And for SDIO, our BSP is not supporting it by default, but the hardware should support it, just need to enable SDIO's wakeup before suspend, normally, you need to enable two levels, first one is to enable the eSDHC module's interrupt in its driver before suspend, the other is to unmask the wake up logic in GPC module, then SDIO should be able to wake up system.

  I had tried to add code to support but failed to be triggered by wlan module. Any one got better suggestion?



Labels (3)
0 Kudos
1 Solution
1,538 Views
raymondwang
Senior Contributor I

Now I split wlan sdio wake up (gpio mode) to several parts in suspend enter and exit . It works now ( I can get wake up in

sdio_irq gpio by wlan module).

Below is my code (share with all guys may encounter similar issue).

static int wlan_wakeup_init=0;

struct wake_lock wlan_wakelock;

static iomux_v3_cfg_t wlan_wakeup_pads_func[] = {

MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,

};

static iomux_v3_cfg_t wlan_wakeup_pads_io[] = {

NEW_PAD_CTRL(MX6Q_PAD_SD3_DAT1__GPIO_7_5,MX6Q_GENERIC_PAD_CTRL),

};

static irqreturn_t wlan_wakup_handler(int irq, void *data){

wake_lock_timeout(&wlan_wakelock, HZ * 2);

       return IRQ_HANDLED;

}

//called in suspend_prepare

static int wlan_wakeup_add(void){

       int ret=0;

if(!wlan_wakeup_init){

gpio_request(QPAD_WIFI_WAKEUP,"wifi-wakeup");

gpio_direction_input(QPAD_WIFI_WAKEUP);

wake_lock_init(&wlan_wakelock , WAKE_LOCK_SUSPEND, "wlan wakelock");

wlan_wakeup_init++;

}

//we can't use both edge trigger ,otherwise GPC will be waken up immediately and we

//will enter an infinite loop

ret = request_any_context_irq(gpio_to_irq(QPAD_WIFI_WAKEUP), wlan_wakup_handler,

IRQF_NO_SUSPEND|IRQF_TRIGGER_FALLING ,

"wlan wakeap", 0);

if (ret) {

pr_warning("Request wlan wakeup failed %d\n", ret);

}else {

enable_irq_wake(gpio_to_irq(QPAD_WIFI_WAKEUP));

}

       return ret;

}


//called in suspend enter

static int wlan_wakeup_enable(void){

//switch to gpio mode

mxc_iomux_v3_setup_multiple_pads(wlan_wakeup_pads_io,1);

return 0;

}

//called in suspend exit

static int wlan_wakeup_disable(void){

mxc_iomux_v3_setup_multiple_pads(wlan_wakeup_pads_func,1);

return 0;

}

//called in suspend wake

static int wlan_wakeup_remove(void){

disable_irq_wake(gpio_to_irq(QPAD_WIFI_WAKEUP));

free_irq(gpio_to_irq(QPAD_WIFI_WAKEUP),0);

return 0;

}

View solution in original post

0 Kudos
12 Replies
1,538 Views
AnsonHuang
NXP Employee
NXP Employee

Hi, Raymong

     I have one question about this SDIO wakeup using DAT1 line, does the SDIO need clock to be on when waiting for this wakeup interrupt? As when suspend, there is no SDIO clock available. If no need SDIO clock, the DAT1 line's level change can trigger our SDIO interrupt, then I think this feature should be feasible.

0 Kudos
1,538 Views
raymondwang
Senior Contributor I

    I'm not familiar with SDIO spec, but I guess that no sdio clock required when device suspended.

I found the uSDHC controller should support that but driver never touch it. Below is a snapshot from uSDHC

uSDHCx_PROT_CTRL.

uSDHC.png

0 Kudos
1,538 Views
AnsonHuang
NXP Employee
NXP Employee

I think you may need to ask SDIO owner for that, from kernel side, as long as GPC can receive interrupt from SDIO, system should be able to resume.

0 Kudos
1,538 Views
raymondwang
Senior Contributor I

  I have confirmed with Marvell FAE that it does not required SDIO clock while suspended. Very strange,I tried to change SDIO_DAT1 to

gpio mode while suspend and request a wake up irq while this pin got edge triggered. But it never be triggered even I saw wlan module

power consumption becoming higher. 

0 Kudos
1,538 Views
JayTu
NXP Employee
NXP Employee

When I'm doiing SDIO 3.0 with BCM43241 on i.MX6, SDIO clock is needed when in-band interrupt mode (SDIO_DAT1 as interrupt). To make wlan module notify system, BCM43241 is reworked as out-of-band interrupt.

If SDIO bus has no clock, I wonder how SDIO_DAT1 interrupts? (In this case, this is just a data line in SDIO bus. No?)

0 Kudos
1,539 Views
raymondwang
Senior Contributor I

Now I split wlan sdio wake up (gpio mode) to several parts in suspend enter and exit . It works now ( I can get wake up in

sdio_irq gpio by wlan module).

Below is my code (share with all guys may encounter similar issue).

static int wlan_wakeup_init=0;

struct wake_lock wlan_wakelock;

static iomux_v3_cfg_t wlan_wakeup_pads_func[] = {

MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,

};

static iomux_v3_cfg_t wlan_wakeup_pads_io[] = {

NEW_PAD_CTRL(MX6Q_PAD_SD3_DAT1__GPIO_7_5,MX6Q_GENERIC_PAD_CTRL),

};

static irqreturn_t wlan_wakup_handler(int irq, void *data){

wake_lock_timeout(&wlan_wakelock, HZ * 2);

       return IRQ_HANDLED;

}

//called in suspend_prepare

static int wlan_wakeup_add(void){

       int ret=0;

if(!wlan_wakeup_init){

gpio_request(QPAD_WIFI_WAKEUP,"wifi-wakeup");

gpio_direction_input(QPAD_WIFI_WAKEUP);

wake_lock_init(&wlan_wakelock , WAKE_LOCK_SUSPEND, "wlan wakelock");

wlan_wakeup_init++;

}

//we can't use both edge trigger ,otherwise GPC will be waken up immediately and we

//will enter an infinite loop

ret = request_any_context_irq(gpio_to_irq(QPAD_WIFI_WAKEUP), wlan_wakup_handler,

IRQF_NO_SUSPEND|IRQF_TRIGGER_FALLING ,

"wlan wakeap", 0);

if (ret) {

pr_warning("Request wlan wakeup failed %d\n", ret);

}else {

enable_irq_wake(gpio_to_irq(QPAD_WIFI_WAKEUP));

}

       return ret;

}


//called in suspend enter

static int wlan_wakeup_enable(void){

//switch to gpio mode

mxc_iomux_v3_setup_multiple_pads(wlan_wakeup_pads_io,1);

return 0;

}

//called in suspend exit

static int wlan_wakeup_disable(void){

mxc_iomux_v3_setup_multiple_pads(wlan_wakeup_pads_func,1);

return 0;

}

//called in suspend wake

static int wlan_wakeup_remove(void){

disable_irq_wake(gpio_to_irq(QPAD_WIFI_WAKEUP));

free_irq(gpio_to_irq(QPAD_WIFI_WAKEUP),0);

return 0;

}

0 Kudos
1,538 Views
mrleo
Contributor IV

Hi Raymond,

I use rtl8723as wifi module,I also have no sdio cd detect. When not enabled wifi or connetcted to wifi,enter suspend,and later resume the system.

I will can not enable  the wifi on android 4.4 setting ui.

Now I use your solution to wake up the sdio.But not ok.



Thanks,


Leo

0 Kudos
1,538 Views
raymondwang
Senior Contributor I

be sure that your WiFi module always powered on in suspended state.

0 Kudos
1,538 Views
johnjohntobias
Contributor II

Hi Raymond,

I have few question with you:

1. How did you wake up your device (assuming your device is in suspend mode)?.

2. Does your wifi maintain the connectivity of your router?. How did you find your device?.

Regards,

john

0 Kudos
1,538 Views
raymondwang
Senior Contributor I

1. How did you wake up your device (assuming your device is in suspend mode)?.

sdio driver will send enter/exit suspend command to device.

2. Does your wifi maintain the connectivity of your router?. How did you find your device?.

If wifi device connected a ap, it will maintain connectivity perodically even in suspend mode, but it must wakeup ap to

helping maintain event.

0 Kudos
1,538 Views
raymondwang
Senior Contributor I

SDIO_DAT1 is shared with SDIO irq as sdio spec claims. Now I switch SDIO_DAT1 to gpio mode in suspend state. But it still ...... can not be waken up by wlan module.

Anyone can help me to review following code ?

#define QPAD_WIFI_WAKEUP IMX_GPIO_NR(7, 5)

static int wlan_wakeup_init=0;
static iomux_v3_cfg_t wlan_wakeup_pads_func[] = {

  MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,

};

static iomux_v3_cfg_t wlan_wakeup_pads_io[] = {

  MX6Q_PAD_SD3_DAT1__GPIO_7_5,

};

static irqreturn_t wlan_wakup_handler(int irq, void *data){

       return IRQ_HANDLED;

}

static int wlan_wakeup_add(void){

       int ret;  

    if(!wlan_wakeup_init){

        gpio_request(QPAD_WIFI_WAKEUP,"wifi-wakeup");

        gpio_direction_input(QPAD_WIFI_WAKEUP);

    }

    //switch to gpio mode

    mxc_iomux_v3_setup_multiple_pads(wlan_wakeup_pads_io,1);

       ret = request_any_context_irq(gpio_to_irq(QPAD_WIFI_WAKEUP), wlan_wakup_handler,

               IRQF_NO_SUSPEND|IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING ,

               "wlan wakeap", 0);

       if (ret) {

               pr_warning("Request wlan wakeup failed %d\n", ret);

       }else {

               enable_irq_wake(gpio_to_irq(QPAD_WIFI_WAKEUP));

       }

       printk("%s\n",__func__);

       return ret;

}

static int wlan_wakeup_remove(void){

       printk("%s\n",__func__);

       disable_irq_wake(gpio_to_irq(QPAD_WIFI_WAKEUP));

       free_irq(gpio_to_irq(QPAD_WIFI_WAKEUP),0);  

    mxc_iomux_v3_setup_multiple_pads(wlan_wakeup_pads_func,1);

       return 0;

}

static void mx6_suspend_enter(void)

{

  if(wlan_poweron) wlan_wakeup_add();

}

static void mx6_suspend_exit(void)

{

  if(wlan_poweron) wlan_wakeup_remove();

}

0 Kudos
1,538 Views
raymondwang
Senior Contributor I

Okay,I will confirm with Marvell.

0 Kudos