/*
 * drv.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * DSP/BIOS Bridge resource allocation module.
 *
 * 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>
#include <linux/list.h>

/*  ----------------------------------- Host OS */
#include <dspbridge/host_os.h>

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

/*  ----------------------------------- This */
#include <dspbridge/drv.h>
#include <dspbridge/dev.h>

#include <dspbridge/node.h>
#include <dspbridge/proc.h>
#include <dspbridge/strm.h>
#include <dspbridge/nodepriv.h>
#include <dspbridge/dspchnl.h>
#include <dspbridge/resourcecleanup.h>

/*  ----------------------------------- Defines, Data Structures, Typedefs */
struct drv_object {
	struct list_head dev_list;
	struct list_head dev_node_string;
};

/*
 *  This is the Device Extension. Named with the Prefix
 *  DRV_ since it is living in this module
 */
struct drv_ext {
	struct list_head link;
	char sz_string[MAXREGPATHLENGTH];
};

/*  ----------------------------------- Globals */
static bool ext_phys_mem_pool_enabled;
struct ext_phys_mem_pool {
	u32 phys_mem_base;
	u32 phys_mem_size;
	u32 virt_mem_base;
	u32 next_phys_alloc_ptr;
};
static struct ext_phys_mem_pool ext_mem_pool;

/*  ----------------------------------- Function Prototypes */
static int request_bridge_resources(struct cfg_hostres *res);


/* GPP PROCESS CLEANUP CODE */

static int drv_proc_free_node_res(int id, void *p, void *data);

/* Allocate and add a node resource element
* This function is called from .Node_Allocate. */
int drv_insert_node_res_element(void *hnode, void *node_resource,
				       void *process_ctxt)
{
	struct node_res_object **node_res_obj =
	    (struct node_res_object **)node_resource;
	struct process_context *ctxt = (struct process_context *)process_ctxt;
	int retval;

	*node_res_obj = kzalloc(sizeof(struct node_res_object), GFP_KERNEL);
	if (!*node_res_obj)
		return -ENOMEM;

	(*node_res_obj)->node = hnode;
	retval = idr_alloc(ctxt->node_id, *node_res_obj, 0, 0, GFP_KERNEL);
	if (retval >= 0) {
		(*node_res_obj)->id = retval;
		return 0;
	}

	kfree(*node_res_obj);

	if (retval == -ENOSPC) {
		pr_err("%s: FAILED, IDR is FULL\n", __func__);
		return -EFAULT;
	} else {
		pr_err("%s: OUT OF MEMORY\n", __func__);
		return -ENOMEM;
	}
}

/* Release all Node resources and its context
 * Actual Node De-Allocation */
static int drv_proc_free_node_res(int id, void *p, void *data)
{
	struct process_context *ctxt = data;
	int status;
	struct node_res_object *node_res_obj = p;
	u32 node_state;

	if (node_res_obj->node_allocated) {
		node_state = node_get_state(node_res_obj->node);
		if (node_state <= NODE_DELETING) {
			if ((node_state == NODE_RUNNING) ||
			    (node_state == NODE_PAUSED) ||
			    (node_state == NODE_TERMINATING))
				node_terminate
				    (node_res_obj->node, &status);

			node_delete(node_res_obj, ctxt);
		}
	}

	return 0;
}

/* Release all Mapped and Reserved DMM resources */
int drv_remove_all_dmm_res_elements(void *process_ctxt)
{
	struct process_context *ctxt = (struct process_context *)process_ctxt;
	int status = 0;
	struct dmm_map_object *temp_map, *map_obj;
	struct dmm_rsv_object *temp_rsv, *rsv_obj;

	/* Free DMM mapped memory resources */
	list_for_each_entry_safe(map_obj, temp_map, &ctxt->dmm_map_list, link) {
		status = proc_un_map(ctxt->processor,
				     (void *)map_obj->dsp_addr, ctxt);
		if (status)
			pr_err("%s: proc_un_map failed!"
			       " status = 0x%xn", __func__, status);
	}

	/* Free DMM reserved memory resources */
	list_for_each_entry_safe(rsv_obj, temp_rsv, &ctxt->dmm_rsv_list, link) {
		status = proc_un_reserve_memory(ctxt->processor, (void *)
						rsv_obj->dsp_reserved_addr,
						ctxt);
		if (status)
			pr_err("%s: proc_un_reserve_memory failed!"
			       " status = 0x%xn", __func__, status);
	}
	return status;
}

