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

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

Merge "devfreq: devfreq_spdm: Support scm and hvc"

parents abbdd6cf d45502f5
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -176,6 +176,15 @@ config MSM_DEVFREQ_DEVBW
	  agnostic interface to so that some of the devfreq governors can be
	  shared across SoCs.

config SPDM_SCM
	bool "MSM SPDM SCM based call support"
	depends on DEVFREQ_SPDM
	help
	  SPDM driver support the dcvs algorithm logic being accessed via
	  scm or hvc calls. This adds the support for SPDM interaction to
          tz via SCM based call. If not selected then Hypervior interaction
          will be activated.

config DEVFREQ_SPDM
	bool "MSM SPDM based bandwidth voting"
	depends on ARCH_MSM
+55 −15
Original line number Diff line number Diff line
/*
*Copyright (c) 2014, The Linux Foundation. All rights reserved.
*Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
*
*This program is free software; you can redistribute it and/or modify
*it under the terms of the GNU General Public License version 2 and
@@ -22,7 +22,6 @@
#include <linux/msm-bus.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <soc/qcom/hvc.h>

#include "governor.h"
#include "devfreq_spdm.h"
@@ -37,14 +36,16 @@ static void *spdm_ipc_log_ctxt;
		ipc_log_string(spdm_ipc_log_ctxt, x); \
} while (0)

#define COPY_SIZE(x, y) ((x) <= (y) ? (x) : (y))

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 hvc_desc desc = { { 0 } };
	int hvc_status = 0;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	if (!dev || !freq)
		return -EINVAL;
@@ -70,10 +71,10 @@ update_thresholds:
	desc.arg[0] = SPDM_CMD_ENABLE;
	desc.arg[1] = data->spdm_client;
	desc.arg[2] = clk_get_rate(data->cci_clk);
	hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
	if (hvc_status)
		pr_err("HVC command %u failed with error %u", (int)desc.arg[0],
			hvc_status);
	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;
}

@@ -241,15 +242,54 @@ no_pdata:
	return ret;
}

int __spdm_hyp_call(u64 func_id, struct hvc_desc *desc)
int __spdm_hyp_call(struct spdm_args *args, int num_args)
{
	int ret = 0;
	struct hvc_desc desc = { { 0 } };
	int status;

	SPDM_IPC_LOG("hvc call fn:0x%llx, cmd:%llu\n", func_id, desc->arg[0]);
	ret = hvc(func_id, desc);
	SPDM_IPC_LOG("hvc return fn:0x%llx cmd:%llu Ret[0]:%llu Ret[1]:%llu\n",
			func_id, desc->arg[0], desc->ret[0], desc->ret[1]);
	return ret;
	memcpy(desc.arg, args->arg,
		COPY_SIZE(sizeof(desc.arg), sizeof(args->arg)));
	SPDM_IPC_LOG("hvc call fn:0x%x, cmd:%llu, num_args:%d\n",
		HVC_FN_SIP(SPDM_HYP_FNID), desc.arg[0], num_args);

	status = hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc);

	memcpy(args->ret, desc.ret,
		COPY_SIZE(sizeof(args->ret), sizeof(desc.ret)));
	SPDM_IPC_LOG("hvc return fn:0x%x cmd:%llu Ret[0]:%llu Ret[1]:%llu\n",
			HVC_FN_SIP(SPDM_HYP_FNID), desc.arg[0],
			desc.ret[0], desc.ret[1]);
	return status;
}

int __spdm_scm_call(struct spdm_args *args, int num_args)
{
	int status = 0;

	SPDM_IPC_LOG("%s:svc_id:%d,cmd_id:%d,cmd:%llu,num_args:%d\n",
		__func__, SPDM_SCM_SVC_ID, SPDM_SCM_CMD_ID,
		args->arg[0], num_args);

	if (!is_scm_armv8()) {
		status = scm_call(SPDM_SCM_SVC_ID, SPDM_SCM_CMD_ID, args->arg,
				sizeof(args->arg), args->ret,
				sizeof(args->ret));
	} else {
		struct scm_desc desc = {0};
		desc.arginfo = SCM_ARGS(num_args);
		memcpy(desc.args, args->arg,
			COPY_SIZE(sizeof(desc.args), sizeof(args->arg)));

		status = scm_call2(SCM_SIP_FNID(SPDM_SCM_SVC_ID,
				SPDM_SCM_CMD_ID), &desc);

		memcpy(args->ret, desc.ret,
			COPY_SIZE(sizeof(args->ret), sizeof(desc.ret)));
	}
	SPDM_IPC_LOG("%s:svc_id:%d,cmd_id:%d,cmd:%llu,Ret[0]:%llu,Ret[1]:%llu\n"
		, __func__, SPDM_SCM_SVC_ID, SPDM_SCM_CMD_ID, args->arg[0],
		args->ret[0], args->ret[1]);
	return status;
}

static int probe(struct platform_device *pdev)
+21 −4
Original line number Diff line number Diff line
/*
*Copyright (c) 2014, The Linux Foundation. All rights reserved.
*Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
*
*This program is free software; you can redistribute it and/or modify
*it under the terms of the GNU General Public License version 2 and
@@ -15,6 +15,8 @@
#define DEVFREQ_SPDM_H

#include <linux/list.h>
#include <soc/qcom/hvc.h>
#include <soc/qcom/scm.h>

enum pl_levels { SPDM_PL1, SPDM_PL2, SPDM_PL3, SPDM_PL_COUNT };
enum actions { SPDM_UP, SPDM_DOWN };
@@ -83,7 +85,9 @@ extern void spdm_init_debugfs(struct device *dev);
extern void spdm_remove_debugfs(struct spdm_data *data);

#define SPDM_HYP_FNID 5
/* CMD ID's for hypervisor */
#define SPDM_SCM_SVC_ID 0x9
#define SPDM_SCM_CMD_ID 0x4
/* SPDM CMD ID's for hypervisor/SCM */
#define SPDM_CMD_GET_BW_ALL 1
#define SPDM_CMD_GET_BW_SPECIFIC 2
#define SPDM_CMD_ENABLE 3
@@ -103,7 +107,20 @@ extern void spdm_remove_debugfs(struct spdm_data *data);
#define SPDM_CMD_CFG_MAXCCI 17
#define SPDM_CMD_CFG_VOTES 18

