// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
 *
 * (C) COPYRIGHT 2020-2022 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU license.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 */

#include <linux/fdtable.h>
#include <linux/module.h>

#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/ktime.h>
#include <linux/version.h>
#if (KERNEL_VERSION(4, 11, 0) <= LINUX_VERSION_CODE)
#include <linux/sched/task.h>
#else
#include <linux/sched.h>
#endif
#include "mali_kbase.h"
#include "backend/gpu/mali_kbase_irq_internal.h"
#include "backend/gpu/mali_kbase_pm_internal.h"
#include "backend/gpu/mali_kbase_clk_rate_trace_mgr.h"

#include <kutf/kutf_suite.h>
#include <kutf/kutf_utils.h>
#include <kutf/kutf_helpers.h>
#include <kutf/kutf_helpers_user.h>

#include "../mali_kutf_clk_rate_trace_test.h"

#define MINOR_FOR_FIRST_KBASE_DEV	(-1)

/* KUTF test application pointer for this test */
static struct kutf_application *kutf_app;

enum portal_server_state {
	PORTAL_STATE_NO_CLK,
	PORTAL_STATE_LIVE,
	PORTAL_STATE_CLOSING,
};

/**
 * struct clk_trace_snapshot - Trace info data on a clock.
 * @previous_rate:   Snapshot start point clock rate.
 * @current_rate:    End point clock rate. It becomes the start rate of the
 *                   next trace snapshot.
 * @rate_up_cnt:     Count in the snapshot duration when the clock trace
 *                   write is a rate of higher value than the last.
 * @rate_down_cnt:   Count in the snapshot duration when the clock trace write
 *                   is a rate of lower value than the last.
 */
struct clk_trace_snapshot {
	unsigned long previous_rate;
	unsigned long current_rate;
	u32 rate_up_cnt;
	u32 rate_down_cnt;
};

/**
 * struct kutf_clk_rate_trace_fixture_data - Fixture data for the test.
 * @kbdev:            kbase device for the GPU.
 * @listener:         Clock rate change listener structure.
 * @invoke_notify:    When true, invoke notify command is being executed.
 * @snapshot:         Clock trace update snapshot data array. A snapshot
 *                    for each clock contains info accumulated between two
 *                    GET_TRACE_SNAPSHOT requests.
 * @nclks:            Number of clocks visible to the trace portal.
 * @pm_ctx_cnt:       Net count of PM (Power Management) context INC/DEC
 *                    PM_CTX_CNT requests made to the portal. On change from
 *                    0 to 1 (INC), or, 1 to 0 (DEC), a PM context action is
 *                    triggered.
 * @total_update_cnt: Total number of received trace write callbacks.
 * @server_state:     Portal server operational state.
 * @result_msg:       Message for the test result.
 * @test_status:      Portal test result status.
 */
struct kutf_clk_rate_trace_fixture_data {
	struct kbase_device *kbdev;
	struct kbase_clk_rate_listener listener;
	bool invoke_notify;
	struct clk_trace_snapshot snapshot[BASE_MAX_NR_CLOCKS_REGULATORS];
	unsigned int nclks;
	unsigned int pm_ctx_cnt;
	unsigned int total_update_cnt;
	enum portal_server_state server_state;
	char const *result_msg;
	enum kutf_result_status test_status;
};

struct clk_trace_portal_input {
	struct kutf_helper_named_val cmd_input;
	enum kbasep_clk_rate_trace_req portal_cmd;
	int named_val_err;
};

struct kbasep_cmd_name_pair {
	enum kbasep_clk_rate_trace_req cmd;
	const char *name;
};

static const struct kbasep_cmd_name_pair kbasep_portal_cmd_name_map[] = {
	{ PORTAL_CMD_GET_PLATFORM, GET_PLATFORM },
	{ PORTAL_CMD_GET_CLK_RATE_MGR, GET_CLK_RATE_MGR },
	{ PORTAL_CMD_GET_CLK_RATE_TRACE, GET_CLK_RATE_TRACE },
	{ PORTAL_CMD_GET_TRACE_SNAPSHOT, GET_TRACE_SNAPSHOT },
	{ PORTAL_CMD_INC_PM_CTX_CNT, INC_PM_CTX_CNT },
	{ PORTAL_CMD_DEC_PM_CTX_CNT, DEC_PM_CTX_CNT },
	{ PORTAL_CMD_CLOSE_PORTAL, CLOSE_PORTAL },
	{ PORTAL_CMD_INVOKE_NOTIFY_42KHZ, INVOKE_NOTIFY_42KHZ },
};

