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;
}