This diff disables sdmmc device detach in the resume path if
APCI reports a non-removable device. This makes hibernate work
for me on a laptop with root disk on internal emmc storage.

With help from kettenis@

diff d7548b5925dd9032f6a15d6aebaed5bffcbcd366 /usr/src
blob - d6afef333a35d34751bc648701701d58dbd2034a
file + sys/dev/acpi/sdhc_acpi.c
--- sys/dev/acpi/sdhc_acpi.c
+++ sys/dev/acpi/sdhc_acpi.c
@@ -237,8 +237,13 @@ sdhc_acpi_do_explore(struct aml_node *node, void *arg)
        /* Override card detect if we have non-removable devices. */
        if (aml_evalinteger(sc->sc_acpi, node, "_RMV", 0, NULL, &rmv))
                rmv = 1;
-       if (rmv == 0 && sc->sc.sc_card_detect == NULL)
-               sc->sc.sc_card_detect = sdhc_acpi_card_detect_nonremovable;
+       if (rmv == 0) {
+               sc->sc.sc_flags |= SDHC_F_NONREMOVABLE;
+               if (sc->sc.sc_card_detect == NULL) {
+                       sc->sc.sc_card_detect =
+                           sdhc_acpi_card_detect_nonremovable;
+               }
+       }
 
        sdhc_acpi_power_on(sc, node);
 
blob - 248878293e30407ccaf8b9c7ce4a901dbd9aca6c
file + sys/dev/sdmmc/sdhc.c
--- sys/dev/sdmmc/sdhc.c
+++ sys/dev/sdmmc/sdhc.c
@@ -335,6 +335,9 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t
        if (ISSET(sc->sc_flags, SDHC_F_NODDR50))
                saa.caps &= ~SMC_CAPS_MMC_DDR52;
 
+       if (ISSET(sc->sc_flags, SDHC_F_NONREMOVABLE))
+               saa.caps |= SMC_CAPS_NONREMOVABLE;
+
        hp->sdmmc = config_found(&sc->sc_dev, &saa, NULL);
        if (hp->sdmmc == NULL) {
                error = 0;
blob - 7775015ac97e7f275f51306e5a0829cd9bd31d83
file + sys/dev/sdmmc/sdhcvar.h
--- sys/dev/sdmmc/sdhcvar.h
+++ sys/dev/sdmmc/sdhcvar.h
@@ -48,5 +48,6 @@ void  sdhc_needs_discover(struct sdhc_softc *);
 /* flag values */
 #define SDHC_F_NOPWR0          (1 << 0)
 #define SDHC_F_NODDR50         (1 << 1)
+#define SDHC_F_NONREMOVABLE    (1 << 2)
 
 #endif
blob - 32285bce1cb57c6778a90551b69f62701dc1c59a
file + sys/dev/sdmmc/sdmmc.c
--- sys/dev/sdmmc/sdmmc.c
+++ sys/dev/sdmmc/sdmmc.c
@@ -181,7 +181,8 @@ sdmmc_activate(struct device *self, int act)
        case DVACT_SUSPEND:
                rv = config_activate_children(self, act);
                /* If card in slot, cause a detach/re-attach */
-               if (ISSET(sc->sc_flags, SMF_CARD_PRESENT))
+               if (ISSET(sc->sc_flags, SMF_CARD_PRESENT) &&
+                   !ISSET(sc->sc_caps, SMC_CAPS_NONREMOVABLE))
                        sc->sc_dying = -1;
                break;
        case DVACT_RESUME:
blob - 1cc635e3182fd8e532d4d534b8010cfa22002b51
file + sys/dev/sdmmc/sdmmcvar.h
--- sys/dev/sdmmc/sdmmcvar.h
+++ sys/dev/sdmmc/sdmmcvar.h
@@ -200,6 +200,7 @@ struct sdmmc_softc {
 #define SMC_CAPS_MMC_DDR52     0x2000  /* eMMC DDR52 timing */
 #define SMC_CAPS_MMC_HS200     0x4000  /* eMMC HS200 timing */
 #define SMC_CAPS_MMC_HS400     0x8000  /* eMMC HS400 timing */
+#define SMC_CAPS_NONREMOVABLE  0x10000 /* non-removable devices */
 
        int sc_function_count;          /* number of I/O functions (SDIO) */
        struct sdmmc_function *sc_card; /* selected card */



Reply via email to