mmc: sdhci-pci: Let suspend/resume callbacks replace default callbacks
authorAdrian Hunter <adrian.hunter@intel.com>
Mon, 20 Mar 2017 17:50:51 +0000 (19:50 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 24 Apr 2017 19:41:38 +0000 (21:41 +0200)
The suspend / resume callbacks lack the flexibility to allow a device to
specify a different function entirely. Change them around so that device
functions are called directly and they in turn can call the default
implementations if needed.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Ludovic Desroches <ludovic.desroches@microchip.com>
drivers/mmc/host/sdhci-pci-core.c
drivers/mmc/host/sdhci-pci-o2micro.c
drivers/mmc/host/sdhci-pci.h

index 47a3965dff4dc2535f98e94566da77ef63348c15..5ed8369704fd14e81fb1fc12b625848976e94eb7 100644 (file)
@@ -37,6 +37,88 @@ static int sdhci_pci_enable_dma(struct sdhci_host *host);
 static void sdhci_pci_set_bus_width(struct sdhci_host *host, int width);
 static void sdhci_pci_hw_reset(struct sdhci_host *host);
 
+#ifdef CONFIG_PM_SLEEP
+static int __sdhci_pci_suspend_host(struct sdhci_pci_chip *chip)
+{
+       int i, ret;
+
+       for (i = 0; i < chip->num_slots; i++) {
+               struct sdhci_pci_slot *slot = chip->slots[i];
+               struct sdhci_host *host;
+
+               if (!slot)
+                       continue;
+
+               host = slot->host;
+
+               if (chip->pm_retune && host->tuning_mode != SDHCI_TUNING_MODE_3)
+                       mmc_retune_needed(host->mmc);
+
+               ret = sdhci_suspend_host(host);
+               if (ret)
+                       goto err_pci_suspend;
+
+               if (host->mmc->pm_flags & MMC_PM_WAKE_SDIO_IRQ)
+                       sdhci_enable_irq_wakeups(host);
+       }
+
+       return 0;
+
+err_pci_suspend:
+       while (--i >= 0)
+               sdhci_resume_host(chip->slots[i]->host);
+       return ret;
+}
+
+static int sdhci_pci_init_wakeup(struct sdhci_pci_chip *chip)
+{
+       mmc_pm_flag_t pm_flags = 0;
+       int i;
+
+       for (i = 0; i < chip->num_slots; i++) {
+               struct sdhci_pci_slot *slot = chip->slots[i];
+
+               if (slot)
+                       pm_flags |= slot->host->mmc->pm_flags;
+       }
+
+       return device_init_wakeup(&chip->pdev->dev,
+                                 (pm_flags & MMC_PM_KEEP_POWER) &&
+                                 (pm_flags & MMC_PM_WAKE_SDIO_IRQ));
+}
+
+static int sdhci_pci_suspend_host(struct sdhci_pci_chip *chip)
+{
+       int ret;
+
+       ret = __sdhci_pci_suspend_host(chip);
+       if (ret)
+               return ret;
+
+       sdhci_pci_init_wakeup(chip);
+
+       return 0;
+}
+
+int sdhci_pci_resume_host(struct sdhci_pci_chip *chip)
+{
+       struct sdhci_pci_slot *slot;
+       int i, ret;
+
+       for (i = 0; i < chip->num_slots; i++) {
+               slot = chip->slots[i];
+               if (!slot)
+                       continue;
+
+               ret = sdhci_resume_host(slot->host);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+#endif
+
 /*****************************************************************************\
  *                                                                           *
  * Hardware specific quirk handling                                          *
@@ -74,7 +156,7 @@ static int ricoh_mmc_resume(struct sdhci_pci_chip *chip)
        /* Otherwise it becomes confused if card state changed
                during suspend */
        msleep(500);
-       return 0;
+       return sdhci_pci_resume_host(chip);
 }
 #endif
 
@@ -758,7 +840,11 @@ static void jmicron_remove_slot(struct sdhci_pci_slot *slot, int dead)
 #ifdef CONFIG_PM_SLEEP
 static int jmicron_suspend(struct sdhci_pci_chip *chip)
 {
-       int i;
+       int i, ret;
+
+       ret = __sdhci_pci_suspend_host(chip);
+       if (ret)
+               return ret;
 
        if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
            chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
@@ -766,6 +852,8 @@ static int jmicron_suspend(struct sdhci_pci_chip *chip)
                        jmicron_enable_mmc(chip->slots[i]->host, 0);
        }
 
+       sdhci_pci_init_wakeup(chip);
+
        return 0;
 }
 
@@ -785,7 +873,7 @@ static int jmicron_resume(struct sdhci_pci_chip *chip)
                return ret;
        }
 
