Skip to content

Commit 13e6262

Browse files
storulfKalle Valo
authored andcommitted
wlcore: sdio: Fixup power on/off sequence
During "wlan-up", we are programming the FW into the WiFi-chip. However, re-programming the FW doesn't work, unless a power cycle of the WiFi-chip is made in-between the programmings. To conform to this requirement and to fix the regression in a simple way, let's start by allowing that the SDIO card (WiFi-chip) may stay powered on (runtime resumed) when wl12xx_sdio_power_off() returns. The intent with the current code is to treat this scenario as an error, but unfortunate this doesn't work as expected, so let's fix this. The other part is to guarantee that a power cycle of the SDIO card has been completed when wl12xx_sdio_power_on() returns, as to allow the FW programming to succeed. However, relying solely on runtime PM to deal with this isn't sufficient. For example, userspace may prevent runtime suspend via sysfs for the device that represents the SDIO card, leading to that the mmc core also keeps it powered on. For this reason, let's instead do a brute force power cycle in wl12xx_sdio_power_on(). Fixes: 728a9dc ("wlcore: sdio: Fix flakey SDIO runtime PM handling") Signed-off-by: Ulf Hansson <[email protected]> Tested-by: Tony Lindgren <[email protected]> Tested-by: Anders Roxell <[email protected]> Signed-off-by: Ulf Hansson <[email protected]> Signed-off-by: Kalle Valo <[email protected]>
1 parent ec5aecc commit 13e6262

File tree

1 file changed

+7
-8
lines changed
  • drivers/net/wireless/ti/wlcore

1 file changed

+7
-8
lines changed

drivers/net/wireless/ti/wlcore/sdio.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@ static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue)
164164
}
165165

166166
sdio_claim_host(func);
167+
/*
168+
* To guarantee that the SDIO card is power cycled, as required to make
169+
* the FW programming to succeed, let's do a brute force HW reset.
170+
*/
171+
mmc_hw_reset(card->host);
172+
167173
sdio_enable_func(func);
168174
sdio_release_host(func);
169175

@@ -174,20 +180,13 @@ static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue)
174180
{
175181
struct sdio_func *func = dev_to_sdio_func(glue->dev);
176182
struct mmc_card *card = func->card;
177-
int error;
178183

179184
sdio_claim_host(func);
180185
sdio_disable_func(func);
181186
sdio_release_host(func);
182187

183188
/* Let runtime PM know the card is powered off */
184-
error = pm_runtime_put(&card->dev);
185-
if (error < 0 && error != -EBUSY) {
186-
dev_err(&card->dev, "%s failed: %i\n", __func__, error);
187-
188-
return error;
189-
}
190-
189+
pm_runtime_put(&card->dev);
191190
return 0;
192191
}
193192

0 commit comments

Comments
 (0)