@@ -597,11 +597,42 @@ static int ni_set_max_freq(struct sdhci_pci_slot *slot)
return 0;
}
+
+static bool __sdhci_pci_child_has_s4w(struct acpi_device *child)
+{
+ acpi_handle handle = child->handle;
+ unsigned long long ret;
+
+ return ACPI_SUCCESS(acpi_evaluate_integer(handle, "_S4W", NULL, &ret));
+}
+
+static bool sdhci_pci_child_has_s4w(struct sdhci_pci_slot *slot)
+{
+ struct acpi_device *adev = ACPI_COMPANION(&slot->chip->pdev->dev);
+ struct acpi_device *child;
+ bool child_has_s4w = false;
+
+ if (!adev)
+ return false;
+
+ list_for_each_entry(child, &adev->children, node)
+ if (child->status.present && child->status.enabled) {
+ if (__sdhci_pci_child_has_s4w(child))
+ child_has_s4w = true;
+ }
+
+ return child_has_s4w;
+}
#else
static inline int ni_set_max_freq(struct sdhci_pci_slot *slot)
{
return 0;
}
+
+static bool sdhci_pci_child_has_s4w(struct sdhci_pci_slot *slot)
+{
+ return false;
+}
#endif
static int ni_byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
@@ -1960,6 +1991,9 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot(
host->ioaddr = pcim_iomap_table(pdev)[bar];
+ if (sdhci_pci_child_has_s4w(slot))
+ host->mmc->caps2 |= MMC_CAP2_NO_SDIO_RESET;
+
if (chip->fixes && chip->fixes->probe_slot) {
ret = chip->fixes->probe_slot(slot);
if (ret)
SDIO reset interferes with a SDIO function driver's restore from hibernation. Set MMC_CAP2_NO_SDIO_RESET if a child node has _S4W method which indicates a capability to wake from S4 (hibernate). Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> --- drivers/mmc/host/sdhci-pci-core.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)