/* Copyright (c) 2012, Code Aurora Forum. 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/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/rbtree.h>
#include <linux/idr.h>
#include <linux/genalloc.h>
#include <linux/of.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <mach/ocmem_priv.h>

enum request_states {
	R_FREE = 0x0,	/* request is not allocated */
	R_PENDING,	/* request has a pending operation */
	R_ALLOCATED,	/* request has been allocated */
	R_MUST_GROW,	/* request must grow as a part of pending operation */
	R_MUST_SHRINK,	/* request must shrink as a part of pending operation */
	R_MUST_MAP,	/* request must be mapped before being used */
	R_MUST_UNMAP,	/* request must be unmapped when not being used */
	R_MAPPED,	/* request is mapped and actively used by client */
	R_UNMAPPED,	/* request is not mapped, so it's not in active use */
	R_EVICTED,	/* request is evicted and must be restored */
};

#define SET_STATE(x, val) (set_bit((val), &(x)->state))
#define CLEAR_STATE(x, val) (clear_bit((val), &(x)->state))
#define TEST_STATE(x, val) (test_bit((val), &(x)->state))

enum op_res {
	OP_COMPLETE = 0x0,
	OP_RESCHED,
	OP_PARTIAL,
	OP_EVICT,
	OP_FAIL = ~0x0,
};

/* Represents various client priorities */
/* Note: More than one client can share a priority level */
enum client_prio {
	MIN_PRIO = 0x0,
	NO_PRIO = MIN_PRIO,
	PRIO_SENSORS = 0x1,
	PRIO_OTHER_OS = 0x1,
	PRIO_LP_AUDIO = 0x1,
	PRIO_HP_AUDIO = 0x2,
	PRIO_VOICE = 0x3,
	PRIO_GFX_GROWTH = 0x4,
	PRIO_VIDEO = 0x5,
	PRIO_GFX = 0x6,
	PRIO_OCMEM = 0x7,
	MAX_OCMEM_PRIO = PRIO_OCMEM + 1,
};

static void __iomem *ocmem_vaddr;
static struct list_head sched_queue[MAX_OCMEM_PRIO];
static struct mutex sched_queue_mutex;

/* The duration in msecs before a pending operation is scheduled
 * This allows an idle window between use case boundaries where various
 * hardware state changes can occur. The value will be tweaked on actual
 * hardware.
*/
/* Delay in ms for switching to low power mode for OCMEM */
#define SCHED_DELAY 5000

static struct list_head rdm_queue;
static struct mutex rdm_mutex;
static struct workqueue_struct *ocmem_rdm_wq;
static struct workqueue_struct *ocmem_eviction_wq;

static struct ocmem_eviction_data *evictions[OCMEM_CLIENT_MAX];

struct ocmem_rdm_work {
	int id;
	struct ocmem_map_list *list;
	struct ocmem_handle *handle;
	int direction;
	struct work_struct work;
};

/* OCMEM Operational modes */
enum ocmem_client_modes {
	OCMEM_PERFORMANCE = 1,
	OCMEM_PASSIVE,
	OCMEM_LOW_POWER,
	OCMEM_MODE_MAX = OCMEM_LOW_POWER
};

/* OCMEM Addressing modes */
enum ocmem_interconnects {
	OCMEM_BLOCKED = 0,
	OCMEM_PORT = 1,
	OCMEM_OCMEMNOC = 2,
	OCMEM_SYSNOC = 3,
};

/**
 * Primary OCMEM Arbitration Table
 **/
struct ocmem_table {
	int client_id;
	int priority;
	int mode;
	int hw_interconnect;
} ocmem_client_table[OCMEM_CLIENT_MAX] = {
	{OCMEM_GRAPHICS, PRIO_GFX, OCMEM_PERFORMANCE, OCMEM_PORT},
	{OCMEM_VIDEO, PRIO_VIDEO, OCMEM_PERFORMANCE, OCMEM_OCMEMNOC},
	{OCMEM_CAMERA, NO_PRIO, OCMEM_PERFORMANCE, OCMEM_OCMEMNOC},
	{OCMEM_HP_AUDIO, PRIO_HP_AUDIO, OCMEM_PASSIVE, OCMEM_BLOCKED},
	{OCMEM_VOICE, PRIO_VOICE, OCMEM_PASSIVE, OCMEM_BLOCKED},
	{OCMEM_LP_AUDIO, PRIO_LP_AUDIO, OCMEM_LOW_POWER, OCMEM_SYSNOC},
	{OCMEM_SENSORS, PRIO_SENSORS, OCMEM_LOW_POWER, OCMEM_SYSNOC},
	{OCMEM_OTHER_OS, PRIO_OTHER_OS, OCMEM_LOW_POWER, OCMEM_SYSNOC},
};

static struct rb_root sched_tree;
static struct mutex sched_mutex;
static struct mutex allocation_mutex;

/* A region represents a continuous interval in OCMEM address space */
struct ocmem_region {
	/* Chain in Interval Tree */
	struct rb_node region_rb;
	/* Hash map of requests */
	struct idr region_idr;
	/* Chain in eviction list */
	struct list_head eviction_list;
	unsigned long r_start;
	unsigned long r_end;
	unsigned long r_sz;
	/* Highest priority of all requests served by this region */
	int max_prio;
};

/* Is OCMEM tightly coupled to the client ?*/
static inline int is_tcm(int id)
{
	if (ocmem_client_table[id].hw_interconnect == OCMEM_PORT ||
		ocmem_client_table[id].hw_interconnect == OCMEM_OCMEMNOC)
		return 1;
	else
		return 0;
}

static inline int is_iface_access(int id)
{
	return ocmem_client_table[id].hw_interconnect == OCMEM_OCMEMNOC ? 1 : 0;
}

static inline int is_remapped_access(int id)
{
	return ocmem_client_table[id].hw_interconnect == OCMEM_SYSNOC ? 1 : 0;
}

static inline int is_blocked(int id)
{
	return ocmem_client_table[id].hw_interconnect == OCMEM_BLOCKED ? 1 : 0;
}

inline struct ocmem_buf *handle_to_buffer(struct ocmem_handle *handle)
{
	if (handle)
		return &handle->buffer;
	else
		return NULL;
}

inline struct ocmem_handle *buffer_to_handle(struct ocmem_buf *buffer)
{
	if (buffer)
		return container_of(buffer, struct ocmem_handle, buffer);
	else
		return NULL;
}

inline struct ocmem_req *handle_to_req(struct ocmem_handle *handle)
{
	if (handle)
		return handle->req;
	else
		return NULL;
}

inline struct ocmem_handle *req_to_handle(struct ocmem_req *req)
{
	if (req && req->buffer)
		return container_of(req->buffer, struct ocmem_handle, buffer);
	else
		return NULL;
}

/* Simple wrappers which will have debug features added later */
inline int ocmem_read(void *at)
{
	return readl_relaxed(at);
}

inline int ocmem_write(unsigned long val, void *at)
{
	writel_relaxed(val, at);
	return 0;
}

inline int get_mode(int id)
{
	if (!check_id(id))
		return MODE_NOT_SET;
	else
		return ocmem_client_table[id].mode == OCMEM_PERFORMANCE ?
							WIDE_MODE : THIN_MODE;
}

/* Returns the address that can be used by a device core to access OCMEM */
static unsigned long device_address(int id, unsigned long addr)
{
	int hw_interconnect = ocmem_client_table[id].hw_interconnect;
	unsigned long ret_addr = 0x0;

	switch (hw_interconnect) {
	case OCMEM_PORT:
	case OCMEM_OCMEMNOC:
		ret_addr = phys_to_offset(addr);
		break;
	case OCMEM_SYSNOC:
		ret_addr = addr;
		break;
	case OCMEM_BLOCKED:
		ret_addr = 0x0;
		break;
	}
	return ret_addr;
}

