/*
 * Copyright (c) Quantenna Communications Incorporated 2012.
 *
 * ########################################################################
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * ########################################################################
 *
 *
 */

#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <asm/board/pm.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include "pm.h"

#define STR_HELPER(x)			#x
#define STR(x)				STR_HELPER(x)

#define PM_PROC_FILE_NAME		"soc_pm"
#define PM_EMAC_PROC_FILE_NAME		"emac_pm"

#define PM_PROC_ADD_CMD			"add"
#define PM_PROC_UPDATE_CMD		"update"
#define PM_PROC_REMOVE_CMD		"remove"

#define PM_MAX_NAME_LEN			64

#define PM_PROC_PARSE_ADD_CMD		PM_PROC_ADD_CMD" %"STR(PM_MAX_NAME_LEN)"s %d"		/* syntax: "add who_ask NNN" */
#define PM_PROC_PARSE_UPDATE_CMD	PM_PROC_UPDATE_CMD" %"STR(PM_MAX_NAME_LEN)"s %d"	/* syntax: "update who_ask NNN" */
#define PM_PROC_PARSE_REMOVE_CMD	PM_PROC_REMOVE_CMD" %"STR(PM_MAX_NAME_LEN)"s"		/* syntax: "remove who_ask" */

static struct workqueue_struct *pm_wq;
static DEFINE_SPINLOCK(pm_wq_lock);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
struct qtn_pm_req_list {
	struct list_head list;
	int class_id;
	char req_name[16];
	struct pm_qos_request req;
};
static LIST_HEAD(qtn_pm_req_list_head);
static struct pm_qos_request *pm_emac_req;
#else
static struct pm_qos_request_list *pm_emac_req;
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
static ssize_t pm_write_proc(struct file *file, const char __user *buffer,
		size_t count, loff_t *f_pos)
#else
static int pm_write_proc(struct file *file, const char __user *buffer,
				unsigned long count, void *data)
