/* arch/arm/mach-msm/smp2p_spinlock_test.c
 *
 * Copyright (c) 2013, 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
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 */
#include <linux/debugfs.h>
#include <linux/ctype.h>
#include <linux/jiffies.h>
#include <linux/delay.h>
#include <linux/completion.h>
#include <linux/remote_spinlock.h>
#include <mach/msm_smsm.h>
#include "smd_private.h"
#include "smp2p_private.h"
#include "smp2p_test_common.h"

#define REMOTE_SPIN_PID 1
#define RS_END_THIEF_PID_BIT 20
#define RS_END_THIEF_MASK 0x00f00000

/* Spinlock commands used for testing Apps<->RPM spinlocks. */
enum RPM_SPINLOCK_CMDS {
	RPM_CMD_INVALID,
	RPM_CMD_START,
	RPM_CMD_LOCKED,
	RPM_CMD_UNLOCKED,
	RPM_CMD_END,
};

/* Shared structure for testing Apps<->RPM spinlocks. */
struct rpm_spinlock_test {
	uint32_t apps_cmd;
	uint32_t apps_lock_count;
	uint32_t rpm_cmd;
	uint32_t rpm_lock_count;
};

/**
 * smp2p_ut_remote_spinlock_core - Verify remote spinlock.
 *
 * @s:           Pointer to output file
 * @remote_pid:  Remote processor to test
 * @use_trylock: Use trylock to prevent an Apps deadlock if the
 *               remote spinlock fails.
 */