/* Global pointer for the kutf_portal_trace_write() to use. When
 * this pointer is engaged, new requests for create fixture will fail
 * hence limiting the use of the portal at any time to a singleton.
 */
static struct kutf_clk_rate_trace_fixture_data *g_ptr_portal_data;

#define PORTAL_MSG_LEN (KUTF_MAX_LINE_LENGTH - MAX_REPLY_NAME_LEN)
static char portal_msg_buf[PORTAL_MSG_LEN];

static void kutf_portal_trace_write(
	struct kbase_clk_rate_listener *listener,
	u32 index, u32 new_rate)
{
	struct clk_trace_snapshot *snapshot;
	struct kutf_clk_rate_trace_fixture_data *data;

	if (listener == NULL) {
		pr_err("%s - index: %u, new_rate: %u, listener is NULL\n",
			__func__, index, new_rate);
		return;
	}

	data = container_of(listener, struct kutf_clk_rate_trace_fixture_data,
		       listener);

	lockdep_assert_held(&data->kbdev->pm.clk_rtm.lock);

	if (WARN_ON(g_ptr_portal_data == NULL))
		return;
	if (WARN_ON(index >= g_ptr_portal_data->nclks))
		return;

	/* This callback is triggered by invoke notify command, skipping */
	if (data->invoke_notify)
		return;

	snapshot = &g_ptr_portal_data->snapshot[index];
	if (new_rate > snapshot->current_rate)
		snapshot->rate_up_cnt++;
	else
		snapshot->rate_down_cnt++;
	snapshot->current_rate = new_rate;
	g_ptr_portal_data->total_update_cnt++;
}

static void kutf_set_pm_ctx_active(struct kutf_context *context)
{
	struct kutf_clk_rate_trace_fixture_data *data = context->fixture;

	if (WARN_ON(data->pm_ctx_cnt != 1))
		return;

	kbase_pm_context_active(data->kbdev);
	kbase_pm_wait_for_desired_state(data->kbdev);
#if !MALI_USE_CSF
	kbase_pm_request_gpu_cycle_counter(data->kbdev);
#endif
}

static void kutf_set_pm_ctx_idle(struct kutf_context *context)
{
	struct kutf_clk_rate_trace_fixture_data *data = context->fixture;

	if (WARN_ON(data->pm_ctx_cnt > 0))
		return;
#if !MALI_USE_CSF
	kbase_pm_release_gpu_cycle_counter(data->kbdev);
#endif
	kbase_pm_context_idle(data->kbdev);
}

static const char *kutf_clk_trace_do_change_pm_ctx(struct kutf_context *context,
				struct clk_trace_portal_input *cmd)
{
	struct kutf_clk_rate_trace_fixture_data *data = context->fixture;
	int seq = cmd->cmd_input.u.val_u64 & 0xFF;
	const unsigned int cnt = data->pm_ctx_cnt;
	const enum kbasep_clk_rate_trace_req req = cmd->portal_cmd;
	char const *errmsg = NULL;

	WARN_ON(req != PORTAL_CMD_INC_PM_CTX_CNT &&
		req != PORTAL_CMD_DEC_PM_CTX_CNT);

	if (req == PORTAL_CMD_INC_PM_CTX_CNT && cnt < UINT_MAX) {
		data->pm_ctx_cnt++;
		if (data->pm_ctx_cnt == 1)
			kutf_set_pm_ctx_active(context);
	}

	if (req == PORTAL_CMD_DEC_PM_CTX_CNT && cnt > 0) {
		data->pm_ctx_cnt--;
		if (data->pm_ctx_cnt == 0)
			kutf_set_pm_ctx_idle(context);
	}

	/* Skip the length check, no chance of overflow for two ints */
	snprintf(portal_msg_buf, PORTAL_MSG_LEN,
			"{SEQ:%d, PM_CTX_CNT:%u}", seq, data->pm_ctx_cnt);

	if (kutf_helper_send_named_str(context, "ACK", portal_msg_buf)) {
		pr_warn("Error in sending ack for adjusting pm_ctx_cnt\n");
		errmsg = kutf_dsprintf(&context->fixture_pool,
				"Error in sending ack for adjusting pm_ctx_cnt");
	}

	return errmsg;
}

static const char *kutf_clk_trace_do_get_rate(struct kutf_context *context,
				struct clk_trace_portal_input *cmd)
{
	struct kutf_clk_rate_trace_fixture_data *data = context->fixture;
	struct kbase_device *kbdev = data->kbdev;
	int seq = cmd->cmd_input.u.val_u64 & 0xFF;
	unsigned long rate;
	bool idle;
	int ret;
	int i;
	char const *errmsg = NULL;

