qseecom: improve error checks in qseecom_probe()

Make change in qseecom_probe() to improve the error return value
checks on some subfunctions, and free memory allocated within
qseecom_retrieve_ce_data.

CRs-fixed: 1075082
Change-Id: I971e555ec8d02ccf4382e83132a696b065a8ff12
Signed-off-by: Zhen Kong <zkong@codeaurora.org>
This commit is contained in:
Zhen Kong 2016-10-24 10:06:45 -07:00 committed by Gerrit - the friendly Code Review server
parent 61f26e3aa5
commit 268b994d27

View file

@ -8125,11 +8125,12 @@ static int qseecom_check_whitelist_feature(void)
static int qseecom_probe(struct platform_device *pdev) static int qseecom_probe(struct platform_device *pdev)
{ {
int rc; int rc;
int ret = 0; int i;
uint32_t feature = 10; uint32_t feature = 10;
struct device *class_dev; struct device *class_dev;
struct msm_bus_scale_pdata *qseecom_platform_support = NULL; struct msm_bus_scale_pdata *qseecom_platform_support = NULL;
struct qseecom_command_scm_resp resp; struct qseecom_command_scm_resp resp;
struct qseecom_ce_info_use *pce_info_use = NULL;
qseecom.qsee_bw_count = 0; qseecom.qsee_bw_count = 0;
qseecom.qsee_perf_client = 0; qseecom.qsee_perf_client = 0;
@ -8171,7 +8172,7 @@ static int qseecom_probe(struct platform_device *pdev)
class_dev = device_create(driver_class, NULL, qseecom_device_no, NULL, class_dev = device_create(driver_class, NULL, qseecom_device_no, NULL,
QSEECOM_DEV); QSEECOM_DEV);
if (!class_dev) { if (IS_ERR(class_dev)) {
pr_err("class_device_create failed %d\n", rc); pr_err("class_device_create failed %d\n", rc);
rc = -ENOMEM; rc = -ENOMEM;
goto exit_destroy_class; goto exit_destroy_class;
@ -8210,7 +8211,7 @@ static int qseecom_probe(struct platform_device *pdev)
qseecom.pdev = class_dev; qseecom.pdev = class_dev;
/* Create ION msm client */ /* Create ION msm client */
qseecom.ion_clnt = msm_ion_client_create("qseecom-kernel"); qseecom.ion_clnt = msm_ion_client_create("qseecom-kernel");
if (qseecom.ion_clnt == NULL) { if (IS_ERR_OR_NULL(qseecom.ion_clnt)) {
pr_err("Ion client cannot be created\n"); pr_err("Ion client cannot be created\n");
rc = -ENOMEM; rc = -ENOMEM;
goto exit_del_cdev; goto exit_del_cdev;
@ -8272,14 +8273,14 @@ static int qseecom_probe(struct platform_device *pdev)
pr_debug("CE operating frequency is not defined, setting to default 100MHZ\n"); pr_debug("CE operating frequency is not defined, setting to default 100MHZ\n");
qseecom.ce_opp_freq_hz = QSEE_CE_CLK_100MHZ; qseecom.ce_opp_freq_hz = QSEE_CE_CLK_100MHZ;
} }
ret = __qseecom_init_clk(CLK_QSEE); rc = __qseecom_init_clk(CLK_QSEE);
if (ret) if (rc)
goto exit_destroy_ion_client; goto exit_destroy_ion_client;
if ((qseecom.qsee.instance != qseecom.ce_drv.instance) && if ((qseecom.qsee.instance != qseecom.ce_drv.instance) &&
(qseecom.support_pfe || qseecom.support_fde)) { (qseecom.support_pfe || qseecom.support_fde)) {
ret = __qseecom_init_clk(CLK_CE_DRV); rc = __qseecom_init_clk(CLK_CE_DRV);
if (ret) { if (rc) {
__qseecom_deinit_clk(CLK_QSEE); __qseecom_deinit_clk(CLK_QSEE);
goto exit_destroy_ion_client; goto exit_destroy_ion_client;
} }
@ -8333,9 +8334,14 @@ static int qseecom_probe(struct platform_device *pdev)
} else { } else {
pr_err("Fail to get secure app region info\n"); pr_err("Fail to get secure app region info\n");
rc = -EINVAL; rc = -EINVAL;
goto exit_destroy_ion_client; goto exit_deinit_clock;
}
rc = __qseecom_enable_clk(CLK_QSEE);
if (rc) {
pr_err("CLK_QSEE enabling failed (%d)\n", rc);
rc = -EIO;
goto exit_deinit_clock;
} }
__qseecom_enable_clk(CLK_QSEE);
rc = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1, rc = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
cmd_buf, cmd_len, cmd_buf, cmd_len,
&resp, sizeof(resp)); &resp, sizeof(resp));
@ -8344,7 +8350,7 @@ static int qseecom_probe(struct platform_device *pdev)
pr_err("send secapp reg fail %d resp.res %d\n", pr_err("send secapp reg fail %d resp.res %d\n",
rc, resp.result); rc, resp.result);
rc = -EINVAL; rc = -EINVAL;
goto exit_destroy_ion_client; goto exit_deinit_clock;
} }
} }
/* /*
@ -8380,7 +8386,28 @@ static int qseecom_probe(struct platform_device *pdev)
atomic_set(&qseecom.qseecom_state, QSEECOM_STATE_READY); atomic_set(&qseecom.qseecom_state, QSEECOM_STATE_READY);
return 0; return 0;
exit_deinit_clock:
__qseecom_deinit_clk(CLK_QSEE);
if ((qseecom.qsee.instance != qseecom.ce_drv.instance) &&
(qseecom.support_pfe || qseecom.support_fde))
__qseecom_deinit_clk(CLK_CE_DRV);
exit_destroy_ion_client: exit_destroy_ion_client:
if (qseecom.ce_info.fde) {
pce_info_use = qseecom.ce_info.fde;
for (i = 0; i < qseecom.ce_info.num_fde; i++) {
kzfree(pce_info_use->ce_pipe_entry);
pce_info_use++;
}
kfree(qseecom.ce_info.fde);
}
if (qseecom.ce_info.pfe) {
pce_info_use = qseecom.ce_info.pfe;
for (i = 0; i < qseecom.ce_info.num_pfe; i++) {
kzfree(pce_info_use->ce_pipe_entry);
pce_info_use++;
}
kfree(qseecom.ce_info.pfe);
}
ion_client_destroy(qseecom.ion_clnt); ion_client_destroy(qseecom.ion_clnt);
exit_del_cdev: exit_del_cdev:
cdev_del(&qseecom.cdev); cdev_del(&qseecom.cdev);