At least HiKey board can fail to bring up wireless interface again if the interface is brought down and up with no delay inbetween. This can be done tested with: # while true; do ifconfig wlan0 down; ifconfig wlan0 up; done According to Ricardo Salveti <rsalveti@xxxxxxxxxxxx>, we need to wait between 30 - 40 ms on HiKey. This seems to happen when we get -EBUSY returned by pm_runtime_put() basedon the check in rpm_check_suspend_allowed(). But as it still unclear if part of the delay needed is because of capacitance, let's always do a at least 50 ms msleep even if no -EBUSY is returned. Cc: Anders Roxell <anders.roxell@xxxxxxxxxx> Cc: Eyal Reizer <eyalr@xxxxxx> Cc: John Stultz <john.stultz@xxxxxxxxxx> Cc: Ricardo Salveti <rsalveti@xxxxxxxxxxxx> Cc: Ulf Hansson <ulf.hansson@xxxxxxxxxx> Reported-by: Ricardo Salveti <rsalveti@xxxxxxxxxxxx> Fixes: 60f36637bbbd ("wlcore: sdio: allow pm to handle sdio power") Signed-off-by: Tony Lindgren <tony@xxxxxxxxxxx> --- Uffe, do you have some better ideas on how to fix this issue? --- drivers/net/wireless/ti/wlcore/sdio.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c @@ -174,7 +174,7 @@ static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue) { struct sdio_func *func = dev_to_sdio_func(glue->dev); struct mmc_card *card = func->card; - int error; + int error, retries = 5; sdio_claim_host(func); sdio_disable_func(func); @@ -188,6 +188,17 @@ static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue) return error; } + /* Wait a bit to ensure the card gets power off. Otherwise + * bringing interface down and up again may not power off the + * card inbetween. And then firmware load will fail on trying + * to bring the card up again. We need to wait between 30 - 40 + * ms for this based on measurements on HiKey board. + */ + do { + msleep(50); + } while (error == -EBUSY && !pm_runtime_suspended(&card->dev) && + retries--); + return 0; } -- 2.19.2