	WARN_ON((cmd->portal_cmd != PORTAL_CMD_GET_CLK_RATE_MGR) &&
		(cmd->portal_cmd != PORTAL_CMD_GET_CLK_RATE_TRACE));

	ret = snprintf(portal_msg_buf, PORTAL_MSG_LEN,
			"{SEQ:%d, RATE:[", seq);

	for (i = 0; i < data->nclks; i++) {
		spin_lock(&kbdev->pm.clk_rtm.lock);
		if (cmd->portal_cmd == PORTAL_CMD_GET_CLK_RATE_MGR)
			rate = kbdev->pm.clk_rtm.clks[i]->clock_val;
		else
			rate = data->snapshot[i].current_rate;
		idle = kbdev->pm.clk_rtm.gpu_idle;
		spin_unlock(&kbdev->pm.clk_rtm.lock);

		if ((i + 1) == data->nclks)
			ret += snprintf(portal_msg_buf + ret,
				PORTAL_MSG_LEN - ret, "0x%lx], GPU_IDLE:%d}",
				rate, idle);
		else
			ret += snprintf(portal_msg_buf + ret,
				PORTAL_MSG_LEN - ret, "0x%lx, ", rate);

		if (ret >= PORTAL_MSG_LEN) {
			pr_warn("Message buf overflow with rate array data\n");
			return kutf_dsprintf(&context->fixture_pool,
						"Message buf overflow with rate array data");
		}
	}

	if (kutf_helper_send_named_str(context, "ACK", portal_msg_buf)) {
		pr_warn("Error in sending back rate array\n");
		errmsg = kutf_dsprintf(&context->fixture_pool,
				"Error in sending rate array");
	}

	return errmsg;
}

/**
 * kutf_clk_trace_do_get_snapshot() - Send back the current snapshot
 * @context:  KUTF context
 * @cmd:      The decoded portal input request
 *
 * The accumulated clock rate trace information is kept inside as an snapshot
 * record. A user request of getting the snapshot marks the closure of the
 * current snapshot record, and the start of the next one. The response
 * message contains the current snapshot record, with each clock's
 * data sequentially placed inside (array marker) [ ].
 *
 * Return: generated string
 */
static const char *kutf_clk_trace_do_get_snapshot(struct kutf_context *context,
				struct clk_trace_portal_input *cmd)
{
	struct kutf_clk_rate_trace_fixture_data *data = context->fixture;
	struct clk_trace_snapshot snapshot;
	int seq = cmd->cmd_input.u.val_u64 & 0xFF;
	int ret;
	int i;
	char const *fmt;
	char const *errmsg = NULL;

	WARN_ON(cmd->portal_cmd != PORTAL_CMD_GET_TRACE_SNAPSHOT);

	ret = snprintf(portal_msg_buf, PORTAL_MSG_LEN,
			"{SEQ:%d, SNAPSHOT_ARRAY:[", seq);

	for (i = 0; i < data->nclks; i++) {
		spin_lock(&data->kbdev->pm.clk_rtm.lock);
		/* copy out the snapshot of the clock */
		snapshot = data->snapshot[i];
		/* Set the next snapshot start condition */
		data->snapshot[i].previous_rate = snapshot.current_rate;
		data->snapshot[i].rate_up_cnt = 0;
		data->snapshot[i].rate_down_cnt = 0;
		spin_unlock(&data->kbdev->pm.clk_rtm.lock);

		/* Check i corresponding to the last clock */
		if ((i + 1) == data->nclks)
			fmt = "(0x%lx, 0x%lx, %u, %u)]}";
		else
			fmt = "(0x%lx, 0x%lx, %u, %u), ";
		ret += snprintf(portal_msg_buf + ret, PORTAL_MSG_LEN - ret,
			    fmt, snapshot.previous_rate, snapshot.current_rate,
			    snapshot.rate_up_cnt, snapshot.rate_down_cnt);
		if (ret >= PORTAL_MSG_LEN) {
			pr_warn("Message buf overflow with snapshot data\n");
			return kutf_dsprintf(&context->fixture_pool,
					"Message buf overflow with snapshot data");
		}
	}

	if (kutf_helper_send_named_str(context, "ACK", portal_msg_buf)) {
		pr_warn("Error in sending back snapshot array\n");
		errmsg = kutf_dsprintf(&context->fixture_pool,
				"Error in sending snapshot array");
	}

	return errmsg;
}

/**
 * kutf_clk_trace_do_invoke_notify_42k() - Invokes the stored notification callback
 * @context:  KUTF context
 * @cmd:      The decoded portal input request
 *
 * Invokes frequency change notification callbacks with a fake
 * GPU frequency 42 kHz for the top clock domain.
 *
 * Return: generated string
 */
