diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom_scm-smc.c index 2fb3b66896cd..a731a5f504f0 100644 --- a/drivers/firmware/qcom_scm-smc.c +++ b/drivers/firmware/qcom_scm-smc.c @@ -2321,7 +2321,7 @@ int __qcom_scm_invoke_smc_legacy(struct device *dev, phys_addr_t in_buf, desc.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_RW, QCOM_SCM_VAL); - ret = qcom_scm_call(dev, &desc); + ret = qcom_scm_call_noretry(dev, &desc); if (result) *result = desc.res[1]; @@ -2353,7 +2353,7 @@ int __qcom_scm_invoke_smc(struct device *dev, phys_addr_t in_buf, desc.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_RW, QCOM_SCM_VAL); - ret = qcom_scm_call(dev, &desc); + ret = qcom_scm_call_noretry(dev, &desc); if (result) *result = desc.res[1]; @@ -2382,7 +2382,7 @@ int __qcom_scm_invoke_callback_response(struct device *dev, phys_addr_t out_buf, desc.args[1] = out_buf_size; desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW, QCOM_SCM_VAL); - ret = qcom_scm_call(dev, &desc); + ret = qcom_scm_call_noretry(dev, &desc); if (result) *result = desc.res[1]; diff --git a/drivers/soc/qcom/smcinvoke.c b/drivers/soc/qcom/smcinvoke.c index 020d9da02104..da8a33932180 100644 --- a/drivers/soc/qcom/smcinvoke.c +++ b/drivers/soc/qcom/smcinvoke.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,9 @@ #define SMCINVOKE_MEM_MAP_OBJ 0 #define SMCINVOKE_MEM_RGN_OBJ 1 #define SMCINVOKE_MEM_PERM_RW 6 +#define SMCINVOKE_SCM_EBUSY_WAIT_MS 30 +#define SMCINVOKE_SCM_EBUSY_MAX_RETRY 67 + /* TZ defined values - Start */ #define SMCINVOKE_INVOKE_PARAM_ID 0x224 @@ -1288,7 +1292,7 @@ static int prepare_send_scm_msg(const uint8_t *in_buf, phys_addr_t in_paddr, bool *tz_acked, struct qtee_shm *in_shm, struct qtee_shm *out_shm) { - int ret = 0, cmd; + int ret = 0, cmd, retry_count = 0; u64 response_type; unsigned int data; struct file *arr_filp[OBJECT_COUNTS_MAX_OO] = {NULL}; @@ -1311,9 +1315,18 @@ static int prepare_send_scm_msg(const uint8_t *in_buf, phys_addr_t in_paddr, while (1) { mutex_lock(&g_smcinvoke_lock); - ret = invoke_cmd_handler(cmd, in_paddr, in_buf_len, out_buf, - out_paddr, out_buf_len, &req->result, &response_type, - &data, in_shm, out_shm); + do { + ret = invoke_cmd_handler(cmd, in_paddr, in_buf_len, out_buf, + out_paddr, out_buf_len, &req->result, &response_type, + &data, in_shm, out_shm); + + if (ret == -EBUSY) { + pr_err("Secure side is busy,will retry after 30 ms\n"); + msleep(SMCINVOKE_SCM_EBUSY_WAIT_MS); + } + + } while ((ret == -EBUSY) && + (retry_count++ < SMCINVOKE_SCM_EBUSY_MAX_RETRY)); if (!ret && !is_inbound_req(response_type)) { /* dont marshal if Obj returns an error */