Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41adaf3f authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "qseecom: Fix issues with qssecom_remove/exit APIs"

parents cab3152f d078cf53
Loading
Loading
Loading
Loading
+63 −66
Original line number Diff line number Diff line
@@ -94,7 +94,6 @@ enum qseecom_ce_hw_instance {

static struct class *driver_class;
static dev_t qseecom_device_no;
static struct cdev qseecom_cdev;

static DEFINE_MUTEX(qsee_bw_mutex);
static DEFINE_MUTEX(app_access_lock);
@@ -171,6 +170,7 @@ struct qseecom_control {
	enum qseecom_bandwidth_request_mode  current_mode;
	struct timer_list bw_scale_down_timer;
	struct work_struct bw_inactive_req_ws;
	struct cdev cdev;
};

struct qseecom_client_handle {
@@ -3396,7 +3396,7 @@ static int qseecom_probe(struct platform_device *pdev)
	if (IS_ERR(driver_class)) {
		rc = -ENOMEM;
		pr_err("class_create failed %d\n", rc);
		goto unregister_chrdev_region;
		goto exit_unreg_chrdev_region;
	}

	class_dev = device_create(driver_class, NULL, qseecom_device_no, NULL,
@@ -3404,16 +3404,16 @@ static int qseecom_probe(struct platform_device *pdev)
	if (!class_dev) {
		pr_err("class_device_create failed %d\n", rc);
		rc = -ENOMEM;
		goto class_destroy;
		goto exit_destroy_class;
	}

	cdev_init(&qseecom_cdev, &qseecom_fops);
	qseecom_cdev.owner = THIS_MODULE;
	cdev_init(&qseecom.cdev, &qseecom_fops);
	qseecom.cdev.owner = THIS_MODULE;

	rc = cdev_add(&qseecom_cdev, MKDEV(MAJOR(qseecom_device_no), 0), 1);
	rc = cdev_add(&qseecom.cdev, MKDEV(MAJOR(qseecom_device_no), 0), 1);
	if (rc < 0) {
		pr_err("cdev_add failed %d\n", rc);
		goto err;
		goto exit_destroy_device;
	}

	INIT_LIST_HEAD(&qseecom.registered_listener_list_head);
@@ -3429,7 +3429,7 @@ static int qseecom_probe(struct platform_device *pdev)
				&qsee_not_legacy, sizeof(qsee_not_legacy));
	if (rc) {
		pr_err("Failed to retrieve QSEOS version information %d\n", rc);
		goto err;
		goto exit_del_cdev;
	}
	if (qsee_not_legacy) {
		uint32_t feature = 10;
@@ -3439,14 +3439,14 @@ static int qseecom_probe(struct platform_device *pdev)
			&qseecom.qsee_version, sizeof(qseecom.qsee_version));
		if (rc) {
			pr_err("Failed to get QSEE version info %d\n", rc);
			goto err;
			goto exit_del_cdev;
		}
		qseecom.qseos_version = QSEOS_VERSION_14;
	} else {
		pr_err("QSEE legacy version is not supported:");
		pr_err("Support for TZ1.3 and earlier is deprecated\n");
		rc = -EINVAL;
		goto err;
		goto exit_del_cdev;
	}
	qseecom.commonlib_loaded = false;
	qseecom.pdev = class_dev;
@@ -3455,7 +3455,7 @@ static int qseecom_probe(struct platform_device *pdev)
	if (qseecom.ion_clnt == NULL) {
		pr_err("Ion client cannot be created\n");
		rc = -ENOMEM;
		goto err;
		goto exit_del_cdev;
	}

	/* register client for bus scaling */
@@ -3469,7 +3469,7 @@ static int qseecom_probe(struct platform_device *pdev)
			pr_err("Fail to get disk-encrypt pipe pair information.\n");
			qseecom.ce_info.disk_encrypt_pipe = 0xff;
			rc = -EINVAL;
			goto err;
			goto exit_destroy_ion_client;
		} else {
			pr_warn("bam_pipe_pair=0x%x",
			qseecom.ce_info.disk_encrypt_pipe);
@@ -3481,7 +3481,7 @@ static int qseecom_probe(struct platform_device *pdev)
			pr_err("Fail to get qsee ce hw instance information.\n");
			qseecom.ce_info.qsee_ce_hw_instance = 0xff;
			rc = -EINVAL;
			goto err;
			goto exit_destroy_ion_client;
		} else {
			pr_warn("qsee-ce-hw-instance=0x%x",
			qseecom.ce_info.qsee_ce_hw_instance);
@@ -3493,7 +3493,7 @@ static int qseecom_probe(struct platform_device *pdev)
			pr_err("Fail to get hlos ce hw instance information.\n");
			qseecom.ce_info.hlos_ce_hw_instance = 0xff;
			rc = -EINVAL;
			goto err;
			goto exit_destroy_ion_client;
		} else {
			pr_warn("hlos-ce-hw-instance=0x%x",
			qseecom.ce_info.hlos_ce_hw_instance);
@@ -3504,13 +3504,13 @@ static int qseecom_probe(struct platform_device *pdev)

		ret = __qseecom_init_clk(CLK_QSEE);
		if (ret)
			goto err;
			goto exit_destroy_ion_client;

		if (qseecom.qsee.instance != qseecom.ce_drv.instance) {
			ret = __qseecom_init_clk(CLK_CE_DRV);
			if (ret) {
				__qseecom_deinit_clk(CLK_QSEE);
				goto err;
				goto exit_destroy_ion_client;
			}
		} else {
			struct qseecom_clk *qclk;
@@ -3540,7 +3540,7 @@ static int qseecom_probe(struct platform_device *pdev)
			} else {
				pr_err("Fail to get secure app region info\n");
				rc = -EINVAL;
				goto err;
				goto exit_destroy_ion_client;
			}
			rc = scm_call(SCM_SVC_TZSCHEDULER, 1, &req, sizeof(req),
							&resp, sizeof(resp));
@@ -3548,7 +3548,7 @@ static int qseecom_probe(struct platform_device *pdev)
				pr_err("send secapp reg fail %d resp.res %d\n",
							rc, resp.result);
				rc = -EINVAL;
				goto err;
				goto exit_destroy_ion_client;
			}
		}
	} else {
@@ -3568,11 +3568,16 @@ static int qseecom_probe(struct platform_device *pdev)
	if (!qseecom.qsee_perf_client)
		pr_err("Unable to register bus client\n");
	return 0;
err:

exit_destroy_ion_client:
	ion_client_destroy(qseecom.ion_clnt);
exit_del_cdev:
	cdev_del(&qseecom.cdev);
exit_destroy_device:
	device_destroy(driver_class, qseecom_device_no);
class_destroy:
exit_destroy_class:
	class_destroy(driver_class);
unregister_chrdev_region:
exit_unreg_chrdev_region:
	unregister_chrdev_region(qseecom_device_no, 1);
	return rc;
}
@@ -3583,69 +3588,64 @@ static int qseecom_remove(struct platform_device *pdev)
	unsigned long flags = 0;
	int ret = 0;

	if (pdev->dev.platform_data != NULL)
		msm_bus_scale_unregister_client(qseecom.qsee_perf_client);

	spin_lock_irqsave(&qseecom.registered_kclient_list_lock, flags);
	kclient = list_entry((&qseecom.registered_kclient_list_head)->next,
		struct qseecom_registered_kclient_list, list);
	if (list_empty(&kclient->list)) {
		spin_unlock_irqrestore(&qseecom.registered_kclient_list_lock,
			flags);
		return 0;
	}

	list_for_each_entry(kclient, &qseecom.registered_kclient_list_head,
								list) {
			if (kclient)
				list_del(&kclient->list);
			break;
	}
	spin_unlock_irqrestore(&qseecom.registered_kclient_list_lock, flags);
		if (!kclient)
			goto exit_irqrestore;

		/* Break the loop if client handle is NULL */
		if (!kclient->handle)
			goto exit_free_kclient;

		if (list_empty(&kclient->list))
			goto exit_free_kc_handle;

	while (kclient->handle != NULL) {
		list_del(&kclient->list);
		ret = qseecom_unload_app(kclient->handle->dev);
		if (ret == 0) {
		if (!ret) {
			kzfree(kclient->handle->dev);
			kzfree(kclient->handle);
			kzfree(kclient);
		}
		spin_lock_irqsave(&qseecom.registered_kclient_list_lock, flags);
		kclient = list_entry(
				(&qseecom.registered_kclient_list_head)->next,
				struct qseecom_registered_kclient_list, list);
		if (list_empty(&kclient->list)) {
			spin_unlock_irqrestore(
				&qseecom.registered_kclient_list_lock, flags);
			return 0;
		}
		list_for_each_entry(kclient,
				&qseecom.registered_kclient_list_head, list) {
			if (kclient)
				list_del(&kclient->list);
			break;
		}
		spin_unlock_irqrestore(&qseecom.registered_kclient_list_lock,
				flags);
		if (!kclient) {
			ret = 0;
			break;
		}
	}

exit_free_kc_handle:
	kzfree(kclient->handle);
exit_free_kclient:
	kzfree(kclient);
exit_irqrestore:
	spin_unlock_irqrestore(&qseecom.registered_kclient_list_lock, flags);

	if (qseecom.qseos_version > QSEEE_VERSION_00)
		qseecom_unload_commonlib_image();

	if (qseecom.qsee_perf_client)
		msm_bus_scale_client_update_request(qseecom.qsee_perf_client,
									0);
	if (pdev->dev.platform_data != NULL)
		msm_bus_scale_unregister_client(qseecom.qsee_perf_client);

	/* register client for bus scaling */
	if (pdev->dev.of_node) {
		__qseecom_deinit_clk(CLK_QSEE);
		if (qseecom.qsee.instance != qseecom.ce_drv.instance)
			__qseecom_deinit_clk(CLK_CE_DRV);
	}

	ion_client_destroy(qseecom.ion_clnt);

	cdev_del(&qseecom.cdev);

	device_destroy(driver_class, qseecom_device_no);

	class_destroy(driver_class);

	unregister_chrdev_region(qseecom_device_no, 1);

	return ret;
};
}

static struct of_device_id qseecom_match[] = {
	{
@@ -3671,10 +3671,7 @@ static int qseecom_init(void)

static void qseecom_exit(void)
{
	device_destroy(driver_class, qseecom_device_no);
	class_destroy(driver_class);
	unregister_chrdev_region(qseecom_device_no, 1);
	ion_client_destroy(qseecom.ion_clnt);
	platform_driver_unregister(&qseecom_plat_driver);
}

MODULE_LICENSE("GPL v2");