static const char *kutf_clk_trace_do_invoke_notify_42k(
	struct kutf_context *context,
	struct clk_trace_portal_input *cmd)
{
	struct kutf_clk_rate_trace_fixture_data *data = context->fixture;
	int seq = cmd->cmd_input.u.val_u64 & 0xFF;
	const unsigned long new_rate_hz = 42000;
	int ret;
	char const *errmsg = NULL;
	struct kbase_clk_rate_trace_manager *clk_rtm = &data->kbdev->pm.clk_rtm;

	WARN_ON(cmd->portal_cmd != PORTAL_CMD_INVOKE_NOTIFY_42KHZ);

	spin_lock(&clk_rtm->lock);

	data->invoke_notify = true;
	kbase_clk_rate_trace_manager_notify_all(
		clk_rtm, 0, new_rate_hz);
	data->invoke_notify = false;

	spin_unlock(&clk_rtm->lock);

	ret = snprintf(portal_msg_buf, PORTAL_MSG_LEN,
		       "{SEQ:%d, HZ:%lu}", seq, new_rate_hz);

	if (ret >= PORTAL_MSG_LEN) {
		pr_warn("Message buf overflow with invoked data\n");
		return kutf_dsprintf(&context->fixture_pool,
				"Message buf overflow with invoked data");
	}

	if (kutf_helper_send_named_str(context, "ACK", portal_msg_buf)) {
		pr_warn("Error in sending ack for " INVOKE_NOTIFY_42KHZ "request\n");
		errmsg = kutf_dsprintf(&context->fixture_pool,
			"Error in sending ack for " INVOKE_NOTIFY_42KHZ "request");
	}

	return errmsg;
}

static const char *kutf_clk_trace_do_close_portal(struct kutf_context *context,
				struct clk_trace_portal_input *cmd)
{
	struct kutf_clk_rate_trace_fixture_data *data = context->fixture;
	int seq = cmd->cmd_input.u.val_u64 & 0xFF;
	char const *errmsg = NULL;

	WARN_ON(cmd->portal_cmd != PORTAL_CMD_CLOSE_PORTAL);

	data->server_state = PORTAL_STATE_CLOSING;

	/* Skip the length check, no chance of overflow for two ints */
	snprintf(portal_msg_buf, PORTAL_MSG_LEN,
			"{SEQ:%d, PM_CTX_CNT:%u}", seq, data->pm_ctx_cnt);

	if (kutf_helper_send_named_str(context, "ACK", portal_msg_buf)) {
		pr_warn("Error in sending ack for " CLOSE_PORTAL "request\n");
		errmsg = kutf_dsprintf(&context->fixture_pool,
			"Error in sending ack for " CLOSE_PORTAL "request");
	}

	return errmsg;
}

/**
 * kutf_clk_trace_do_get_platform() - Gets platform information
 * @context:  KUTF context
 * @cmd:      The decoded portal input request
 *
 * Checks the gpu node in the device tree to see if arbitration is enabled
 * If so determines device tree whether platform is PV or PTM
 *
 * Return: A string to indicate the platform (PV/PTM/GPU/UNKNOWN)
 */
static const char *kutf_clk_trace_do_get_platform(
	struct kutf_context *context,
	struct clk_trace_portal_input *cmd)
{
	int seq = cmd->cmd_input.u.val_u64 & 0xFF;
	char const *errmsg = NULL;
	const void *arbiter_if_node = NULL;
	const void *power_node = NULL;
	const char *platform = "GPU";
#if defined(CONFIG_MALI_ARBITER_SUPPORT) && defined(CONFIG_OF)
	struct kutf_clk_rate_trace_fixture_data *data = context->fixture;

	arbiter_if_node =
		of_get_property(data->kbdev->dev->of_node, "arbiter_if", NULL);
#endif
	if (arbiter_if_node) {
		power_node = of_find_compatible_node(NULL, NULL,
						     "arm,mali-gpu-power");
		if (power_node) {
			platform = "PV";
		} else {
			power_node = of_find_compatible_node(NULL, NULL,
							     "arm,mali-ptm");
			if (power_node)
				platform = "PTM";
			else
				platform = "UNKNOWN";
		}
	} else {
		platform = "GPU";
	}

	pr_debug("%s - platform is %s\n", __func__, platform);
	snprintf(portal_msg_buf, PORTAL_MSG_LEN,
			  "{SEQ:%d, PLATFORM:%s}", seq, platform);

	WARN_ON(cmd->portal_cmd != PORTAL_CMD_GET_PLATFORM);

	if (kutf_helper_send_named_str(context, "ACK", portal_msg_buf)) {
		pr_warn("Error in sending ack for " CLOSE_PORTAL "request\n");
		errmsg = kutf_dsprintf(&context->fixture_pool,
			"Error in sending ack for " GET_PLATFORM "request");
	}

	return errmsg;
}

static bool kutf_clk_trace_dequeue_portal_cmd(struct kutf_context *context,
				struct clk_trace_portal_input *cmd)
{
	int i;
	int err = kutf_helper_receive_named_val(context, &cmd->cmd_input);

	cmd->named_val_err = err;
	if (err == KUTF_HELPER_ERR_NONE &&
		cmd->cmd_input.type == KUTF_HELPER_VALTYPE_U64) {
		/* All portal request commands are of format (named u64):
		 *   CMD_NAME=1234
		 * where, 1234 is a (variable) sequence number tag.
		 */
		for (i = 0; i < PORTAL_TOTAL_CMDS; i++) {
			if (strcmp(cmd->cmd_input.val_name,
				kbasep_portal_cmd_name_map[i].name))
				continue;

			cmd->portal_cmd = kbasep_portal_cmd_name_map[i].cmd;
			return true;
		}
	}

	cmd->portal_cmd = PORTAL_CMD_INVALID;
	return false;
}

static void kutf_clk_trace_flag_result(struct kutf_context *context,
			enum kutf_result_status result, char const *msg)
{
	struct kutf_clk_rate_trace_fixture_data *data = context->fixture;

	if (result > data->test_status) {
		data->test_status = result;
		if (msg)
			data->result_msg = msg;
		if (data->server_state == PORTAL_STATE_LIVE &&
			result > KUTF_RESULT_WARN) {
			data->server_state = PORTAL_STATE_CLOSING;
		}
	}
}

static bool kutf_clk_trace_process_portal_cmd(struct kutf_context *context,
				struct clk_trace_portal_input *cmd)
{
	char const *errmsg = NULL;

	BUILD_BUG_ON(ARRAY_SIZE(kbasep_portal_cmd_name_map) !=
				PORTAL_TOTAL_CMDS);
	WARN_ON(cmd->portal_cmd == PORTAL_CMD_INVALID);

	switch (cmd->portal_cmd) {
	case PORTAL_CMD_GET_PLATFORM:
		errmsg = kutf_clk_trace_do_get_platform(context, cmd);
		break;
	case PORTAL_CMD_GET_CLK_RATE_MGR:
		fallthrough;
	case PORTAL_CMD_GET_CLK_RATE_TRACE:
		errmsg = kutf_clk_trace_do_get_rate(context, cmd);
		break;
	case PORTAL_CMD_GET_TRACE_SNAPSHOT:
		errmsg = kutf_clk_trace_do_get_snapshot(context, cmd);
		break;
	case PORTAL_CMD_INC_PM_CTX_CNT:
		fallthrough;
	case PORTAL_CMD_DEC_PM_CTX_CNT:
		errmsg = kutf_clk_trace_do_change_pm_ctx(context, cmd);
		break;
	case PORTAL_CMD_CLOSE_PORTAL:
		errmsg = kutf_clk_trace_do_close_portal(context, cmd);
		break;
	case PORTAL_CMD_INVOKE_NOTIFY_42KHZ:
		errmsg = kutf_clk_trace_do_invoke_notify_42k(context, cmd);
		break;
	default:
		pr_warn("Don't know how to handle portal_cmd: %d, abort session.\n",
				cmd->portal_cmd);
		errmsg = kutf_dsprintf(&context->fixture_pool,
				"Don't know how to handle portal_cmd: %d",
				cmd->portal_cmd);
		break;
	}

	if (errmsg)
		kutf_clk_trace_flag_result(context, KUTF_RESULT_FAIL, errmsg);

	return (errmsg == NULL);
}

/**
 * kutf_clk_trace_do_nack_response() - respond a NACK to erroneous input
 * @context:  KUTF context
 * @cmd:      The erroneous input request
 *
 * This function deal with an erroneous input request, and respond with
 * a proper 'NACK' message.
 *
 * Return: 0 on success, non-zero on failure
 */
static int kutf_clk_trace_do_nack_response(struct kutf_context *context,
				struct clk_trace_portal_input *cmd)
{
	int seq;
	int err;
	char const *errmsg = NULL;

	WARN_ON(cmd->portal_cmd != PORTAL_CMD_INVALID);

	if (cmd->named_val_err == KUTF_HELPER_ERR_NONE &&
			  cmd->cmd_input.type == KUTF_HELPER_VALTYPE_U64) {
		/* Keep seq number as % 256 */
		seq = cmd->cmd_input.u.val_u64 & 255;
		snprintf(portal_msg_buf, PORTAL_MSG_LEN,
				 "{SEQ:%d, MSG: Unknown command '%s'.}", seq,
				 cmd->cmd_input.val_name);
		err = kutf_helper_send_named_str(context, "NACK",
						portal_msg_buf);
	} else
		err = kutf_helper_send_named_str(context, "NACK",
			"Wrong portal cmd format (Ref example: CMD_NAME=0X16)");

	if (err) {
		errmsg = kutf_dsprintf(&context->fixture_pool,
						"Failed to send portal NACK response");
		kutf_clk_trace_flag_result(context, KUTF_RESULT_FAIL, errmsg);
	}

	return err;
}

/**
 * kutf_clk_trace_barebone_check() - Sanity test on the clock tracing
 * @context:	KUTF context
 *
 * This function carries out some basic test on the tracing operation:
 *     1). GPU idle on test start, trace rate should be 0 (low power state)
 *     2). Make sure GPU is powered up, the trace rate should match
 *         that from the clock manager's internal recorded rate
 *     3). If the GPU active transition occurs following 2), there
 *         must be rate change event from tracing.
 */
static void kutf_clk_trace_barebone_check(struct kutf_context *context)
{
	struct kutf_clk_rate_trace_fixture_data *data = context->fixture;
	struct kbase_device *kbdev = data->kbdev;
	bool fail = false;
	bool idle[2] = { false };
	char const *msg = NULL;
	int i;

	/* Check consistency if gpu happens to be idle */
	spin_lock(&kbdev->pm.clk_rtm.lock);
	idle[0] = kbdev->pm.clk_rtm.gpu_idle;
	if (kbdev->pm.clk_rtm.gpu_idle) {
		for (i = 0; i < data->nclks; i++) {
			if (data->snapshot[i].current_rate) {
				/* Idle should have a rate 0 */
				fail = true;
				break;
			}
		}
	}
	spin_unlock(&kbdev->pm.clk_rtm.lock);
	if (fail) {
		msg = kutf_dsprintf(&context->fixture_pool,
				"GPU Idle not yielding 0-rate");
		pr_err("Trace did not see idle rate\n");
	} else {
		/* Make local PM active if not done so yet */
		if (data->pm_ctx_cnt == 0) {
			/* Ensure the GPU is powered */
			data->pm_ctx_cnt++;
			kutf_set_pm_ctx_active(context);
		}
		/* Checking the rate is consistent */
		spin_lock(&kbdev->pm.clk_rtm.lock);
		idle[1] = kbdev->pm.clk_rtm.gpu_idle;
		for (i = 0; i < data->nclks; i++) {
			/* Rate match between the manager and the trace */
			if (kbdev->pm.clk_rtm.clks[i]->clock_val !=
				data->snapshot[i].current_rate) {
				fail = true;
				break;
			}
		}
		spin_unlock(&kbdev->pm.clk_rtm.lock);

		if (idle[1]) {
			msg = kutf_dsprintf(&context->fixture_pool,
				"GPU still idle after set_pm_ctx_active");
			pr_err("GPU still idle after set_pm_ctx_active\n");
		}

		if (!msg && fail) {
			msg = kutf_dsprintf(&context->fixture_pool,
				"Trace rate not matching Clk manager's read");
			pr_err("Trace rate not matching Clk manager's read\n");
		}
	}

	if (!msg && idle[0] && !idle[1] && !data->total_update_cnt) {
		msg = kutf_dsprintf(&context->fixture_pool,
				"Trace update did not occur");
		pr_err("Trace update did not occur\n");
	}
	if (msg)
		kutf_clk_trace_flag_result(context, KUTF_RESULT_FAIL, msg);
	else if (!data->total_update_cnt) {
		msg = kutf_dsprintf(&context->fixture_pool,
				    "No trace update seen during the test!");
		kutf_clk_trace_flag_result(context, KUTF_RESULT_WARN, msg);
	}
}

static bool kutf_clk_trace_end_of_stream(struct clk_trace_portal_input *cmd)
{
	return (cmd->named_val_err == -EBUSY);
}

