diff options
Diffstat (limited to 'drivers/firmware/qcom_scm.c')
-rw-r--r-- | drivers/firmware/qcom_scm.c | 55 |
1 files changed, 27 insertions, 28 deletions
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 2be5573dce53..21e07a464bd9 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -113,11 +113,10 @@ static void qcom_scm_clk_disable(void) clk_disable_unprepare(__scm->bus_clk); } -enum qcom_scm_convention qcom_scm_convention; -static bool has_queried __read_mostly; -static DEFINE_SPINLOCK(query_lock); +enum qcom_scm_convention qcom_scm_convention = SMC_CONVENTION_UNKNOWN; +static DEFINE_SPINLOCK(scm_query_lock); -static void __query_convention(void) +static enum qcom_scm_convention __get_convention(void) { unsigned long flags; struct qcom_scm_desc desc = { @@ -130,36 +129,36 @@ static void __query_convention(void) .owner = ARM_SMCCC_OWNER_SIP, }; struct qcom_scm_res res; + enum qcom_scm_convention probed_convention; int ret; - spin_lock_irqsave(&query_lock, flags); - if (has_queried) - goto out; + if (likely(qcom_scm_convention != SMC_CONVENTION_UNKNOWN)) + return qcom_scm_convention; - qcom_scm_convention = SMC_CONVENTION_ARM_64; - // Device isn't required as there is only one argument - no device - // needed to dma_map_single to secure world - ret = scm_smc_call(NULL, &desc, &res, true); + /* + * Device isn't required as there is only one argument - no device + * needed to dma_map_single to secure world + */ + probed_convention = SMC_CONVENTION_ARM_64; + ret = __scm_smc_call(NULL, &desc, probed_convention, &res, true); if (!ret && res.result[0] == 1) - goto out; + goto found; - qcom_scm_convention = SMC_CONVENTION_ARM_32; - ret = scm_smc_call(NULL, &desc, &res, true); + probed_convention = SMC_CONVENTION_ARM_32; + ret = __scm_smc_call(NULL, &desc, probed_convention, &res, true); if (!ret && res.result[0] == 1) - goto out; - - qcom_scm_convention = SMC_CONVENTION_LEGACY; -out: - has_queried = true; - spin_unlock_irqrestore(&query_lock, flags); - pr_info("qcom_scm: convention: %s\n", - qcom_scm_convention_names[qcom_scm_convention]); -} + goto found; + + probed_convention = SMC_CONVENTION_LEGACY; +found: + spin_lock_irqsave(&scm_query_lock, flags); + if (probed_convention != qcom_scm_convention) { + qcom_scm_convention = probed_convention; + pr_info("qcom_scm: convention: %s\n", + qcom_scm_convention_names[qcom_scm_convention]); + } + spin_unlock_irqrestore(&scm_query_lock, flags); -static inline enum qcom_scm_convention __get_convention(void) -{ - if (unlikely(!has_queried)) - __query_convention(); return qcom_scm_convention; } @@ -1239,7 +1238,7 @@ static int qcom_scm_probe(struct platform_device *pdev) __scm = scm; __scm->dev = &pdev->dev; - __query_convention(); + __get_convention(); /* * If requested enable "download mode", from this point on warmboot |