/* Update Node allocation status */
void drv_proc_node_update_status(void *node_resource, s32 status)
{
	struct node_res_object *node_res_obj =
	    (struct node_res_object *)node_resource;
	node_res_obj->node_allocated = status;
}

/* Update Node Heap status */
void drv_proc_node_update_heap_status(void *node_resource, s32 status)
{
	struct node_res_object *node_res_obj =
	    (struct node_res_object *)node_resource;
	node_res_obj->heap_allocated = status;
}

/* Release all Node resources and its context
* This is called from .bridge_release.
 */
int drv_remove_all_node_res_elements(void *process_ctxt)
{
	struct process_context *ctxt = process_ctxt;

	idr_for_each(ctxt->node_id, drv_proc_free_node_res, ctxt);
	idr_destroy(ctxt->node_id);

	return 0;
}

/* Allocate the STRM resource element
* This is called after the actual resource is allocated
 */
int drv_proc_insert_strm_res_element(void *stream_obj,
					    void *strm_res, void *process_ctxt)
{
	struct strm_res_object **pstrm_res =
	    (struct strm_res_object **)strm_res;
	struct process_context *ctxt = (struct process_context *)process_ctxt;
	int retval;

	*pstrm_res = kzalloc(sizeof(struct strm_res_object), GFP_KERNEL);
	if (*pstrm_res == NULL)
		return -EFAULT;

	(*pstrm_res)->stream = stream_obj;
	retval = idr_alloc(ctxt->stream_id, *pstrm_res, 0, 0, GFP_KERNEL);
	if (retval >= 0) {
		(*pstrm_res)->id = retval;
		return 0;
	}

	if (retval == -ENOSPC) {
		pr_err("%s: FAILED, IDR is FULL\n", __func__);
		return -EPERM;
	} else {
		pr_err("%s: OUT OF MEMORY\n", __func__);
		return -ENOMEM;
	}
}

static int drv_proc_free_strm_res(int id, void *p, void *process_ctxt)
{
	struct process_context *ctxt = process_ctxt;
	struct strm_res_object *strm_res = p;
	struct stream_info strm_info;
	struct dsp_streaminfo user;
	u8 **ap_buffer = NULL;
	u8 *buf_ptr;
	u32 ul_bytes;
	u32 dw_arg;
	s32 ul_buf_size;

	if (strm_res->num_bufs) {
		ap_buffer = kmalloc((strm_res->num_bufs *
				       sizeof(u8 *)), GFP_KERNEL);
		if (ap_buffer) {
			strm_free_buffer(strm_res,
						  ap_buffer,
						  strm_res->num_bufs,
						  ctxt);
			kfree(ap_buffer);
		}
	}
	strm_info.user_strm = &user;
	user.number_bufs_in_stream = 0;
	strm_get_info(strm_res->stream, &strm_info, sizeof(strm_info));
	while (user.number_bufs_in_stream--)
		strm_reclaim(strm_res->stream, &buf_ptr, &ul_bytes,
			     (u32 *) &ul_buf_size, &dw_arg);
	strm_close(strm_res, ctxt);
	return 0;
}

/* Release all Stream resources and its context
* This is called from .bridge_release.
 */
int drv_remove_all_strm_res_elements(void *process_ctxt)
{
	struct process_context *ctxt = process_ctxt;

	idr_for_each(ctxt->stream_id, drv_proc_free_strm_res, ctxt);
	idr_destroy(ctxt->stream_id);

	return 0;
}

/* Updating the stream resource element */
int drv_proc_update_strm_res(u32 num_bufs, void *strm_resources)
{
	int status = 0;
	struct strm_res_object **strm_res =
	    (struct strm_res_object **)strm_resources;

	(*strm_res)->num_bufs = num_bufs;
	return status;
}

/* GPP PROCESS CLEANUP CODE END */

/*
 *  ======== = drv_create ======== =
 *  Purpose:
 *      DRV Object gets created only once during Driver Loading.
 */
