/*
 * Exynos PM domain debugfs support.
 *
 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
 *              http://www.samsung.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

#include <soc/samsung/exynos-pd.h>

#ifdef CONFIG_DEBUG_FS
static struct dentry *exynos_pd_dbg_root;

static int exynos_pd_dbg_long_test(struct device *dev)
{
	int ret, i;

	pr_info("%s %s: test start.\n", EXYNOS_PD_DBG_PREFIX, __func__);

	if (pm_runtime_enabled(dev) && pm_runtime_active(dev)) {
		ret = pm_runtime_put_sync(dev);
		if (ret) {
			pr_err("%s %s: put sync failed.\n",
					EXYNOS_PD_DBG_PREFIX, __func__);
			return ret;
		}
	}

	for (i = 0; i < 100; i++) {
		ret = pm_runtime_get_sync(dev);
		if (ret) {
			pr_err("%s %s: get sync failed.\n",
					EXYNOS_PD_DBG_PREFIX, __func__);
			return ret;
		}
		mdelay(50);
		ret = pm_runtime_put_sync(dev);
		if (ret) {
			pr_err("%s %s: put sync failed.\n",
					EXYNOS_PD_DBG_PREFIX, __func__);
			return ret;
		}
		mdelay(50);
	}

	pr_info("%s %s: test done.\n", EXYNOS_PD_DBG_PREFIX, __func__);

	return ret;
}

static struct generic_pm_domain *exynos_pd_dbg_dev_to_genpd(struct device *dev)
{
	if (IS_ERR_OR_NULL(dev->pm_domain))
		return ERR_PTR(-EINVAL);

	return pd_to_genpd(dev->pm_domain);
}

static void exynos_pd_dbg_summary_show(struct generic_pm_domain *genpd)
{
	static const char * const gpd_status_lookup[] = {
		[GPD_STATE_ACTIVE] = "on",
		[GPD_STATE_POWER_OFF] = "off"
	};
	static const char * const rpm_status_lookup[] = {
		[RPM_ACTIVE] = "active",
		[RPM_RESUMING] = "resuming",
		[RPM_SUSPENDED] = "suspended",
		[RPM_SUSPENDING] = "suspending"
	};
	const char *p = "";
	struct pm_domain_data *pm_data;
	struct gpd_link *link;

	mutex_lock(&genpd->lock);

	if (genpd->status >= ARRAY_SIZE(gpd_status_lookup)) {
		pr_err("%s invalid GPD_STATUS\n", EXYNOS_PD_DBG_PREFIX);
		mutex_unlock(&genpd->lock);
		return ;
	}

	pr_info("[GENPD] : %-30s [GPD_STATUS] : %-15s\n",
			genpd->name, gpd_status_lookup[genpd->status]);

	list_for_each_entry(pm_data, &genpd->dev_list, list_node) {
		if (pm_data->dev->power.runtime_error)
			p = "error";
		else if (pm_data->dev->power.disable_depth)
			p = "unsupported";
		else if (pm_data->dev->power.runtime_status < ARRAY_SIZE(rpm_status_lookup))
			p = rpm_status_lookup[pm_data->dev->power.runtime_status];
		else
			WARN_ON(1);

		pr_info("\t[DEV] : %-30s [RPM_STATUS] : %-15s\n",
					dev_name(pm_data->dev), p);
	}

	list_for_each_entry(link, &genpd->master_links, master_node)
		exynos_pd_dbg_summary_show(link->slave);

	mutex_unlock(&genpd->lock);
}

static ssize_t exynos_pd_dbg_read(struct file *file, char __user *user_buf,
				size_t count, loff_t *ppos)
{
	const struct file_operations *ops = file->f_op;
	struct exynos_pd_dbg_info *info = container_of(ops, struct exynos_pd_dbg_info, fops);
	struct device *dev = info->dev;
	struct generic_pm_domain *genpd = exynos_pd_dbg_dev_to_genpd(dev);

	exynos_pd_dbg_summary_show(genpd);

	return 0;
}

static ssize_t exynos_pd_dbg_write(struct file *file, const char __user *user_buf,
				size_t count, loff_t *ppos)
{
	const struct file_operations *ops = file->f_op;
	struct exynos_pd_dbg_info *info = container_of(ops, struct exynos_pd_dbg_info, fops);
	struct device *dev = info->dev;
	char buf[32];
	size_t buf_size;

	buf_size = min(count, (sizeof(buf)-1));
	if (copy_from_user(buf, user_buf, buf_size))
		return -EFAULT;

	switch (buf[0]) {
	case '0':
		if (pm_runtime_put_sync(dev))
			pr_err("%s %s: put sync failed.\n",
					EXYNOS_PD_DBG_PREFIX, __func__);
		break;
	case '1':
		if (pm_runtime_get_sync(dev))
			pr_err("%s %s: get sync failed.\n",
					EXYNOS_PD_DBG_PREFIX, __func__);
		break;
	case 'c':
		exynos_pd_dbg_long_test(dev);
		break;
	default:
		pr_err("%s %s: Invalid input ['0'|'1'|'c']\n",
				EXYNOS_PD_DBG_PREFIX, __func__);
		break;
	}

	return count;
}

static const struct file_operations exynos_pd_dbg_fops = {
	.open = simple_open,
	.read = exynos_pd_dbg_read,
	.write = exynos_pd_dbg_write,
	.llseek = default_llseek,
};
#endif

static int exynos_pd_dbg_probe(struct platform_device *pdev)
{
	int ret;
	struct exynos_pd_dbg_info *dbg_info;

	dbg_info = kzalloc(sizeof(struct exynos_pd_dbg_info), GFP_KERNEL);
	if (!dbg_info) {
		pr_err("%s %s: could not allocate mem for dbg_info\n",
				EXYNOS_PD_DBG_PREFIX, __func__);
		ret = -ENOMEM;
		goto err_dbg_info;
	}
	dbg_info->dev = &pdev->dev;
#ifdef CONFIG_DEBUG_FS
	if (!exynos_pd_dbg_root) {
		exynos_pd_dbg_root = debugfs_create_dir("exynos-pd", NULL);
		if (!exynos_pd_dbg_root) {
			pr_err("%s %s: could not create debugfs dir\n",
					EXYNOS_PD_DBG_PREFIX, __func__);
			ret = -ENOMEM;
			goto err_dbgfs_root;
		}
	}

	dbg_info->fops = exynos_pd_dbg_fops;
	dbg_info->d = debugfs_create_file(dev_name(&pdev->dev), 0644,
			exynos_pd_dbg_root, NULL, &dbg_info->fops);
	if (!dbg_info->d) {
		pr_err("%s %s: could not creatd debugfs file\n",
				EXYNOS_PD_DBG_PREFIX, __func__);
		ret = -ENOMEM;
		goto err_dbgfs_pd;
	}
#endif
	platform_set_drvdata(pdev, dbg_info);

	pm_runtime_enable(&pdev->dev);

	ret = pm_runtime_get_sync(&pdev->dev);
	if (ret) {
		pr_err("%s %s: get_sync of %s failed.\n",
			EXYNOS_PD_DBG_PREFIX, __func__, dev_name(&pdev->dev));
		goto err_get_sync;
	}

	ret = pm_runtime_put_sync(&pdev->dev);
	if (ret) {
		pr_err("%s %s: put sync of %s failed.\n",
			EXYNOS_PD_DBG_PREFIX, __func__, dev_name(&pdev->dev));
		goto err_put_sync;
	}

	return 0;

err_get_sync:
err_put_sync:
#ifdef CONFIG_DEBUG_FS
	debugfs_remove_recursive(dbg_info->d);
err_dbgfs_pd:
	debugfs_remove_recursive(exynos_pd_dbg_root);
err_dbgfs_root:
#endif
	kfree(dbg_info);
err_dbg_info:
	return ret;
}

static int exynos_pd_dbg_remove(struct platform_device *pdev)
{
	struct exynos_pd_dbg_info *dbg_info = platform_get_drvdata(pdev);
	struct device *dev = dbg_info->dev;

	if (pm_runtime_enabled(dev) && pm_runtime_active(dev))
		pm_runtime_put_sync(dev);

	pm_runtime_disable(dev);

#ifdef CONFIG_DEBUG_FS
	debugfs_remove_recursive(dbg_info->d);
	debugfs_remove_recursive(exynos_pd_dbg_root);
#endif
	kfree(dbg_info);

	platform_set_drvdata(pdev, NULL);

	return 0;
}

static int exynos_pd_dbg_runtime_suspend(struct device *dev)
{
	pr_info("%s %s's Runtime_Suspend\n",
			EXYNOS_PD_DBG_PREFIX, dev_name(dev));
	return 0;
}

static int exynos_pd_dbg_runtime_resume(struct device *dev)
{
	pr_info("%s %s's Runtime_Resume\n",
			EXYNOS_PD_DBG_PREFIX, dev_name(dev));
	return 0;
}

static struct dev_pm_ops exynos_pd_dbg_pm_ops = {
	SET_RUNTIME_PM_OPS(exynos_pd_dbg_runtime_suspend,
			exynos_pd_dbg_runtime_resume,
			NULL)
};

#ifdef CONFIG_OF
static const struct of_device_id exynos_pd_dbg_match[] = {
	{
		.compatible = "samsung,exynos-pd-dbg",
	},
	{},
};
#endif

static struct platform_driver exynos_pd_dbg_drv = {
	.probe		= exynos_pd_dbg_probe,
	.remove		= exynos_pd_dbg_remove,
	.driver		= {
		.name	= "exynos_pd_dbg",
		.owner	= THIS_MODULE,
		.pm	= &exynos_pd_dbg_pm_ops,
#ifdef CONFIG_OF
		.of_match_table = exynos_pd_dbg_match,
#endif
	},
};

static int __init exynos_pd_dbg_init(void)
{
	return platform_driver_register(&exynos_pd_dbg_drv);
}
late_initcall(exynos_pd_dbg_init);