#endif
{
	char cmd[PM_MAX_NAME_LEN + 32];
	char name[PM_MAX_NAME_LEN + 1];
	int val;
	int ret = 0;

	if (!count) {
		return -EINVAL;
	} else if (count > sizeof(cmd) - 1) {
		return -EINVAL;
	} else if (copy_from_user(cmd, buffer, count)) {
		return -EFAULT;
	}
	cmd[count] = '\0';

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	switch ((int)PDE_DATA(file_inode(file))) {
#else
	switch ((int)data) {
#endif
	case PM_QOS_POWER_SAVE:
		if (sscanf(cmd, PM_PROC_PARSE_ADD_CMD, name, &val) == 2) {
			ret = pm_qos_add_requirement(PM_QOS_POWER_SAVE, name, val);
		} else if (sscanf(cmd, PM_PROC_PARSE_UPDATE_CMD, name, &val) == 2) {
			ret = pm_qos_update_requirement(PM_QOS_POWER_SAVE, name, val);
		} else if (sscanf(cmd, PM_PROC_PARSE_REMOVE_CMD, name) == 1) {
			pm_qos_remove_requirement(PM_QOS_POWER_SAVE, name);
		} else {
			ret = -EINVAL;
		}
		break;
	case PM_QOS_POWER_EMAC:
		if (sscanf(cmd, "%d", &val) == 1) {
			pm_qos_update_request(pm_emac_req, val);
		} else {
			ret = -EINVAL;
		}
		break;
	default:
		ret = -EINVAL;
		break;
	}

	return ret ? ret : count;
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
static int pm_show(struct seq_file *seq, void *v)
{
	int class_id = (int)seq->private;

	seq_printf(seq, "class=%d, level=%d\n", class_id, pm_qos_requirement(class_id));
	return 0;
}

static int pm_open_proc(struct inode *inode, struct file *file)
{
	return single_open(file, pm_show, PDE_DATA(inode));
}

static const struct file_operations pm_save_fops = {
	.owner = THIS_MODULE,
	.open = pm_open_proc,
	.write = pm_write_proc,
	.read = seq_read,
};
#else
static int pm_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
{
	return sprintf(page, "%d", pm_qos_requirement((int)data));
}
#endif

static int __init pm_create_proc(void)
{
	struct proc_dir_entry *entry;
	struct proc_dir_entry *emac_proc_entry;
	/*
	 * Proc interface to change power save levels.
	 * Main purpose is debugging.
	 * Other kernel modules can directly use pm_qos_*() functions.
	 * User-space application (safe way) can open misc character device
	 * (major number 10, minor see by "cat /proc/misc")
	 * provided by PM QoS kernel module and control through it.
	 * It is safe because 'name' is chosen based on PID,
	 * and when application quit all its requests are removed.
	 */

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	entry = proc_create_data(PM_PROC_FILE_NAME, 0600, NULL, &pm_save_fops, (void *)PM_QOS_POWER_SAVE);
	if (!entry) {
		return -ENODEV;
	}

	emac_proc_entry = proc_create_data(PM_EMAC_PROC_FILE_NAME, 0600, NULL, &pm_save_fops, (void *)PM_QOS_POWER_EMAC);
	if (!emac_proc_entry) {
		return -ENODEV;
	}
#else
	entry = create_proc_entry(PM_PROC_FILE_NAME, 0600, NULL);
	if (!entry) {
		return -ENODEV;
	}
	entry->write_proc = pm_write_proc;
	entry->read_proc = pm_read_proc;
	entry->data = (void *)PM_QOS_POWER_SAVE;

	emac_proc_entry = create_proc_entry(PM_EMAC_PROC_FILE_NAME, 0600, NULL);
	if (!emac_proc_entry) {
		return -ENODEV;
	}
	emac_proc_entry->write_proc = pm_write_proc;
	emac_proc_entry->read_proc = pm_read_proc;
	emac_proc_entry->data = (void *)PM_QOS_POWER_EMAC;
#endif
	return 0;
}

static void __init pm_create_wq(void)
{
	pm_wq = create_workqueue("ruby_pm");
}

static int __init pm_init(void)
{
	pm_qos_add_requirement(PM_QOS_POWER_SAVE, BOARD_PM_GOVERNOR_QCSAPI, BOARD_PM_LEVEL_INIT);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	if(NULL == (pm_emac_req = kzalloc(sizeof(*pm_emac_req), GFP_KERNEL))) {
		return -ENOMEM;
	}
	pm_qos_add_request(pm_emac_req, PM_QOS_POWER_EMAC, BOARD_PM_LEVEL_NO);
#else
	pm_emac_req = pm_qos_add_request(PM_QOS_POWER_EMAC, BOARD_PM_LEVEL_NO);
	if (!pm_emac_req)
		return -ENOMEM;
#endif
	pm_create_wq();
	return pm_create_proc();
}
arch_initcall(pm_init);

static int __pm_cancel_work(struct delayed_work *dwork)
{
	int ret = 0;

	if (delayed_work_pending(dwork)) {
		cancel_delayed_work(dwork);
		ret = 1;
	} else if (work_pending(&dwork->work)) {
		cancel_work_sync(&dwork->work);
		ret = 1;
	}

	return ret;
}

int pm_queue_work(struct delayed_work *dwork, unsigned long delay)
{
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(&pm_wq_lock, flags);

	ret = __pm_cancel_work(dwork);
	queue_delayed_work(pm_wq, dwork, delay);

	spin_unlock_irqrestore(&pm_wq_lock, flags);

	return ret;
}
EXPORT_SYMBOL(pm_queue_work);

int pm_cancel_work(struct delayed_work *dwork)
{
	unsigned long flags;
	int ret = 0;

	spin_lock_irqsave(&pm_wq_lock, flags);

	ret = __pm_cancel_work(dwork);

	spin_unlock_irqrestore(&pm_wq_lock, flags);

	return ret;
}
EXPORT_SYMBOL(pm_cancel_work);

int pm_flush_work(struct delayed_work *dwork)
{
	might_sleep();
	return cancel_delayed_work_sync(dwork);
}
EXPORT_SYMBOL(pm_flush_work);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,24)
int pm_qos_add_requirement(int pm_qos_class, const char *name, s32 value)
{
	struct qtn_pm_req_list *req_list = NULL;

	if ((NULL == name) || (pm_qos_class < PM_QOS_POWER_SAVE)
		|| (pm_qos_class > PM_QOS_POWER_EMAC)) {
		return -EINVAL;
	}

	list_for_each_entry(req_list, &qtn_pm_req_list_head, list) {
		if ((pm_qos_class == req_list->class_id)
			&& !strncmp(name, req_list->req_name, sizeof(req_list->req_name))) {
			return -EEXIST;
		}
	}

	if(NULL == (req_list = kzalloc(sizeof(*req_list), GFP_KERNEL))) {
		return -ENOMEM;
	}
	req_list->class_id = pm_qos_class;
	strncpy(req_list->req_name, name, sizeof(req_list->req_name));

	pm_qos_add_request(&req_list->req, pm_qos_class, value);

	list_add(&req_list->list, &qtn_pm_req_list_head);
	return 0;
}
EXPORT_SYMBOL(pm_qos_add_requirement);

int pm_qos_update_requirement(int pm_qos_class, const char *name, s32 new_value)
{
	struct qtn_pm_req_list *req_list = NULL;

	if ((NULL == name) || (pm_qos_class < PM_QOS_POWER_SAVE)
		|| (pm_qos_class > PM_QOS_POWER_EMAC)) {
		return -EINVAL;
	}

	printk("%s: name=%s, value=%d\n", __func__, name, new_value);

	list_for_each_entry(req_list, &qtn_pm_req_list_head, list) {
		if ((pm_qos_class == req_list->class_id)
			&& !strncmp(name, req_list->req_name, sizeof(req_list->req_name))) {
			pm_qos_update_request(&req_list->req, new_value);
			return 0;
		}
	}

	return 0;
}
EXPORT_SYMBOL(pm_qos_update_requirement);

void pm_qos_remove_requirement(int pm_qos_class, const char *name)
{
	struct qtn_pm_req_list *req_list = NULL;

	if ((NULL == name) || (pm_qos_class < PM_QOS_POWER_SAVE)
		|| (pm_qos_class > PM_QOS_POWER_EMAC)) {
		return ;
	}

	list_for_each_entry(req_list, &qtn_pm_req_list_head, list) {
		if ((pm_qos_class == req_list->class_id)
			&& !strncmp(name, req_list->req_name, sizeof(req_list->req_name))) {
			break;
		}
	}
	pm_qos_remove_request(&req_list->req);
	list_del(&req_list->list);
	kfree(req_list);
}
EXPORT_SYMBOL(pm_qos_remove_requirement);

int pm_qos_requirement(int pm_qos_class)
{
	return pm_qos_request(pm_qos_class);
}
EXPORT_SYMBOL(pm_qos_requirement);
#endif

MODULE_AUTHOR("Quantenna");
MODULE_LICENSE("GPL");

