/*
 * Copyright (c) 2019, 2021 The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pm_wakeup.h>
#include <linux/rwsem.h>
#include <linux/suspend.h>
#include <linux/platform_device.h>
#include <linux/remoteproc.h>
#include <linux/debugfs.h>

#include "../../remoteproc/remoteproc_internal.h"
/*
 * To call rproc boot and shutdown of WCSS alone,
 * 1) insmod testssr.ko (test_id by default is set to 1)
 * 2) rmmod testssr
 * In case if multipd architectire used in WCSS/QDSP6
 * 1)insmod testssr.ko test_id=1 mpd=1
 * 2)rmmod testssr.ko
 */

static struct notifier_block nb;
static struct notifier_block atomic_nb;

#define WCSS_RPROC	"cd00000.remoteproc"
static int test_id = 1;
module_param(test_id, int, S_IRUGO | S_IWUSR | S_IWGRP);
static ulong mpd;
module_param(mpd, ulong, S_IRUGO | S_IWUSR | S_IWGRP);

#define MAX_USERPD_CNT	3

struct userpd_info {
	struct rproc *rproc;
	/*0-stop, 1-start*/
	bool pd_curr_state;
};

struct userpd_dbgfs_info {
	struct dentry *userpd;
	/*0-stop, 1-start*/
	struct dentry *start_stop;
	struct userpd_info userpd_hdl;
};

static struct dentry *q6_userpd_debug;
static struct userpd_dbgfs_info *userpd_dbgfs_hdl[MAX_USERPD_CNT];

static const char *action_to_string(enum subsys_notif_type action)
{
	switch (action) {

	case	SUBSYS_BEFORE_SHUTDOWN:
		return __stringify(SUBSYS_BEFORE_SHUTDOWN);

	case	SUBSYS_AFTER_SHUTDOWN:
		return __stringify(SUBSYS_AFTER_SHUTDOWN);

	case	SUBSYS_BEFORE_POWERUP:
		return __stringify(SUBSYS_BEFORE_POWERUP);

	case	SUBSYS_AFTER_POWERUP:
		return __stringify(SUBSYS_AFTER_POWERUP);

	case	SUBSYS_RAMDUMP_NOTIFICATION:
		return __stringify(SUBSYS_RAMDUMP_NOTIFICATION);

	case	SUBSYS_POWERUP_FAILURE:
		return __stringify(SUBSYS_POWERUP_FAILURE);

	case	SUBSYS_PROXY_VOTE:
		return __stringify(SUBSYS_PROXY_VOTE);

	case	SUBSYS_PROXY_UNVOTE:
		return __stringify(SUBSYS_PROXY_UNVOTE);

	case	SUBSYS_SOC_RESET:
		return __stringify(SUBSYS_SOC_RESET);

	case	SUBSYS_PREPARE_FOR_FATAL_SHUTDOWN:
		return __stringify(SUBSYS_PREPARE_FOR_FATAL_SHUTDOWN);

	default:
		return "unknown";
	}
}

static int tssr_notifier(struct notifier_block *nb, unsigned long action,
								void *data)
{
	struct notif_data *notif = (struct notif_data *)data;

	pr_emerg("%s:\tReceived [%s] notification from [%s]subsystem\n",
		THIS_MODULE->name, action_to_string(action), notif->pdev->name);

	return NOTIFY_DONE;
}

static int test_rproc_notif_register(const char *rproc_name)
{
	int ret;

	ret = rproc_register_subsys_notifier(rproc_name, &nb, &atomic_nb);
	if (ret)
		pr_emerg("rproc notif reg failed\n");

	return ret;
}

#if defined(CONFIG_QCOM_Q6V5_WCSS)
static struct rproc *get_rproc_from_phandle(void)
{
		struct device_node *of_np;
		phandle rproc_phandle;
		struct rproc *q6rproc;

		of_np = of_find_node_with_property(NULL, "qcom,rproc");
		if (!of_np) {
			pr_err("no node with qcom,rproc NULLi\n");
			return NULL;
		}
		if (of_property_read_u32(of_np, "qcom,rproc", &rproc_phandle)) {
			pr_err("could not get rproc phandle\n");
			return  NULL;
		}
		q6rproc  = rproc_get_by_phandle(rproc_phandle);
		if (!q6rproc) {
			pr_err("could not get the rproc handle\n");
			return NULL;
		}
		return q6rproc;
}
#endif

static ssize_t show_start_stop(struct file *file, char __user *user_buf,
			size_t count, loff_t *ppos)
{
	struct userpd_dbgfs_info *hdl = file->private_data;
	char _buf[16] = {0};
	int ret;

	snprintf(_buf, sizeof(_buf), "%d\n", hdl->userpd_hdl.pd_curr_state);
	ret = simple_read_from_buffer(user_buf, count, ppos, _buf,
						strnlen(_buf, 16));
	return ret;
}

