summaryrefslogtreecommitdiff
path: root/drivers/staging/tidspbridge/rmgr/drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/tidspbridge/rmgr/drv.c')
-rw-r--r--drivers/staging/tidspbridge/rmgr/drv.c816
1 files changed, 0 insertions, 816 deletions
diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c
deleted file mode 100644
index 757ae20b38ee..000000000000
--- a/drivers/staging/tidspbridge/rmgr/drv.c
+++ /dev/null
@@ -1,816 +0,0 @@
-/*
- * 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);
-}