Index: sys/dev/mmc/mmc.c =================================================================== --- sys/dev/mmc/mmc.c +++ sys/dev/mmc/mmc.c @@ -53,6 +53,8 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_platform.h" + #include #include #include @@ -65,12 +67,22 @@ #include #include +#ifdef FDT +#include +#include +#endif + #include #include #include #include "mmcbr_if.h" #include "mmcbus_if.h" +#ifdef FDT +#include +#include +#endif + struct mmc_softc { device_t dev; struct mtx sc_mtx; @@ -80,6 +92,10 @@ int squelched; /* suppress reporting of (expected) errors */ int log_count; struct timeval log_time; +#ifdef FDT + gpio_pin_t cd_gpio; + bool cd_value; +#endif }; #define LOG_PPS 5 /* Log no more than 5 errors per second. */ @@ -224,11 +240,31 @@ mmc_attach(device_t dev) { struct mmc_softc *sc; +#ifdef FDT + phandle_t node; +#endif sc = device_get_softc(dev); sc->dev = dev; MMC_LOCK_INIT(sc); +#ifdef FDT + /* Map the cd-gpios if it exists */ + + if ((node = ofw_bus_get_node(device_get_parent(dev))) == -1) + return (ENXIO); + + ofw_gpiobus_parse_gpios(device_get_parent(dev), "cd-gpios", &sc->cd_gpio); + if (sc->cd_gpio) { + gpio_pin_setflags(sc->cd_gpio, GPIO_PIN_INPUT); + + if (OF_hasprop(node, "cd-inverted") == 1) + sc->cd_value = false; + else + sc->cd_value = true; + } +#endif + /* We'll probe and attach our children later, but before / mount */ sc->config_intrhook.ich_func = mmc_delayed_attach; sc->config_intrhook.ich_arg = sc; @@ -1770,7 +1806,19 @@ mmc_delayed_attach(void *xsc) { struct mmc_softc *sc = xsc; - +#ifdef FDT + bool cd_status; + + if (sc->cd_gpio) { + gpio_pin_is_active(sc->cd_gpio, &cd_status); + + if (cd_status != sc->cd_value) { + config_intrhook_disestablish(&sc->config_intrhook); + return; + } + } +#endif + mmc_scan(sc); config_intrhook_disestablish(&sc->config_intrhook); }