diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c index 372fb6e..a54c290 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c @@ -14,10 +14,12 @@ #include #include #include +#include #include #include "dw_mmc.h" #include "dw_mmc-pltfm.h" +#include "../core/core.h" #define RK3288_CLKGEN_DIV 2 @@ -353,6 +355,27 @@ static int dw_mci_rockchip_probe(struct platform_device *pdev) return 0; } +static void dw_mci_rockchip_platfm_shutdown(struct platform_device *pdev) +{ + struct dw_mci *host = platform_get_drvdata(pdev); + struct mmc_host *mmc = host->slot->mmc; + int ret; + + if(of_machine_is_compatible("asus,rk3288-tinker")){ + + mmc_power_off(mmc); + + mdelay(20); + + if (!IS_ERR(mmc->supply.vmmc)) + ret = regulator_enable(mmc->supply.vmmc); + + if (!IS_ERR(mmc->supply.vqmmc)) + regulator_set_voltage(mmc->supply.vqmmc, 3000000, 3300000); + } + +} + static int dw_mci_rockchip_remove(struct platform_device *pdev) { pm_runtime_get_sync(&pdev->dev); @@ -373,6 +396,7 @@ static const struct dev_pm_ops dw_mci_rockchip_dev_pm_ops = { static struct platform_driver dw_mci_rockchip_pltfm_driver = { .probe = dw_mci_rockchip_probe, .remove = dw_mci_rockchip_remove, + .shutdown = dw_mci_rockchip_platfm_shutdown, .driver = { .name = "dwmmc_rockchip", .of_match_table = dw_mci_rockchip_match, diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index e45129f..faad52d 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -39,8 +39,10 @@ #include #include #include +#include #include "dw_mmc.h" +#include "../core/core.h" /* Common flag combinations */ #define DW_MCI_DATA_ERROR_FLAGS (SDMMC_INT_DRTO | SDMMC_INT_DCRC | \ @@ -2686,6 +2688,30 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +struct dw_mci *mSdhost; + +void setmmcEmergency() { + + struct mmc_host *mmc = mSdhost->slot->mmc; + int ret; + + if(of_machine_is_compatible("asus,rk3288-tinker")){ + + mmc_power_off(mmc); + + mdelay(20); + + if (!IS_ERR(mmc->supply.vmmc)) { + ret = regulator_enable(mmc->supply.vmmc); + } + + if (!IS_ERR(mmc->supply.vqmmc)) + regulator_set_voltage(mmc->supply.vqmmc, 3000000, 3300000); + } + +} + +EXPORT_SYMBOL(setmmcEmergency); static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) { @@ -2717,6 +2743,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) mmc->f_min = freq[0]; mmc->f_max = freq[1]; } + if (of_find_property(host->dev->of_node, "supports-sd", NULL)) + mSdhost = host; /*if there are external regulators, get them*/ ret = mmc_regulator_get_supply(mmc); diff --git a/include/linux/reboot.h b/include/linux/reboot.h index a7ff409..e045bc2 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h @@ -73,6 +73,7 @@ extern char poweroff_cmd[POWEROFF_CMD_PATH_LEN]; extern void orderly_poweroff(bool force); extern void orderly_reboot(void); +extern void setmmcEmergency(void); /* * Emergency restart, callable from an interrupt handler. */ diff --git a/kernel/reboot.c b/kernel/reboot.c index bd30a97..9f99488 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c @@ -61,6 +61,7 @@ void (*pm_power_off_prepare)(void); void emergency_restart(void) { kmsg_dump(KMSG_DUMP_EMERG); + setmmcEmergency(); machine_emergency_restart(); } EXPORT_SYMBOL_GPL(emergency_restart);