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?
Solved! Go to Solution.
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;
}
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.
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.
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.
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.
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?)
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;
}
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
be sure that your WiFi module always powered on in suspended state.
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
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.
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();
}
Okay,I will confirm with Marvell.