mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
        mwifiex_dbg(adapter, MSG, "driver_version = %s\n", fmt);
+       adapter->is_up = true;
        goto done;
 
 err_add_intf:
        mwifiex_deauthenticate(priv, NULL);
 
        mwifiex_uninit_sw(adapter);
+       adapter->is_up = false;
 
        if (adapter->if_ops.down_dev)
                adapter->if_ops.down_dev(adapter);
        if (!adapter)
                return 0;
 
-       mwifiex_uninit_sw(adapter);
+       if (adapter->is_up)
+               mwifiex_uninit_sw(adapter);
 
        if (adapter->irq_wakeup >= 0)
                device_init_wakeup(adapter->dev, false);
 
                return 0;
        }
 
+       if (!adapter->is_up)
+               return -EBUSY;
+
        mwifiex_enable_wake(adapter);
 
        /* Enable the Host Sleep */
        struct sdio_func *func = card->func;
        int ret;
 
+       /* Prepare the adapter for the reset. */
        mwifiex_shutdown_sw(adapter);
+       clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
+       clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
 
-       /* power cycle the adapter */
+       /* Run a HW reset of the SDIO interface. */
        sdio_claim_host(func);
-       mmc_hw_reset(func->card->host);
+       ret = mmc_hw_reset(func->card->host);
        sdio_release_host(func);
 
-       /* Previous save_adapter won't be valid after this. We will cancel
-        * pending work requests.
-        */
-       clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
-       clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
-
-       ret = mwifiex_reinit_sw(adapter);
-       if (ret)
-               dev_err(&func->dev, "reinit failed: %d\n", ret);
+       switch (ret) {
+       case 1:
+               dev_dbg(&func->dev, "SDIO HW reset asynchronous\n");
+               complete_all(adapter->fw_done);
+               break;
+       case 0:
+               ret = mwifiex_reinit_sw(adapter);
+               if (ret)
+                       dev_err(&func->dev, "reinit failed: %d\n", ret);
+               break;
+       default:
+               dev_err(&func->dev, "SDIO HW reset failed: %d\n", ret);
+               break;
+       }
 }
 
 /* This function read/write firmware */