/*
 * proc.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Processor interface at the driver level.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package 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.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <linux/types.h>
/* ------------------------------------ Host OS */
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
#include <dspbridge/host_os.h>

/*  ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>

/*  ----------------------------------- Trace & Debug */
#include <dspbridge/dbc.h>

/*  ----------------------------------- OS Adaptation Layer */
#include <dspbridge/ntfy.h>
#include <dspbridge/sync.h>
/*  ----------------------------------- Bridge Driver */
#include <dspbridge/dspdefs.h>
#include <dspbridge/dspdeh.h>
/*  ----------------------------------- Platform Manager */
#include <dspbridge/cod.h>
#include <dspbridge/dev.h>
#include <dspbridge/procpriv.h>
#include <dspbridge/dmm.h>

/*  ----------------------------------- Resource Manager */
#include <dspbridge/mgr.h>
#include <dspbridge/node.h>
#include <dspbridge/nldr.h>
#include <dspbridge/rmm.h>

/*  ----------------------------------- Others */
#include <dspbridge/dbdcd.h>
#include <dspbridge/msg.h>
#include <dspbridge/dspioctl.h>
#include <dspbridge/drv.h>

/*  ----------------------------------- This */
#include <dspbridge/proc.h>
#include <dspbridge/pwr.h>

#include <dspbridge/resourcecleanup.h>
/*  ----------------------------------- Defines, Data Structures, Typedefs */
#define MAXCMDLINELEN       255
#define PROC_ENVPROCID      "PROC_ID=%d"
#define MAXPROCIDLEN	(8 + 5)
#define PROC_DFLT_TIMEOUT   10000	/* Time out in milliseconds */
#define PWR_TIMEOUT	 500	/* Sleep/wake timout in msec */
#define EXTEND	      "_EXT_END"	/* Extmem end addr in DSP binary */

#define DSP_CACHE_LINE 128

#define BUFMODE_MASK	(3 << 14)

/* Buffer modes from DSP perspective */
#define RBUF		0x4000		/* Input buffer */
#define WBUF		0x8000		/* Output Buffer */

extern struct device *bridge;

/*  ----------------------------------- Globals */

/* The proc_object structure. */
struct proc_object {
	struct list_head link;	/* Link to next proc_object */
	struct dev_object *dev_obj;	/* Device this PROC represents */
	u32 process;		/* Process owning this Processor */
	struct mgr_object *mgr_obj;	/* Manager Object Handle */
	u32 attach_count;	/* Processor attach count */
	u32 processor_id;	/* Processor number */
	u32 timeout;		/* Time out count */
	enum dsp_procstate proc_state;	/* Processor state */
	u32 unit;		/* DDSP unit number */
	bool is_already_attached;	/*
					 * True if the Device below has
					 * GPP Client attached
					 */
	struct ntfy_object *ntfy_obj;	/* Manages  notifications */
	/* Bridge Context Handle */
	struct bridge_dev_context *bridge_context;
	/* Function interface to Bridge driver */
	struct bridge_drv_interface *intf_fxns;
	char *last_coff;
	struct list_head proc_list;
};

static u32 refs;

DEFINE_MUTEX(proc_lock);	/* For critical sections */

/*  ----------------------------------- Function Prototypes */
static int proc_monitor(struct proc_object *proc_obj);
static s32 get_envp_count(char **envp);
static char **prepend_envp(char **new_envp, char **envp, s32 envp_elems,
			   s32 cnew_envp, char *sz_var);

/* remember mapping information */
static struct dmm_map_object *add_mapping_info(struct process_context *pr_ctxt,
				u32 mpu_addr, u32 dsp_addr, u32 size)
{
	struct dmm_map_object *map_obj;

	u32 num_usr_pgs = size / PG_SIZE4K;

	pr_debug("%s: adding map info: mpu_addr 0x%x virt 0x%x size 0x%x\n",
						__func__, mpu_addr,
						dsp_addr, size);

	map_obj = kzalloc(sizeof(struct dmm_map_object), GFP_KERNEL);
	if (!map_obj) {
		pr_err("%s: kzalloc failed\n", __func__);
		return NULL;
	}
	INIT_LIST_HEAD(&map_obj->link);

	map_obj->pages = kcalloc(num_usr_pgs, sizeof(struct page *),
							GFP_KERNEL);
	if (!map_obj->pages) {
		pr_err("%s: kzalloc failed\n", __func__);
		kfree(map_obj);
		return NULL;
	}

	map_obj->mpu_addr = mpu_addr;
	map_obj->dsp_addr = dsp_addr;
	map_obj->size = size;
	map_obj->num_usr_pgs = num_usr_pgs;

	spin_lock(&pr_ctxt->dmm_map_lock);
	list_add(&map_obj->link, &pr_ctxt->dmm_map_list);
	spin_unlock(&pr_ctxt->dmm_map_lock);

	return map_obj;
}

static int match_exact_map_obj(struct dmm_map_object *map_obj,
					u32 dsp_addr, u32 size)
{
	if (map_obj->dsp_addr == dsp_addr && map_obj->size != size)
		pr_err("%s: addr match (0x%x), size don't (0x%x != 0x%x)\n",
				__func__, dsp_addr, map_obj->size, size);

	return map_obj->dsp_addr == dsp_addr &&
		map_obj->size == size;
}

static void remove_mapping_information(struct process_context *pr_ctxt,
						u32 dsp_addr, u32 size)
{
	struct dmm_map_object *map_obj;

	pr_debug("%s: looking for virt 0x%x size 0x%x\n", __func__,
							dsp_addr, size);

	spin_lock(&pr_ctxt->dmm_map_lock);
	list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) {
		pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n",
							__func__,
							map_obj->mpu_addr,
							map_obj->dsp_addr,
							map_obj->size);

		if (match_exact_map_obj(map_obj, dsp_addr, size)) {
			pr_debug("%s: match, deleting map info\n", __func__);
			list_del(&map_obj->link);
			kfree(map_obj->dma_info.sg);
			kfree(map_obj->pages);
			kfree(map_obj);
			goto out;
		}
		pr_debug("%s: candidate didn't match\n", __func__);
	}

	pr_err("%s: failed to find given map info\n", __func__);
out:
	spin_unlock(&pr_ctxt->dmm_map_lock);
}

static int match_containing_map_obj(struct dmm_map_object *map_obj,
					u32 mpu_addr, u32 size)
{
	u32 map_obj_end = map_obj->mpu_addr + map_obj->size;

	return mpu_addr >= map_obj->mpu_addr &&
		mpu_addr + size <= map_obj_end;
}

static struct dmm_map_object *find_containing_mapping(
				struct process_context *pr_ctxt,
				u32 mpu_addr, u32 size)
{
	struct dmm_map_object *map_obj;
	pr_debug("%s: looking for mpu_addr 0x%x size 0x%x\n", __func__,
						mpu_addr, size);

	spin_lock(&pr_ctxt->dmm_map_lock);
	list_for_each_entry(map_obj, &pr_ctxt->dmm_map_list, link) {
		pr_debug("%s: candidate: mpu_addr 0x%x virt 0x%x size 0x%x\n",
						__func__,
						map_obj->mpu_addr,
						map_obj->dsp_addr,
						map_obj->size);
		if (match_containing_map_obj(map_obj, mpu_addr, size)) {
			pr_debug("%s: match!\n", __func__);
			goto out;
		}

		pr_debug("%s: no match!\n", __func__);
	}

	map_obj = NULL;
out:
	spin_unlock(&pr_ctxt->dmm_map_lock);
	return map_obj;
}