static ssize_t store_start_stop(struct file *file, const char __user *user_buf,
			size_t count, loff_t *ppos)
{
	struct userpd_dbgfs_info *hdl = file->private_data;
	bool state;
	int ret;

	ret = kstrtobool_from_user(user_buf, count, &state);
	if (ret) {
		pr_err("Failed to retrieve userbuf value\n");
		return ret;
	}

	if (state == hdl->userpd_hdl.pd_curr_state)
		return -EINVAL;

	if (state) {
		ret = rproc_boot(hdl->userpd_hdl.rproc);
		if (ret) {
			pr_err("couldn't boot q6v5: %d\n", ret);
			return ret;
		}
		/*userpd started*/
		hdl->userpd_hdl.pd_curr_state = true;
	} else {
		rproc_shutdown(hdl->userpd_hdl.rproc);
		/*userpd stopped*/
		hdl->userpd_hdl.pd_curr_state = false;
	}
	return count;
}

static const struct file_operations userpd_ops = {
	.open = simple_open,
	.write = store_start_stop,
	.read = show_start_stop,
};

static int get_userpd_cnt(struct rproc *q6rproc)
{
	struct device_node *upd_np;
	int cnt = 0;

	for_each_available_child_of_node(q6rproc->dev.parent->of_node, upd_np)
		cnt += strstr(upd_np->name, "pd") ? 1 : 0;

	return cnt;
}

struct rproc *get_userpd_rproc(struct rproc *q6rproc, int pd_asid)
{
	struct device_node *upd_np;
	int cnt = 0;
	struct platform_device *upd_pdev;
	struct rproc *rproc;

	for_each_available_child_of_node(q6rproc->dev.parent->of_node, upd_np) {
		if (!strstr(upd_np->name, "pd"))
			continue;

		if (pd_asid == ++cnt) {
			upd_pdev = of_find_device_by_node(upd_np);
			if (!upd_pdev) {
				pr_info("upd pdev is null\n");
				return NULL;
			}
			rproc = platform_get_drvdata(upd_pdev);
			return rproc;
		}
	}
	return NULL;
}

static int register_userpd_rproc_notif(struct rproc *q6rproc)
{
	struct device_node *upd_np;

	for_each_available_child_of_node(q6rproc->dev.parent->of_node, upd_np) {
		struct platform_device *upd_pdev;
		struct rproc *upd_rproc; int ret;

		if (!strstr(upd_np->name, "pd"))
			continue;

		upd_pdev = of_find_device_by_node(upd_np);
		if (!upd_pdev) {
			pr_info("upd pdev is null\n");
			return -1;
		}
		upd_rproc = platform_get_drvdata(upd_pdev);

		ret = test_rproc_notif_register(upd_rproc->name);
		if (ret)
			return ret;
	}
	return 0;
}

static void unregister_userpd_rproc_notif(struct rproc *q6rproc)
{
	struct device_node *upd_np;

	for_each_available_child_of_node(q6rproc->dev.parent->of_node, upd_np) {
		struct platform_device *upd_pdev;
		struct rproc *upd_rproc;

		if (!strstr(upd_np->name, "pd"))
			continue;

		upd_pdev = of_find_device_by_node(upd_np);
		upd_rproc = platform_get_drvdata(upd_pdev);

		rproc_unregister_subsys_notifier(upd_rproc->name, &nb,
&atomic_nb);
	}
}

