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

Commit 369a4ace authored by Zhen Kong's avatar Zhen Kong
Browse files

qseecom: Enable/disable clock for client if bus scaling is not enabled



To avoid the service failure on a target where bus scaling flag is not
enabled in target device tree file by mistake, make a change to enable/
disable crypto clocks when the client calls to scale up bus bandwidth
and send command even if bus scaling feature is not enabled.

CRs-Fixed: 726840
Change-Id: Ib33a535051b68561bde5ab6a23ad0f02dc27ab13
Signed-off-by: default avatarZhen Kong <zkong@codeaurora.org>
parent c3b06b92
Loading
Loading
Loading
Loading
+97 −51
Original line number Diff line number Diff line
@@ -943,6 +943,25 @@ static int __qseecom_register_bus_bandwidth_needs(
	return ret;
}

static int qseecom_perf_enable(struct qseecom_dev_handle *data)
{
	int ret = 0;
	ret = qsee_vote_for_clock(data, CLK_DFAB);
	if (ret) {
		pr_err("Failed to vote for DFAB clock with err %d\n", ret);
		goto perf_enable_exit;
	}
	ret = qsee_vote_for_clock(data, CLK_SFPB);
	if (ret) {
		qsee_disable_clock_vote(data, CLK_DFAB);
		pr_err("Failed to vote for SFPB clock with err %d\n", ret);
		goto perf_enable_exit;
	}

perf_enable_exit:
	return ret;
}

static int qseecom_scale_bus_bandwidth(struct qseecom_dev_handle *data,
						void __user *argp)
{
@@ -961,10 +980,29 @@ static int qseecom_scale_bus_bandwidth(struct qseecom_dev_handle *data,
		pr_err("Invalid bandwidth mode (%d)\n", req_mode);
		return ret;
	}

	/*
	* Register bus bandwidth needs if bus scaling feature is enabled;
	* otherwise, qseecom enable/disable clocks for the client directly.
	*/
	if (qseecom.support_bus_scaling) {
		mutex_lock(&qsee_bw_mutex);
		ret = __qseecom_register_bus_bandwidth_needs(data, req_mode);
		mutex_unlock(&qsee_bw_mutex);

	} else {
		pr_debug("Bus scaling feature is NOT enabled\n");
		pr_debug("request bandwidth mode %d for the client\n",
				req_mode);
		if (req_mode != INACTIVE) {
			ret = qseecom_perf_enable(data);
			if (ret)
				pr_err("Failed to vote for clock with err %d\n",
						ret);
		} else {
			qsee_disable_clock_vote(data, CLK_DFAB);
			qsee_disable_clock_vote(data, CLK_SFPB);
		}
	}
	return ret;
}

@@ -1733,15 +1771,9 @@ static int qseecom_send_service_cmd(struct qseecom_dev_handle *data,
			return ret;
		}
	} else {
		ret = qsee_vote_for_clock(data, CLK_DFAB);
		ret = qseecom_perf_enable(data);
		if (ret) {
			pr_err("Failed to vote for DFAB clock%d\n", ret);
			return ret;
		}
		ret = qsee_vote_for_clock(data, CLK_SFPB);
		if (ret) {
			qsee_disable_clock_vote(data, CLK_DFAB);
			pr_err("Failed to vote for SFPB clock%d\n", ret);
			pr_err("Failed to vote for clocks with err %d\n", ret);
			goto exit;
		}
	}