/* Returns the address as viewed by the core */
static unsigned long core_address(int id, unsigned long addr)
{
	int hw_interconnect = ocmem_client_table[id].hw_interconnect;
	unsigned long ret_addr = 0x0;

	switch (hw_interconnect) {
	case OCMEM_PORT:
	case OCMEM_OCMEMNOC:
		ret_addr = offset_to_phys(addr);
		break;
	case OCMEM_SYSNOC:
		ret_addr = addr;
		break;
	case OCMEM_BLOCKED:
		ret_addr = 0x0;
		break;
	}
	return ret_addr;
}

static inline struct ocmem_zone *zone_of(struct ocmem_req *req)
{
	int owner;
	if (!req)
		return NULL;
	owner = req->owner;
	return get_zone(owner);
}

static int insert_region(struct ocmem_region *region)
{

	struct rb_root *root = &sched_tree;
	struct rb_node **p = &root->rb_node;
	struct rb_node *parent = NULL;
	struct ocmem_region *tmp = NULL;
	unsigned long addr = region->r_start;

	while (*p) {
		parent = *p;
		tmp = rb_entry(parent, struct ocmem_region, region_rb);

		if (tmp->r_end > addr) {
			if (tmp->r_start <= addr)
				break;
			p =  &(*p)->rb_left;
		} else if (tmp->r_end <= addr)
			p = &(*p)->rb_right;
	}
	rb_link_node(&region->region_rb, parent, p);
	rb_insert_color(&region->region_rb, root);
	return 0;
}

static int remove_region(struct ocmem_region *region)
{
	struct rb_root *root = &sched_tree;
	rb_erase(&region->region_rb, root);
	return 0;
}

static struct ocmem_req *ocmem_create_req(void)
{
	struct ocmem_req *p = NULL;

	p =  kzalloc(sizeof(struct ocmem_req), GFP_KERNEL);
	if (!p)
		return NULL;

	INIT_LIST_HEAD(&p->zone_list);
	INIT_LIST_HEAD(&p->sched_list);
	init_rwsem(&p->rw_sem);
	SET_STATE(p, R_FREE);
	pr_debug("request %p created\n", p);
	return p;
}

static int ocmem_destroy_req(struct ocmem_req *req)
{
	kfree(req);
	return 0;
}

static struct ocmem_region *create_region(void)
{
	struct ocmem_region *p = NULL;

	p =  kzalloc(sizeof(struct ocmem_region), GFP_KERNEL);
	if (!p)
		return NULL;
	idr_init(&p->region_idr);
	INIT_LIST_HEAD(&p->eviction_list);
	p->r_start = p->r_end = p->r_sz = 0x0;
	p->max_prio = NO_PRIO;
	return p;
}

static int destroy_region(struct ocmem_region *region)
{
	kfree(region);
	return 0;
}

static int attach_req(struct ocmem_region *region, struct ocmem_req *req)
{
	int ret, id;

	while (1) {
		if (idr_pre_get(&region->region_idr, GFP_KERNEL) == 0)
			return -ENOMEM;

		ret = idr_get_new_above(&region->region_idr, req, 1, &id);

		if (ret != -EAGAIN)
			break;
	}

	if (!ret) {
		req->req_id = id;
		pr_debug("ocmem: request %p(id:%d) attached to region %p\n",
				req, id, region);
		return 0;
	}
	return -EINVAL;
}

static int detach_req(struct ocmem_region *region, struct ocmem_req *req)
{
	idr_remove(&region->region_idr, req->req_id);
	return 0;
}

static int populate_region(struct ocmem_region *region, struct ocmem_req *req)
{
	region->r_start = req->req_start;
	region->r_end = req->req_end;
	region->r_sz =  req->req_end - req->req_start + 1;
	return 0;
}

static int region_req_count(int id, void *ptr, void *data)
{
	int *count = data;
	*count = *count + 1;
	return 0;
}

static int req_count(struct ocmem_region *region)
{
	int count = 0;
	idr_for_each(&region->region_idr, region_req_count, &count);
	return count;
}

static int compute_max_prio(int id, void *ptr, void *data)
{
	int *max = data;
	struct ocmem_req *req = ptr;

	if (req->prio > *max)
		*max = req->prio;
	return 0;
}

static int update_region_prio(struct ocmem_region *region)
{
	int max_prio;
	if (req_count(region) != 0) {
		idr_for_each(&region->region_idr, compute_max_prio, &max_prio);
		region->max_prio = max_prio;
	} else {
		region->max_prio = NO_PRIO;
	}
	pr_debug("ocmem: Updating prio of region %p as %d\n",
			region, max_prio);

	return 0;
}

static struct ocmem_region *find_region(unsigned long addr)
{
	struct ocmem_region *region = NULL;
	struct rb_node *rb_node = NULL;

	rb_node = sched_tree.rb_node;

	while (rb_node) {
		struct ocmem_region *tmp_region = NULL;
		tmp_region = rb_entry(rb_node, struct ocmem_region, region_rb);

		if (tmp_region->r_end > addr) {
			region = tmp_region;
			if (tmp_region->r_start <= addr)
				break;
			rb_node = rb_node->rb_left;
		} else {
			rb_node = rb_node->rb_right;
		}
	}
	return region;
}

static struct ocmem_region *find_region_intersection(unsigned long start,
					unsigned long end)
{

	struct ocmem_region *region = NULL;
	region = find_region(start);
	if (region && end <= region->r_start)
		region = NULL;
	return region;
}

static struct ocmem_region *find_region_match(unsigned long start,
					unsigned long end)
{

	struct ocmem_region *region = NULL;
	region = find_region(start);
	if (region && start == region->r_start && end == region->r_end)
		return region;
	return NULL;
}

static struct ocmem_req *find_req_match(int owner, struct ocmem_region *region)
{
	struct ocmem_req *req = NULL;

	if (!region)
		return NULL;

	req = idr_find(&region->region_idr, owner);

	return req;
}

/* Must be called with req->sem held */
static inline int is_mapped(struct ocmem_req *req)
{
	return TEST_STATE(req, R_MAPPED);
}

/* Must be called with sched_mutex held */
static int __sched_unmap(struct ocmem_req *req)
{
	struct ocmem_req *matched_req = NULL;
	struct ocmem_region *matched_region = NULL;

	matched_region = find_region_match(req->req_start, req->req_end);
	matched_req = find_req_match(req->req_id, matched_region);

	if (!matched_region || !matched_req) {
		pr_err("Could not find backing region for req");
		goto invalid_op_error;
	}

	if (matched_req != req) {
		pr_err("Request does not match backing req");
		goto invalid_op_error;
	}

	if (!is_mapped(req)) {
		pr_err("Request is not currently mapped");
		goto invalid_op_error;
	}

	/* Update the request state */
	CLEAR_STATE(req, R_MAPPED);
	SET_STATE(req, R_MUST_MAP);

	return OP_COMPLETE;

invalid_op_error:
	return OP_FAIL;
}

/* Must be called with sched_mutex held */
static int __sched_map(struct ocmem_req *req)
{
	struct ocmem_req *matched_req = NULL;
	struct ocmem_region *matched_region = NULL;

	matched_region = find_region_match(req->req_start, req->req_end);
	matched_req = find_req_match(req->req_id, matched_region);

	if (!matched_region || !matched_req) {
		pr_err("Could not find backing region for req");
		goto invalid_op_error;
	}

	if (matched_req != req) {
		pr_err("Request does not match backing req");
		goto invalid_op_error;
	}

	/* Update the request state */
	CLEAR_STATE(req, R_MUST_MAP);
	SET_STATE(req, R_MAPPED);

	return OP_COMPLETE;

invalid_op_error:
	return OP_FAIL;
}