int drv_create(struct drv_object **drv_obj)
{
	int status = 0;
	struct drv_object *pdrv_object = NULL;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	pdrv_object = kzalloc(sizeof(struct drv_object), GFP_KERNEL);
	if (pdrv_object) {
		/* Create and Initialize List of device objects */
		INIT_LIST_HEAD(&pdrv_object->dev_list);
		INIT_LIST_HEAD(&pdrv_object->dev_node_string);
	} else {
		status = -ENOMEM;
	}
	/* Store the DRV Object in the driver data */
	if (!status) {
		if (drv_datap) {
			drv_datap->drv_object = (void *)pdrv_object;
		} else {
			status = -EPERM;
			pr_err("%s: Failed to store DRV object\n", __func__);
		}
	}

	if (!status) {
		*drv_obj = pdrv_object;
	} else {
		/* Free the DRV Object */
		kfree(pdrv_object);
	}

	return status;
}

/*
 *  ======== = drv_destroy ======== =
 *  purpose:
 *      Invoked during bridge de-initialization
 */
int drv_destroy(struct drv_object *driver_obj)
{
	int status = 0;
	struct drv_object *pdrv_object = (struct drv_object *)driver_obj;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	kfree(pdrv_object);
	/* Update the DRV Object in the driver data */
	if (drv_datap) {
		drv_datap->drv_object = NULL;
	} else {
		status = -EPERM;
		pr_err("%s: Failed to store DRV object\n", __func__);
	}

	return status;
}

/*
 *  ======== drv_get_dev_object ========
 *  Purpose:
 *      Given a index, returns a handle to DevObject from the list.
 */
int drv_get_dev_object(u32 index, struct drv_object *hdrv_obj,
			      struct dev_object **device_obj)
{
	int status = 0;
	struct dev_object *dev_obj;
	u32 i;

	dev_obj = (struct dev_object *)drv_get_first_dev_object();
	for (i = 0; i < index; i++) {
		dev_obj =
		    (struct dev_object *)drv_get_next_dev_object((u32) dev_obj);
	}
	if (dev_obj) {
		*device_obj = (struct dev_object *)dev_obj;
	} else {
		*device_obj = NULL;
		status = -EPERM;
	}

	return status;
}

/*
 *  ======== drv_get_first_dev_object ========
 *  Purpose:
 *      Retrieve the first Device Object handle from an internal linked list of
 *      of DEV_OBJECTs maintained by DRV.
 */
u32 drv_get_first_dev_object(void)
{
	u32 dw_dev_object = 0;
	struct drv_object *pdrv_obj;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	if (drv_datap && drv_datap->drv_object) {
		pdrv_obj = drv_datap->drv_object;
		if (!list_empty(&pdrv_obj->dev_list))
			dw_dev_object = (u32) pdrv_obj->dev_list.next;
	} else {
		pr_err("%s: Failed to retrieve the object handle\n", __func__);
	}

	return dw_dev_object;
}

/*
 *  ======== DRV_GetFirstDevNodeString ========
 *  Purpose:
 *      Retrieve the first Device Extension from an internal linked list of
 *      of Pointer to dev_node Strings maintained by DRV.
 */
u32 drv_get_first_dev_extension(void)
{
	u32 dw_dev_extension = 0;
	struct drv_object *pdrv_obj;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	if (drv_datap && drv_datap->drv_object) {
		pdrv_obj = drv_datap->drv_object;
		if (!list_empty(&pdrv_obj->dev_node_string)) {
			dw_dev_extension =
			    (u32) pdrv_obj->dev_node_string.next;
		}
	} else {
		pr_err("%s: Failed to retrieve the object handle\n", __func__);
	}

	return dw_dev_extension;
}

/*
 *  ======== drv_get_next_dev_object ========
 *  Purpose:
 *      Retrieve the next Device Object handle from an internal linked list of
 *      of DEV_OBJECTs maintained by DRV, after having previously called
 *      drv_get_first_dev_object() and zero or more DRV_GetNext.
 */
u32 drv_get_next_dev_object(u32 hdev_obj)
{
	u32 dw_next_dev_object = 0;
	struct drv_object *pdrv_obj;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);
	struct list_head *curr;

	if (drv_datap && drv_datap->drv_object) {
		pdrv_obj = drv_datap->drv_object;
		if (!list_empty(&pdrv_obj->dev_list)) {
			curr = (struct list_head *)hdev_obj;
			if (list_is_last(curr, &pdrv_obj->dev_list))
				return 0;
			dw_next_dev_object = (u32) curr->next;
		}
	} else {
		pr_err("%s: Failed to retrieve the object handle\n", __func__);
	}

	return dw_next_dev_object;
}

