diff options
| author | Emmanuel Vadot <manu@FreeBSD.org> | 2019-12-11 18:41:13 +0000 |
|---|---|---|
| committer | Emmanuel Vadot <manu@FreeBSD.org> | 2019-12-11 18:41:13 +0000 |
| commit | 87dc015dbf35da3ff8b484602f631bc2dd1a2784 (patch) | |
| tree | 12ac6c5366c705c969066a2423bb347aebbb2aa2 /sys/dev/mmc | |
| parent | 6fe4e8bdbd52c3d45cba127536aba065ed6f6155 (diff) | |
Notes
Diffstat (limited to 'sys/dev/mmc')
| -rw-r--r-- | sys/dev/mmc/host/dwmmc.c | 61 | ||||
| -rw-r--r-- | sys/dev/mmc/host/dwmmc_rockchip.c | 1 | ||||
| -rw-r--r-- | sys/dev/mmc/host/dwmmc_var.h | 2 |
3 files changed, 63 insertions, 1 deletions
diff --git a/sys/dev/mmc/host/dwmmc.c b/sys/dev/mmc/host/dwmmc.c index a6b01f9ad4f0..38e5b63fc6ee 100644 --- a/sys/dev/mmc/host/dwmmc.c +++ b/sys/dev/mmc/host/dwmmc.c @@ -537,6 +537,22 @@ parse_fdt(struct dwmmc_softc *sc) clk_get_freq(sc->ciu, &sc->bus_hz); } + /* Enable regulators */ + if (sc->vmmc != NULL) { + error = regulator_enable(sc->vmmc); + if (error != 0) { + device_printf(sc->dev, "Cannot enable vmmc regulator\n"); + goto fail; + } + } + if (sc->vqmmc != NULL) { + error = regulator_enable(sc->vqmmc); + if (error != 0) { + device_printf(sc->dev, "Cannot enable vqmmc regulator\n"); + goto fail; + } + } + /* Take dwmmc out of reset */ if (sc->hwreset != NULL) { error = hwreset_deassert(sc->hwreset); @@ -661,10 +677,53 @@ dwmmc_attach(device_t dev) sc->host.caps |= MMC_CAP_HSPEED; sc->host.caps |= MMC_CAP_SIGNALING_330; - device_add_child(dev, "mmc", -1); + sc->child = device_add_child(dev, "mmc", -1); return (bus_generic_attach(dev)); } +int +dwmmc_detach(device_t dev) +{ + struct dwmmc_softc *sc; + int ret; + + sc = device_get_softc(dev); + + ret = bus_generic_detach(dev); + if (ret != 0) + return (ret); + + DWMMC_LOCK_DESTROY(sc); + if (sc->intr_cookie != NULL) { + ret = bus_teardown_intr(dev, sc->res[1], sc->intr_cookie); + if (ret != 0) + return (ret); + } + bus_release_resources(dev, dwmmc_spec, sc->res); + + if (sc->child) { + ret = device_delete_child(dev, sc->child); + if (ret != 0) + return (ret); + } + +#ifdef EXT_RESOURCES + if (sc->hwreset != NULL && hwreset_deassert(sc->hwreset) != 0) + device_printf(sc->dev, "cannot deassert reset\n"); + if (sc->biu != NULL && clk_disable(sc->biu) != 0) + device_printf(sc->dev, "cannot disable biu clock\n"); + if (sc->ciu != NULL && clk_disable(sc->ciu) != 0) + device_printf(sc->dev, "cannot disable ciu clock\n"); + + if (sc->vmmc && regulator_disable(sc->vmmc) != 0) + device_printf(sc->dev, "Cannot disable vmmc regulator\n"); + if (sc->vqmmc && regulator_disable(sc->vqmmc) != 0) + device_printf(sc->dev, "Cannot disable vqmmc regulator\n"); +#endif + + return (0); +} + static int dwmmc_setup_bus(struct dwmmc_softc *sc, int freq) { diff --git a/sys/dev/mmc/host/dwmmc_rockchip.c b/sys/dev/mmc/host/dwmmc_rockchip.c index b0452da3d405..d21e72d88aef 100644 --- a/sys/dev/mmc/host/dwmmc_rockchip.c +++ b/sys/dev/mmc/host/dwmmc_rockchip.c @@ -133,6 +133,7 @@ static device_method_t rockchip_dwmmc_methods[] = { /* bus interface */ DEVMETHOD(device_probe, rockchip_dwmmc_probe), DEVMETHOD(device_attach, rockchip_dwmmc_attach), + DEVMETHOD(device_detach, dwmmc_detach), DEVMETHOD_END }; diff --git a/sys/dev/mmc/host/dwmmc_var.h b/sys/dev/mmc/host/dwmmc_var.h index ae4f547a88bd..52956bfc3566 100644 --- a/sys/dev/mmc/host/dwmmc_var.h +++ b/sys/dev/mmc/host/dwmmc_var.h @@ -61,6 +61,7 @@ struct dwmmc_softc { uint32_t use_pio; uint32_t pwren_inverted; u_int desc_count; + device_t child; int (*update_ios)(struct dwmmc_softc *sc, struct mmc_ios *ios); @@ -94,5 +95,6 @@ struct dwmmc_softc { DECLARE_CLASS(dwmmc_driver); int dwmmc_attach(device_t); +int dwmmc_detach(device_t); #endif |