-       return 0;
+       return sdhci_pci_resume_host(chip);
 }
 #endif
 
@@ -1678,89 +1766,29 @@ static const struct sdhci_ops sdhci_pci_ops = {
 static int sdhci_pci_suspend(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
-       struct sdhci_pci_chip *chip;
-       struct sdhci_pci_slot *slot;
-       struct sdhci_host *host;
-       mmc_pm_flag_t slot_pm_flags;
-       mmc_pm_flag_t pm_flags = 0;
-       int i, ret;
+       struct sdhci_pci_chip *chip = pci_get_drvdata(pdev);
 
-       chip = pci_get_drvdata(pdev);
        if (!chip)
                return 0;
 
-       for (i = 0; i < chip->num_slots; i++) {
-               slot = chip->slots[i];
-               if (!slot)
-                       continue;
-
-               host = slot->host;
-
-               if (chip->pm_retune && host->tuning_mode != SDHCI_TUNING_MODE_3)
-                       mmc_retune_needed(host->mmc);
-
-               ret = sdhci_suspend_host(host);
-
-               if (ret)
-                       goto err_pci_suspend;
-
-               slot_pm_flags = host->mmc->pm_flags;
-               if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ)
-                       sdhci_enable_irq_wakeups(host);
+       if (chip->fixes && chip->fixes->suspend)
+               return chip->fixes->suspend(chip);
 
-               pm_flags |= slot_pm_flags;
-       }
-
-       if (chip->fixes && chip->fixes->suspend) {
-               ret = chip->fixes->suspend(chip);
-               if (ret)
-                       goto err_pci_suspend;
-       }
-
-       if (pm_flags & MMC_PM_KEEP_POWER) {
-               if (pm_flags & MMC_PM_WAKE_SDIO_IRQ)
-                       device_init_wakeup(dev, true);
-               else
-                       device_init_wakeup(dev, false);
-       } else
-               device_init_wakeup(dev, false);
-
-       return 0;
-
-err_pci_suspend:
-       while (--i >= 0)
-               sdhci_resume_host(chip->slots[i]->host);
-       return ret;
+       return sdhci_pci_suspend_host(chip);
 }
 
 static int sdhci_pci_resume(struct device *dev)
 {
        struct pci_dev *pdev = to_pci_dev(dev);
-       struct sdhci_pci_chip *chip;
-       struct sdhci_pci_slot *slot;
-       int i, ret;
+       struct sdhci_pci_chip *chip = pci_get_drvdata(pdev);
 
-       chip = pci_get_drvdata(pdev);
        if (!chip)
                return 0;
 
-       if (chip->fixes && chip->fixes->resume) {
-               ret = chip->fixes->resume(chip);
-               if (ret)
-                       return ret;
-       }
-
-       for (i = 0; i < chip->num_slots; i++) {
-               slot = chip->slots[i];
-               if (!slot)
-                       continue;
-
-               ret = sdhci_resume_host(slot->host);
-               if (ret)
-                       return ret;
-       }
+       if (chip->fixes && chip->fixes->resume)
+               return chip->fixes->resume(chip);
 
-       return 0;
+       return sdhci_pci_resume_host(chip);
 }
 #endif
 
index 0ea34e2c7cba53b0425a80aff0edad1265b6a3f9..14273ca0064195af371e9e0859f1d83caa34365a 100644 (file)
@@ -388,6 +388,6 @@ int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip)
 int sdhci_pci_o2_resume(struct sdhci_pci_chip *chip)
 {
        sdhci_pci_o2_probe(chip);
-       return 0;
+       return sdhci_pci_resume_host(chip);
 }
 #endif
index e70a27058e0b13a7bad894e8c0455aaed6f0e68a..ec8f91c403d630ccd4a16e128a443ee982c29826 100644 (file)
@@ -111,4 +111,8 @@ static inline void *sdhci_pci_priv(struct sdhci_pci_slot *slot)
        return (void *)slot->private;
 }
 
+#ifdef CONFIG_PM_SLEEP
+int sdhci_pci_resume_host(struct sdhci_pci_chip *chip);
+#endif
+
 #endif /* __SDHCI_PCI_H */