/* arch/arm/mach-msm/smp2p_test_common.h
 *
 * 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.
 */
#ifndef _ARCH_ARM_MACH_MSM_SMP2P_TEST_COMMON_H_
#define _ARCH_ARM_MACH_MSM_SMP2P_TEST_COMMON_H_

#include <linux/debugfs.h>

/**
 * Unit test assertion for logging test cases.
 *
 * @a lval
 * @b rval
 * @cmp comparison operator
 *
 * Assertion fails if (@a cmp @b) is not true which then
 * logs the function and line number where the error occurred
 * along with the values of @a and @b.
 *
 * Assumes that the following local variables exist:
 * @s - sequential output file pointer
 * @failed - set to true if test fails
 */
#define UT_ASSERT_INT(a, cmp, b) \
	{ \
	int a_tmp = (a); \
	int b_tmp = (b); \
	if (!((a_tmp)cmp(b_tmp))) { \
		seq_printf(s, \
			"%s:%d Fail: " #a "(%d) " #cmp " " #b "(%d)\n", \
				__func__, __LINE__, \
				a_tmp, b_tmp); \
		failed = 1; \
		break; \
	} \
	}

#define UT_ASSERT_PTR(a, cmp, b) \
	{ \
	void *a_tmp = (a); \
	void *b_tmp = (b); \
	if (!((a_tmp)cmp(b_tmp))) { \
		seq_printf(s, \
			"%s:%d Fail: " #a "(%p) " #cmp " " #b "(%p)\n", \
				__func__, __LINE__, \
				a_tmp, b_tmp); \
		failed = 1; \
		break; \
	} \
	}

#define UT_ASSERT_UINT(a, cmp, b) \
	{ \
	unsigned a_tmp = (a); \
	unsigned b_tmp = (b); \
	if (!((a_tmp)cmp(b_tmp))) { \
		seq_printf(s, \
			"%s:%d Fail: " #a "(%u) " #cmp " " #b "(%u)\n", \
				__func__, __LINE__, \
				a_tmp, b_tmp); \
		failed = 1; \
		break; \
	} \
	}

#define UT_ASSERT_HEX(a, cmp, b) \
	{ \
	unsigned a_tmp = (a); \
	unsigned b_tmp = (b); \
	if (!((a_tmp)cmp(b_tmp))) { \
		seq_printf(s, \
			"%s:%d Fail: " #a "(%x) " #cmp " " #b "(%x)\n", \
				__func__, __LINE__, \
				a_tmp, b_tmp); \
		failed = 1; \
		break; \
	} \
	}

/**
 * In-range unit test assertion for test cases.
 *
 * @a lval
 * @minv Minimum value
 * @maxv Maximum value
 *
 * Assertion fails if @a is not on the exclusive range minv, maxv
 * ((@a < @minv) or (@a > @maxv)).  In the failure case, the macro
 * logs the function and line number where the error occurred along
 * with the values of @a and @minv, @maxv.
 *
 * Assumes that the following local variables exist:
 * @s - sequential output file pointer
 * @failed - set to true if test fails
 */
#define UT_ASSERT_INT_IN_RANGE(a, minv, maxv) \
	{ \
	int a_tmp = (a); \
	int minv_tmp = (minv); \
	int maxv_tmp = (maxv); \
	if (((a_tmp) < (minv_tmp)) || ((a_tmp) > (maxv_tmp))) { \
		seq_printf(s, \
			"%s:%d Fail: " #a "(%d) < " #minv "(%d) or " \
				 #a "(%d) > " #maxv "(%d)\n", \
				__func__, __LINE__, \
				a_tmp, minv_tmp, a_tmp, maxv_tmp); \
		failed = 1; \
		break; \
	} \
	}

/* Structure to track state changes for the notifier callback. */
struct mock_cb_data {
	bool initialized;
	spinlock_t lock;
	struct notifier_block nb;

	/* events */
	struct completion cb_completion;
	int cb_count;
	int event_open;
	int event_entry_update;
	struct msm_smp2p_update_notif entry_data;
};

void smp2p_debug_create(const char *name, void (*show)(struct seq_file *));
static inline int smp2p_test_notify(struct notifier_block *self,
	unsigned long event, void *data);

/**
 * Reset mock callback data to default values.
 *
 * @cb:  Mock callback data
 */
static inline void mock_cb_data_reset(struct mock_cb_data *cb)
{
	INIT_COMPLETION(cb->cb_completion);
	cb->cb_count = 0;
	cb->event_open = 0;
	cb->event_entry_update = 0;
	memset(&cb->entry_data, 0,
		sizeof(struct msm_smp2p_update_notif));
}


/**
 * Initialize mock callback data.
 *
 * @cb:  Mock callback data
 */
static inline void mock_cb_data_init(struct mock_cb_data *cb)
{
	if (!cb->initialized) {
		init_completion(&cb->cb_completion);
		spin_lock_init(&cb->lock);
		cb->initialized = true;
		cb->nb.notifier_call = smp2p_test_notify;
		memset(&cb->entry_data, 0,
			sizeof(struct msm_smp2p_update_notif));
	}
	mock_cb_data_reset(cb);
}

/**
 * Notifier function passed into SMP2P for testing.
 *
 * @self:       Pointer to calling notifier block
 * @event:	    Event
 * @data:       Event-specific data
 * @returns:    0
 */
static inline int smp2p_test_notify(struct notifier_block *self,
		unsigned long event, void *data)
{
	struct mock_cb_data *cb_data_ptr;
	unsigned long flags;

	cb_data_ptr = container_of(self, struct mock_cb_data, nb);

	spin_lock_irqsave(&cb_data_ptr->lock, flags);

	switch (event) {
	case SMP2P_OPEN:
		++cb_data_ptr->event_open;
		if (data) {
			cb_data_ptr->entry_data =
			*(struct msm_smp2p_update_notif *)(data);
		}
		break;
	case SMP2P_ENTRY_UPDATE:
		++cb_data_ptr->event_entry_update;
		if (data) {
			cb_data_ptr->entry_data =
			*(struct msm_smp2p_update_notif *)(data);
		}
		break;
	default:
		pr_err("%s Unknown event\n", __func__);
		break;
	}

	++cb_data_ptr->cb_count;
	complete(&cb_data_ptr->cb_completion);
	spin_unlock_irqrestore(&cb_data_ptr->lock, flags);
	return 0;
}
#endif /* _ARCH_ARM_MACH_MSM_SMP2P_TEST_COMMON_H_ */