static int find_first_page_in_cache(struct dmm_map_object *map_obj,
					unsigned long mpu_addr)
{
	u32 mapped_base_page = map_obj->mpu_addr >> PAGE_SHIFT;
	u32 requested_base_page = mpu_addr >> PAGE_SHIFT;
	int pg_index = requested_base_page - mapped_base_page;

	if (pg_index < 0 || pg_index >= map_obj->num_usr_pgs) {
		pr_err("%s: failed (got %d)\n", __func__, pg_index);
		return -1;
	}

	pr_debug("%s: first page is %d\n", __func__, pg_index);
	return pg_index;
}

static inline struct page *get_mapping_page(struct dmm_map_object *map_obj,
								int pg_i)
{
	pr_debug("%s: looking for pg_i %d, num_usr_pgs: %d\n", __func__,
					pg_i, map_obj->num_usr_pgs);

	if (pg_i < 0 || pg_i >= map_obj->num_usr_pgs) {
		pr_err("%s: requested pg_i %d is out of mapped range\n",
				__func__, pg_i);
		return NULL;
	}

	return map_obj->pages[pg_i];
}

/*
 *  ======== proc_attach ========
 *  Purpose:
 *      Prepare for communication with a particular DSP processor, and return
 *      a handle to the processor object.
 */
int
proc_attach(u32 processor_id,
	    const struct dsp_processorattrin *attr_in,
	    void **ph_processor, struct process_context *pr_ctxt)
{
	int status = 0;
	struct dev_object *hdev_obj;
	struct proc_object *p_proc_object = NULL;
	struct mgr_object *hmgr_obj = NULL;
	struct drv_object *hdrv_obj = NULL;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);
	u8 dev_type;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(ph_processor != NULL);

	if (pr_ctxt->processor) {
		*ph_processor = pr_ctxt->processor;
		return status;
	}

	/* Get the Driver and Manager Object Handles */
	if (!drv_datap || !drv_datap->drv_object || !drv_datap->mgr_object) {
		status = -ENODATA;
		pr_err("%s: Failed to get object handles\n", __func__);
	} else {
		hdrv_obj = drv_datap->drv_object;
		hmgr_obj = drv_datap->mgr_object;
	}

	if (!status) {
		/* Get the Device Object */
		status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj);
	}
	if (!status)
		status = dev_get_dev_type(hdev_obj, &dev_type);

	if (status)
		goto func_end;

	/* If we made it this far, create the Proceesor object: */
	p_proc_object = kzalloc(sizeof(struct proc_object), GFP_KERNEL);
	/* Fill out the Processor Object: */
	if (p_proc_object == NULL) {
		status = -ENOMEM;
		goto func_end;
	}
	p_proc_object->dev_obj = hdev_obj;
	p_proc_object->mgr_obj = hmgr_obj;
	p_proc_object->processor_id = dev_type;
	/* Store TGID instead of process handle */
	p_proc_object->process = current->tgid;

	INIT_LIST_HEAD(&p_proc_object->proc_list);

	if (attr_in)
		p_proc_object->timeout = attr_in->timeout;
	else
		p_proc_object->timeout = PROC_DFLT_TIMEOUT;

	status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns);
	if (!status) {
		status = dev_get_bridge_context(hdev_obj,
					     &p_proc_object->bridge_context);
		if (status)
			kfree(p_proc_object);
	} else
		kfree(p_proc_object);

	if (status)
		goto func_end;

	/* Create the Notification Object */
	/* This is created with no event mask, no notify mask
	 * and no valid handle to the notification. They all get
	 * filled up when proc_register_notify is called */
	p_proc_object->ntfy_obj = kmalloc(sizeof(struct ntfy_object),
							GFP_KERNEL);
	if (p_proc_object->ntfy_obj)
		ntfy_init(p_proc_object->ntfy_obj);
	else
		status = -ENOMEM;

	if (!status) {
		/* Insert the Processor Object into the DEV List.
		 * Return handle to this Processor Object:
		 * Find out if the Device is already attached to a
		 * Processor. If so, return AlreadyAttached status */
		status = dev_insert_proc_object(p_proc_object->dev_obj,
						(u32) p_proc_object,
						&p_proc_object->
						is_already_attached);
		if (!status) {
			if (p_proc_object->is_already_attached)
				status = 0;
		} else {
			if (p_proc_object->ntfy_obj) {
				ntfy_delete(p_proc_object->ntfy_obj);
				kfree(p_proc_object->ntfy_obj);
			}

			kfree(p_proc_object);
		}
		if (!status) {
			*ph_processor = (void *)p_proc_object;
			pr_ctxt->processor = *ph_processor;
			(void)proc_notify_clients(p_proc_object,
						  DSP_PROCESSORATTACH);
		}
	} else {
		/* Don't leak memory if status is failed */
		kfree(p_proc_object);
	}
func_end:
	DBC_ENSURE((status == -EPERM && *ph_processor == NULL) ||
		   (!status && p_proc_object) ||
		   (status == 0 && p_proc_object));

	return status;
}

static int get_exec_file(struct cfg_devnode *dev_node_obj,
				struct dev_object *hdev_obj,
				u32 size, char *exec_file)
{
	u8 dev_type;
	s32 len;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	dev_get_dev_type(hdev_obj, (u8 *) &dev_type);

	if (!exec_file)
		return -EFAULT;

	if (dev_type == DSP_UNIT) {
		if (!drv_datap || !drv_datap->base_img)
			return -EFAULT;

		if (strlen(drv_datap->base_img) > size)
			return -EINVAL;

		strcpy(exec_file, drv_datap->base_img);
	} else if (dev_type == IVA_UNIT && iva_img) {
		len = strlen(iva_img);
		strncpy(exec_file, iva_img, len + 1);
	} else {
		return -ENOENT;
	}

	return 0;
}

/*
 *  ======== proc_auto_start ======== =
 *  Purpose:
 *      A Particular device gets loaded with the default image
 *      if the AutoStart flag is set.
 *  Parameters:
 *      hdev_obj:     Handle to the Device
 *  Returns:
 *      0:   On Successful Loading
 *      -EPERM  General Failure
 *  Requires:
 *      hdev_obj != NULL
 *  Ensures:
 */
int proc_auto_start(struct cfg_devnode *dev_node_obj,
			   struct dev_object *hdev_obj)
{
	int status = -EPERM;
	struct proc_object *p_proc_object;
	char sz_exec_file[MAXCMDLINELEN];
	char *argv[2];
	struct mgr_object *hmgr_obj = NULL;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);
	u8 dev_type;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(dev_node_obj != NULL);
	DBC_REQUIRE(hdev_obj != NULL);

	/* Create a Dummy PROC Object */
	if (!drv_datap || !drv_datap->mgr_object) {
		status = -ENODATA;
		pr_err("%s: Failed to retrieve the object handle\n", __func__);
		goto func_end;
	} else {
		hmgr_obj = drv_datap->mgr_object;
	}

	p_proc_object = kzalloc(sizeof(struct proc_object), GFP_KERNEL);
	if (p_proc_object == NULL) {
		status = -ENOMEM;
		goto func_end;
	}
	p_proc_object->dev_obj = hdev_obj;
	p_proc_object->mgr_obj = hmgr_obj;
	status = dev_get_intf_fxns(hdev_obj, &p_proc_object->intf_fxns);
	if (!status)
		status = dev_get_bridge_context(hdev_obj,
					     &p_proc_object->bridge_context);
	if (status)
		goto func_cont;

	/* Stop the Device, put it into standby mode */
	status = proc_stop(p_proc_object);

	if (status)
		goto func_cont;

	/* Get the default executable for this board... */
	dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
	p_proc_object->processor_id = dev_type;
	status = get_exec_file(dev_node_obj, hdev_obj, sizeof(sz_exec_file),
			       sz_exec_file);
	if (!status) {
		argv[0] = sz_exec_file;
		argv[1] = NULL;
		/* ...and try to load it: */
		status = proc_load(p_proc_object, 1, (const char **)argv, NULL);
		if (!status)
			status = proc_start(p_proc_object);
	}
	kfree(p_proc_object->last_coff);
	p_proc_object->last_coff = NULL;