static void kutf_clk_trace_no_clks_dummy(struct kutf_context *context)
{
	struct clk_trace_portal_input cmd;
	unsigned long timeout = jiffies + HZ * 2;
	bool has_cmd;

	while (time_before(jiffies, timeout)) {
		if (kutf_helper_pending_input(context)) {
			has_cmd = kutf_clk_trace_dequeue_portal_cmd(context,
									&cmd);
			if (!has_cmd && kutf_clk_trace_end_of_stream(&cmd))
				break;

			kutf_helper_send_named_str(context, "NACK",
				"Fatal! No clocks visible, aborting");
		}
		msleep(20);
	}

	kutf_clk_trace_flag_result(context, KUTF_RESULT_FATAL,
				"No clocks visable to the portal");
}

/**
 * mali_kutf_clk_rate_trace_test_portal() - Service portal input
 * @context:	KUTF context
 *
 * The test portal operates on input requests. If the input request is one
 * of the recognized portal commands, it handles it accordingly. Otherwise
 * a negative response 'NACK' is returned. The portal service terminates
 * when a 'CLOSE_PORTAL' request is received, or due to an internal error.
 * Both case would result in the server_state transitioned to CLOSING.
 *
 * If the portal is closed on request, a sanity test on the clock rate
 * trace operation is undertaken via function:
 *    kutf_clk_trace_barebone_check();
 */
static void mali_kutf_clk_rate_trace_test_portal(struct kutf_context *context)
{
	struct kutf_clk_rate_trace_fixture_data *data = context->fixture;
	struct clk_trace_portal_input new_cmd;

	pr_debug("Test portal service start\n");

	while (data->server_state == PORTAL_STATE_LIVE) {
		if (kutf_clk_trace_dequeue_portal_cmd(context, &new_cmd))
			kutf_clk_trace_process_portal_cmd(context, &new_cmd);
		else if (kutf_clk_trace_end_of_stream(&new_cmd))
			/* Dequeue on portal input, end of stream */
			data->server_state = PORTAL_STATE_CLOSING;
		else
			kutf_clk_trace_do_nack_response(context, &new_cmd);
	}

	/* Closing, exhausting all the pending inputs with NACKs. */
	if (data->server_state == PORTAL_STATE_CLOSING) {
		while (kutf_helper_pending_input(context) &&
		       (kutf_clk_trace_dequeue_portal_cmd(context, &new_cmd) ||
				!kutf_clk_trace_end_of_stream(&new_cmd))) {
			kutf_helper_send_named_str(context, "NACK",
					"Portal closing down");
		}
	}

	/* If no portal error, do a barebone test here irrespective
	 * whatever the portal live session has been testing, which
	 * is entirely driven by the user-side via portal requests.
	 */
	if (data->test_status <= KUTF_RESULT_WARN) {
		if (data->server_state != PORTAL_STATE_NO_CLK)
			kutf_clk_trace_barebone_check(context);
		else {
			/* No clocks case, NACK 2-sec for the fatal situation */
			kutf_clk_trace_no_clks_dummy(context);
		}
	}

	/* If we have changed pm_ctx count, drop it back */
	if (data->pm_ctx_cnt) {
		/* Although we count on portal requests, it only has material
		 * impact when from 0 -> 1. So the reverse is a simple one off.
		 */
		data->pm_ctx_cnt = 0;
		kutf_set_pm_ctx_idle(context);
	}

	/* Finally log the test result line */
	if (data->test_status < KUTF_RESULT_WARN)
		kutf_test_pass(context, data->result_msg);
	else if (data->test_status == KUTF_RESULT_WARN)
		kutf_test_warn(context, data->result_msg);
	else if (data->test_status == KUTF_RESULT_FATAL)
		kutf_test_fatal(context, data->result_msg);
	else
		kutf_test_fail(context, data->result_msg);

	pr_debug("Test end\n");
}

/**
 * mali_kutf_clk_rate_trace_create_fixture() - Creates the fixture data
 *                           required for mali_kutf_clk_rate_trace_test_portal.
 * @context:	KUTF context.
 *
 * Return: Fixture data created on success or NULL on failure
 */
static void *mali_kutf_clk_rate_trace_create_fixture(
		struct kutf_context *context)
{
	struct kutf_clk_rate_trace_fixture_data *data;
	struct kbase_device *kbdev;
	unsigned long rate;
	int i;

	/* Acquire the kbase device */
	pr_debug("Finding device\n");
	kbdev = kbase_find_device(MINOR_FOR_FIRST_KBASE_DEV);
	if (kbdev == NULL) {
		kutf_test_fail(context, "Failed to find kbase device");
		return NULL;
	}

	pr_debug("Creating fixture\n");
	data = kutf_mempool_alloc(&context->fixture_pool,
			sizeof(struct kutf_clk_rate_trace_fixture_data));
	if (!data)
		return NULL;