static void smp2p_ut_remote_spinlock_core(struct seq_file *s, int remote_pid,
		bool use_trylock)
{
	int failed = 0;
	unsigned lock_count = 0;
	struct msm_smp2p_out *handle = NULL;
	int ret;
	uint32_t test_request;
	uint32_t test_response;
	struct mock_cb_data cb_out;
	struct mock_cb_data cb_in;
	unsigned long flags;
	unsigned n;
	unsigned test_num;
	bool have_lock;
	bool timeout;
	int failed_tmp;
	int spinlock_owner;
	remote_spinlock_t *smem_spinlock;

	seq_printf(s, "Running %s for '%s' remote pid %d\n",
		   __func__, smp2p_pid_to_name(remote_pid), remote_pid);

	cb_out.initialized = false;
	cb_in.initialized = false;
	mock_cb_data_init(&cb_out);
	mock_cb_data_init(&cb_in);
	do {
		smem_spinlock = smem_get_remote_spinlock();
		UT_ASSERT_PTR(smem_spinlock, !=, NULL);

		/* Open output entry */
		ret = msm_smp2p_out_open(remote_pid, SMP2P_RLPB_ENTRY_NAME,
			&cb_out.nb, &handle);
		UT_ASSERT_INT(ret, ==, 0);
		UT_ASSERT_INT(
			(int)wait_for_completion_timeout(
					&cb_out.cb_completion, HZ * 2),
			>, 0);
		UT_ASSERT_INT(cb_out.cb_count, ==, 1);
		UT_ASSERT_INT(cb_out.event_open, ==, 1);

		/* Open inbound entry */
		ret = msm_smp2p_in_register(remote_pid, SMP2P_RLPB_ENTRY_NAME,
				&cb_in.nb);
		UT_ASSERT_INT(ret, ==, 0);
		UT_ASSERT_INT(
			(int)wait_for_completion_timeout(
					&cb_in.cb_completion, HZ * 2),
			>, 0);
		UT_ASSERT_INT(cb_in.cb_count, ==, 1);
		UT_ASSERT_INT(cb_in.event_open, ==, 1);

		/* Send start */
		mock_cb_data_reset(&cb_in);
		mock_cb_data_reset(&cb_out);
		test_request = 0x0;
		SMP2P_SET_RMT_CMD_TYPE_REQ(test_request);
		SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_RSPIN_START);
		SMP2P_SET_RMT_DATA(test_request, 0x0);
		ret = msm_smp2p_out_write(handle, test_request);
		UT_ASSERT_INT(ret, ==, 0);

		UT_ASSERT_INT(
			(int)wait_for_completion_timeout(
					&cb_in.cb_completion, HZ * 2),
			>, 0);
		UT_ASSERT_INT(cb_in.cb_count, ==, 1);
		UT_ASSERT_INT(cb_in.event_entry_update, ==, 1);
		ret = msm_smp2p_in_read(remote_pid, SMP2P_RLPB_ENTRY_NAME,
				&test_response);
		UT_ASSERT_INT(ret, ==, 0);

		test_response = SMP2P_GET_RMT_CMD(test_response);
		if (test_response != SMP2P_LB_CMD_RSPIN_LOCKED &&
				test_response != SMP2P_LB_CMD_RSPIN_UNLOCKED) {
			/* invalid response from remote - abort test */
			test_request = 0x0;
			SMP2P_SET_RMT_CMD_TYPE(test_request, 1);
			SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_RSPIN_END);
			SMP2P_SET_RMT_DATA(test_request, 0x0);
			ret = msm_smp2p_out_write(handle, test_request);
			UT_ASSERT_HEX(SMP2P_LB_CMD_RSPIN_LOCKED, ==,
					test_response);
		}

		/* Run spinlock test */
		if (use_trylock)
			seq_printf(s, "\tUsing remote_spin_trylock\n");
		else
			seq_printf(s, "\tUsing remote_spin_lock\n");

		flags = 0;
		have_lock = false;
		timeout = false;
		spinlock_owner = 0;
		test_request = 0x0;
		SMP2P_SET_RMT_CMD_TYPE_REQ(test_request);
		for (test_num = 0; !failed && test_num < 10000; ++test_num) {
			/* try to acquire spinlock */
			if (use_trylock) {
				unsigned long j_start = jiffies;
				while (!remote_spin_trylock_irqsave(
						smem_spinlock, flags)) {
					if (jiffies_to_msecs(jiffies - j_start)
							> 1000) {
						seq_printf(s,
							"\tFail: Timeout trying to get the lock\n");
						timeout = true;
						break;
					}
				}
				if (timeout)
					break;
			} else {
				remote_spin_lock_irqsave(smem_spinlock, flags);
			}
			have_lock = true;
			++lock_count;

			/* tell the remote side that we have the lock */
			SMP2P_SET_RMT_DATA(test_request, lock_count);
			SMP2P_SET_RMT_CMD(test_request,
					SMP2P_LB_CMD_RSPIN_LOCKED);
			ret = msm_smp2p_out_write(handle, test_request);
			UT_ASSERT_INT(ret, ==, 0);

			/* verify the other side doesn't say it has the lock */
			for (n = 0; n < 1000; ++n) {
				spinlock_owner =
					remote_spin_owner(smem_spinlock);
				if (spinlock_owner != REMOTE_SPIN_PID) {
					/* lock stolen by remote side */
					seq_printf(s,
						"\tFail: Remote side (%d) stole lock (pid %d)\n",
						remote_pid, spinlock_owner);
					failed = true;
					break;
				}
				spinlock_owner = 0;

				ret = msm_smp2p_in_read(remote_pid,
					SMP2P_RLPB_ENTRY_NAME, &test_response);
				UT_ASSERT_INT(ret, ==, 0);
				test_response =
					SMP2P_GET_RMT_CMD(test_response);
				UT_ASSERT_HEX(SMP2P_LB_CMD_RSPIN_UNLOCKED, ==,
					test_response);
			}
			if (failed)
				break;

			/* tell remote side we are unlocked and release lock */
			SMP2P_SET_RMT_CMD(test_request,
					SMP2P_LB_CMD_RSPIN_UNLOCKED);
			(void)msm_smp2p_out_write(handle, test_request);
			have_lock = false;
			remote_spin_unlock_irqrestore(smem_spinlock, flags);
		}
		if (have_lock)
			remote_spin_unlock_irqrestore(smem_spinlock, flags);

		/* End test */
		mock_cb_data_reset(&cb_in);
		SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_RSPIN_END);
		SMP2P_SET_RMT_DATA(test_request, lock_count |
				(spinlock_owner << RS_END_THIEF_PID_BIT));
		(void)msm_smp2p_out_write(handle, test_request);

		failed_tmp = failed;
		failed = false;
		do {
			UT_ASSERT_INT(
				(int)wait_for_completion_timeout(
					&cb_in.cb_completion, HZ * 2),
				>, 0);
			INIT_COMPLETION(cb_in.cb_completion);
			ret = msm_smp2p_in_read(remote_pid,
					SMP2P_RLPB_ENTRY_NAME, &test_response);
			UT_ASSERT_INT(ret, ==, 0);
		} while (!failed &&
			SMP2P_GET_RMT_CMD(test_response) !=
			SMP2P_LB_CMD_RSPIN_END);
		if (failed)
			break;
		failed = failed_tmp;

		test_response = SMP2P_GET_RMT_DATA(test_response);
		seq_printf(s,
			"\tLocked spinlock local %u times; remote %u times",
			lock_count,
			test_response & ((1 << RS_END_THIEF_PID_BIT) - 1)
			);
		if (test_response & RS_END_THIEF_MASK) {
			seq_printf(s,
				"Remote side reporting lock stolen by pid %d.\n",
				SMP2P_GET_BITS(test_response,
					RS_END_THIEF_MASK,
					RS_END_THIEF_PID_BIT));
			failed = 1;
		}
		seq_printf(s, "\n");

		/* Cleanup */
		ret = msm_smp2p_out_close(&handle);
		UT_ASSERT_INT(ret, ==, 0);
		UT_ASSERT_PTR(handle, ==, NULL);
		ret = msm_smp2p_in_unregister(remote_pid,
				SMP2P_RLPB_ENTRY_NAME, &cb_in.nb);
		UT_ASSERT_INT(ret, ==, 0);

		if (!failed && !timeout)
			seq_printf(s, "\tOK\n");
	} while (0);

	if (failed) {
		if (handle) {
			/* send end command */
			test_request = 0;
			SMP2P_SET_RMT_CMD(test_request, SMP2P_LB_CMD_RSPIN_END);
			SMP2P_SET_RMT_DATA(test_request, lock_count);
			(void)msm_smp2p_out_write(handle, test_request);
			(void)msm_smp2p_out_close(&handle);
		}
		(void)msm_smp2p_in_unregister(remote_pid,
				SMP2P_RLPB_ENTRY_NAME, &cb_in.nb);

		pr_err("%s: Failed\n", __func__);
		seq_printf(s, "\tFailed\n");
	}
}

