dwmmc: Add a detach method
This method will disable the regulators, clocks and assert the reset of the module. It will also detach it's children (the mmc device) and release it's resources. While here enable the regulators on attach as we need them to power up the sdcard or emmc. MFC after: 1 month
This commit is contained in:
parent
6fe4e8bdbd
commit
87dc015dbf
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user