static int do_map(struct ocmem_req *req)
{
	int rc = 0;

	down_write(&req->rw_sem);

	mutex_lock(&sched_mutex);
	rc = __sched_map(req);
	mutex_unlock(&sched_mutex);

	up_write(&req->rw_sem);

	if (rc == OP_FAIL)
		return -EINVAL;

	return 0;
}

static int do_unmap(struct ocmem_req *req)
{
	int rc = 0;

	down_write(&req->rw_sem);

	mutex_lock(&sched_mutex);
	rc = __sched_unmap(req);
	mutex_unlock(&sched_mutex);

	up_write(&req->rw_sem);

	if (rc == OP_FAIL)
		return -EINVAL;

	return 0;
}

static int process_map(struct ocmem_req *req, unsigned long start,
				unsigned long end)
{
	int rc = 0;

	rc = ocmem_enable_core_clock();

	if (rc < 0)
		goto core_clock_fail;


	if (is_iface_access(req->owner)) {
		rc = ocmem_enable_iface_clock();

		if (rc < 0)
			goto iface_clock_fail;
	}

	if (is_remapped_access(req->owner)) {
		rc = ocmem_enable_br_clock();

		if (rc < 0)
			goto br_clock_fail;
	}

	rc = ocmem_lock(req->owner, phys_to_offset(req->req_start), req->req_sz,
							get_mode(req->owner));

	if (rc < 0) {
		pr_err("ocmem: Failed to secure request %p for %d\n", req,
				req->owner);
		goto lock_failed;
	}

	rc = do_map(req);

	if (rc < 0) {
		pr_err("ocmem: Failed to map request %p for %d\n",
							req, req->owner);
		goto process_map_fail;

	}
	pr_debug("ocmem: Mapped request %p\n", req);
	return 0;

process_map_fail:
	ocmem_unlock(req->owner, phys_to_offset(req->req_start), req->req_sz);
lock_failed:
	if (is_remapped_access(req->owner))
		ocmem_disable_br_clock();
br_clock_fail:
	if (is_iface_access(req->owner))
		ocmem_disable_iface_clock();
iface_clock_fail:
	ocmem_disable_core_clock();
core_clock_fail:
	pr_err("ocmem: Failed to map ocmem request\n");
	return rc;
}

static int process_unmap(struct ocmem_req *req, unsigned long start,
				unsigned long end)
{
	int rc = 0;

	rc = do_unmap(req);

	if (rc < 0)
		goto process_unmap_fail;

	rc = ocmem_unlock(req->owner, phys_to_offset(req->req_start),
						req->req_sz);

	if (rc < 0) {
		pr_err("ocmem: Failed to un-secure request %p for %d\n", req,
				req->owner);
		goto unlock_failed;
	}

	if (is_remapped_access(req->owner))
		ocmem_disable_br_clock();
	if (is_iface_access(req->owner))
		ocmem_disable_iface_clock();
	ocmem_disable_core_clock();
	pr_debug("ocmem: Unmapped request %p\n", req);
	return 0;

unlock_failed:
process_unmap_fail:
	pr_err("ocmem: Failed to unmap ocmem request\n");
	return rc;
}

static int __sched_grow(struct ocmem_req *req, bool can_block)
{
	unsigned long min = req->req_min;
	unsigned long max = req->req_max;
	unsigned long step = req->req_step;
	int owner = req->owner;
	unsigned long curr_sz = 0;
	unsigned long growth_sz = 0;
	unsigned long curr_start = 0;
	enum client_prio prio = req->prio;
	unsigned long alloc_addr = 0x0;
	bool retry;
	struct ocmem_region *spanned_r = NULL;
	struct ocmem_region *overlap_r = NULL;

	struct ocmem_req *matched_req = NULL;
	struct ocmem_region *matched_region = NULL;

	struct ocmem_zone *zone = get_zone(owner);
	struct ocmem_region *region = NULL;

	matched_region = find_region_match(req->req_start, req->req_end);
	matched_req = find_req_match(req->req_id, matched_region);

	if (!matched_region || !matched_req) {
		pr_err("Could not find backing region for req");
		goto invalid_op_error;
	}

	if (matched_req != req) {
		pr_err("Request does not match backing req");
		goto invalid_op_error;
	}

	curr_sz = matched_req->req_sz;
	curr_start = matched_req->req_start;
	growth_sz = matched_req->req_max - matched_req->req_sz;

	pr_debug("Attempting to grow req %p from %lx to %lx\n",
			req, matched_req->req_sz, matched_req->req_max);

	retry = false;

	pr_debug("ocmem: GROW: growth size %lx\n", growth_sz);

retry_next_step:

	spanned_r = NULL;
	overlap_r = NULL;

	spanned_r = find_region(zone->z_head);
	overlap_r = find_region_intersection(zone->z_head,
				zone->z_head + growth_sz);

	if (overlap_r == NULL) {
		/* no conflicting regions, schedule this region */
		zone->z_ops->free(zone, curr_start, curr_sz);
		alloc_addr = zone->z_ops->allocate(zone, curr_sz + growth_sz);

		if (alloc_addr < 0) {
			pr_err("ocmem: zone allocation operation failed\n");
			goto internal_error;
		}

		curr_sz += growth_sz;
		/* Detach the region from the interval tree */
		/* This is to guarantee that any change in size
		 * causes the tree to be rebalanced if required */

		detach_req(matched_region, req);
		if (req_count(matched_region) == 0) {
			remove_region(matched_region);
			region = matched_region;
		} else {
			region = create_region();
			if (!region) {
				pr_err("ocmem: Unable to create region\n");
				goto region_error;
			}
		}

		/* update the request */
		req->req_start = alloc_addr;
		/* increment the size to reflect new length */
		req->req_sz = curr_sz;
		req->req_end = alloc_addr + req->req_sz - 1;

		/* update request state */
		CLEAR_STATE(req, R_MUST_GROW);
		SET_STATE(req, R_ALLOCATED);
		SET_STATE(req, R_MUST_MAP);
		req->op = SCHED_MAP;

		/* update the region with new req */
		attach_req(region, req);
		populate_region(region, req);
		update_region_prio(region);

		/* update the tree with new region */
		if (insert_region(region)) {
			pr_err("ocmem: Failed to insert the region\n");
			goto region_error;
		}

		if (retry) {
			SET_STATE(req, R_MUST_GROW);
			SET_STATE(req, R_PENDING);
			req->op = SCHED_GROW;
			return OP_PARTIAL;
		}
	} else if (spanned_r != NULL && overlap_r != NULL) {
		/* resolve conflicting regions based on priority */
		if (overlap_r->max_prio < prio) {
			/* Growth cannot be triggered unless a previous
			 * client of lower priority was evicted */
			pr_err("ocmem: Invalid growth scheduled\n");
			/* This is serious enough to fail */
			BUG();
			return OP_FAIL;
		} else if (overlap_r->max_prio > prio) {
			if (min == max) {
				/* Cannot grow at this time, try later */
				SET_STATE(req, R_PENDING);
				SET_STATE(req, R_MUST_GROW);
				return OP_RESCHED;
			} else {
			/* Try to grow in steps */
				growth_sz -= step;
				/* We are OOM at this point so need to retry */
				if (growth_sz <= curr_sz) {
					SET_STATE(req, R_PENDING);
					SET_STATE(req, R_MUST_GROW);
					return OP_RESCHED;
				}
				retry = true;
				pr_debug("ocmem: Attempting with reduced size %lx\n",
						growth_sz);
				goto retry_next_step;
			}
		} else {
			pr_err("ocmem: grow: New Region %p Existing %p\n",
				matched_region, overlap_r);
			pr_err("ocmem: Undetermined behavior\n");
			/* This is serious enough to fail */
			BUG();
		}
	} else if (spanned_r == NULL && overlap_r != NULL) {
		goto err_not_supported;
	}

	return OP_COMPLETE;

err_not_supported:
	pr_err("ocmem: Scheduled unsupported operation\n");
	return OP_FAIL;
region_error:
	zone->z_ops->free(zone, alloc_addr, curr_sz);
	detach_req(region, req);
	update_region_prio(region);
	/* req is going to be destroyed by the caller anyways */
internal_error:
	destroy_region(region);
invalid_op_error:
	return OP_FAIL;
}

