static ssize_t rejrate_med_write(struct file *file, const char __user *data,
		 size_t size, loff_t *offset)
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	buf = kzalloc(size, GFP_KERNEL);

	if (!buf)
		return -ENOMEM;
	if (copy_from_user(buf, data, size))
		return -EINVAL;
	sscanf(buf, "%u %u\n", &spdm_data->config_data.reject_rate[2],
		&spdm_data->config_data.reject_rate[3]);

	desc.arg[0] = SPDM_CMD_CFG_REJRATE_MED;
	desc.arg[1] = spdm_data->spdm_client;
	desc.arg[2] = spdm_data->config_data.reject_rate[2];
	desc.arg[3] = spdm_data->config_data.reject_rate[3];
	ext_status = spdm_ext_call(&desc, 4);
	if (ext_status)
		pr_err("External command %u failed with error %u",
			(int)desc.arg[0], ext_status);
	*offset += size;
	kfree(buf);
	return size;
}
static ssize_t vote_cfg_write(struct file *file, const char __user *data,
		 size_t size, loff_t *offset)
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	buf = kzalloc(size, GFP_KERNEL);

	if (!buf)
		return -ENOMEM;
	if (copy_from_user(buf, data, size))
		return -EINVAL;
	sscanf(buf, "%u %u %u %u\n", &spdm_data->config_data.upstep,
		&spdm_data->config_data.downstep,
		&spdm_data->config_data.max_vote,
		&spdm_data->config_data.up_step_multp);

	desc.arg[0] = SPDM_CMD_CFG_VOTES;
	desc.arg[1] = spdm_data->spdm_client;
	desc.arg[2] = spdm_data->config_data.upstep;
	desc.arg[3] = spdm_data->config_data.downstep;
	desc.arg[4] = spdm_data->config_data.max_vote;
	desc.arg[5] = spdm_data->config_data.up_step_multp;
	ext_status = spdm_ext_call(&desc, 6);
	if (ext_status)
		pr_err("External command %u failed with error %u",
			(int)desc.arg[0], ext_status);
	*offset += size;
	kfree(buf);
	return size;
}
static ssize_t pl_write(struct file *file, const char __user *data,
		 size_t size, loff_t *offset)
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;
	int i;

	buf = kzalloc(size, GFP_KERNEL);

	if (!buf)
		return -ENOMEM;
	if (copy_from_user(buf, data, size))
		return -EINVAL;

	sscanf(buf, "%u %u\n", &spdm_data->config_data.pl_freqs[0],
		&spdm_data->config_data.pl_freqs[1]);


	desc.arg[0] = SPDM_CMD_CFG_PL;
	desc.arg[1] = spdm_data->spdm_client;
	for (i = 0; i < SPDM_PL_COUNT - 1; i++)
		desc.arg[i+2] = spdm_data->config_data.pl_freqs[i];
	ext_status = spdm_ext_call(&desc, SPDM_PL_COUNT + 1);
	if (ext_status)
		pr_err("External command %u failed with error %u",
			(int)desc.arg[0], ext_status);
	*offset += size;
	kfree(buf);
	return size;
}
static ssize_t cciresptime_high_write(struct file *file,
				      const char __user *data,
				      size_t size, loff_t *offset)
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	buf = kzalloc(size, GFP_KERNEL);

	if (!buf)
		return -ENOMEM;
	if (copy_from_user(buf, data, size))
		return -EINVAL;
	sscanf(buf, "%u %u\n", &spdm_data->config_data.cci_response_time_us[4],
		&spdm_data->config_data.cci_response_time_us[5]);

	desc.arg[0] = SPDM_CMD_CFG_CCIRESPTIME_HIGH;
	desc.arg[1] = spdm_data->spdm_client;
	desc.arg[2] = spdm_data->config_data.cci_response_time_us[4];
	desc.arg[3] = spdm_data->config_data.cci_response_time_us[5];
	ext_status = spdm_ext_call(&desc, 4);
	if (ext_status)
		pr_err("External command %u failed with error %u",
			(int)desc.arg[0], ext_status);
	*offset += size;
	kfree(buf);
	return size;
}
static int change_bw(struct device *dev, unsigned long *freq, u32 flags)
{
	struct spdm_data *data = 0;
	int i;
	int next_idx;
	int ret = 0;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	if (!dev || !freq)
		return -EINVAL;

	data = dev_get_drvdata(dev);
	if (!data)
		return -EINVAL;

	if (data->devfreq->previous_freq == *freq)
		goto update_thresholds;

	next_idx = data->cur_idx + 1;
	next_idx = next_idx % 2;

	for (i = 0; i < data->pdata->usecase[next_idx].num_paths; i++)
		data->pdata->usecase[next_idx].vectors[i].ab = (*freq) << 6;

	data->cur_idx = next_idx;
	ret = msm_bus_scale_client_update_request(data->bus_scale_client_id,
						  data->cur_idx);

update_thresholds:
	desc.arg[0] = SPDM_CMD_ENABLE;
	desc.arg[1] = data->spdm_client;
	desc.arg[2] = clk_get_rate(data->cci_clk);
	ext_status = spdm_ext_call(&desc, 3);
	if (ext_status)
		pr_err("External command %u failed with error %u",
			(int)desc.arg[0], ext_status);
	return ret;
}