/* * ======== dmm_un_reserve_memory ======== * Purpose: * Free a chunk of reserved DSP/IVA address space. */ int dmm_un_reserve_memory(struct dmm_object *dmm_mgr, u32 rsv_addr) { struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; struct map_page *chunk; u32 i; int status = 0; u32 chunk_size; spin_lock(&dmm_obj->dmm_lock); /* Find the chunk containing the reserved address */ chunk = get_mapped_region(rsv_addr); if (chunk == NULL) status = -ENOENT; if (!status) { /* Free all the mapped pages for this reserved region */ i = 0; while (i < chunk->region_size) { if (chunk[i].mapped) { /* Remove mapping from the page tables. */ chunk_size = chunk[i].mapped_size; /* Clear the mapping flags */ chunk[i].mapped = false; chunk[i].mapped_size = 0; i += chunk_size; } else i++; } /* Clear the flags (mark the region 'free') */ chunk->reserved = false; /* NOTE: We do NOT coalesce free regions here. * Free regions are coalesced in get_region(), as it traverses *the whole mapping table */ } spin_unlock(&dmm_obj->dmm_lock); dev_dbg(bridge, "%s: dmm_mgr %p, rsv_addr %x\n\tstatus %x chunk %p", __func__, dmm_mgr, rsv_addr, status, chunk); return status; }
int dmm_un_reserve_memory(struct dmm_object *dmm_mgr, u32 rsv_addr) { struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; struct map_page *chunk; u32 i; int status = 0; u32 chunk_size; spin_lock(&dmm_obj->dmm_lock); /* */ chunk = get_mapped_region(rsv_addr); if (chunk == NULL) status = -ENOENT; if (!status) { /* */ i = 0; while (i < chunk->region_size) { if (chunk[i].mapped) { /* */ chunk_size = chunk[i].mapped_size; /* */ chunk[i].mapped = false; chunk[i].mapped_size = 0; i += chunk_size; } else i++; } /* */ chunk->reserved = false; /* */ } spin_unlock(&dmm_obj->dmm_lock); dev_dbg(bridge, "%s: dmm_mgr %p, rsv_addr %x\n\tstatus %x chunk %p", __func__, dmm_mgr, rsv_addr, status, chunk); return status; }
/* * ======== dmm_un_map_memory ======== * Purpose: * Remove the mapped block from the reserved chunk. */ int dmm_un_map_memory(struct dmm_object *dmm_mgr, u32 addr, u32 *psize) { struct dmm_object *dmm_obj = (struct dmm_object *)dmm_mgr; struct map_page *chunk; int status = 0; spin_lock(&dmm_obj->dmm_lock); chunk = get_mapped_region(addr); if (chunk == NULL) status = -ENOENT; if (!status) { /* Unmap the region */ *psize = chunk->mapped_size * PG_SIZE4K; chunk->mapped = false; chunk->mapped_size = 0; } spin_unlock(&dmm_obj->dmm_lock); dev_dbg(bridge, "%s: dmm_mgr %p, addr %x, psize %p\n\tstatus %x, " "chunk %p\n", __func__, dmm_mgr, addr, psize, status, chunk); return status; }