ODROID-COMMON:Reset uSD card to high-speed mode on reboot.

Fixes a problem where watchdog reset does not work properly on some cards that support UHS.

Change-Id: I940b993ea6d06196220a59557dede8fd2b556af7
Signed-off-by: femto <ckkim@hardkernel.com>
Signed-off-by: Yang Deokgyu <secugyu@gmail.com>
This commit is contained in:
femto
2019-10-15 17:48:00 +09:00
committed by Dongjin Kim
parent a107404a1f
commit 18432c8a65
3 changed files with 66 additions and 1 deletions

View File

@@ -375,6 +375,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;

View File

@@ -327,7 +327,7 @@
cpuinfo_cmd = <0x82000044>;
};
aml_reboot{
reboot: aml_reboot{
compatible = "aml, reboot";
sys_reset = <0x84000009>;
sys_poweroff = <0x84000008>;

View File

@@ -35,9 +35,24 @@
#include <linux/arm-smccc.h>
static void __iomem *reboot_reason_vaddr;
#if defined(CONFIG_ARCH_MESON64_ODROID_COMMON)
#include <linux/gpio.h>
#include <linux/of_gpio.h>
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;
@@ -107,8 +122,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);
}
@@ -149,6 +197,9 @@ DEVICE_ATTR(reboot_reason, 0444, reboot_reason_show, NULL);
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;
u32 paddr = 0;
@@ -171,6 +222,15 @@ static int aml_restart_probe(struct platform_device *pdev)
device_create_file(&pdev->dev, &dev_attr_reboot_reason);
}
#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);
if (ret != 0) {
pr_err("%s,register die notifier failed,ret =%d!\n",