return 0;
 }
 
+/*
+ * Handle the detection and initialisation of a card.
+ *
+ * In the case of a resume, "oldcard" will contain the card
+ * we're trying to reinitialise.
+ */
+static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
+                             struct mmc_card *oldcard)
+{
+       struct mmc_card *card;
+       int err;
+
+       BUG_ON(!host);
+       WARN_ON(!host->claimed);
+
+       /*
+        * Inform the card of the voltage
+        */
+       err = mmc_send_io_op_cond(host, host->ocr, &ocr);
+       if (err)
+               goto err;
+
+       /*
+        * For SPI, enable CRC as appropriate.
+        */
+       if (mmc_host_is_spi(host)) {
+               err = mmc_spi_set_crc(host, use_spi_crc);
+               if (err)
+                       goto err;
+       }
+
+       /*
+        * Allocate card structure.
+        */
+       card = mmc_alloc_card(host, NULL);
+       if (IS_ERR(card)) {
+               err = PTR_ERR(card);
+               goto err;
+       }
+
+       card->type = MMC_TYPE_SDIO;
+
+       /*
+        * For native busses:  set card RCA and quit open drain mode.
+        */
+       if (!mmc_host_is_spi(host)) {
+               err = mmc_send_relative_addr(host, &card->rca);
+               if (err)
+                       goto remove;
+
+               mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
+       }
+
+       /*
+        * Select card, as all following commands rely on that.
+        */
+       if (!mmc_host_is_spi(host)) {
+               err = mmc_select_card(card);
+               if (err)
+                       goto remove;
+       }
+
+       /*
+        * Read the common registers.
+        */
+       err = sdio_read_cccr(card);
+       if (err)
+               goto remove;
+
+       /*
+        * Read the common CIS tuples.
+        */
+       err = sdio_read_common_cis(card);
+       if (err)
+               goto remove;
+
+       if (oldcard) {
+               int same = (card->cis.vendor == oldcard->cis.vendor &&
+                           card->cis.device == oldcard->cis.device);
+               mmc_remove_card(card);
+               if (!same) {
+                       err = -ENOENT;
+                       goto err;
+               }
+               card = oldcard;
+       }
+
+       /*
+        * Switch to high-speed (if supported).
+        */
+       err = sdio_enable_hs(card);
+       if (err)
+               goto remove;
+
+       /*
+        * Change to the card's maximum speed.
+        */
+       if (mmc_card_highspeed(card)) {
+               /*
+                * The SDIO specification doesn't mention how
+                * the CIS transfer speed register relates to
+                * high-speed, but it seems that 50 MHz is
+                * mandatory.
+                */
+               mmc_set_clock(host, 50000000);
+       } else {
+               mmc_set_clock(host, card->cis.max_dtr);
+       }
+
+       /*
+        * Switch to wider bus (if supported).
+        */
+       err = sdio_enable_wide(card);
+       if (err)
+               goto remove;
+
+       if (!oldcard)
+               host->card = card;
+       return 0;
+
+remove:
+       if (!oldcard)
+               mmc_remove_card(card);
+
+err:
+       return err;
+}
+
 /*
  * Host is being removed. Free up the current card.
  */
        }
 }
 