/*
 *  ======== drv_get_next_dev_extension ========
 *  Purpose:
 *      Retrieve the next Device Extension from an internal linked list of
 *      of pointer to DevNodeString maintained by DRV, after having previously
 *      called drv_get_first_dev_extension() and zero or more
 *      drv_get_next_dev_extension().
 */
u32 drv_get_next_dev_extension(u32 dev_extension)
{
	u32 dw_dev_extension = 0;
	struct drv_object *pdrv_obj;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);
	struct list_head *curr;

	if (drv_datap && drv_datap->drv_object) {
		pdrv_obj = drv_datap->drv_object;
		if (!list_empty(&pdrv_obj->dev_node_string)) {
			curr = (struct list_head *)dev_extension;
			if (list_is_last(curr, &pdrv_obj->dev_node_string))
				return 0;
			dw_dev_extension = (u32) curr->next;
		}
	} else {
		pr_err("%s: Failed to retrieve the object handle\n", __func__);
	}

	return dw_dev_extension;
}

/*
 *  ======== drv_insert_dev_object ========
 *  Purpose:
 *      Insert a DevObject into the list of Manager object.
 */
int drv_insert_dev_object(struct drv_object *driver_obj,
				 struct dev_object *hdev_obj)
{
	struct drv_object *pdrv_object = (struct drv_object *)driver_obj;

	list_add_tail((struct list_head *)hdev_obj, &pdrv_object->dev_list);

	return 0;
}

/*
 *  ======== drv_remove_dev_object ========
 *  Purpose:
 *      Search for and remove a DeviceObject from the given list of DRV
 *      objects.
 */
int drv_remove_dev_object(struct drv_object *driver_obj,
				 struct dev_object *hdev_obj)
{
	int status = -EPERM;
	struct drv_object *pdrv_object = (struct drv_object *)driver_obj;
	struct list_head *cur_elem;

	/* Search list for p_proc_object: */
	list_for_each(cur_elem, &pdrv_object->dev_list) {
		/* If found, remove it. */
		if ((struct dev_object *)cur_elem == hdev_obj) {
			list_del(cur_elem);
			status = 0;
			break;
		}
	}

	return status;
}

/*
 *  ======== drv_request_resources ========
 *  Purpose:
 *      Requests  resources from the OS.
 */
int drv_request_resources(u32 dw_context, u32 *dev_node_strg)
{
	int status = 0;
	struct drv_object *pdrv_object;
	struct drv_ext *pszdev_node;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	/*
	 *  Allocate memory to hold the string. This will live until
	 *  it is freed in the Release resources. Update the driver object
	 *  list.
	 */

	if (!drv_datap || !drv_datap->drv_object)
		status = -ENODATA;
	else
		pdrv_object = drv_datap->drv_object;

	if (!status) {
		pszdev_node = kzalloc(sizeof(struct drv_ext), GFP_KERNEL);
		if (pszdev_node) {
			strncpy(pszdev_node->sz_string,
				(char *)dw_context, MAXREGPATHLENGTH - 1);
			pszdev_node->sz_string[MAXREGPATHLENGTH - 1] = '\0';
			/* Update the Driver Object List */
			*dev_node_strg = (u32) pszdev_node->sz_string;
			list_add_tail(&pszdev_node->link,
					&pdrv_object->dev_node_string);
		} else {
			status = -ENOMEM;
			*dev_node_strg = 0;
		}
	} else {
		dev_dbg(bridge, "%s: Failed to get Driver Object from Registry",
			__func__);
		*dev_node_strg = 0;
	}

	return status;
}

/*
 *  ======== drv_release_resources ========
 *  Purpose:
 *      Releases  resources from the OS.
 */
int drv_release_resources(u32 dw_context, struct drv_object *hdrv_obj)
{
	int status = 0;
	struct drv_ext *pszdev_node;

	/*
	 *  Irrespective of the status go ahead and clean it
	 *  The following will over write the status.
	 */
	for (pszdev_node = (struct drv_ext *)drv_get_first_dev_extension();
	     pszdev_node != NULL; pszdev_node = (struct drv_ext *)
	     drv_get_next_dev_extension((u32) pszdev_node)) {
		if ((u32) pszdev_node == dw_context) {
			/* Found it */
			/* Delete from the Driver object list */
			list_del(&pszdev_node->link);
			kfree(pszdev_node);
			break;
		}
	}
	return status;
}