/* Must be called with sched_mutex held */
static int __sched_free(struct ocmem_req *req)
{
	int owner = req->owner;
	int ret = 0;

	struct ocmem_req *matched_req = NULL;
	struct ocmem_region *matched_region = NULL;

	struct ocmem_zone *zone = get_zone(owner);

	BUG_ON(!zone);

	matched_region = find_region_match(req->req_start, req->req_end);
	matched_req = find_req_match(req->req_id, matched_region);

	if (!matched_region || !matched_req)
		goto invalid_op_error;
	if (matched_req != req)
		goto invalid_op_error;

	ret = zone->z_ops->free(zone,
		matched_req->req_start, matched_req->req_sz);

	if (ret < 0)
		goto err_op_fail;

	detach_req(matched_region, matched_req);
	update_region_prio(matched_region);
	if (req_count(matched_region) == 0) {
		remove_region(matched_region);
		destroy_region(matched_region);
	}

	/* Update the request */
	req->req_start = 0x0;
	req->req_sz = 0x0;
	req->req_end = 0x0;
	SET_STATE(req, R_FREE);
	return OP_COMPLETE;
invalid_op_error:
	pr_err("ocmem: free: Failed to find matching region\n");
err_op_fail:
	pr_err("ocmem: free: Failed\n");
	return OP_FAIL;
}

/* Must be called with sched_mutex held */
static int __sched_shrink(struct ocmem_req *req, unsigned long new_sz)
{
	int owner = req->owner;
	int ret = 0;

	struct ocmem_req *matched_req = NULL;
	struct ocmem_region *matched_region = NULL;
	struct ocmem_region *region = NULL;
	unsigned long alloc_addr = 0x0;

	struct ocmem_zone *zone = get_zone(owner);

	BUG_ON(!zone);

	/* The shrink should not be called for zero size */
	BUG_ON(new_sz == 0);

	matched_region = find_region_match(req->req_start, req->req_end);
	matched_req = find_req_match(req->req_id, matched_region);

	if (!matched_region || !matched_req)
		goto invalid_op_error;
	if (matched_req != req)
		goto invalid_op_error;

	ret = zone->z_ops->free(zone,
		matched_req->req_start, matched_req->req_sz);

	if (ret < 0) {
		pr_err("Zone Allocation operation failed\n");
		goto internal_error;
	}

	alloc_addr = zone->z_ops->allocate(zone, new_sz);

	if (alloc_addr < 0) {
		pr_err("Zone Allocation operation failed\n");
		goto internal_error;
	}

	/* Detach the region from the interval tree */
	/* This is to guarantee that the change in size
	 * causes the tree to be rebalanced if required */

	detach_req(matched_region, req);
	if (req_count(matched_region) == 0) {
		remove_region(matched_region);
		region = matched_region;
	} else {
		region = create_region();
		if (!region) {
			pr_err("ocmem: Unable to create region\n");
			goto internal_error;
		}
	}
	/* update the request */
	req->req_start = alloc_addr;
	req->req_sz = new_sz;
	req->req_end = alloc_addr + req->req_sz;

	if (req_count(region) == 0) {
		remove_region(matched_region);
		destroy_region(matched_region);
	}

	/* update request state */
	SET_STATE(req, R_MUST_GROW);
	SET_STATE(req, R_MUST_MAP);
	req->op = SCHED_MAP;

	/* attach the request to the region */
	attach_req(region, req);
	populate_region(region, req);
	update_region_prio(region);

	/* update the tree with new region */
	if (insert_region(region)) {
		pr_err("ocmem: Failed to insert the region\n");
		zone->z_ops->free(zone, alloc_addr, new_sz);
		detach_req(region, req);
		update_region_prio(region);
		/* req will be destroyed by the caller */
		goto region_error;
	}
	return OP_COMPLETE;

region_error:
	destroy_region(region);
internal_error:
	pr_err("ocmem: shrink: Failed\n");
	return OP_FAIL;
invalid_op_error:
	pr_err("ocmem: shrink: Failed to find matching region\n");
	return OP_FAIL;
}

/* Must be called with sched_mutex held */
static int __sched_allocate(struct ocmem_req *req, bool can_block,
				bool can_wait)
{
	unsigned long min = req->req_min;
	unsigned long max = req->req_max;
	unsigned long step = req->req_step;
	int owner = req->owner;
	unsigned long sz = max;
	enum client_prio prio = req->prio;
	unsigned long alloc_addr = 0x0;
	bool retry;

	struct ocmem_region *spanned_r = NULL;
	struct ocmem_region *overlap_r = NULL;

	struct ocmem_zone *zone = get_zone(owner);
	struct ocmem_region *region = NULL;

	BUG_ON(!zone);

	if (min > (zone->z_end - zone->z_start)) {
		pr_err("ocmem: requested minimum size exceeds quota\n");
		goto invalid_op_error;
	}

	if (max > (zone->z_end - zone->z_start)) {
		pr_err("ocmem: requested maximum size exceeds quota\n");
		goto invalid_op_error;
	}

	if (min > zone->z_free) {
			pr_err("ocmem: out of memory for zone %d\n", owner);
			goto invalid_op_error;
	}

	region = create_region();

	if (!region) {
		pr_err("ocmem: Unable to create region\n");
		goto invalid_op_error;
	}

	retry = false;

	pr_debug("ocmem: do_allocate: %s request size %lx\n",
						get_name(owner), sz);

retry_next_step:

	spanned_r = NULL;
	overlap_r = NULL;

	spanned_r = find_region(zone->z_head);
	overlap_r = find_region_intersection(zone->z_head, zone->z_head + sz);

	if (overlap_r == NULL) {
		/* no conflicting regions, schedule this region */
		alloc_addr = zone->z_ops->allocate(zone, sz);

		if (alloc_addr < 0) {
			pr_err("Zone Allocation operation failed\n");
			goto internal_error;
		}

		/* update the request */
		req->req_start = alloc_addr;
		req->req_end = alloc_addr + sz - 1;
		req->req_sz = sz;
		req->zone = zone;

		/* update request state */
		CLEAR_STATE(req, R_FREE);
		CLEAR_STATE(req, R_PENDING);
		SET_STATE(req, R_ALLOCATED);
		SET_STATE(req, R_MUST_MAP);
		req->op = SCHED_NOP;

		/* attach the request to the region */
		attach_req(region, req);
		populate_region(region, req);
		update_region_prio(region);

		/* update the tree with new region */
		if (insert_region(region)) {
			pr_err("ocmem: Failed to insert the region\n");
			zone->z_ops->free(zone, alloc_addr, sz);
			detach_req(region, req);
			update_region_prio(region);
			/* req will be destroyed by the caller */
			goto internal_error;
		}

		if (retry) {
			SET_STATE(req, R_MUST_GROW);
			SET_STATE(req, R_PENDING);
			req->op = SCHED_GROW;
			return OP_PARTIAL;
		}
	} else if (spanned_r != NULL && overlap_r != NULL) {
		/* resolve conflicting regions based on priority */
		if (overlap_r->max_prio < prio) {
			if (min == max) {
				req->req_start = zone->z_head;
				req->req_end = zone->z_head + sz - 1;
				req->req_sz = 0x0;
				req->edata = NULL;
				goto trigger_eviction;
			} else {
			/* Try to allocate atleast >= 'min' immediately */
				sz -= step;
				if (sz < min)
					goto err_out_of_mem;
				retry = true;
				pr_debug("ocmem: Attempting with reduced size %lx\n",
						sz);
				goto retry_next_step;
			}
		} else if (overlap_r->max_prio > prio) {
			if (can_block == true) {
				SET_STATE(req, R_PENDING);
				SET_STATE(req, R_MUST_GROW);
				return OP_RESCHED;
			} else {
				if (min == max) {
					pr_err("Cannot allocate %lx synchronously\n",
							sz);
					goto err_out_of_mem;
				} else {
					sz -= step;
					if (sz < min)
						goto err_out_of_mem;
					retry = true;
					pr_debug("ocmem: Attempting reduced size %lx\n",
							sz);
					goto retry_next_step;
				}
			}
		} else {
			pr_err("ocmem: Undetermined behavior\n");
			pr_err("ocmem: New Region %p Existing %p\n", region,
					overlap_r);
			/* This is serious enough to fail */
			BUG();
		}
	} else if (spanned_r == NULL && overlap_r != NULL)
		goto err_not_supported;

	return OP_COMPLETE;

trigger_eviction:
	pr_debug("Trigger eviction of region %p\n", overlap_r);
	destroy_region(region);
	return OP_EVICT;

err_not_supported:
	pr_err("ocmem: Scheduled unsupported operation\n");
	return OP_FAIL;

err_out_of_mem:
	pr_err("ocmem: Out of memory during allocation\n");
internal_error:
	destroy_region(region);
invalid_op_error:
	return OP_FAIL;
}

static int sched_enqueue(struct ocmem_req *priv)
{
	struct ocmem_req *next = NULL;
	mutex_lock(&sched_queue_mutex);
	list_add_tail(&priv->sched_list, &sched_queue[priv->owner]);
	pr_debug("enqueued req %p\n", priv);
	list_for_each_entry(next, &sched_queue[priv->owner], sched_list) {
		pr_debug("pending requests for client %p\n", next);
	}
	mutex_unlock(&sched_queue_mutex);
	return 0;
}

static void sched_dequeue(struct ocmem_req *victim_req)
{
	struct ocmem_req *req = NULL;
	struct ocmem_req *next = NULL;
	int id;

	if (!victim_req)
		return;

	id = victim_req->owner;

	mutex_lock(&sched_queue_mutex);

	if (list_empty(&sched_queue[id]))
		goto dequeue_done;

	list_for_each_entry_safe(req, next, &sched_queue[id], sched_list)
	{
		if (req == victim_req) {
			pr_debug("ocmem: Cancelling pending request %p\n",
							req);
			list_del(&req->sched_list);
			goto dequeue_done;
		}
	}

dequeue_done:
	mutex_unlock(&sched_queue_mutex);
	return;
}

static struct ocmem_req *ocmem_fetch_req(void)
{
	int i;
	struct ocmem_req *req = NULL;
	struct ocmem_req *next = NULL;

	mutex_lock(&sched_queue_mutex);
	for (i = MIN_PRIO; i < MAX_OCMEM_PRIO; i++) {
		if (list_empty(&sched_queue[i]))
			continue;
		list_for_each_entry_safe(req, next, &sched_queue[i], sched_list)
		{
			if (req) {
				pr_debug("ocmem: Fetched pending request %p\n",
									req);
				list_del(&req->sched_list);
			break;
			}
		}
	}
	mutex_unlock(&sched_queue_mutex);
	return req;
}


unsigned long process_quota(int id)
{
	struct ocmem_zone *zone = NULL;

	if (is_blocked(id))
		return 0;

	zone = get_zone(id);

	if (zone && zone->z_pool)
		return zone->z_end - zone->z_start;
	else
		return 0;
}

static int do_grow(struct ocmem_req *req)
{
	struct ocmem_buf *buffer = NULL;
	bool can_block = true;
	int rc = 0;

	down_write(&req->rw_sem);
	buffer = req->buffer;

	/* Take the scheduler mutex */
	mutex_lock(&sched_mutex);
	rc = __sched_grow(req, can_block);
	mutex_unlock(&sched_mutex);

	if (rc == OP_FAIL)
		goto err_op_fail;

	if (rc == OP_RESCHED) {
		pr_debug("ocmem: Enqueue this allocation");
		sched_enqueue(req);
	}

	else if (rc == OP_COMPLETE || rc == OP_PARTIAL) {
		buffer->addr = device_address(req->owner, req->req_start);
		buffer->len = req->req_sz;
	}

	up_write(&req->rw_sem);
	return 0;
err_op_fail:
	up_write(&req->rw_sem);
	return -EINVAL;
}

static int process_grow(struct ocmem_req *req)
{
	int rc = 0;
	unsigned long offset = 0;

	/* Attempt to grow the region */
	rc = do_grow(req);

	if (rc < 0)
		return -EINVAL;

	rc = process_map(req, req->req_start, req->req_end);
	if (rc < 0)
		return -EINVAL;

	offset = phys_to_offset(req->req_start);

	rc = ocmem_memory_on(req->owner, offset, req->req_sz);

	if (rc < 0) {
		pr_err("Failed to switch ON memory macros\n");
		goto power_ctl_error;
	}

	/* Notify the client about the buffer growth */
	rc = dispatch_notification(req->owner, OCMEM_ALLOC_GROW, req->buffer);
	if (rc < 0) {
		pr_err("No notifier callback to cater for req %p event: %d\n",
				req, OCMEM_ALLOC_GROW);
		BUG();
	}
	return 0;
power_ctl_error:
	return -EINVAL;
}

static int do_shrink(struct ocmem_req *req, unsigned long shrink_size)
{

	int rc = 0;
	struct ocmem_buf *buffer = NULL;

	down_write(&req->rw_sem);
	buffer = req->buffer;

	/* Take the scheduler mutex */
	mutex_lock(&sched_mutex);
	rc = __sched_shrink(req, shrink_size);
	mutex_unlock(&sched_mutex);

	if (rc == OP_FAIL)
		goto err_op_fail;

	else if (rc == OP_COMPLETE) {
		buffer->addr = device_address(req->owner, req->req_start);
		buffer->len = req->req_sz;
	}

	up_write(&req->rw_sem);
	return 0;
err_op_fail:
	up_write(&req->rw_sem);
	return -EINVAL;
}

static void ocmem_sched_wk_func(struct work_struct *work);
DECLARE_DELAYED_WORK(ocmem_sched_thread, ocmem_sched_wk_func);

static int ocmem_schedule_pending(void)
{

	bool need_sched = false;
	int i = 0;

	for (i = MIN_PRIO; i < MAX_OCMEM_PRIO; i++) {
		if (!list_empty(&sched_queue[i])) {
			need_sched = true;
			break;
		}
	}

	if (need_sched == true) {
		cancel_delayed_work(&ocmem_sched_thread);
		schedule_delayed_work(&ocmem_sched_thread,
					msecs_to_jiffies(SCHED_DELAY));
		pr_debug("ocmem: Scheduled delayed work\n");
	}
	return 0;
}

static int do_free(struct ocmem_req *req)
{
	int rc = 0;
	struct ocmem_buf *buffer = req->buffer;

	down_write(&req->rw_sem);

	if (is_mapped(req)) {
		pr_err("ocmem: Buffer needs to be unmapped before free\n");
		goto err_free_fail;
	}

	pr_debug("ocmem: do_free: client %s req %p\n", get_name(req->owner),
					req);
	/* Grab the sched mutex */
	mutex_lock(&sched_mutex);
	rc = __sched_free(req);
	mutex_unlock(&sched_mutex);

	switch (rc) {

	case OP_COMPLETE:
		buffer->addr = 0x0;
		buffer->len = 0x0;
		break;
	case OP_FAIL:
	default:
		goto err_free_fail;
		break;
	}

	up_write(&req->rw_sem);
	return 0;
err_free_fail:
	up_write(&req->rw_sem);
	pr_err("ocmem: freeing req %p failed\n", req);
	return -EINVAL;
}