+/*
+ * SDIO suspend.  We need to suspend all functions separately.
+ * Therefore all registered functions must have drivers with suspend
+ * and resume methods.  Failing that we simply remove the whole card.
+ */
+static void mmc_sdio_suspend(struct mmc_host *host)
+{
+       int i;
+
+       /* make sure all registered functions can suspend/resume */
+       for (i = 0; i < host->card->sdio_funcs; i++) {
+               struct sdio_func *func = host->card->sdio_func[i];
+               if (func && sdio_func_present(func) && func->dev.driver) {
+                       const struct dev_pm_ops *pmops = func->dev.driver->pm;
+                       if (!pmops || !pmops->suspend || !pmops->resume) {
+                               /* just remove the entire card in that case */
+                               mmc_sdio_remove(host);
+                               mmc_claim_host(host);
+                               mmc_detach_bus(host);
+                               mmc_release_host(host);
+                               return;
+                       }
+               }
+       }
+
+       /* now suspend them */
+       for (i = 0; i < host->card->sdio_funcs; i++) {
+               struct sdio_func *func = host->card->sdio_func[i];
+               if (func && sdio_func_present(func) && func->dev.driver) {
+                       const struct dev_pm_ops *pmops = func->dev.driver->pm;
+                       pmops->suspend(&func->dev);
+               }
+       }
+}
+
+static void mmc_sdio_resume(struct mmc_host *host)
+{
+       int i, err;
+
+       BUG_ON(!host);
+       BUG_ON(!host->card);
+
+       mmc_claim_host(host);
+       err = mmc_sdio_init_card(host, host->ocr, host->card);
+       mmc_release_host(host);
+       if (err) {
+               mmc_sdio_remove(host);
+               mmc_claim_host(host);
+               mmc_detach_bus(host);
+               mmc_release_host(host);
+               return;
+       }
+
+       /* resume all functions */
+       for (i = 0; i < host->card->sdio_funcs; i++) {
+               struct sdio_func *func = host->card->sdio_func[i];
+               if (func && sdio_func_present(func) && func->dev.driver) {
+                       const struct dev_pm_ops *pmops = func->dev.driver->pm;
+                       pmops->resume(&func->dev);
+               }
+       }
+}
 
 static const struct mmc_bus_ops mmc_sdio_ops = {
        .remove = mmc_sdio_remove,
        .detect = mmc_sdio_detect,
+       .suspend = mmc_sdio_suspend,
+       .resume = mmc_sdio_resume,
 };
 
 
        }
 
        /*
-        * Inform the card of the voltage
+        * Detect and init the card.
         */
-       err = mmc_send_io_op_cond(host, host->ocr, &ocr);
+       err = mmc_sdio_init_card(host, host->ocr, NULL);
        if (err)
                goto err;
-
-       /*
-        * For SPI, enable CRC as appropriate.
-        */
-       if (mmc_host_is_spi(host)) {
-               err = mmc_spi_set_crc(host, use_spi_crc);
-               if (err)
-                       goto err;
-       }
+       card = host->card;
 
        /*
         * The number of functions on the card is encoded inside
         * the ocr.
         */
-       funcs = (ocr & 0x70000000) >> 28;
-
-       /*
-        * Allocate card structure.
-        */
-       card = mmc_alloc_card(host, NULL);
-       if (IS_ERR(card)) {
-               err = PTR_ERR(card);
-               goto err;
-       }
-
-       card->type = MMC_TYPE_SDIO;
-       card->sdio_funcs = funcs;
-
-       host->card = card;
-
-       /*
-        * For native busses:  set card RCA and quit open drain mode.
-        */
-       if (!mmc_host_is_spi(host)) {
-               err = mmc_send_relative_addr(host, &card->rca);
-               if (err)
-                       goto remove;
-
-               mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL);
-       }
-
-       /*
-        * Select card, as all following commands rely on that.
-        */
-       if (!mmc_host_is_spi(host)) {
-               err = mmc_select_card(card);
-               if (err)
-                       goto remove;
-       }
-
-       /*
-        * Read the common registers.
-        */
-       err = sdio_read_cccr(card);
-       if (err)
-               goto remove;
-
-       /*
-        * Read the common CIS tuples.
-        */
-       err = sdio_read_common_cis(card);
-       if (err)
-               goto remove;
-
-       /*
-        * Switch to high-speed (if supported).
-        */
-       err = sdio_enable_hs(card);
-       if (err)
-               goto remove;
-
-       /*
-        * Change to the card's maximum speed.
-        */
-       if (mmc_card_highspeed(card)) {
-               /*
-                * The SDIO specification doesn't mention how
-                * the CIS transfer speed register relates to
-                * high-speed, but it seems that 50 MHz is
-                * mandatory.
-                */
-               mmc_set_clock(host, 50000000);
-       } else {
-               mmc_set_clock(host, card->cis.max_dtr);
-       }
-
-       /*
-        * Switch to wider bus (if supported).
-        */
-       err = sdio_enable_wide(card);
-       if (err)
-               goto remove;
+       card->sdio_funcs = funcs = (ocr & 0x70000000) >> 28;
 
        /*
         * If needed, disconnect card detection pull-up resistor.