/**
 * smp2p_ut_remote_spinlock_pid - Verify remote spinlock for a processor.
 *
 * @s:           Pointer to output file
 * @pid:         Processor to test
 * @use_trylock: Use trylock to prevent an Apps deadlock if the
 *               remote spinlock fails.
 */
static void smp2p_ut_remote_spinlock_pid(struct seq_file *s, int pid,
		bool use_trylock)
{
	struct smp2p_interrupt_config *int_cfg;

	int_cfg = smp2p_get_interrupt_config();
	if (!int_cfg) {
		seq_printf(s, "Remote processor config unavailable\n");
		return;
	}

	if (pid >= SMP2P_NUM_PROCS || !int_cfg[pid].is_configured)
		return;

	msm_smp2p_deinit_rmt_lpb_proc(pid);
	smp2p_ut_remote_spinlock_core(s, pid, use_trylock);
	msm_smp2p_init_rmt_lpb_proc(pid);
}

/**
 * smp2p_ut_remote_spinlock - Verify remote spinlock for all processors.
 *
 * @s:   pointer to output file
 */
static void smp2p_ut_remote_spinlock(struct seq_file *s)
{
	int pid;

	for (pid = 0; pid < SMP2P_NUM_PROCS; ++pid)
		smp2p_ut_remote_spinlock_pid(s, pid, false);
}

/**
 * smp2p_ut_remote_spin_trylock - Verify remote trylock for all processors.
 *
 * @s:   Pointer to output file
 */
static void smp2p_ut_remote_spin_trylock(struct seq_file *s)
{
	int pid;

	for (pid = 0; pid < SMP2P_NUM_PROCS; ++pid)
		smp2p_ut_remote_spinlock_pid(s, pid, true);
}

/**
 * smp2p_ut_remote_spinlock - Verify remote spinlock for all processors.
 *
 * @s:   pointer to output file
 *
 * This test verifies inbound and outbound functionality for all
 * configured remote processor.
 */
static void smp2p_ut_remote_spinlock_modem(struct seq_file *s)
{
	smp2p_ut_remote_spinlock_pid(s, SMP2P_MODEM_PROC, false);
}

static void smp2p_ut_remote_spinlock_adsp(struct seq_file *s)
{
	smp2p_ut_remote_spinlock_pid(s, SMP2P_AUDIO_PROC, false);
}

static void smp2p_ut_remote_spinlock_wcnss(struct seq_file *s)
{
	smp2p_ut_remote_spinlock_pid(s, SMP2P_WIRELESS_PROC, false);
}

/**
 * smp2p_ut_remote_spinlock_rpm - Verify remote spinlock.
 *
 * @s:   pointer to output file
 * @remote_pid:  Remote processor to test
 */