static int create_userpd_debugfs(struct rproc *q6rproc)
{
	int ret, cnt, tmp;
	char name[40];

	/*Get userpd count*/
	cnt = get_userpd_cnt(q6rproc);
	if (cnt > MAX_USERPD_CNT) {
		pr_err("Current implementation don't support %d userpd's\n",
			cnt);
		return -EINVAL;
	}

	if (!cnt) {
		pr_err("No userpd is registered\n");
		return -EINVAL;
	}


	/*create a sysfs entry to start/stop registered user pd's*/
	q6_userpd_debug = debugfs_create_dir("q6v5_userpd_debug", NULL);
	if (IS_ERR(q6_userpd_debug)) {
		pr_err("Failed to create q6v5 userpd debug directory\n");
		return PTR_ERR(q6_userpd_debug);
	}

	for (tmp = 0; tmp < cnt; tmp++) {

		userpd_dbgfs_hdl[tmp] = kzalloc(sizeof(*userpd_dbgfs_hdl[tmp]),
				GFP_KERNEL);
		if (!userpd_dbgfs_hdl[tmp]) {
			pr_err("Failed to allocate memory\n");
			ret = PTR_ERR(userpd_dbgfs_hdl[tmp]);
			goto err_free_mem;
		}

		/*get rproc handle*/
		userpd_dbgfs_hdl[tmp]->userpd_hdl.rproc =
			get_userpd_rproc(q6rproc, tmp+1);
		if (!userpd_dbgfs_hdl[tmp]->userpd_hdl.rproc) {
			pr_err("failed to get rproc handle\n");
			return -1;
		}

		snprintf(name, sizeof(name), "q6v5_wcss_userpd%d", (tmp + 1));

		/*sysfs entry for each userpd*/
		userpd_dbgfs_hdl[tmp]->userpd = debugfs_create_dir(name,
				q6_userpd_debug);
		if (IS_ERR(userpd_dbgfs_hdl[tmp]->userpd)) {
			pr_err("Failed to create q6v5 userpd%d debug directory\n",
					(tmp + 1));
			ret = PTR_ERR(userpd_dbgfs_hdl[tmp]->userpd);
			goto err_release_userpd;
		}
		/*sysfs entry for userpd start/stop*/
		userpd_dbgfs_hdl[tmp]->start_stop =
			debugfs_create_file("start_stop",
					0600, userpd_dbgfs_hdl[tmp]->userpd,
					userpd_dbgfs_hdl[tmp],
					&userpd_ops);
		if (IS_ERR(userpd_dbgfs_hdl[tmp]->start_stop)) {
			pr_err("Failed to create q6v5\
					userpd%d start/stop\n", (tmp + 1));
			ret = PTR_ERR(userpd_dbgfs_hdl[tmp]->start_stop);
			goto err_release_userpd_start_stop;
		}

	}
	/* register call back for every userpd*/
	ret = register_userpd_rproc_notif(q6rproc);
	if (ret)
		return ret;
	return 0;

	for (; tmp >= 0; tmp--) {
err_release_userpd_start_stop:
		debugfs_remove(userpd_dbgfs_hdl[tmp]->start_stop);
err_release_userpd:
		debugfs_remove(userpd_dbgfs_hdl[tmp]->userpd);
err_free_mem:
		kfree(userpd_dbgfs_hdl[tmp]);
	}
	debugfs_remove(q6_userpd_debug);
	return ret;
}

static int remove_userpd_debugfs(struct rproc *q6rproc)
{
	int tmp, cnt;

	/*Get userpd count*/
	cnt = get_userpd_cnt(q6rproc);
	if (cnt > MAX_USERPD_CNT) {
		pr_err("Current implementation don't support %d userpd's\n",
			cnt);
		return -EINVAL;
	}

	if (!cnt) {
		pr_err("No userpd is registered\n");
		return -EINVAL;
	}

	/*shutdown any userpd's subsequently rootpd
	 * also will be shutted down
	 */
	for (tmp = 0; tmp < cnt; tmp++) {
		if (userpd_dbgfs_hdl[tmp]->userpd_hdl.pd_curr_state) {
			rproc_shutdown(userpd_dbgfs_hdl[tmp]->
					userpd_hdl.rproc);
		}
	}

	for (tmp = 0; tmp < cnt; tmp++) {
		debugfs_remove(userpd_dbgfs_hdl[tmp]->start_stop);
		debugfs_remove(userpd_dbgfs_hdl[tmp]->userpd);
		kfree(userpd_dbgfs_hdl[tmp]);
	}
	debugfs_remove(q6_userpd_debug);
	unregister_userpd_rproc_notif(q6rproc);
	return 0;
}

static int __init testssr_init(void)
{
	struct rproc *q6rproc;
	int ret;

	nb.notifier_call = tssr_notifier;
	atomic_nb.notifier_call = tssr_notifier;

	switch (test_id) {
	case 1:
		q6rproc = get_rproc_from_phandle();
		if (!q6rproc) {
			pr_err("could not get rproc..\n");
			return -ENODEV;
		}

		if (mpd) {
			ret = create_userpd_debugfs(q6rproc);
			if (ret) {
				pr_err("Failed to create sysfs entry for\
						userpd\n");
				return ret;
			}
			return 0;
		}

		ret = test_rproc_notif_register(q6rproc->name);
		if (ret)
			return ret;

		ret = rproc_boot(q6rproc);
		if (ret) {
			pr_err("couldn't boot q6v5: %d\n", ret);
			ret = rproc_unregister_subsys_notifier(q6rproc->name,
							&nb, &atomic_nb);
			return ret;
		}
		break;
	default:
		pr_err("Enter a valid test case id\n");
	}

	return 0;
}

static void __exit testssr_exit(void)
{
	struct rproc *q6rproc;
	int ret;

	switch (test_id) {
	case 1:
		q6rproc = get_rproc_from_phandle();
		if (!q6rproc) {
			pr_err("could not get rproc..\n");
				return;
		}

		if (mpd) {
			remove_userpd_debugfs(q6rproc);
			return;
		}
		rproc_shutdown(q6rproc);
		ret = rproc_unregister_subsys_notifier(q6rproc->name,
							&nb, &atomic_nb);
		break;
	default:
		break;
	}
}

module_init(testssr_init);
module_exit(testssr_exit);
MODULE_LICENSE("Dual BSD/GPL");
