diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index bfc5e6723eb9..2abac54ed1f3 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -534,23 +534,23 @@ static int qcom_scm_io_rmw(phys_addr_t addr, unsigned int mask, unsigned int val return qcom_scm_io_writel(addr, new); } -static void qcom_scm_set_download_mode(u32 dload_mode) +static void qcom_scm_set_download_mode(struct qcom_scm *scm, u32 dload_mode) { int ret = 0; - if (__scm->dload_mode_addr) { - ret = qcom_scm_io_rmw(__scm->dload_mode_addr, QCOM_DLOAD_MASK, + if (scm->dload_mode_addr) { + ret = qcom_scm_io_rmw(scm->dload_mode_addr, QCOM_DLOAD_MASK, FIELD_PREP(QCOM_DLOAD_MASK, dload_mode)); - } else if (__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_BOOT, + } else if (__qcom_scm_is_call_available(scm->dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_DLOAD_MODE)) { - ret = __qcom_scm_set_dload_mode(__scm->dev, !!dload_mode); + ret = __qcom_scm_set_dload_mode(scm->dev, !!dload_mode); } else if (dload_mode) { - dev_err(__scm->dev, + dev_err(scm->dev, "No available mechanism for setting download mode\n"); } if (ret) - dev_err(__scm->dev, "failed to set download mode: %d\n", ret); + dev_err(scm->dev, "failed to set download mode: %d\n", ret); } struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev, @@ -2673,6 +2673,7 @@ static int get_download_mode(char *buffer, const struct kernel_param *kp) static int set_download_mode(const char *val, const struct kernel_param *kp) { + struct qcom_scm *scm; bool tmp; int ret; @@ -2688,8 +2689,10 @@ static int set_download_mode(const char *val, const struct kernel_param *kp) } download_mode = ret; - if (__scm) - qcom_scm_set_download_mode(download_mode); + /* Pairs with smp_store_release() in qcom_scm_probe(). */ + scm = smp_load_acquire(&__scm); + if (scm) + qcom_scm_set_download_mode(scm, download_mode); return 0; } @@ -2815,7 +2818,7 @@ static int qcom_scm_probe(struct platform_device *pdev) * will cause the boot stages to enter download mode, unless * disabled below by a clean shutdown/reboot. */ - qcom_scm_set_download_mode(download_mode); + qcom_scm_set_download_mode(scm, download_mode); /* * Disable SDI if indicated by DT that it is enabled by default. @@ -2848,7 +2851,7 @@ static int qcom_scm_probe(struct platform_device *pdev) static void qcom_scm_shutdown(struct platform_device *pdev) { /* Clean shutdown, disable download mode to allow normal restart */ - qcom_scm_set_download_mode(QCOM_DLOAD_NODUMP); + qcom_scm_set_download_mode(__scm, QCOM_DLOAD_NODUMP); qcom_pas_ops_unregister(); }