/*
 *  ======== request_bridge_resources ========
 *  Purpose:
 *      Reserves shared memory for bridge.
 */
static int request_bridge_resources(struct cfg_hostres *res)
{
	struct cfg_hostres *host_res = res;

	/* num_mem_windows must not be more than CFG_MAXMEMREGISTERS */
	host_res->num_mem_windows = 2;

	/* First window is for DSP internal memory */
	dev_dbg(bridge, "mem_base[0] 0x%x\n", host_res->mem_base[0]);
	dev_dbg(bridge, "mem_base[3] 0x%x\n", host_res->mem_base[3]);
	dev_dbg(bridge, "dmmu_base %p\n", host_res->dmmu_base);

	/* for 24xx base port is not mapping the mamory for DSP
	 * internal memory TODO Do a ioremap here */
	/* Second window is for DSP external memory shared with MPU */

	/* These are hard-coded values */
	host_res->birq_registers = 0;
	host_res->birq_attrib = 0;
	host_res->offset_for_monitor = 0;
	host_res->chnl_offset = 0;
	/* CHNL_MAXCHANNELS */
	host_res->num_chnls = CHNL_MAXCHANNELS;
	host_res->chnl_buf_size = 0x400;

	return 0;
}

/*
 *  ======== drv_request_bridge_res_dsp ========
 *  Purpose:
 *      Reserves shared memory for bridge.
 */
int drv_request_bridge_res_dsp(void **phost_resources)
{
	int status = 0;
	struct cfg_hostres *host_res;
	u32 dw_buff_size;
	u32 dma_addr;
	u32 shm_size;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);

	dw_buff_size = sizeof(struct cfg_hostres);

	host_res = kzalloc(dw_buff_size, GFP_KERNEL);

	if (host_res != NULL) {
		request_bridge_resources(host_res);
		/* num_mem_windows must not be more than CFG_MAXMEMREGISTERS */
		host_res->num_mem_windows = 4;

		host_res->mem_base[0] = 0;
		host_res->mem_base[2] = (u32) ioremap(OMAP_DSP_MEM1_BASE,
							 OMAP_DSP_MEM1_SIZE);
		host_res->mem_base[3] = (u32) ioremap(OMAP_DSP_MEM2_BASE,
							 OMAP_DSP_MEM2_SIZE);
		host_res->mem_base[4] = (u32) ioremap(OMAP_DSP_MEM3_BASE,
							 OMAP_DSP_MEM3_SIZE);
		host_res->per_base = ioremap(OMAP_PER_CM_BASE,
						OMAP_PER_CM_SIZE);
		host_res->per_pm_base = ioremap(OMAP_PER_PRM_BASE,
						OMAP_PER_PRM_SIZE);
		host_res->core_pm_base = ioremap(OMAP_CORE_PRM_BASE,
							OMAP_CORE_PRM_SIZE);
		host_res->dmmu_base = ioremap(OMAP_DMMU_BASE,
						 OMAP_DMMU_SIZE);

		dev_dbg(bridge, "mem_base[0] 0x%x\n",
			host_res->mem_base[0]);
		dev_dbg(bridge, "mem_base[1] 0x%x\n",
			host_res->mem_base[1]);
		dev_dbg(bridge, "mem_base[2] 0x%x\n",
			host_res->mem_base[2]);
		dev_dbg(bridge, "mem_base[3] 0x%x\n",
			host_res->mem_base[3]);
		dev_dbg(bridge, "mem_base[4] 0x%x\n",
			host_res->mem_base[4]);
		dev_dbg(bridge, "dmmu_base %p\n", host_res->dmmu_base);

		shm_size = drv_datap->shm_size;
		if (shm_size >= 0x10000) {
			/* Allocate Physically contiguous,
			 * non-cacheable  memory */
			host_res->mem_base[1] =
			    (u32) mem_alloc_phys_mem(shm_size, 0x100000,
						     &dma_addr);
			if (host_res->mem_base[1] == 0) {
				status = -ENOMEM;
				pr_err("shm reservation Failed\n");
			} else {
				host_res->mem_length[1] = shm_size;
				host_res->mem_phys[1] = dma_addr;

				dev_dbg(bridge, "%s: Bridge shm address 0x%x "
					"dma_addr %x size %x\n", __func__,
					host_res->mem_base[1],
					dma_addr, shm_size);
			}
		}
		if (!status) {
			/* These are hard-coded values */
			host_res->birq_registers = 0;
			host_res->birq_attrib = 0;
			host_res->offset_for_monitor = 0;
			host_res->chnl_offset = 0;
			/* CHNL_MAXCHANNELS */
			host_res->num_chnls = CHNL_MAXCHANNELS;
			host_res->chnl_buf_size = 0x400;
			dw_buff_size = sizeof(struct cfg_hostres);
		}
		*phost_resources = host_res;
	}
	/* End Mem alloc */
	return status;
}