@@ -2779,6 +2811,7 @@ int qseecom_send_command(struct qseecom_handle *handle, void *send_buf,
	int ret = 0;
	struct qseecom_send_cmd_req req = {0, 0, 0, 0};
	struct qseecom_dev_handle *data;
	bool perf_enabled = false;

	if (handle == NULL) {
		pr_err("Handle is not initialized\n");
@@ -2806,21 +2839,32 @@ int qseecom_send_command(struct qseecom_handle *handle, void *send_buf,
	* On targets where crypto clock is handled by HLOS,
	* if clk_access_cnt is zero and perf_enabled is false,
	* then the crypto clock was not enabled before sending cmd
	* to tz, qseecom will release mutex lock and return error.
	* to tz, qseecom will enable the clock to avoid service failure.
	*/
	if (!qseecom.no_clock_support &&
		!qseecom.qsee.clk_access_cnt && !data->perf_enabled) {
		pr_err("ce clock is not enabled!\n");
		pr_debug("ce clock is not enabled!\n");
		ret = qseecom_perf_enable(data);
		if (ret) {
			pr_err("Failed to vote for clock with err %d\n",
						ret);
			atomic_dec(&data->ioctl_count);
			mutex_unlock(&app_access_lock);
			return -EINVAL;
		}
		perf_enabled = true;
	}

	ret = __qseecom_send_cmd(data, &req);
	if (qseecom.support_bus_scaling)
		__qseecom_add_bw_scale_down_timer(
			QSEECOM_SEND_CMD_CRYPTO_TIMEOUT);

	if (perf_enabled) {
		qsee_disable_clock_vote(data, CLK_DFAB);
		qsee_disable_clock_vote(data, CLK_SFPB);
	}

	atomic_dec(&data->ioctl_count);
	mutex_unlock(&app_access_lock);

@@ -2849,16 +2893,10 @@ int qseecom_set_bandwidth(struct qseecom_handle *handle, bool high)
			if (ret)
				pr_err("Failed to scale bus (med) %d\n", ret);
		} else {
			ret = qsee_vote_for_clock(handle->dev, CLK_DFAB);
			ret = qseecom_perf_enable(handle->dev);
			if (ret)
				pr_err("Failed to vote for DFAB clock%d\n",
				pr_err("Failed to vote for clock with err %d\n",
						ret);
			ret = qsee_vote_for_clock(handle->dev, CLK_SFPB);
			if (ret) {
				pr_err("Failed to vote for SFPB clock%d\n",
									ret);
				qsee_disable_clock_vote(handle->dev, CLK_DFAB);
			}
		}
	} else {
		if (!qseecom.support_bus_scaling) {
@@ -4216,6 +4254,7 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg)
	int ret = 0;
	struct qseecom_dev_handle *data = file->private_data;
	void __user *argp = (void __user *) arg;
	bool perf_enabled = false;

	if (!data) {
		pr_err("Invalid/uninitialized device handle\n");
@@ -4292,20 +4331,30 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg)
		* On targets where crypto clock is handled by HLOS,
		* if clk_access_cnt is zero and perf_enabled is false,
		* then the crypto clock was not enabled before sending cmd
		* to tz, qseecom will release mutex lock and return error.
		* to tz, qseecom will enable the clock to avoid service failure.
		*/
		if (!qseecom.no_clock_support &&
			!qseecom.qsee.clk_access_cnt && !data->perf_enabled) {
			pr_err("ce clock is not enabled!\n");
			ret = -EINVAL;
			pr_debug("ce clock is not enabled!\n");
			ret = qseecom_perf_enable(data);
			if (ret) {
				pr_err("Failed to vote for clock with err %d\n",
						ret);
				mutex_unlock(&app_access_lock);
				ret = -EINVAL;
				break;
			}
			perf_enabled = true;
		}
		atomic_inc(&data->ioctl_count);
		ret = qseecom_send_cmd(data, argp);
		if (qseecom.support_bus_scaling)
			__qseecom_add_bw_scale_down_timer(
				QSEECOM_SEND_CMD_CRYPTO_TIMEOUT);
		if (perf_enabled) {
			qsee_disable_clock_vote(data, CLK_DFAB);
			qsee_disable_clock_vote(data, CLK_SFPB);
		}
		atomic_dec(&data->ioctl_count);
		wake_up_all(&data->abort_wq);
		mutex_unlock(&app_access_lock);
@@ -4342,20 +4391,30 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg)
		* On targets where crypto clock is handled by HLOS,
		* if clk_access_cnt is zero and perf_enabled is false,
		* then the crypto clock was not enabled before sending cmd
		* to tz, qseecom will release mutex lock and return error.
		* to tz, qseecom will enable the clock to avoid service failure.
		*/
		if (!qseecom.no_clock_support &&
			!qseecom.qsee.clk_access_cnt && !data->perf_enabled) {
			pr_err("ce clock is not enabled!\n");
			ret = -EINVAL;
			pr_debug("ce clock is not enabled!\n");
			ret = qseecom_perf_enable(data);
			if (ret) {
				pr_err("Failed to vote for clock with err %d\n",
						ret);
				mutex_unlock(&app_access_lock);
				ret = -EINVAL;
				break;
			}
			perf_enabled = true;
		}
		atomic_inc(&data->ioctl_count);
		ret = qseecom_send_modfd_cmd(data, argp);
		if (qseecom.support_bus_scaling)
			__qseecom_add_bw_scale_down_timer(
				QSEECOM_SEND_CMD_CRYPTO_TIMEOUT);
		if (perf_enabled) {
			qsee_disable_clock_vote(data, CLK_DFAB);
			qsee_disable_clock_vote(data, CLK_SFPB);
		}
		atomic_dec(&data->ioctl_count);
		wake_up_all(&data->abort_wq);
		mutex_unlock(&app_access_lock);
@@ -4485,12 +4544,9 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg)
			__qseecom_register_bus_bandwidth_needs(data, HIGH);
			mutex_unlock(&qsee_bw_mutex);
		} else {
			ret = qsee_vote_for_clock(data, CLK_DFAB);
			ret = qseecom_perf_enable(data);
			if (ret)
				pr_err("Fail to vote for DFAB clock%d\n", ret);
			ret = qsee_vote_for_clock(data, CLK_SFPB);
			if (ret)
				pr_err("Fail to vote for SFPB clock%d\n", ret);
				pr_err("Fail to vote for clocks %d\n", ret);
		}
		atomic_dec(&data->ioctl_count);
		break;
@@ -4524,20 +4580,10 @@ long qseecom_ioctl(struct file *file, unsigned cmd, unsigned long arg)
	}

	case QSEECOM_IOCTL_SET_BUS_SCALING_REQ: {
		/*
		* If crypto clock is not handled by HLOS, return directly.
		* If crypto clock need to be handled by HLOS but qseecom
		* bus scaling flag is not enabled, then return error.
		*/
		/* If crypto clock is not handled by HLOS, return directly. */
		if (qseecom.no_clock_support) {
			pr_debug("crypto clock is not handled by HLOS\n");
			break;
		} else {
			if (!qseecom.support_bus_scaling) {
				pr_err("Bus scaling feature is NOT enabled\n");
				ret = -EINVAL;
				break;
			}
		}
		if ((data->client.app_id == 0) ||
			(data->type != QSEECOM_CLIENT_APP)) {