	*data = (const struct kutf_clk_rate_trace_fixture_data){ NULL };
	pr_debug("Hooking up the test portal to kbdev clk rate trace\n");
	spin_lock(&kbdev->pm.clk_rtm.lock);

	if (g_ptr_portal_data != NULL) {
		pr_warn("Test portal is already in use, run aborted\n");
		spin_unlock(&kbdev->pm.clk_rtm.lock);
		kutf_test_fail(context, "Portal allows single session only");
		return NULL;
	}

	for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) {
		if (kbdev->pm.clk_rtm.clks[i]) {
			data->nclks++;
			if (kbdev->pm.clk_rtm.gpu_idle)
				rate = 0;
			else
				rate = kbdev->pm.clk_rtm.clks[i]->clock_val;
			data->snapshot[i].previous_rate = rate;
			data->snapshot[i].current_rate = rate;
		}
	}

	spin_unlock(&kbdev->pm.clk_rtm.lock);

	if (data->nclks) {
		/* Subscribe this test server portal */
		data->listener.notify = kutf_portal_trace_write;
		data->invoke_notify = false;

		kbase_clk_rate_trace_manager_subscribe(
			&kbdev->pm.clk_rtm, &data->listener);
		/* Update the kutf_server_portal fixture_data pointer */
		g_ptr_portal_data = data;
	}

	data->kbdev = kbdev;
	data->result_msg = NULL;
	data->test_status = KUTF_RESULT_PASS;

	if (data->nclks == 0) {
		data->server_state = PORTAL_STATE_NO_CLK;
		pr_debug("Kbdev has no clocks for rate trace");
	} else
		data->server_state = PORTAL_STATE_LIVE;

	pr_debug("Created fixture\n");

	return data;
}

/**
 * mali_kutf_clk_rate_trace_remove_fixture - Destroy fixture data previously created by
 *                                           mali_kutf_clk_rate_trace_create_fixture.
 *
 * @context:             KUTF context.
 */
static void mali_kutf_clk_rate_trace_remove_fixture(
		struct kutf_context *context)
{
	struct kutf_clk_rate_trace_fixture_data *data = context->fixture;
	struct kbase_device *kbdev = data->kbdev;

	if (data->nclks) {
		/* Clean up the portal trace write arrangement */
		g_ptr_portal_data = NULL;

		kbase_clk_rate_trace_manager_unsubscribe(
			&kbdev->pm.clk_rtm, &data->listener);
	}
	pr_debug("Destroying fixture\n");
	kbase_release_device(kbdev);
	pr_debug("Destroyed fixture\n");
}

/**
 * mali_kutf_clk_rate_trace_test_module_init() - Entry point for test module.
 *
 * Return: 0 on success, error code otherwise
 */
static int __init mali_kutf_clk_rate_trace_test_module_init(void)
{
	struct kutf_suite *suite;
	unsigned int filters;
	union kutf_callback_data suite_data = { NULL };

	pr_debug("Creating app\n");

	g_ptr_portal_data = NULL;
	kutf_app = kutf_create_application(CLK_RATE_TRACE_APP_NAME);

	if (!kutf_app) {
		pr_warn("Creation of app " CLK_RATE_TRACE_APP_NAME
				" failed!\n");
		return -ENOMEM;
	}

	pr_debug("Create suite %s\n", CLK_RATE_TRACE_SUITE_NAME);
	suite = kutf_create_suite_with_filters_and_data(
			kutf_app, CLK_RATE_TRACE_SUITE_NAME, 1,
			mali_kutf_clk_rate_trace_create_fixture,
			mali_kutf_clk_rate_trace_remove_fixture,
			KUTF_F_TEST_GENERIC,
			suite_data);

	if (!suite) {
		pr_warn("Creation of suite %s failed!\n",
				CLK_RATE_TRACE_SUITE_NAME);
		kutf_destroy_application(kutf_app);
		return -ENOMEM;
	}

	filters = suite->suite_default_flags;
	kutf_add_test_with_filters(
			suite, 0x0, CLK_RATE_TRACE_PORTAL,
			mali_kutf_clk_rate_trace_test_portal,
			filters);

	pr_debug("Init complete\n");
	return 0;
}

/**
 * mali_kutf_clk_rate_trace_test_module_exit() - Module exit point for this
 *                                               test.
 */
static void __exit mali_kutf_clk_rate_trace_test_module_exit(void)
{
	pr_debug("Exit start\n");
	kutf_destroy_application(kutf_app);
	pr_debug("Exit complete\n");
}


module_init(mali_kutf_clk_rate_trace_test_module_init);
module_exit(mali_kutf_clk_rate_trace_test_module_exit);

MODULE_LICENSE("GPL");