void mem_ext_phys_pool_init(u32 pool_phys_base, u32 pool_size)
{
	u32 pool_virt_base;

	/* get the virtual address for the physical memory pool passed */
	pool_virt_base = (u32) ioremap(pool_phys_base, pool_size);

	if ((void **)pool_virt_base == NULL) {
		pr_err("%s: external physical memory map failed\n", __func__);
		ext_phys_mem_pool_enabled = false;
	} else {
		ext_mem_pool.phys_mem_base = pool_phys_base;
		ext_mem_pool.phys_mem_size = pool_size;
		ext_mem_pool.virt_mem_base = pool_virt_base;
		ext_mem_pool.next_phys_alloc_ptr = pool_phys_base;
		ext_phys_mem_pool_enabled = true;
	}
}

void mem_ext_phys_pool_release(void)
{
	if (ext_phys_mem_pool_enabled) {
		iounmap((void *)(ext_mem_pool.virt_mem_base));
		ext_phys_mem_pool_enabled = false;
	}
}

/*
 *  ======== mem_ext_phys_mem_alloc ========
 *  Purpose:
 *     Allocate physically contiguous, uncached memory from external memory pool
 */

static void *mem_ext_phys_mem_alloc(u32 bytes, u32 align, u32 * phys_addr)
{
	u32 new_alloc_ptr;
	u32 offset;
	u32 virt_addr;

	if (align == 0)
		align = 1;

	if (bytes > ((ext_mem_pool.phys_mem_base + ext_mem_pool.phys_mem_size)
		     - ext_mem_pool.next_phys_alloc_ptr)) {
		phys_addr = NULL;
		return NULL;
	} else {
		offset = (ext_mem_pool.next_phys_alloc_ptr & (align - 1));
		if (offset == 0)
			new_alloc_ptr = ext_mem_pool.next_phys_alloc_ptr;
		else
			new_alloc_ptr = (ext_mem_pool.next_phys_alloc_ptr) +
			    (align - offset);
		if ((new_alloc_ptr + bytes) <=
		    (ext_mem_pool.phys_mem_base + ext_mem_pool.phys_mem_size)) {
			/* we can allocate */
			*phys_addr = new_alloc_ptr;
			ext_mem_pool.next_phys_alloc_ptr =
			    new_alloc_ptr + bytes;
			virt_addr =
			    ext_mem_pool.virt_mem_base + (new_alloc_ptr -
							  ext_mem_pool.
							  phys_mem_base);
			return (void *)virt_addr;
		} else {
			*phys_addr = 0;
			return NULL;
		}
	}
}

/*
 *  ======== mem_alloc_phys_mem ========
 *  Purpose:
 *      Allocate physically contiguous, uncached memory
 */
void *mem_alloc_phys_mem(u32 byte_size, u32 align_mask,
				u32 *physical_address)
{
	void *va_mem = NULL;
	dma_addr_t pa_mem;

	if (byte_size > 0) {
		if (ext_phys_mem_pool_enabled) {
			va_mem = mem_ext_phys_mem_alloc(byte_size, align_mask,
							(u32 *) &pa_mem);
		} else
			va_mem = dma_alloc_coherent(NULL, byte_size, &pa_mem,
								GFP_KERNEL);
		if (va_mem == NULL)
			*physical_address = 0;
		else
			*physical_address = pa_mem;
	}
	return va_mem;
}

/*
 *  ======== mem_free_phys_mem ========
 *  Purpose:
 *      Free the given block of physically contiguous memory.
 */
void mem_free_phys_mem(void *virtual_address, u32 physical_address,
		       u32 byte_size)
{
	if (!ext_phys_mem_pool_enabled)
		dma_free_coherent(NULL, byte_size, virtual_address,
				  physical_address);
}
