diff --git a/arch/arm64/boot/dts/amlogic/meson64_odroidn2.dts b/arch/arm64/boot/dts/amlogic/meson64_odroidn2.dts index 2c7bd0c5a99f..1b431804bd2d 100644 --- a/arch/arm64/boot/dts/amlogic/meson64_odroidn2.dts +++ b/arch/arm64/boot/dts/amlogic/meson64_odroidn2.dts @@ -487,6 +487,11 @@ status = "disabled"; }; +&reboot { + sd_volsw_gpio = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>; + sd_power_gpio = <&gpio_ao GPIOAO_8 GPIO_ACTIVE_HIGH>; +}; + &sd_emmc_b { status = "okay"; sd-uhs-sdr25; diff --git a/arch/arm64/boot/dts/amlogic/mesong12b_a.dtsi b/arch/arm64/boot/dts/amlogic/mesong12b_a.dtsi index e806327d9b18..428fe4552ca2 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12b_a.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12b_a.dtsi @@ -327,7 +327,7 @@ cpuinfo_cmd = <0x82000044>; }; - aml_reboot{ + reboot: aml_reboot{ compatible = "aml, reboot"; sys_reset = <0x84000009>; sys_poweroff = <0x84000008>; diff --git a/drivers/amlogic/mmc/aml_sd_emmc.c b/drivers/amlogic/mmc/aml_sd_emmc.c index 933093c70e74..0218c4deeac9 100644 --- a/drivers/amlogic/mmc/aml_sd_emmc.c +++ b/drivers/amlogic/mmc/aml_sd_emmc.c @@ -3386,39 +3386,6 @@ static int meson_mmc_remove(struct platform_device *pdev) return 0; } -/* - * Shutdown callback - */ -#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON) -static void meson_mmc_shutdown(struct platform_device *pdev) -{ - struct amlsd_host *host = dev_get_drvdata(&pdev->dev); - struct mmc_host *mmc = host->mmc; - - if (mmc) { - struct amlsd_platform *pdata = mmc_priv(mmc); - - if ((pdata->vol_switch) && (pdata->gpio_power)) { - gpio_direction_output(pdata->vol_switch, 0); - mdelay(500); - gpio_direction_output(pdata->vol_switch, 1); - gpio_direction_output(pdata->gpio_power, 0); - mdelay(500); - gpio_direction_output(pdata->vol_switch, 0); - gpio_direction_output(pdata->gpio_power, 1); - mdelay(200); - gpio_free(pdata->vol_switch); - gpio_free(pdata->gpio_power); - } - if (pdata->hw_reset) { - gpio_direction_output(pdata->hw_reset, 0); - mdelay(500); - gpio_direction_output(pdata->hw_reset, 1); - } - } -} -#endif - static struct meson_mmc_data mmc_data_gxbb = { .chip_type = MMC_CHIP_GXBB, .port_a_base = 0xd0070000, @@ -3748,9 +3715,6 @@ MODULE_DEVICE_TABLE(of, meson_mmc_of_match); static struct platform_driver meson_mmc_driver = { .probe = meson_mmc_probe, .remove = meson_mmc_remove, -#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON) - .shutdown = meson_mmc_shutdown, -#endif .driver = { .name = "meson-aml-mmc", .owner = THIS_MODULE, diff --git a/drivers/amlogic/reboot/reboot.c b/drivers/amlogic/reboot/reboot.c index 6e5cd09ad035..112939baa7e5 100644 --- a/drivers/amlogic/reboot/reboot.c +++ b/drivers/amlogic/reboot/reboot.c @@ -38,9 +38,23 @@ #define RAMDUMP_REPLACE_MSG "ramdump disabled, replase panic to normal\n" #endif /* CONFIG_AMLOGIC_RAMDUMP */ +#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON) +#include +#include + +int sd_volsw_gpio; +int sd_power_gpio; +#define CHECK_RET(ret) { \ + if (ret) \ + pr_err("[%s] gpio op failed(%d) at line %d\n",\ + __func__, ret, __LINE__); \ +} +#endif + static u32 psci_function_id_restart; static u32 psci_function_id_poweroff; static char *kernel_panic; + static u32 parse_reason(const char *cmd) { u32 reboot_reason = MESON_NORMAL_BOOT; @@ -114,8 +128,41 @@ void meson_common_restart(char mode, const char *cmd) meson_smc_restart((u64)psci_function_id_restart, (u64)reboot_reason); } + +#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON) +void odroid_card_reset(void) +{ + int ret = 0; + + if ((sd_volsw_gpio == 0) && (sd_power_gpio == 0)) + return; + + gpio_free(sd_volsw_gpio); + gpio_free(sd_power_gpio); + ret = gpio_request_one(sd_volsw_gpio, + GPIOF_OUT_INIT_LOW, "REBOOT"); + CHECK_RET(ret); + mdelay(10); + ret = gpio_direction_output(sd_volsw_gpio, 1); + CHECK_RET(ret); + ret = gpio_request_one(sd_power_gpio, + GPIOF_OUT_INIT_LOW, "REBOOT"); + CHECK_RET(ret); + mdelay(10); + ret = gpio_direction_output(sd_volsw_gpio, 0); + CHECK_RET(ret); + ret = gpio_direction_output(sd_power_gpio, 1); + CHECK_RET(ret); + mdelay(5); + gpio_free(sd_volsw_gpio); + gpio_free(sd_power_gpio); +} +#endif // CONFIG_ARCH_MESON64_ODROID_COMMON static void do_aml_restart(enum reboot_mode reboot_mode, const char *cmd) { +#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON) + odroid_card_reset(); +#endif meson_common_restart(reboot_mode, cmd); } @@ -140,6 +187,9 @@ static struct notifier_block panic_notifier = { static int aml_restart_probe(struct platform_device *pdev) { +#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON) + struct device_node *of_node; +#endif u32 id; int ret; @@ -153,6 +203,14 @@ static int aml_restart_probe(struct platform_device *pdev) pm_power_off = do_aml_poweroff; } +#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON) + of_node = pdev->dev.of_node; + sd_volsw_gpio = 0; + sd_power_gpio = 0; + + sd_volsw_gpio = of_get_named_gpio(of_node, "sd_volsw_gpio", 0); + sd_power_gpio = of_get_named_gpio(of_node, "sd_power_gpio", 0); +#endif ret = register_die_notifier(&panic_notifier); return ret; }