extern int __spdm_hyp_call(u64 func_id, struct hvc_desc *desc);
#define spdm_ext_call	__spdm_hyp_call
#define SPDM_MAX_ARGS 6
#define SPDM_MAX_RETS 3

struct spdm_args {
	u64 arg[SPDM_MAX_ARGS];
	u64 ret[SPDM_MAX_RETS];
};

extern int __spdm_hyp_call(struct spdm_args *args, int num_args);
extern int __spdm_scm_call(struct spdm_args *args, int num_args);

#ifdef CONFIG_SPDM_SCM
#define spdm_ext_call __spdm_scm_call
#else
#define spdm_ext_call __spdm_hyp_call
#endif
#endif
+73 −38
Original line number Diff line number Diff line
/*
*Copyright (c) 2014, The Linux Foundation. All rights reserved.
*Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
*
*This program is free software; you can redistribute it and/or modify
*it under the terms of the GNU General Public License version 2 and
@@ -15,7 +15,6 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <soc/qcom/hvc.h>
#include "devfreq_spdm.h"

static int spdm_open(struct inode *inode, struct file *file)
@@ -29,7 +28,8 @@ static ssize_t pl_write(struct file *file, const char __user *data,
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct hvc_desc desc;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;
	int i;

	buf = kzalloc(size, GFP_KERNEL);
@@ -47,8 +47,10 @@ static ssize_t pl_write(struct file *file, const char __user *data,
	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];
	if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
		pr_debug("check hvc logs");
	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;
@@ -64,7 +66,8 @@ static ssize_t rejrate_low_write(struct file *file, const char __user *data,
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct hvc_desc desc;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	buf = kzalloc(size, GFP_KERNEL);

@@ -80,8 +83,10 @@ static ssize_t rejrate_low_write(struct file *file, const char __user *data,
	desc.arg[1] = spdm_data->spdm_client;
	desc.arg[2] = spdm_data->config_data.reject_rate[0];
	desc.arg[3] = spdm_data->config_data.reject_rate[1];
	if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
		pr_debug("check hvc logs");
	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;
@@ -97,7 +102,8 @@ static ssize_t rejrate_med_write(struct file *file, const char __user *data,
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct hvc_desc desc;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	buf = kzalloc(size, GFP_KERNEL);

@@ -112,8 +118,10 @@ static ssize_t rejrate_med_write(struct file *file, const char __user *data,
	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];
	if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
		pr_debug("check hvc logs");
	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;
@@ -129,7 +137,8 @@ static ssize_t rejrate_high_write(struct file *file, const char __user *data,
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct hvc_desc desc;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	buf = kzalloc(size, GFP_KERNEL);

@@ -144,8 +153,10 @@ static ssize_t rejrate_high_write(struct file *file, const char __user *data,
	desc.arg[1] = spdm_data->spdm_client;
	desc.arg[2] = spdm_data->config_data.reject_rate[4];
	desc.arg[3] = spdm_data->config_data.reject_rate[5];
	if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
		pr_debug("check hvc logs");
	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;
@@ -161,7 +172,8 @@ static ssize_t resptime_low_write(struct file *file, const char __user *data,
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct hvc_desc desc;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	buf = kzalloc(size, GFP_KERNEL);

@@ -176,8 +188,10 @@ static ssize_t resptime_low_write(struct file *file, const char __user *data,
	desc.arg[1] = spdm_data->spdm_client;
	desc.arg[2] = spdm_data->config_data.response_time_us[0];
	desc.arg[3] = spdm_data->config_data.response_time_us[1];
	if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
		pr_debug("check hvc logs");
	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;
@@ -193,7 +207,8 @@ static ssize_t resptime_med_write(struct file *file, const char __user *data,
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct hvc_desc desc;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	buf = kzalloc(size, GFP_KERNEL);

@@ -208,8 +223,10 @@ static ssize_t resptime_med_write(struct file *file, const char __user *data,
	desc.arg[1] = spdm_data->spdm_client;
	desc.arg[2] = spdm_data->config_data.response_time_us[2];
	desc.arg[3] = spdm_data->config_data.response_time_us[3];
	if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
		pr_debug("check hvc logs");
	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;
@@ -225,7 +242,8 @@ static ssize_t resptime_high_write(struct file *file, const char __user *data,
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct hvc_desc desc;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	buf = kzalloc(size, GFP_KERNEL);

@@ -240,8 +258,10 @@ static ssize_t resptime_high_write(struct file *file, const char __user *data,
	desc.arg[1] = spdm_data->spdm_client;
	desc.arg[2] = spdm_data->config_data.response_time_us[4];
	desc.arg[3] = spdm_data->config_data.response_time_us[5];
	if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
		pr_debug("check hvc logs");
	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;
@@ -257,7 +277,8 @@ static ssize_t cciresptime_low_write(struct file *file, const char __user *data,
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct hvc_desc desc;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	buf = kzalloc(size, GFP_KERNEL);

@@ -272,8 +293,10 @@ static ssize_t cciresptime_low_write(struct file *file, const char __user *data,
	desc.arg[1] = spdm_data->spdm_client;
	desc.arg[2] = spdm_data->config_data.cci_response_time_us[0];
	desc.arg[3] = spdm_data->config_data.cci_response_time_us[1];
	if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
		pr_debug("check hvc logs");
	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;
@@ -289,7 +312,8 @@ static ssize_t cciresptime_med_write(struct file *file, const char __user *data,
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct hvc_desc desc;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	buf = kzalloc(size, GFP_KERNEL);

@@ -304,8 +328,10 @@ static ssize_t cciresptime_med_write(struct file *file, const char __user *data,
	desc.arg[1] = spdm_data->spdm_client;
	desc.arg[2] = spdm_data->config_data.cci_response_time_us[2];
	desc.arg[3] = spdm_data->config_data.cci_response_time_us[3];
	if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
		pr_debug("check hvc logs");
	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;
@@ -322,7 +348,8 @@ static ssize_t cciresptime_high_write(struct file *file,
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct hvc_desc desc;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	buf = kzalloc(size, GFP_KERNEL);

@@ -337,8 +364,10 @@ static ssize_t cciresptime_high_write(struct file *file,
	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];
	if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
		pr_debug("check hvc logs");
	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;
@@ -354,7 +383,8 @@ static ssize_t cci_max_write(struct file *file, const char __user *data,
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct hvc_desc desc;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	buf = kzalloc(size, GFP_KERNEL);

@@ -367,8 +397,10 @@ static ssize_t cci_max_write(struct file *file, const char __user *data,
	desc.arg[0] = SPDM_CMD_CFG_MAXCCI;
	desc.arg[1] = spdm_data->spdm_client;
	desc.arg[2] = spdm_data->config_data.max_cci_freq;
	if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
		pr_debug("check hvc logs");
	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);
	*offset += size;
	kfree(buf);
	return size;
@@ -384,7 +416,8 @@ static ssize_t vote_cfg_write(struct file *file, const char __user *data,
{
	struct spdm_data *spdm_data = file->private_data;
	char *buf;
	struct hvc_desc desc;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	buf = kzalloc(size, GFP_KERNEL);

@@ -403,8 +436,10 @@ static ssize_t vote_cfg_write(struct file *file, const char __user *data,
	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;
	if (hvc(HVC_FN_SIP(SPDM_HYP_FNID), &desc))
		pr_debug("check hvc logs");
	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;
+80 −80
Original line number Diff line number Diff line
/*
*Copyright (c) 2014, The Linux Foundation. All rights reserved.
*Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
*
*This program is free software; you can redistribute it and/or modify
*it under the terms of the GNU General Public License version 2 and
@@ -21,7 +21,6 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <soc/qcom/rpm-smd.h>
#include <soc/qcom/hvc.h>
#include "governor.h"
#include "devfreq_spdm.h"

@@ -74,15 +73,15 @@ static int disable_clocks(void)
static irqreturn_t threaded_isr(int irq, void *dev_id)
{
	struct spdm_data *data;
	struct hvc_desc desc = { { 0 } };
	int hvc_status = 0;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	/* call hyp to get bw_vote */
	desc.arg[0] = SPDM_CMD_GET_BW_ALL;
	hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
	if (hvc_status)
		pr_err("HVC command %u failed with error %u", (int)desc.arg[0],
			hvc_status);
	ext_status = spdm_ext_call(&desc, 1);
	if (ext_status)
		pr_err("External command %u failed with error %u",
			(int)desc.arg[0], ext_status);
	mutex_lock(&devfreqs_lock);
	list_for_each_entry(data, &devfreqs, list) {
		if (data->spdm_client == desc.ret[0]) {
@@ -112,8 +111,8 @@ static int gov_spdm_hyp_target_bw(struct devfreq *devfreq, unsigned long *freq,
	struct devfreq_dev_status status;
	int ret = -EINVAL;
	int usage;
	struct hvc_desc desc = { { 0 } };
	int hvc_status = 0;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;

	if (!devfreq || !devfreq->profile || !devfreq->profile->get_dev_status)
		return ret;
@@ -131,10 +130,10 @@ static int gov_spdm_hyp_target_bw(struct devfreq *devfreq, unsigned long *freq,
	} else {
		desc.arg[0] = SPDM_CMD_GET_BW_SPECIFIC;
		desc.arg[1] = ((struct spdm_data *)devfreq->data)->spdm_client;
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		ext_status = spdm_ext_call(&desc, 2);
		if (ext_status)
			pr_err("External command %u failed with error %u",
				(int)desc.arg[0], ext_status);
		*freq = desc.ret[0] >> 6;
	}

@@ -144,8 +143,8 @@ static int gov_spdm_hyp_target_bw(struct devfreq *devfreq, unsigned long *freq,
static int gov_spdm_hyp_eh(struct devfreq *devfreq, unsigned int event,
			   void *data)
{
	struct hvc_desc desc = { { 0 } };
	int hvc_status = 0;
	struct spdm_args desc = { { 0 } };
	int ext_status = 0;
	struct spdm_data *spdm_data = (struct spdm_data *)devfreq->data;
	int i;

@@ -160,112 +159,113 @@ static int gov_spdm_hyp_eh(struct devfreq *devfreq, unsigned int event,
		desc.arg[2] = spdm_data->config_data.num_ports;
		for (i = 0; i < spdm_data->config_data.num_ports; i++)
			desc.arg[i+3] = spdm_data->config_data.ports[i];
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		ext_status = spdm_ext_call(&desc,
				spdm_data->config_data.num_ports + 3);
		if (ext_status)
			pr_err("External command %u failed with error %u",
				(int)desc.arg[0], ext_status);

		desc.arg[0] = SPDM_CMD_CFG_FLTR;
		desc.arg[1] = spdm_data->spdm_client;
		desc.arg[2] = spdm_data->config_data.aup;
		desc.arg[3] = spdm_data->config_data.adown;
		desc.arg[4] = spdm_data->config_data.bucket_size;
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		ext_status = spdm_ext_call(&desc, 5);
		if (ext_status)
			pr_err("External command %u failed with error %u",
				(int)desc.arg[0], ext_status);

		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];
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		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);

		desc.arg[0] = SPDM_CMD_CFG_REJRATE_LOW;
		desc.arg[1] = spdm_data->spdm_client;
		desc.arg[2] = spdm_data->config_data.reject_rate[0];
		desc.arg[3] = spdm_data->config_data.reject_rate[1];
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		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);
		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];
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		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);
		desc.arg[0] = SPDM_CMD_CFG_REJRATE_HIGH;
		desc.arg[1] = spdm_data->spdm_client;
		desc.arg[2] = spdm_data->config_data.reject_rate[4];
		desc.arg[3] = spdm_data->config_data.reject_rate[5];
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		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);

		desc.arg[0] = SPDM_CMD_CFG_RESPTIME_LOW;
		desc.arg[1] = spdm_data->spdm_client;
		desc.arg[2] = spdm_data->config_data.response_time_us[0];
		desc.arg[3] = spdm_data->config_data.response_time_us[1];
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		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);
		desc.arg[0] = SPDM_CMD_CFG_RESPTIME_MED;
		desc.arg[1] = spdm_data->spdm_client;
		desc.arg[2] = spdm_data->config_data.response_time_us[2];
		desc.arg[3] = spdm_data->config_data.response_time_us[3];
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		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);
		desc.arg[0] = SPDM_CMD_CFG_RESPTIME_HIGH;
		desc.arg[1] = spdm_data->spdm_client;
		desc.arg[2] = spdm_data->config_data.response_time_us[4];
		desc.arg[3] = spdm_data->config_data.response_time_us[5];
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		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);

		desc.arg[0] = SPDM_CMD_CFG_CCIRESPTIME_LOW;
		desc.arg[1] = spdm_data->spdm_client;
		desc.arg[2] = spdm_data->config_data.cci_response_time_us[0];
		desc.arg[3] = spdm_data->config_data.cci_response_time_us[1];
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		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);
		desc.arg[0] = SPDM_CMD_CFG_CCIRESPTIME_MED;
		desc.arg[1] = spdm_data->spdm_client;
		desc.arg[2] = spdm_data->config_data.cci_response_time_us[2];
		desc.arg[3] = spdm_data->config_data.cci_response_time_us[3];
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		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);
		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];
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		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);

		desc.arg[0] = SPDM_CMD_CFG_MAXCCI;
		desc.arg[1] = spdm_data->spdm_client;
		desc.arg[2] = spdm_data->config_data.max_cci_freq;
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		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);

		desc.arg[0] = SPDM_CMD_CFG_VOTES;
		desc.arg[1] = spdm_data->spdm_client;
@@ -273,19 +273,19 @@ static int gov_spdm_hyp_eh(struct devfreq *devfreq, unsigned int event,
		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;
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		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);

		/* call hyp enable/commit */
		desc.arg[0] = SPDM_CMD_ENABLE;
		desc.arg[1] = spdm_data->spdm_client;
		desc.arg[2] = 0;
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status) {
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		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);
			mutex_lock(&devfreqs_lock);
			/*
			 * the spdm device probe will fail so remove it from
@@ -309,10 +309,10 @@ static int gov_spdm_hyp_eh(struct devfreq *devfreq, unsigned int event,
		/* call hypvervisor to disable */
		desc.arg[0] = SPDM_CMD_DISABLE;
		desc.arg[1] = spdm_data->spdm_client;
		hvc_status = spdm_ext_call(HVC_FN_SIP(SPDM_HYP_FNID), &desc);
		if (hvc_status)
			pr_err("HVC command %u failed with error %u",
				(int)desc.arg[0], hvc_status);
		ext_status = spdm_ext_call(&desc, 2);
		if (ext_status)
			pr_err("External command %u failed with error %u",
				(int)desc.arg[0], ext_status);
		break;

	case DEVFREQ_GOV_INTERVAL: