/* * ======== dmm_reserve_memory ======== * Purpose: * Reserve a chunk of virtually contiguous DSP/IVA address space. */ int dmm_reserve_memory(struct dmm_object *dmm_mgr, u32 size, u32 *prsv_addr) { int status = 0; struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; struct map_page *node; u32 rsv_addr = 0; u32 rsv_size = 0; spin_lock(&dmm_obj->dmm_lock); /* Try to get a DSP chunk from the free list */ node = get_free_region(size); if (node != NULL) { /* DSP chunk of given size is available. */ rsv_addr = DMM_ADDR_VIRTUAL(node); /* Calculate the number entries to use */ rsv_size = size / PG_SIZE4K; if (rsv_size < node->region_size) { /* Mark remainder of free region */ node[rsv_size].mapped = false; node[rsv_size].reserved = false; node[rsv_size].region_size = node->region_size - rsv_size; node[rsv_size].mapped_size = 0; } /* get_region will return first fit chunk. But we only use what is requested. */ node->mapped = false; node->reserved = true; node->region_size = rsv_size; node->mapped_size = 0; /* Return the chunk's starting address */ *prsv_addr = rsv_addr; } else /*dSP chunk of given size is not available */ status = -ENOMEM; spin_unlock(&dmm_obj->dmm_lock); dev_dbg(bridge, "%s dmm_mgr %p, size %x, prsv_addr %p\n\tstatus %x, " "rsv_addr %x, rsv_size %x\n", __func__, dmm_mgr, size, prsv_addr, status, rsv_addr, rsv_size); return status; }
int dmm_reserve_memory(struct dmm_object *dmm_mgr, u32 size, u32 *prsv_addr) { int status = 0; struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; struct map_page *node; u32 rsv_addr = 0; u32 rsv_size = 0; spin_lock(&dmm_obj->dmm_lock); /* */ node = get_free_region(size); if (node != NULL) { /* */ rsv_addr = DMM_ADDR_VIRTUAL(node); /* */ rsv_size = size / PG_SIZE4K; if (rsv_size < node->region_size) { /* */ node[rsv_size].mapped = false; node[rsv_size].reserved = false; node[rsv_size].region_size = node->region_size - rsv_size; node[rsv_size].mapped_size = 0; } /* */ node->mapped = false; node->reserved = true; node->region_size = rsv_size; node->mapped_size = 0; /* */ *prsv_addr = rsv_addr; } else /* */ status = -ENOMEM; spin_unlock(&dmm_obj->dmm_lock); dev_dbg(bridge, "%s dmm_mgr %p, size %x, prsv_addr %p\n\tstatus %x, " "rsv_addr %x, rsv_size %x\n", __func__, dmm_mgr, size, prsv_addr, status, rsv_addr, rsv_size); return status; }