static inline void wl1271_power_off(struct wl1271 *wl)
 {
-       wl->if_ops->power(wl->dev, false);
-       clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
+       int ret;
+
+       if (!test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags))
+               return;
+
+       ret = wl->if_ops->power(wl->dev, false);
+       if (!ret)
+               clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
 }
 
 static inline int wl1271_power_on(struct wl1271 *wl)
 
 {
        int ret;
        struct sdio_func *func = dev_to_sdio_func(glue->dev);
+       struct mmc_card *card = func->card;
 
-       /* If enabled, tell runtime PM not to power off the card */
-       if (pm_runtime_enabled(&func->dev)) {
-               ret = pm_runtime_get_sync(&func->dev);
-               if (ret < 0)
-                       goto out;
-       } else {
-               /* Runtime PM is disabled: power up the card manually */
-               ret = mmc_power_restore_host(func->card->host);
-               if (ret < 0)
+       ret = pm_runtime_get_sync(&card->dev);
+       if (ret) {
+               /*
+                * Runtime PM might be temporarily disabled, or the device
+                * might have a positive reference counter. Make sure it is
+                * really powered on.
+                */
+               ret = mmc_power_restore_host(card->host);
+               if (ret < 0) {
+                       pm_runtime_put_sync(&card->dev);
                        goto out;
+               }
        }
 
        sdio_claim_host(func);
 {
        int ret;
        struct sdio_func *func = dev_to_sdio_func(glue->dev);
+       struct mmc_card *card = func->card;
 
        sdio_claim_host(func);
        sdio_disable_func(func);
        sdio_release_host(func);
 
-       /* Power off the card manually, even if runtime PM is enabled. */
-       ret = mmc_power_save_host(func->card->host);
+       /* Power off the card manually in case it wasn't powered off above */
+       ret = mmc_power_save_host(card->host);
        if (ret < 0)
-               return ret;
+               goto out;
 
-       /* If enabled, let runtime PM know the card is powered off */
-       if (pm_runtime_enabled(&func->dev))
-               ret = pm_runtime_put_sync(&func->dev);
+       /* Let runtime PM know the card is powered off */
+       pm_runtime_put_sync(&card->dev);
 
+out:
        return ret;
 }