--- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -404,6 +404,20 @@ static int __qcom_scm_set_dload_mode(str return qcom_scm_call_atomic(__scm->dev, &desc, NULL); } +static int __qcom_scm_disable_sdi(struct device *dev) +{ + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_CONFIG_SDI, + .arginfo = QCOM_SCM_ARGS(2), + .args[0] = 1 /* 1: disable watchdog debug */, + .args[1] = 0 /* 0: disable SDI */, + .owner = ARM_SMCCC_OWNER_SIP, + }; + + return qcom_scm_call(__scm->dev, &desc, NULL); +} + static void qcom_scm_set_download_mode(bool enable) { bool avail; @@ -1256,6 +1270,13 @@ static int qcom_scm_probe(struct platfor if (download_mode) qcom_scm_set_download_mode(true); + /* + * Factory firmware leaves SDI (a debug interface), which prevents + * clean reboot. + */ + if (of_machine_is_compatible("google,wifi")) + __qcom_scm_disable_sdi(__scm->dev); + return 0; } --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -77,6 +77,7 @@ extern int scm_legacy_call(struct device #define QCOM_SCM_SVC_BOOT 0x01 #define QCOM_SCM_BOOT_SET_ADDR 0x01 #define QCOM_SCM_BOOT_TERMINATE_PC 0x02 +#define QCOM_SCM_BOOT_CONFIG_SDI 0x09 #define QCOM_SCM_BOOT_SET_DLOAD_MODE 0x10 #define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a #define QCOM_SCM_FLUSH_FLAG_MASK 0x3