func_cont:
	kfree(p_proc_object);
func_end:
	return status;
}

/*
 *  ======== proc_ctrl ========
 *  Purpose:
 *      Pass control information to the GPP device driver managing the
 *      DSP processor.
 *
 *      This will be an OEM-only function, and not part of the DSP/BIOS Bridge
 *      application developer's API.
 *      Call the bridge_dev_ctrl fxn with the Argument. This is a Synchronous
 *      Operation. arg can be null.
 */
int proc_ctrl(void *hprocessor, u32 dw_cmd, struct dsp_cbdata * arg)
{
	int status = 0;
	struct proc_object *p_proc_object = hprocessor;
	u32 timeout = 0;

	DBC_REQUIRE(refs > 0);

	if (p_proc_object) {
		/* intercept PWR deep sleep command */
		if (dw_cmd == BRDIOCTL_DEEPSLEEP) {
			timeout = arg->cb_data;
			status = pwr_sleep_dsp(PWR_DEEPSLEEP, timeout);
		}
		/* intercept PWR emergency sleep command */
		else if (dw_cmd == BRDIOCTL_EMERGENCYSLEEP) {
			timeout = arg->cb_data;
			status = pwr_sleep_dsp(PWR_EMERGENCYDEEPSLEEP, timeout);
		} else if (dw_cmd == PWR_DEEPSLEEP) {
			/* timeout = arg->cb_data; */
			status = pwr_sleep_dsp(PWR_DEEPSLEEP, timeout);
		}
		/* intercept PWR wake commands */
		else if (dw_cmd == BRDIOCTL_WAKEUP) {
			timeout = arg->cb_data;
			status = pwr_wake_dsp(timeout);
		} else if (dw_cmd == PWR_WAKEUP) {
			/* timeout = arg->cb_data; */
			status = pwr_wake_dsp(timeout);
		} else
		    if (!((*p_proc_object->intf_fxns->dev_cntrl)
				      (p_proc_object->bridge_context, dw_cmd,
				       arg))) {
			status = 0;
		} else {
			status = -EPERM;
		}
	} else {
		status = -EFAULT;
	}

	return status;
}

/*
 *  ======== proc_detach ========
 *  Purpose:
 *      Destroys the  Processor Object. Removes the notification from the Dev
 *      List.
 */
int proc_detach(struct process_context *pr_ctxt)
{
	int status = 0;
	struct proc_object *p_proc_object = NULL;

	DBC_REQUIRE(refs > 0);

	p_proc_object = (struct proc_object *)pr_ctxt->processor;

	if (p_proc_object) {
		/* Notify the Client */
		ntfy_notify(p_proc_object->ntfy_obj, DSP_PROCESSORDETACH);
		/* Remove the notification memory */
		if (p_proc_object->ntfy_obj) {
			ntfy_delete(p_proc_object->ntfy_obj);
			kfree(p_proc_object->ntfy_obj);
		}

		kfree(p_proc_object->last_coff);
		p_proc_object->last_coff = NULL;
		/* Remove the Proc from the DEV List */
		(void)dev_remove_proc_object(p_proc_object->dev_obj,
					     (u32) p_proc_object);
		/* Free the Processor Object */
		kfree(p_proc_object);
		pr_ctxt->processor = NULL;
	} else {
		status = -EFAULT;
	}

	return status;
}

/*
 *  ======== proc_enum_nodes ========
 *  Purpose:
 *      Enumerate and get configuration information about nodes allocated
 *      on a DSP processor.
 */
int proc_enum_nodes(void *hprocessor, void **node_tab,
			   u32 node_tab_size, u32 *pu_num_nodes,
			   u32 *pu_allocated)
{
	int status = -EPERM;
	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
	struct node_mgr *hnode_mgr = NULL;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(node_tab != NULL || node_tab_size == 0);
	DBC_REQUIRE(pu_num_nodes != NULL);
	DBC_REQUIRE(pu_allocated != NULL);

	if (p_proc_object) {
		if (!(dev_get_node_manager(p_proc_object->dev_obj,
						       &hnode_mgr))) {
			if (hnode_mgr) {
				status = node_enum_nodes(hnode_mgr, node_tab,
							 node_tab_size,
							 pu_num_nodes,
							 pu_allocated);
			}
		}
	} else {
		status = -EFAULT;
	}

	return status;
}

/* Cache operation against kernel address instead of users */
static int build_dma_sg(struct dmm_map_object *map_obj, unsigned long start,
						ssize_t len, int pg_i)
{
	struct page *page;
	unsigned long offset;
	ssize_t rest;
	int ret = 0, i = 0;
	struct scatterlist *sg = map_obj->dma_info.sg;

	while (len) {
		page = get_mapping_page(map_obj, pg_i);
		if (!page) {
			pr_err("%s: no page for %08lx\n", __func__, start);
			ret = -EINVAL;
			goto out;
		} else if (IS_ERR(page)) {
			pr_err("%s: err page for %08lx(%lu)\n", __func__, start,
			       PTR_ERR(page));
			ret = PTR_ERR(page);
			goto out;
		}

		offset = start & ~PAGE_MASK;
		rest = min_t(ssize_t, PAGE_SIZE - offset, len);

		sg_set_page(&sg[i], page, rest, offset);

		len -= rest;
		start += rest;
		pg_i++, i++;
	}

	if (i != map_obj->dma_info.num_pages) {
		pr_err("%s: bad number of sg iterations\n", __func__);
		ret = -EFAULT;
		goto out;
	}

out:
	return ret;
}

static int memory_regain_ownership(struct dmm_map_object *map_obj,
		unsigned long start, ssize_t len, enum dma_data_direction dir)
{
	int ret = 0;
	unsigned long first_data_page = start >> PAGE_SHIFT;
	unsigned long last_data_page = ((u32)(start + len - 1) >> PAGE_SHIFT);
	/* calculating the number of pages this area spans */
	unsigned long num_pages = last_data_page - first_data_page + 1;
	struct bridge_dma_map_info *dma_info = &map_obj->dma_info;

	if (!dma_info->sg)
		goto out;

	if (dma_info->dir != dir || dma_info->num_pages != num_pages) {
		pr_err("%s: dma info doesn't match given params\n", __func__);
		return -EINVAL;
	}

	dma_unmap_sg(bridge, dma_info->sg, num_pages, dma_info->dir);

	pr_debug("%s: dma_map_sg unmapped\n", __func__);

	kfree(dma_info->sg);

	map_obj->dma_info.sg = NULL;

out:
	return ret;
}

/* Cache operation against kernel address instead of users */
static int memory_give_ownership(struct dmm_map_object *map_obj,
		unsigned long start, ssize_t len, enum dma_data_direction dir)
{
	int pg_i, ret, sg_num;
	struct scatterlist *sg;
	unsigned long first_data_page = start >> PAGE_SHIFT;
	unsigned long last_data_page = ((u32)(start + len - 1) >> PAGE_SHIFT);
	/* calculating the number of pages this area spans */
	unsigned long num_pages = last_data_page - first_data_page + 1;

	pg_i = find_first_page_in_cache(map_obj, start);
	if (pg_i < 0) {
		pr_err("%s: failed to find first page in cache\n", __func__);
		ret = -EINVAL;
		goto out;
	}

	sg = kcalloc(num_pages, sizeof(*sg), GFP_KERNEL);
	if (!sg) {
		pr_err("%s: kcalloc failed\n", __func__);
		ret = -ENOMEM;
		goto out;
	}

	sg_init_table(sg, num_pages);

	/* cleanup a previous sg allocation */
	/* this may happen if application doesn't signal for e/o DMA */
	kfree(map_obj->dma_info.sg);

	map_obj->dma_info.sg = sg;
	map_obj->dma_info.dir = dir;
	map_obj->dma_info.num_pages = num_pages;

	ret = build_dma_sg(map_obj, start, len, pg_i);
	if (ret)
		goto kfree_sg;

	sg_num = dma_map_sg(bridge, sg, num_pages, dir);
	if (sg_num < 1) {
		pr_err("%s: dma_map_sg failed: %d\n", __func__, sg_num);
		ret = -EFAULT;
		goto kfree_sg;
	}

	pr_debug("%s: dma_map_sg mapped %d elements\n", __func__, sg_num);
	map_obj->dma_info.sg_num = sg_num;

	return 0;

kfree_sg:
	kfree(sg);
	map_obj->dma_info.sg = NULL;
out:
	return ret;
}

int proc_begin_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
				enum dma_data_direction dir)
{
	/* Keep STATUS here for future additions to this function */
	int status = 0;
	struct process_context *pr_ctxt = (struct process_context *) hprocessor;
	struct dmm_map_object *map_obj;

	DBC_REQUIRE(refs > 0);

	if (!pr_ctxt) {
		status = -EFAULT;
		goto err_out;
	}

	pr_debug("%s: addr 0x%x, size 0x%x, type %d\n", __func__,
							(u32)pmpu_addr,
							ul_size, dir);

	mutex_lock(&proc_lock);

	/* find requested memory are in cached mapping information */
	map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size);
	if (!map_obj) {
		pr_err("%s: find_containing_mapping failed\n", __func__);
		status = -EFAULT;
		goto no_map;
	}

	if (memory_give_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) {
		pr_err("%s: InValid address parameters %p %x\n",
			       __func__, pmpu_addr, ul_size);
		status = -EFAULT;
	}

no_map:
	mutex_unlock(&proc_lock);
err_out:

	return status;
}

int proc_end_dma(void *hprocessor, void *pmpu_addr, u32 ul_size,
			enum dma_data_direction dir)
{
	/* Keep STATUS here for future additions to this function */
	int status = 0;
	struct process_context *pr_ctxt = (struct process_context *) hprocessor;
	struct dmm_map_object *map_obj;

	DBC_REQUIRE(refs > 0);

	if (!pr_ctxt) {
		status = -EFAULT;
		goto err_out;
	}

	pr_debug("%s: addr 0x%x, size 0x%x, type %d\n", __func__,
							(u32)pmpu_addr,
							ul_size, dir);

	mutex_lock(&proc_lock);

	/* find requested memory are in cached mapping information */
	map_obj = find_containing_mapping(pr_ctxt, (u32) pmpu_addr, ul_size);
	if (!map_obj) {
		pr_err("%s: find_containing_mapping failed\n", __func__);
		status = -EFAULT;
		goto no_map;
	}

	if (memory_regain_ownership(map_obj, (u32) pmpu_addr, ul_size, dir)) {
		pr_err("%s: InValid address parameters %p %x\n",
		       __func__, pmpu_addr, ul_size);
		status = -EFAULT;
	}

no_map:
	mutex_unlock(&proc_lock);
err_out:
	return status;
}

/*
 *  ======== proc_flush_memory ========
 *  Purpose:
 *     Flush cache
 */
int proc_flush_memory(void *hprocessor, void *pmpu_addr,
			     u32 ul_size, u32 ul_flags)
{
	enum dma_data_direction dir = DMA_BIDIRECTIONAL;

	return proc_begin_dma(hprocessor, pmpu_addr, ul_size, dir);
}

/*
 *  ======== proc_invalidate_memory ========
 *  Purpose:
 *     Invalidates the memory specified
 */
int proc_invalidate_memory(void *hprocessor, void *pmpu_addr, u32 size)
{
	enum dma_data_direction dir = DMA_FROM_DEVICE;

	return proc_begin_dma(hprocessor, pmpu_addr, size, dir);
}

/*
 *  ======== proc_get_resource_info ========
 *  Purpose:
 *      Enumerate the resources currently available on a processor.
 */
int proc_get_resource_info(void *hprocessor, u32 resource_type,
				  struct dsp_resourceinfo *resource_info,
				  u32 resource_info_size)
{
	int status = -EPERM;
	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
	struct node_mgr *hnode_mgr = NULL;
	struct nldr_object *nldr_obj = NULL;
	struct rmm_target_obj *rmm = NULL;
	struct io_mgr *hio_mgr = NULL;	/* IO manager handle */

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(resource_info != NULL);
	DBC_REQUIRE(resource_info_size >= sizeof(struct dsp_resourceinfo));

	if (!p_proc_object) {
		status = -EFAULT;
		goto func_end;
	}
	switch (resource_type) {
	case DSP_RESOURCE_DYNDARAM:
	case DSP_RESOURCE_DYNSARAM:
	case DSP_RESOURCE_DYNEXTERNAL:
	case DSP_RESOURCE_DYNSRAM:
		status = dev_get_node_manager(p_proc_object->dev_obj,
					      &hnode_mgr);
		if (!hnode_mgr) {
			status = -EFAULT;
			goto func_end;
		}

		status = node_get_nldr_obj(hnode_mgr, &nldr_obj);
		if (!status) {
			status = nldr_get_rmm_manager(nldr_obj, &rmm);
			if (rmm) {
				if (!rmm_stat(rmm,
					      (enum dsp_memtype)resource_type,
					      (struct dsp_memstat *)
					      &(resource_info->result.
						mem_stat)))
					status = -EINVAL;
			} else {
				status = -EFAULT;
			}
		}
		break;
	case DSP_RESOURCE_PROCLOAD:
		status = dev_get_io_mgr(p_proc_object->dev_obj, &hio_mgr);
		if (hio_mgr)
			status =
			    p_proc_object->intf_fxns->
			    io_get_proc_load(hio_mgr,
						 (struct dsp_procloadstat *)
						 &(resource_info->result.
						   proc_load_stat));
		else
			status = -EFAULT;
		break;
	default:
		status = -EPERM;
		break;
	}
func_end:
	return status;
}

/*
 *  ======== proc_exit ========
 *  Purpose:
 *      Decrement reference count, and free resources when reference count is
 *      0.
 */
void proc_exit(void)
{
	DBC_REQUIRE(refs > 0);

	refs--;

	DBC_ENSURE(refs >= 0);
}

/*
 *  ======== proc_get_dev_object ========
 *  Purpose:
 *      Return the Dev Object handle for a given Processor.
 *
 */
int proc_get_dev_object(void *hprocessor,
			       struct dev_object **device_obj)
{
	int status = -EPERM;
	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(device_obj != NULL);

	if (p_proc_object) {
		*device_obj = p_proc_object->dev_obj;
		status = 0;
	} else {
		*device_obj = NULL;
		status = -EFAULT;
	}

	DBC_ENSURE((!status && *device_obj != NULL) ||
		   (status && *device_obj == NULL));

	return status;
}

/*
 *  ======== proc_get_state ========
 *  Purpose:
 *      Report the state of the specified DSP processor.
 */
int proc_get_state(void *hprocessor,
			  struct dsp_processorstate *proc_state_obj,
			  u32 state_info_size)
{
	int status = 0;
	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
	int brd_status;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(proc_state_obj != NULL);
	DBC_REQUIRE(state_info_size >= sizeof(struct dsp_processorstate));

	if (p_proc_object) {
		/* First, retrieve BRD state information */
		status = (*p_proc_object->intf_fxns->brd_status)
		    (p_proc_object->bridge_context, &brd_status);
		if (!status) {
			switch (brd_status) {
			case BRD_STOPPED:
				proc_state_obj->proc_state = PROC_STOPPED;
				break;
			case BRD_SLEEP_TRANSITION:
			case BRD_DSP_HIBERNATION:
				/* Fall through */
			case BRD_RUNNING:
				proc_state_obj->proc_state = PROC_RUNNING;
				break;
			case BRD_LOADED:
				proc_state_obj->proc_state = PROC_LOADED;
				break;
			case BRD_ERROR:
				proc_state_obj->proc_state = PROC_ERROR;
				break;
			default:
				proc_state_obj->proc_state = 0xFF;
				status = -EPERM;
				break;
			}
		}
	} else {
		status = -EFAULT;
	}
	dev_dbg(bridge, "%s, results: status: 0x%x proc_state_obj: 0x%x\n",
		__func__, status, proc_state_obj->proc_state);
	return status;
}

/*
 *  ======== proc_get_trace ========
 *  Purpose:
 *      Retrieve the current contents of the trace buffer, located on the
 *      Processor.  Predefined symbols for the trace buffer must have been
 *      configured into the DSP executable.
 *  Details:
 *      We support using the symbols SYS_PUTCBEG and SYS_PUTCEND to define a
 *      trace buffer, only.  Treat it as an undocumented feature.
 *      This call is destructive, meaning the processor is placed in the monitor
 *      state as a result of this function.
 */
int proc_get_trace(void *hprocessor, u8 * pbuf, u32 max_size)
{
	int status;
	status = -ENOSYS;
	return status;
}

/*
 *  ======== proc_init ========
 *  Purpose:
 *      Initialize PROC's private state, keeping a reference count on each call
 */
bool proc_init(void)
{
	bool ret = true;

	DBC_REQUIRE(refs >= 0);

	if (ret)
		refs++;

	DBC_ENSURE((ret && (refs > 0)) || (!ret && (refs >= 0)));

	return ret;
}

/*
 *  ======== proc_load ========
 *  Purpose:
 *      Reset a processor and load a new base program image.
 *      This will be an OEM-only function, and not part of the DSP/BIOS Bridge
 *      application developer's API.
 */
int proc_load(void *hprocessor, const s32 argc_index,
		     const char **user_args, const char **user_envp)
{
	int status = 0;
	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
	struct io_mgr *hio_mgr;	/* IO manager handle */
	struct msg_mgr *hmsg_mgr;
	struct cod_manager *cod_mgr;	/* Code manager handle */
	char *pargv0;		/* temp argv[0] ptr */
	char **new_envp;	/* Updated envp[] array. */
	char sz_proc_id[MAXPROCIDLEN];	/* Size of "PROC_ID=<n>" */
	s32 envp_elems;		/* Num elements in envp[]. */
	s32 cnew_envp;		/* "  " in new_envp[] */
	s32 nproc_id = 0;	/* Anticipate MP version. */
	struct dcd_manager *hdcd_handle;
	struct dmm_object *dmm_mgr;
	u32 dw_ext_end;
	u32 proc_id;
	int brd_state;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

#ifdef OPT_LOAD_TIME_INSTRUMENTATION
	struct timeval tv1;
	struct timeval tv2;
#endif

#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
	struct dspbridge_platform_data *pdata =
	    omap_dspbridge_dev->dev.platform_data;
#endif

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(argc_index > 0);
	DBC_REQUIRE(user_args != NULL);

#ifdef OPT_LOAD_TIME_INSTRUMENTATION
	do_gettimeofday(&tv1);
#endif
	if (!p_proc_object) {
		status = -EFAULT;
		goto func_end;
	}
	dev_get_cod_mgr(p_proc_object->dev_obj, &cod_mgr);
	if (!cod_mgr) {
		status = -EPERM;
		goto func_end;
	}
	status = proc_stop(hprocessor);
	if (status)
		goto func_end;

	/* Place the board in the monitor state. */
	status = proc_monitor(hprocessor);
	if (status)
		goto func_end;

	/* Save ptr to  original argv[0]. */
	pargv0 = (char *)user_args[0];
	/*Prepend "PROC_ID=<nproc_id>"to envp array for target. */
	envp_elems = get_envp_count((char **)user_envp);
	cnew_envp = (envp_elems ? (envp_elems + 1) : (envp_elems + 2));
	new_envp = kzalloc(cnew_envp * sizeof(char **), GFP_KERNEL);
	if (new_envp) {
		status = snprintf(sz_proc_id, MAXPROCIDLEN, PROC_ENVPROCID,
				  nproc_id);
		if (status == -1) {
			dev_dbg(bridge, "%s: Proc ID string overflow\n",
				__func__);
			status = -EPERM;
		} else {
			new_envp =
			    prepend_envp(new_envp, (char **)user_envp,
					 envp_elems, cnew_envp, sz_proc_id);
			/* Get the DCD Handle */
			status = mgr_get_dcd_handle(p_proc_object->mgr_obj,
						    (u32 *) &hdcd_handle);
			if (!status) {
				/*  Before proceeding with new load,
				 *  check if a previously registered COFF
				 *  exists.
				 *  If yes, unregister nodes in previously
				 *  registered COFF.  If any error occurred,
				 *  set previously registered COFF to NULL. */
				if (p_proc_object->last_coff != NULL) {
					status =
					    dcd_auto_unregister(hdcd_handle,
								p_proc_object->
								last_coff);
					/* Regardless of auto unregister status,
					 *  free previously allocated
					 *  memory. */
					kfree(p_proc_object->last_coff);
					p_proc_object->last_coff = NULL;
				}
			}
			/* On success, do cod_open_base() */
			status = cod_open_base(cod_mgr, (char *)user_args[0],
					       COD_SYMB);
		}
	} else {
		status = -ENOMEM;
	}
	if (!status) {
		/* Auto-register data base */
		/* Get the DCD Handle */
		status = mgr_get_dcd_handle(p_proc_object->mgr_obj,
					    (u32 *) &hdcd_handle);
		if (!status) {
			/*  Auto register nodes in specified COFF
			 *  file.  If registration did not fail,
			 *  (status = 0 or -EACCES)
			 *  save the name of the COFF file for
			 *  de-registration in the future. */
			status =
			    dcd_auto_register(hdcd_handle,
					      (char *)user_args[0]);
			if (status == -EACCES)
				status = 0;

			if (status) {
				status = -EPERM;
			} else {
				DBC_ASSERT(p_proc_object->last_coff ==
					   NULL);
				/* Allocate memory for pszLastCoff */
				p_proc_object->last_coff =
						kzalloc((strlen(user_args[0]) +
						1), GFP_KERNEL);
				/* If memory allocated, save COFF file name */
				if (p_proc_object->last_coff) {
					strncpy(p_proc_object->last_coff,
						(char *)user_args[0],
						(strlen((char *)user_args[0]) +
						 1));
				}
			}
		}
	}
	/* Update shared memory address and size */
	if (!status) {
		/*  Create the message manager. This must be done
		 *  before calling the IOOnLoaded function. */
		dev_get_msg_mgr(p_proc_object->dev_obj, &hmsg_mgr);
		if (!hmsg_mgr) {
			status = msg_create(&hmsg_mgr, p_proc_object->dev_obj,
					    (msg_onexit) node_on_exit);
			DBC_ASSERT(!status);
			dev_set_msg_mgr(p_proc_object->dev_obj, hmsg_mgr);
		}
	}
	if (!status) {
		/* Set the Device object's message manager */
		status = dev_get_io_mgr(p_proc_object->dev_obj, &hio_mgr);
		if (hio_mgr)
			status = (*p_proc_object->intf_fxns->io_on_loaded)
								(hio_mgr);
		else
			status = -EFAULT;
	}
	if (!status) {
		/* Now, attempt to load an exec: */

		/* Boost the OPP level to Maximum level supported by baseport */
#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
		if (pdata->cpu_set_freq)
			(*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP5]);
#endif
		status = cod_load_base(cod_mgr, argc_index, (char **)user_args,
				       dev_brd_write_fxn,
				       p_proc_object->dev_obj, NULL);
		if (status) {
			if (status == -EBADF) {
				dev_dbg(bridge, "%s: Failure to Load the EXE\n",
					__func__);
			}
			if (status == -ESPIPE) {
				pr_err("%s: Couldn't parse the file\n",
				       __func__);
			}
		}
		/* Requesting the lowest opp supported */
#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
		if (pdata->cpu_set_freq)
			(*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP1]);
#endif

	}
	if (!status) {
		/* Update the Processor status to loaded */
		status = (*p_proc_object->intf_fxns->brd_set_state)
		    (p_proc_object->bridge_context, BRD_LOADED);
		if (!status) {
			p_proc_object->proc_state = PROC_LOADED;
			if (p_proc_object->ntfy_obj)
				proc_notify_clients(p_proc_object,
						    DSP_PROCESSORSTATECHANGE);
		}
	}
	if (!status) {
		status = proc_get_processor_id(hprocessor, &proc_id);
		if (proc_id == DSP_UNIT) {
			/* Use all available DSP address space after EXTMEM
			 * for DMM */
			if (!status)
				status = cod_get_sym_value(cod_mgr, EXTEND,
							   &dw_ext_end);

			/* Reset DMM structs and add an initial free chunk */
			if (!status) {
				status =
				    dev_get_dmm_mgr(p_proc_object->dev_obj,
						    &dmm_mgr);
				if (dmm_mgr) {
					/* Set dw_ext_end to DMM START u8
					 * address */
					dw_ext_end =
					    (dw_ext_end + 1) * DSPWORDSIZE;
					/* DMM memory is from EXT_END */
					status = dmm_create_tables(dmm_mgr,
								   dw_ext_end,
								   DMMPOOLSIZE);
				} else {
					status = -EFAULT;
				}
			}
		}
	}
	/* Restore the original argv[0] */
	kfree(new_envp);
	user_args[0] = pargv0;
	if (!status) {
		if (!((*p_proc_object->intf_fxns->brd_status)
				(p_proc_object->bridge_context, &brd_state))) {
			pr_info("%s: Processor Loaded %s\n", __func__, pargv0);
			kfree(drv_datap->base_img);
			drv_datap->base_img = kmalloc(strlen(pargv0) + 1,
								GFP_KERNEL);
			if (drv_datap->base_img)
				strncpy(drv_datap->base_img, pargv0,
							strlen(pargv0) + 1);
			else
				status = -ENOMEM;
			DBC_ASSERT(brd_state == BRD_LOADED);
		}
	}

func_end:
	if (status) {
		pr_err("%s: Processor failed to load\n", __func__);
		proc_stop(p_proc_object);
	}
	DBC_ENSURE((!status
		    && p_proc_object->proc_state == PROC_LOADED)
		   || status);
#ifdef OPT_LOAD_TIME_INSTRUMENTATION
	do_gettimeofday(&tv2);
	if (tv2.tv_usec < tv1.tv_usec) {
		tv2.tv_usec += 1000000;
		tv2.tv_sec--;
	}
	dev_dbg(bridge, "%s: time to load %d sec and %d usec\n", __func__,
		tv2.tv_sec - tv1.tv_sec, tv2.tv_usec - tv1.tv_usec);
#endif
	return status;
}

/*
 *  ======== proc_map ========
 *  Purpose:
 *      Maps a MPU buffer to DSP address space.
 */
int proc_map(void *hprocessor, void *pmpu_addr, u32 ul_size,
		    void *req_addr, void **pp_map_addr, u32 ul_map_attr,
		    struct process_context *pr_ctxt)
{
	u32 va_align;
	u32 pa_align;
	struct dmm_object *dmm_mgr;
	u32 size_align;
	int status = 0;
	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
	struct dmm_map_object *map_obj;
	u32 tmp_addr = 0;

#ifdef CONFIG_TIDSPBRIDGE_CACHE_LINE_CHECK
	if ((ul_map_attr & BUFMODE_MASK) != RBUF) {
		if (!IS_ALIGNED((u32)pmpu_addr, DSP_CACHE_LINE) ||
		    !IS_ALIGNED(ul_size, DSP_CACHE_LINE)) {
			pr_err("%s: not aligned: 0x%x (%d)\n", __func__,
						(u32)pmpu_addr, ul_size);
			return -EFAULT;
		}
	}
#endif

	/* Calculate the page-aligned PA, VA and size */
	va_align = PG_ALIGN_LOW((u32) req_addr, PG_SIZE4K);
	pa_align = PG_ALIGN_LOW((u32) pmpu_addr, PG_SIZE4K);
	size_align = PG_ALIGN_HIGH(ul_size + (u32) pmpu_addr - pa_align,
				   PG_SIZE4K);

	if (!p_proc_object) {
		status = -EFAULT;
		goto func_end;
	}
	/* Critical section */
	mutex_lock(&proc_lock);
	dmm_get_handle(p_proc_object, &dmm_mgr);
	if (dmm_mgr)
		status = dmm_map_memory(dmm_mgr, va_align, size_align);
	else
		status = -EFAULT;

	/* Add mapping to the page tables. */
	if (!status) {

		/* Mapped address = MSB of VA | LSB of PA */
		tmp_addr = (va_align | ((u32) pmpu_addr & (PG_SIZE4K - 1)));
		/* mapped memory resource tracking */
		map_obj = add_mapping_info(pr_ctxt, pa_align, tmp_addr,
						size_align);
		if (!map_obj)
			status = -ENOMEM;
		else
			status = (*p_proc_object->intf_fxns->brd_mem_map)
			    (p_proc_object->bridge_context, pa_align, va_align,
			     size_align, ul_map_attr, map_obj->pages);
	}
	if (!status) {
		/* Mapped address = MSB of VA | LSB of PA */
		*pp_map_addr = (void *) tmp_addr;
	} else {
		remove_mapping_information(pr_ctxt, tmp_addr, size_align);
		dmm_un_map_memory(dmm_mgr, va_align, &size_align);
	}
	mutex_unlock(&proc_lock);

	if (status)
		goto func_end;

func_end:
	dev_dbg(bridge, "%s: hprocessor %p, pmpu_addr %p, ul_size %x, "
		"req_addr %p, ul_map_attr %x, pp_map_addr %p, va_align %x, "
		"pa_align %x, size_align %x status 0x%x\n", __func__,
		hprocessor, pmpu_addr, ul_size, req_addr, ul_map_attr,
		pp_map_addr, va_align, pa_align, size_align, status);

	return status;
}

/*
 *  ======== proc_register_notify ========
 *  Purpose:
 *      Register to be notified of specific processor events.
 */
int proc_register_notify(void *hprocessor, u32 event_mask,
				u32 notify_type, struct dsp_notification
				* hnotification)
{
	int status = 0;
	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
	struct deh_mgr *hdeh_mgr;

	DBC_REQUIRE(hnotification != NULL);
	DBC_REQUIRE(refs > 0);

	/* Check processor handle */
	if (!p_proc_object) {
		status = -EFAULT;
		goto func_end;
	}
	/* Check if event mask is a valid processor related event */
	if (event_mask & ~(DSP_PROCESSORSTATECHANGE | DSP_PROCESSORATTACH |
			DSP_PROCESSORDETACH | DSP_PROCESSORRESTART |
			DSP_MMUFAULT | DSP_SYSERROR | DSP_PWRERROR |
			DSP_WDTOVERFLOW))
		status = -EINVAL;

	/* Check if notify type is valid */
	if (notify_type != DSP_SIGNALEVENT)
		status = -EINVAL;

	if (!status) {
		/* If event mask is not DSP_SYSERROR, DSP_MMUFAULT,
		 * or DSP_PWRERROR then register event immediately. */
		if (event_mask &
		    ~(DSP_SYSERROR | DSP_MMUFAULT | DSP_PWRERROR |
				DSP_WDTOVERFLOW)) {
			status = ntfy_register(p_proc_object->ntfy_obj,
					       hnotification, event_mask,
					       notify_type);
			/* Special case alert, special case alert!
			 * If we're trying to *deregister* (i.e. event_mask
			 * is 0), a DSP_SYSERROR or DSP_MMUFAULT notification,
			 * we have to deregister with the DEH manager.
			 * There's no way to know, based on event_mask which
			 * manager the notification event was registered with,
			 * so if we're trying to deregister and ntfy_register
			 * failed, we'll give the deh manager a shot.
			 */
			if ((event_mask == 0) && status) {
				status =
				    dev_get_deh_mgr(p_proc_object->dev_obj,
						    &hdeh_mgr);
				status =
					bridge_deh_register_notify(hdeh_mgr,
							event_mask,
							notify_type,
							hnotification);
			}
		} else {
			status = dev_get_deh_mgr(p_proc_object->dev_obj,
						 &hdeh_mgr);
			status =
			    bridge_deh_register_notify(hdeh_mgr,
					    event_mask,
					    notify_type,
					    hnotification);

		}
	}
func_end:
	return status;
}

/*
 *  ======== proc_reserve_memory ========
 *  Purpose:
 *      Reserve a virtually contiguous region of DSP address space.
 */
int proc_reserve_memory(void *hprocessor, u32 ul_size,
			       void **pp_rsv_addr,
			       struct process_context *pr_ctxt)
{
	struct dmm_object *dmm_mgr;
	int status = 0;
	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
	struct dmm_rsv_object *rsv_obj;

	if (!p_proc_object) {
		status = -EFAULT;
		goto func_end;
	}

	status = dmm_get_handle(p_proc_object, &dmm_mgr);
	if (!dmm_mgr) {
		status = -EFAULT;
		goto func_end;
	}

	status = dmm_reserve_memory(dmm_mgr, ul_size, (u32 *) pp_rsv_addr);
	if (status != 0)
		goto func_end;

	/*
	 * A successful reserve should be followed by insertion of rsv_obj
	 * into dmm_rsv_list, so that reserved memory resource tracking
	 * remains uptodate
	 */
	rsv_obj = kmalloc(sizeof(struct dmm_rsv_object), GFP_KERNEL);
	if (rsv_obj) {
		rsv_obj->dsp_reserved_addr = (u32) *pp_rsv_addr;
		spin_lock(&pr_ctxt->dmm_rsv_lock);
		list_add(&rsv_obj->link, &pr_ctxt->dmm_rsv_list);
		spin_unlock(&pr_ctxt->dmm_rsv_lock);
	}

func_end:
	dev_dbg(bridge, "%s: hprocessor: 0x%p ul_size: 0x%x pp_rsv_addr: 0x%p "
		"status 0x%x\n", __func__, hprocessor,
		ul_size, pp_rsv_addr, status);
	return status;
}

/*
 *  ======== proc_start ========
 *  Purpose:
 *      Start a processor running.
 */
int proc_start(void *hprocessor)
{
	int status = 0;
	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
	struct cod_manager *cod_mgr;	/* Code manager handle */
	u32 dw_dsp_addr;	/* Loaded code's entry point. */
	int brd_state;

	DBC_REQUIRE(refs > 0);
	if (!p_proc_object) {
		status = -EFAULT;
		goto func_end;
	}
	/* Call the bridge_brd_start */
	if (p_proc_object->proc_state != PROC_LOADED) {
		status = -EBADR;
		goto func_end;
	}
	status = dev_get_cod_mgr(p_proc_object->dev_obj, &cod_mgr);
	if (!cod_mgr) {
		status = -EFAULT;
		goto func_cont;
	}

	status = cod_get_entry(cod_mgr, &dw_dsp_addr);
	if (status)
		goto func_cont;

	status = (*p_proc_object->intf_fxns->brd_start)
	    (p_proc_object->bridge_context, dw_dsp_addr);
	if (status)
		goto func_cont;

	/* Call dev_create2 */
	status = dev_create2(p_proc_object->dev_obj);
	if (!status) {
		p_proc_object->proc_state = PROC_RUNNING;
		/* Deep sleep switces off the peripheral clocks.
		 * we just put the DSP CPU in idle in the idle loop.
		 * so there is no need to send a command to DSP */

		if (p_proc_object->ntfy_obj) {
			proc_notify_clients(p_proc_object,
					    DSP_PROCESSORSTATECHANGE);
		}
	} else {
		/* Failed to Create Node Manager and DISP Object
		 * Stop the Processor from running. Put it in STOPPED State */
		(void)(*p_proc_object->intf_fxns->
		       brd_stop) (p_proc_object->bridge_context);
		p_proc_object->proc_state = PROC_STOPPED;
	}
func_cont:
	if (!status) {
		if (!((*p_proc_object->intf_fxns->brd_status)
				(p_proc_object->bridge_context, &brd_state))) {
			pr_info("%s: dsp in running state\n", __func__);
			DBC_ASSERT(brd_state != BRD_HIBERNATION);
		}
	} else {
		pr_err("%s: Failed to start the dsp\n", __func__);
		proc_stop(p_proc_object);
	}

func_end:
	DBC_ENSURE((!status && p_proc_object->proc_state ==
		    PROC_RUNNING) || status);
	return status;
}

/*
 *  ======== proc_stop ========
 *  Purpose:
 *      Stop a processor running.
 */
int proc_stop(void *hprocessor)
{
	int status = 0;
	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
	struct msg_mgr *hmsg_mgr;
	struct node_mgr *hnode_mgr;
	void *hnode;
	u32 node_tab_size = 1;
	u32 num_nodes = 0;
	u32 nodes_allocated = 0;
	int brd_state;

	DBC_REQUIRE(refs > 0);
	if (!p_proc_object) {
		status = -EFAULT;
		goto func_end;
	}
	/* check if there are any running nodes */
	status = dev_get_node_manager(p_proc_object->dev_obj, &hnode_mgr);
	if (!status && hnode_mgr) {
		status = node_enum_nodes(hnode_mgr, &hnode, node_tab_size,
					 &num_nodes, &nodes_allocated);
		if ((status == -EINVAL) || (nodes_allocated > 0)) {
			pr_err("%s: Can't stop device, active nodes = %d \n",
			       __func__, nodes_allocated);
			return -EBADR;
		}
	}
	/* Call the bridge_brd_stop */
	/* It is OK to stop a device that does n't have nodes OR not started */
	status =
	    (*p_proc_object->intf_fxns->
	     brd_stop) (p_proc_object->bridge_context);
	if (!status) {
		dev_dbg(bridge, "%s: processor in standby mode\n", __func__);
		p_proc_object->proc_state = PROC_STOPPED;
		/* Destroy the Node Manager, msg_ctrl Manager */
		if (!(dev_destroy2(p_proc_object->dev_obj))) {
			/* Destroy the msg_ctrl by calling msg_delete */
			dev_get_msg_mgr(p_proc_object->dev_obj, &hmsg_mgr);
			if (hmsg_mgr) {
				msg_delete(hmsg_mgr);
				dev_set_msg_mgr(p_proc_object->dev_obj, NULL);
			}
			if (!((*p_proc_object->
			      intf_fxns->brd_status) (p_proc_object->
							  bridge_context,
							  &brd_state)))
				DBC_ASSERT(brd_state == BRD_STOPPED);
		}
	} else {
		pr_err("%s: Failed to stop the processor\n", __func__);
	}
func_end:

	return status;
}

/*
 *  ======== proc_un_map ========
 *  Purpose:
 *      Removes a MPU buffer mapping from the DSP address space.
 */