int process_free(int id, struct ocmem_handle *handle)
{
	struct ocmem_req *req = NULL;
	struct ocmem_buf *buffer = NULL;
	unsigned long offset = 0;
	int rc = 0;

	if (is_blocked(id)) {
		pr_err("Client %d cannot request free\n", id);
		return -EINVAL;
	}

	req = handle_to_req(handle);
	buffer = handle_to_buffer(handle);

	if (!req)
		return -EINVAL;

	if (req->req_start != core_address(id, buffer->addr)) {
		pr_err("Invalid buffer handle passed for free\n");
		return -EINVAL;
	}

	mutex_lock(&sched_mutex);
	sched_dequeue(req);
	mutex_unlock(&sched_mutex);

	if (!TEST_STATE(req, R_FREE)) {

		rc = process_unmap(req, req->req_start, req->req_end);
		if (rc < 0)
			return -EINVAL;

		rc = do_free(req);
		if (rc < 0)
			return -EINVAL;
	}

	if (req->req_sz != 0) {

		offset = phys_to_offset(req->req_start);

		rc = ocmem_memory_off(req->owner, offset, req->req_sz);

		if (rc < 0) {
			pr_err("Failed to switch OFF memory macros\n");
			return -EINVAL;
		}

	}

	inc_ocmem_stat(zone_of(req), NR_FREES);

	ocmem_destroy_req(req);
	handle->req = NULL;

	ocmem_schedule_pending();
	return 0;
}

static void ocmem_rdm_worker(struct work_struct *work)
{
	int offset = 0;
	int rc = 0;
	int event;
	struct ocmem_rdm_work *work_data = container_of(work,
				struct ocmem_rdm_work, work);
	int id = work_data->id;
	struct ocmem_map_list *list = work_data->list;
	int direction = work_data->direction;
	struct ocmem_handle *handle = work_data->handle;
	struct ocmem_req *req = handle_to_req(handle);
	struct ocmem_buf *buffer = handle_to_buffer(handle);

	down_write(&req->rw_sem);
	offset = phys_to_offset(req->req_start);
	rc = ocmem_rdm_transfer(id, list, offset, direction);
	if (work_data->direction == TO_OCMEM)
		event = (rc == 0) ? OCMEM_MAP_DONE : OCMEM_MAP_FAIL;
	else
		event = (rc == 0) ? OCMEM_UNMAP_DONE : OCMEM_UNMAP_FAIL;
	up_write(&req->rw_sem);
	kfree(work_data);
	dispatch_notification(id, event, buffer);
}

int queue_transfer(struct ocmem_req *req, struct ocmem_handle *handle,
			struct ocmem_map_list *list, int direction)
{
	struct ocmem_rdm_work *work_data = NULL;

	down_write(&req->rw_sem);

	work_data = kzalloc(sizeof(struct ocmem_rdm_work), GFP_ATOMIC);
	if (!work_data)
		BUG();

	work_data->handle = handle;
	work_data->list = list;
	work_data->id = req->owner;
	work_data->direction = direction;
	INIT_WORK(&work_data->work, ocmem_rdm_worker);
	up_write(&req->rw_sem);
	queue_work(ocmem_rdm_wq, &work_data->work);
	return 0;
}

int process_xfer_out(int id, struct ocmem_handle *handle,
			struct ocmem_map_list *list)
{
	struct ocmem_req *req = NULL;
	int rc = 0;

	req = handle_to_req(handle);

	if (!req)
		return -EINVAL;

	if (!is_mapped(req)) {
		pr_err("Buffer is not currently mapped\n");
		goto transfer_out_error;
	}

	rc = queue_transfer(req, handle, list, TO_DDR);

	if (rc < 0) {
		pr_err("Failed to queue rdm transfer to DDR\n");
		inc_ocmem_stat(zone_of(req), NR_TRANSFER_FAILS);
		goto transfer_out_error;
	}

	inc_ocmem_stat(zone_of(req), NR_TRANSFERS_TO_DDR);
	return 0;

transfer_out_error:
	return -EINVAL;
}

int process_xfer_in(int id, struct ocmem_handle *handle,
			struct ocmem_map_list *list)
{
	struct ocmem_req *req = NULL;
	int rc = 0;

	req = handle_to_req(handle);

	if (!req)
		return -EINVAL;


	if (!is_mapped(req)) {
		pr_err("Buffer is not already mapped for transfer\n");
		goto transfer_in_error;
	}


	inc_ocmem_stat(zone_of(req), NR_TRANSFERS_TO_OCMEM);
	rc = queue_transfer(req, handle, list, TO_OCMEM);

	if (rc < 0) {
		pr_err("Failed to queue rdm transfer to OCMEM\n");
		inc_ocmem_stat(zone_of(req), NR_TRANSFER_FAILS);
		goto transfer_in_error;
	}

	return 0;
transfer_in_error:
	return -EINVAL;
}

int process_shrink(int id, struct ocmem_handle *handle, unsigned long size)
{
	struct ocmem_req *req = NULL;
	struct ocmem_buf *buffer = NULL;
	struct ocmem_eviction_data *edata = NULL;
	int rc = 0;

	if (is_blocked(id)) {
		pr_err("Client %d cannot request free\n", id);
		return -EINVAL;
	}

	req = handle_to_req(handle);
	buffer = handle_to_buffer(handle);

	if (!req)
		return -EINVAL;

	if (req->req_start != core_address(id, buffer->addr)) {
		pr_err("Invalid buffer handle passed for shrink\n");
		return -EINVAL;
	}

	edata = req->edata;

	if (!edata) {
		pr_err("Unable to find eviction data\n");
		return -EINVAL;
	}

	pr_debug("Found edata %p in request %p\n", edata, req);

	inc_ocmem_stat(zone_of(req), NR_SHRINKS);

	if (size == 0) {
		pr_debug("req %p being shrunk to zero\n", req);
		if (is_mapped(req))
			rc = process_unmap(req, req->req_start, req->req_end);
			if (rc < 0)
				return -EINVAL;
		rc = do_free(req);
		if (rc < 0)
			return -EINVAL;
	} else {
		rc = do_shrink(req, size);
		if (rc < 0)
			return -EINVAL;
	}

	req->edata = NULL;
	CLEAR_STATE(req, R_ALLOCATED);
	SET_STATE(req, R_FREE);

	if (atomic_dec_and_test(&edata->pending)) {
		pr_debug("ocmem: All conflicting allocations were shrunk\n");
		complete(&edata->completion);
	}

	return 0;
}

int process_xfer(int id, struct ocmem_handle *handle,
		struct ocmem_map_list *list, int direction)
{
	int rc = 0;

	if (is_tcm(id)) {
		WARN(1, "Mapping operation is invalid for client\n");
		return -EINVAL;
	}

	if (direction == TO_DDR)
		rc = process_xfer_out(id, handle, list);
	else if (direction == TO_OCMEM)
		rc = process_xfer_in(id, handle, list);
	return rc;
}

static struct ocmem_eviction_data *init_eviction(int id)
{
	struct ocmem_eviction_data *edata = NULL;
	int prio = ocmem_client_table[id].priority;

	edata = kzalloc(sizeof(struct ocmem_eviction_data), GFP_ATOMIC);

	if (!edata) {
		pr_err("ocmem: Could not allocate eviction data\n");
		return NULL;
	}

	INIT_LIST_HEAD(&edata->victim_list);
	INIT_LIST_HEAD(&edata->req_list);
	edata->prio = prio;
	atomic_set(&edata->pending, 0);
	return edata;
}

static void free_eviction(struct ocmem_eviction_data *edata)
{

	if (!edata)
		return;

	if (!list_empty(&edata->req_list))
		pr_err("ocmem: Eviction data %p not empty\n", edata);

	kfree(edata);
	edata = NULL;
}

static bool is_overlapping(struct ocmem_req *new, struct ocmem_req *old)
{

	if (!new || !old)
		return false;

	pr_debug("check overlap [%lx -- %lx] on [%lx -- %lx]\n",
			new->req_start, new->req_end,
			old->req_start, old->req_end);

	if ((new->req_start < old->req_start &&
		new->req_end >= old->req_start) ||
		(new->req_start >= old->req_start &&
		 new->req_start <= old->req_end &&
		 new->req_end >= old->req_end)) {
		pr_debug("request %p overlaps with existing req %p\n",
						new, old);
		return true;
	}
	return false;
}

static int __evict_common(struct ocmem_eviction_data *edata,
						struct ocmem_req *req)
{
	struct rb_node *rb_node = NULL;
	struct ocmem_req *e_req = NULL;
	bool needs_eviction = false;
	int j = 0;

	for (rb_node = rb_first(&sched_tree); rb_node;
			rb_node = rb_next(rb_node)) {

		struct ocmem_region *tmp_region = NULL;

		tmp_region = rb_entry(rb_node, struct ocmem_region, region_rb);

		if (tmp_region->max_prio < edata->prio) {
			for (j = edata->prio - 1; j > NO_PRIO; j--) {
				needs_eviction = false;
				e_req = find_req_match(j, tmp_region);
				if (!e_req)
					continue;
				if (edata->passive == true) {
					needs_eviction = true;
				} else {
					needs_eviction = is_overlapping(req,
								e_req);
				}

				if (needs_eviction) {
					pr_debug("adding %p in region %p to eviction list\n",
							e_req, tmp_region);
					list_add_tail(
						&e_req->eviction_list,
						&edata->req_list);
					atomic_inc(&edata->pending);
					e_req->edata = edata;
				}
			}
		} else {
			pr_debug("Skipped region %p\n", tmp_region);
		}
	}

	pr_debug("%d requests will be evicted\n", atomic_read(&edata->pending));

	if (!atomic_read(&edata->pending))
		return -EINVAL;
	return 0;
}

static void trigger_eviction(struct ocmem_eviction_data *edata)
{
	struct ocmem_req *req = NULL;
	struct ocmem_req *next = NULL;
	struct ocmem_buf buffer;

	if (!edata)
		return;

	BUG_ON(atomic_read(&edata->pending) == 0);

	init_completion(&edata->completion);

	list_for_each_entry_safe(req, next, &edata->req_list, eviction_list)
	{
		if (req) {
			pr_debug("ocmem: Evicting request %p\n", req);
			buffer.addr = req->req_start;
			buffer.len = 0x0;
			dispatch_notification(req->owner, OCMEM_ALLOC_SHRINK,
								&buffer);
		}
	}
	return;
}

int process_evict(int id)
{
	struct ocmem_eviction_data *edata = NULL;
	int rc = 0;

	edata = init_eviction(id);

	if (!edata)
		return -EINVAL;

	edata->passive = true;

	mutex_lock(&sched_mutex);

	rc = __evict_common(edata, NULL);

	if (rc < 0)
		goto skip_eviction;

	trigger_eviction(edata);

	evictions[id] = edata;

	mutex_unlock(&sched_mutex);

	wait_for_completion(&edata->completion);

	return 0;

skip_eviction:
	evictions[id] = NULL;
	mutex_unlock(&sched_mutex);
	return 0;
}

static int run_evict(struct ocmem_req *req)
{
	struct ocmem_eviction_data *edata = NULL;
	int rc = 0;

	if (!req)
		return -EINVAL;

	edata = init_eviction(req->owner);

	if (!edata)
		return -EINVAL;

	edata->passive = false;

	rc = __evict_common(edata, req);

	if (rc < 0)
		goto skip_eviction;

	trigger_eviction(edata);

	pr_debug("ocmem: attaching eviction %p to request %p", edata, req);
	req->edata = edata;

	wait_for_completion(&edata->completion);

	pr_debug("ocmem: eviction completed successfully\n");
	return 0;

skip_eviction:
	pr_err("ocmem: Unable to run eviction\n");
	free_eviction(edata);
	return -EINVAL;
}

static int __restore_common(struct ocmem_eviction_data *edata)
{

	struct ocmem_req *req = NULL;
	struct ocmem_req *next = NULL;

	if (!edata)
		return -EINVAL;

	list_for_each_entry_safe(req, next, &edata->req_list, eviction_list)
	{
		if (req) {
			pr_debug("ocmem: restoring evicted request %p\n",
								req);
			list_del(&req->eviction_list);
			req->op = SCHED_ALLOCATE;
			sched_enqueue(req);
			inc_ocmem_stat(zone_of(req), NR_RESTORES);
		}
	}

	pr_debug("Scheduled all evicted regions\n");

	return 0;
}

static int sched_restore(struct ocmem_req *req)
{

	int rc = 0;

	if (!req)
		return -EINVAL;

	if (!req->edata)
		return 0;

	rc = __restore_common(req->edata);

	if (rc < 0)
		return -EINVAL;

	free_eviction(req->edata);
	return 0;
}

int process_restore(int id)
{
	struct ocmem_eviction_data *edata = evictions[id];
	int rc = 0;

	if (!edata)
		return -EINVAL;

	rc = __restore_common(edata);

	if (rc < 0) {
		pr_err("Failed to restore evicted requests\n");
		return -EINVAL;
	}

	free_eviction(edata);
	evictions[id] = NULL;
	ocmem_schedule_pending();
	return 0;
}

static int do_allocate(struct ocmem_req *req, bool can_block, bool can_wait)
{
	int rc = 0;
	int ret = 0;
	struct ocmem_buf *buffer = req->buffer;

	down_write(&req->rw_sem);

	mutex_lock(&allocation_mutex);
retry_allocate:

	/* Take the scheduler mutex */
	mutex_lock(&sched_mutex);
	rc = __sched_allocate(req, can_block, can_wait);
	mutex_unlock(&sched_mutex);

	if (rc == OP_EVICT) {

		ret = run_evict(req);

		if (ret == 0) {
			rc = sched_restore(req);
			if (rc < 0) {
				pr_err("Failed to restore for req %p\n", req);
				goto err_allocate_fail;
			}
			req->edata = NULL;

			pr_debug("Attempting to re-allocate req %p\n", req);
			req->req_start = 0x0;
			req->req_end = 0x0;
			goto retry_allocate;
		} else {
			goto err_allocate_fail;
		}
	}

	mutex_unlock(&allocation_mutex);

	if (rc == OP_FAIL) {
		inc_ocmem_stat(zone_of(req), NR_ALLOCATION_FAILS);
		goto err_allocate_fail;
	}

	if (rc == OP_RESCHED) {
		buffer->addr = 0x0;
		buffer->len = 0x0;
		pr_debug("ocmem: Enqueuing req %p\n", req);
		sched_enqueue(req);
	} else if (rc == OP_PARTIAL) {
		buffer->addr = device_address(req->owner, req->req_start);
		buffer->len = req->req_sz;
		inc_ocmem_stat(zone_of(req), NR_RANGE_ALLOCATIONS);
		pr_debug("ocmem: Enqueuing req %p\n", req);
		sched_enqueue(req);
	} else if (rc == OP_COMPLETE) {
		buffer->addr = device_address(req->owner, req->req_start);
		buffer->len = req->req_sz;
	}

	up_write(&req->rw_sem);
	return 0;
err_allocate_fail:
	mutex_unlock(&allocation_mutex);
	up_write(&req->rw_sem);
	return -EINVAL;
}

static int do_dump(struct ocmem_req *req, unsigned long addr)
{

	void __iomem *req_vaddr;
	unsigned long offset = 0x0;

	down_write(&req->rw_sem);

	offset = phys_to_offset(req->req_start);

	req_vaddr = ocmem_vaddr + offset;

	if (!req_vaddr)
		goto err_do_dump;

	pr_debug("Dumping client %s buffer ocmem p: %lx (v: %p) to ddr %lx\n",
				get_name(req->owner), req->req_start,
				req_vaddr, addr);

	memcpy((void *)addr, req_vaddr, req->req_sz);

	up_write(&req->rw_sem);
	return 0;
err_do_dump:
	up_write(&req->rw_sem);
	return -EINVAL;
}

int process_allocate(int id, struct ocmem_handle *handle,
			unsigned long min, unsigned long max,
			unsigned long step, bool can_block, bool can_wait)
{

	struct ocmem_req *req = NULL;
	struct ocmem_buf *buffer = NULL;
	int rc = 0;
	unsigned long offset = 0;

	/* sanity checks */
	if (is_blocked(id)) {
		pr_err("Client %d cannot request allocation\n", id);
		return -EINVAL;
	}

	if (handle->req != NULL) {
		pr_err("Invalid handle passed in\n");
		return -EINVAL;
	}

	buffer = handle_to_buffer(handle);
	BUG_ON(buffer == NULL);

	/* prepare a request structure to represent this transaction */
	req = ocmem_create_req();
	if (!req)
		return -ENOMEM;

	req->owner = id;
	req->req_min = min;
	req->req_max = max;
	req->req_step = step;
	req->prio = ocmem_client_table[id].priority;
	req->op = SCHED_ALLOCATE;
	req->buffer = buffer;

	inc_ocmem_stat(zone_of(req), NR_REQUESTS);

	rc = do_allocate(req, can_block, can_wait);

	if (rc < 0)
		goto do_allocate_error;

	inc_ocmem_stat(zone_of(req), NR_SYNC_ALLOCATIONS);

	handle->req = req;

	if (req->req_sz != 0) {

		rc = process_map(req, req->req_start, req->req_end);
		if (rc < 0)
			goto map_error;

		offset = phys_to_offset(req->req_start);

		rc = ocmem_memory_on(req->owner, offset, req->req_sz);

		if (rc < 0) {
			pr_err("Failed to switch ON memory macros\n");
			goto power_ctl_error;
		}
	}

	return 0;

power_ctl_error:
	process_unmap(req, req->req_start, req->req_end);
map_error:
	handle->req = NULL;
	do_free(req);
do_allocate_error:
	ocmem_destroy_req(req);
	return -EINVAL;
}

int process_delayed_allocate(struct ocmem_req *req)
{

	struct ocmem_handle *handle = NULL;
	int rc = 0;
	int id = req->owner;
	unsigned long offset = 0;

	handle = req_to_handle(req);
	BUG_ON(handle == NULL);

	rc = do_allocate(req, true, false);

	if (rc < 0)
		goto do_allocate_error;

	/* The request can still be pending */
	if (TEST_STATE(req, R_PENDING))
		return 0;

	inc_ocmem_stat(zone_of(req), NR_ASYNC_ALLOCATIONS);

	if (req->req_sz != 0) {

		rc = process_map(req, req->req_start, req->req_end);
		if (rc < 0)
			goto map_error;


		offset = phys_to_offset(req->req_start);

		rc = ocmem_memory_on(req->owner, offset, req->req_sz);

		if (rc < 0) {
			pr_err("Failed to switch ON memory macros\n");
			goto power_ctl_error;
		}
	}

	/* Notify the client about the buffer growth */
	rc = dispatch_notification(id, OCMEM_ALLOC_GROW, req->buffer);
	if (rc < 0) {
		pr_err("No notifier callback to cater for req %p event: %d\n",
				req, OCMEM_ALLOC_GROW);
		BUG();
	}
	return 0;

power_ctl_error:
	process_unmap(req, req->req_start, req->req_end);
map_error:
	handle->req = NULL;
	do_free(req);
do_allocate_error:
	ocmem_destroy_req(req);
	return -EINVAL;
}

int process_dump(int id, struct ocmem_handle *handle, unsigned long addr)
{
	struct ocmem_req *req = NULL;
	int rc = 0;

	req = handle_to_req(handle);

	if (!req)
		return -EINVAL;

	if (!is_mapped(req)) {
		pr_err("Buffer is not mapped\n");
		goto dump_error;
	}

	inc_ocmem_stat(zone_of(req), NR_DUMP_REQUESTS);

	mutex_lock(&sched_mutex);
	rc = do_dump(req, addr);
	mutex_unlock(&sched_mutex);

	if (rc < 0)
		goto dump_error;

	inc_ocmem_stat(zone_of(req), NR_DUMP_COMPLETE);
	return 0;

dump_error:
	pr_err("Dumping OCMEM memory failed for client %d\n", id);
	return -EINVAL;
}

static void ocmem_sched_wk_func(struct work_struct *work)
{

	struct ocmem_buf *buffer = NULL;
	struct ocmem_handle *handle = NULL;
	struct ocmem_req *req = ocmem_fetch_req();

	if (!req) {
		pr_debug("No Pending Requests found\n");
		return;
	}

	pr_debug("ocmem: sched_wk pending req %p\n", req);
	handle = req_to_handle(req);
	buffer = handle_to_buffer(handle);
	BUG_ON(req->op == SCHED_NOP);

	switch (req->op) {
	case SCHED_GROW:
		process_grow(req);
		break;
	case SCHED_ALLOCATE:
		process_delayed_allocate(req);
		break;
	default:
		pr_err("ocmem: Unknown operation encountered\n");
		break;
	}
	return;
}

static int ocmem_allocations_show(struct seq_file *f, void *dummy)
{
	struct rb_node *rb_node = NULL;
	struct ocmem_req *req = NULL;
	unsigned j;
	mutex_lock(&sched_mutex);
	for (rb_node = rb_first(&sched_tree); rb_node;
				rb_node = rb_next(rb_node)) {
		struct ocmem_region *tmp_region = NULL;
		tmp_region = rb_entry(rb_node, struct ocmem_region, region_rb);
		for (j = MAX_OCMEM_PRIO - 1; j > NO_PRIO; j--) {
			req = find_req_match(j, tmp_region);
			if (req) {
				seq_printf(f,
					"owner: %s 0x%lx -- 0x%lx size 0x%lx [state: %2lx]\n",
					get_name(req->owner),
					req->req_start, req->req_end,
					req->req_sz, req->state);
			}
		}
	}
	mutex_unlock(&sched_mutex);
	return 0;
}

static int ocmem_allocations_open(struct inode *inode, struct file *file)
{
	return single_open(file, ocmem_allocations_show, inode->i_private);
}

static const struct file_operations allocations_show_fops = {
	.open = ocmem_allocations_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = seq_release,
};

int ocmem_sched_init(struct platform_device *pdev)
{
	int i = 0;
	struct ocmem_plat_data *pdata = NULL;
	struct device   *dev = &pdev->dev;

	sched_tree = RB_ROOT;
	pdata = platform_get_drvdata(pdev);
	mutex_init(&allocation_mutex);
	mutex_init(&sched_mutex);
	mutex_init(&sched_queue_mutex);
	ocmem_vaddr = pdata->vbase;
	for (i = MIN_PRIO; i < MAX_OCMEM_PRIO; i++)
		INIT_LIST_HEAD(&sched_queue[i]);

	mutex_init(&rdm_mutex);
	INIT_LIST_HEAD(&rdm_queue);
	ocmem_rdm_wq = alloc_workqueue("ocmem_rdm_wq", 0, 0);
	if (!ocmem_rdm_wq)
		return -ENOMEM;
	ocmem_eviction_wq = alloc_workqueue("ocmem_eviction_wq", 0, 0);
	if (!ocmem_eviction_wq)
		return -ENOMEM;

	if (!debugfs_create_file("allocations", S_IRUGO, pdata->debug_node,
					NULL, &allocations_show_fops)) {
		dev_err(dev, "Unable to create debugfs node for scheduler\n");
		return -EBUSY;
	}
	return 0;
}