static void smp2p_ut_remote_spinlock_rpm(struct seq_file *s)
{
	int failed = 0;
	unsigned long flags;
	unsigned n;
	unsigned test_num;
	struct rpm_spinlock_test *data_ptr;
	remote_spinlock_t *smem_spinlock;
	bool have_lock;

	seq_printf(s, "Running %s for Apps<->RPM Test\n",
		   __func__);
	do {
		smem_spinlock = smem_get_remote_spinlock();
		UT_ASSERT_PTR(smem_spinlock, !=, NULL);

		data_ptr = smem_alloc2(SMEM_ID_VENDOR0,
				sizeof(struct rpm_spinlock_test));
		UT_ASSERT_PTR(0, !=, data_ptr);

		/* Send start */
		writel_relaxed(0, &data_ptr->apps_lock_count);
		writel_relaxed(RPM_CMD_START, &data_ptr->apps_cmd);

		seq_printf(s, "\tWaiting for RPM to start test\n");
		for (n = 0; n < 1000; ++n) {
			if (readl_relaxed(&data_ptr->rpm_cmd) !=
					RPM_CMD_INVALID)
				break;
			usleep(1000);
		}
		if (readl_relaxed(&data_ptr->rpm_cmd) == RPM_CMD_INVALID) {
			/* timeout waiting for RPM */
			writel_relaxed(RPM_CMD_INVALID, &data_ptr->apps_cmd);
			UT_ASSERT_INT(RPM_CMD_LOCKED, !=, RPM_CMD_INVALID);
		}

		/* Run spinlock test */
		flags = 0;
		have_lock = false;
		for (test_num = 0; !failed && test_num < 10000; ++test_num) {
			/* acquire spinlock */
			remote_spin_lock_irqsave(smem_spinlock, flags);
			have_lock = true;
			writel_relaxed(++data_ptr->apps_lock_count,
				&data_ptr->apps_lock_count);
			writel_relaxed(RPM_CMD_LOCKED, &data_ptr->apps_cmd);
			/*
			 * Ensure that the remote side sees our lock has
			 * been acquired before we start polling their status.
			 */
			wmb();

			/* verify the other side doesn't say it has the lock */
			for (n = 0; n < 1000; ++n) {
				UT_ASSERT_HEX(RPM_CMD_UNLOCKED, ==,
					readl_relaxed(&data_ptr->rpm_cmd));
			}
			if (failed)
				break;

			/* release spinlock */
			have_lock = false;
			writel_relaxed(RPM_CMD_UNLOCKED, &data_ptr->apps_cmd);
			/*
			 * Ensure that our status-update write was committed
			 * before we unlock the spinlock.
			 */
			wmb();
			remote_spin_unlock_irqrestore(smem_spinlock, flags);
		}
		if (have_lock)
			remote_spin_unlock_irqrestore(smem_spinlock, flags);

		/* End test */
		writel_relaxed(RPM_CMD_INVALID, &data_ptr->apps_cmd);
		seq_printf(s,
				"\tLocked spinlock local %u remote %u\n",
				readl_relaxed(&data_ptr->apps_lock_count),
				readl_relaxed(&data_ptr->rpm_lock_count));

		if (!failed)
			seq_printf(s, "\tOK\n");
	} while (0);

	if (failed) {
		pr_err("%s: Failed\n", __func__);
		seq_printf(s, "\tFailed\n");
	}
}

static int __init smp2p_debugfs_init(void)
{
	/*
	 * Add Unit Test entries.
	 *
	 * The idea with unit tests is that you can run all of them
	 * from ADB shell by doing:
	 *  adb shell
	 *  cat ut*
	 *
	 * And if particular tests fail, you can then repeatedly run the
	 * failing tests as you debug and resolve the failing test.
	 */
	smp2p_debug_create("ut_remote_spinlock",
		smp2p_ut_remote_spinlock);
	smp2p_debug_create("ut_remote_spin_trylock",
		smp2p_ut_remote_spin_trylock);
	smp2p_debug_create("ut_remote_spinlock_modem",
		smp2p_ut_remote_spinlock_modem);
	smp2p_debug_create("ut_remote_spinlock_adsp",
		smp2p_ut_remote_spinlock_adsp);
	smp2p_debug_create("ut_remote_spinlock_wcnss",
		smp2p_ut_remote_spinlock_wcnss);
	smp2p_debug_create("ut_remote_spinlock_rpm",
		smp2p_ut_remote_spinlock_rpm);

	return 0;
}
module_init(smp2p_debugfs_init);