int proc_un_map(void *hprocessor, void *map_addr,
		       struct process_context *pr_ctxt)
{
	int status = 0;
	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
	struct dmm_object *dmm_mgr;
	u32 va_align;
	u32 size_align;

	va_align = PG_ALIGN_LOW((u32) map_addr, PG_SIZE4K);
	if (!p_proc_object) {
		status = -EFAULT;
		goto func_end;
	}

	status = dmm_get_handle(hprocessor, &dmm_mgr);
	if (!dmm_mgr) {
		status = -EFAULT;
		goto func_end;
	}

	/* Critical section */
	mutex_lock(&proc_lock);
	/*
	 * Update DMM structures. Get the size to unmap.
	 * This function returns error if the VA is not mapped
	 */
	status = dmm_un_map_memory(dmm_mgr, (u32) va_align, &size_align);
	/* Remove mapping from the page tables. */
	if (!status) {
		status = (*p_proc_object->intf_fxns->brd_mem_un_map)
		    (p_proc_object->bridge_context, va_align, size_align);
	}

	if (status)
		goto unmap_failed;

	/*
	 * A successful unmap should be followed by removal of map_obj
	 * from dmm_map_list, so that mapped memory resource tracking
	 * remains uptodate
	 */
	remove_mapping_information(pr_ctxt, (u32) map_addr, size_align);

unmap_failed:
	mutex_unlock(&proc_lock);

func_end:
	dev_dbg(bridge, "%s: hprocessor: 0x%p map_addr: 0x%p status: 0x%x\n",
		__func__, hprocessor, map_addr, status);
	return status;
}

/*
 *  ======== proc_un_reserve_memory ========
 *  Purpose:
 *      Frees a previously reserved region of DSP address space.
 */
int proc_un_reserve_memory(void *hprocessor, void *prsv_addr,
				  struct process_context *pr_ctxt)
{
	struct dmm_object *dmm_mgr;
	int status = 0;
	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
	struct dmm_rsv_object *rsv_obj;

	if (!p_proc_object) {
		status = -EFAULT;
		goto func_end;
	}

	status = dmm_get_handle(p_proc_object, &dmm_mgr);
	if (!dmm_mgr) {
		status = -EFAULT;
		goto func_end;
	}

	status = dmm_un_reserve_memory(dmm_mgr, (u32) prsv_addr);
	if (status != 0)
		goto func_end;

	/*
	 * A successful unreserve should be followed by removal of rsv_obj
	 * from dmm_rsv_list, so that reserved memory resource tracking
	 * remains uptodate
	 */
	spin_lock(&pr_ctxt->dmm_rsv_lock);
	list_for_each_entry(rsv_obj, &pr_ctxt->dmm_rsv_list, link) {
		if (rsv_obj->dsp_reserved_addr == (u32) prsv_addr) {
			list_del(&rsv_obj->link);
			kfree(rsv_obj);
			break;
		}
	}
	spin_unlock(&pr_ctxt->dmm_rsv_lock);

func_end:
	dev_dbg(bridge, "%s: hprocessor: 0x%p prsv_addr: 0x%p status: 0x%x\n",
		__func__, hprocessor, prsv_addr, status);
	return status;
}

/*
 *  ======== = proc_monitor ======== ==
 *  Purpose:
 *      Place the Processor in Monitor State. This is an internal
 *      function and a requirement before Processor is loaded.
 *      This does a bridge_brd_stop, dev_destroy2 and bridge_brd_monitor.
 *      In dev_destroy2 we delete the node manager.
 *  Parameters:
 *      p_proc_object:    Pointer to Processor Object
 *  Returns:
 *      0:	Processor placed in monitor mode.
 *      !0:       Failed to place processor in monitor mode.
 *  Requires:
 *      Valid Processor Handle
 *  Ensures:
 *      Success:	ProcObject state is PROC_IDLE
 */
static int proc_monitor(struct proc_object *proc_obj)
{
	int status = -EPERM;
	struct msg_mgr *hmsg_mgr;
	int brd_state;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(proc_obj);

	/* This is needed only when Device is loaded when it is
	 * already 'ACTIVE' */
	/* Destroy the Node Manager, msg_ctrl Manager */
	if (!dev_destroy2(proc_obj->dev_obj)) {
		/* Destroy the msg_ctrl by calling msg_delete */
		dev_get_msg_mgr(proc_obj->dev_obj, &hmsg_mgr);
		if (hmsg_mgr) {
			msg_delete(hmsg_mgr);
			dev_set_msg_mgr(proc_obj->dev_obj, NULL);
		}
	}
	/* Place the Board in the Monitor State */
	if (!((*proc_obj->intf_fxns->brd_monitor)
			  (proc_obj->bridge_context))) {
		status = 0;
		if (!((*proc_obj->intf_fxns->brd_status)
				  (proc_obj->bridge_context, &brd_state)))
			DBC_ASSERT(brd_state == BRD_IDLE);
	}

	DBC_ENSURE((!status && brd_state == BRD_IDLE) ||
		   status);
	return status;
}

/*
 *  ======== get_envp_count ========
 *  Purpose:
 *      Return the number of elements in the envp array, including the
 *      terminating NULL element.
 */
static s32 get_envp_count(char **envp)
{
	s32 ret = 0;
	if (envp) {
		while (*envp++)
			ret++;

		ret += 1;	/* Include the terminating NULL in the count. */
	}

	return ret;
}

/*
 *  ======== prepend_envp ========
 *  Purpose:
 *      Prepend an environment variable=value pair to the new envp array, and
 *      copy in the existing var=value pairs in the old envp array.
 */
static char **prepend_envp(char **new_envp, char **envp, s32 envp_elems,
			   s32 cnew_envp, char *sz_var)
{
	char **pp_envp = new_envp;

	DBC_REQUIRE(new_envp);

	/* Prepend new environ var=value string */
	*new_envp++ = sz_var;

	/* Copy user's environment into our own. */
	while (envp_elems--)
		*new_envp++ = *envp++;

	/* Ensure NULL terminates the new environment strings array. */
	if (envp_elems == 0)
		*new_envp = NULL;

	return pp_envp;
}

/*
 *  ======== proc_notify_clients ========
 *  Purpose:
 *      Notify the processor the events.
 */
int proc_notify_clients(void *proc, u32 events)
{
	int status = 0;
	struct proc_object *p_proc_object = (struct proc_object *)proc;

	DBC_REQUIRE(p_proc_object);
	DBC_REQUIRE(is_valid_proc_event(events));
	DBC_REQUIRE(refs > 0);
	if (!p_proc_object) {
		status = -EFAULT;
		goto func_end;
	}

	ntfy_notify(p_proc_object->ntfy_obj, events);
func_end:
	return status;
}

/*
 *  ======== proc_notify_all_clients ========
 *  Purpose:
 *      Notify the processor the events. This includes notifying all clients
 *      attached to a particulat DSP.
 */
int proc_notify_all_clients(void *proc, u32 events)
{
	int status = 0;
	struct proc_object *p_proc_object = (struct proc_object *)proc;

	DBC_REQUIRE(is_valid_proc_event(events));
	DBC_REQUIRE(refs > 0);

	if (!p_proc_object) {
		status = -EFAULT;
		goto func_end;
	}

	dev_notify_clients(p_proc_object->dev_obj, events);

func_end:
	return status;
}

/*
 *  ======== proc_get_processor_id ========
 *  Purpose:
 *      Retrieves the processor ID.
 */
int proc_get_processor_id(void *proc, u32 * proc_id)
{
	int status = 0;
	struct proc_object *p_proc_object = (struct proc_object *)proc;

	if (p_proc_object)
		*proc_id = p_proc_object->processor_id;
	else
		status = -EFAULT;

	return status;
}
