int ion_cp_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer, struct vm_area_struct *vma) { int ret_value = -EAGAIN; struct ion_cp_heap *cp_heap = container_of(heap, struct ion_cp_heap, heap); mutex_lock(&cp_heap->lock); if (cp_heap->heap_protected == HEAP_NOT_PROTECTED) { if (ion_cp_request_region(cp_heap)) { mutex_unlock(&cp_heap->lock); return -EINVAL; } if (!ION_IS_CACHED(buffer->flags)) vma->vm_page_prot = pgprot_writecombine( vma->vm_page_prot); ret_value = remap_pfn_range(vma, vma->vm_start, __phys_to_pfn(buffer->priv_phys) + vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot); if (ret_value) ion_cp_release_region(cp_heap); else ++cp_heap->umap_count; } mutex_unlock(&cp_heap->lock); return ret_value; }
void *ion_cp_heap_map_kernel(struct ion_heap *heap, struct ion_buffer *buffer, unsigned long flags) { struct ion_cp_heap *cp_heap = container_of(heap, struct ion_cp_heap, heap); void *ret_value = NULL; mutex_lock(&cp_heap->lock); if ((cp_heap->heap_protected == HEAP_NOT_PROTECTED) || ((cp_heap->heap_protected == HEAP_PROTECTED) && !ION_IS_CACHED(flags))) { if (ion_cp_request_region(cp_heap)) { mutex_unlock(&cp_heap->lock); return NULL; } if (ION_IS_CACHED(flags)) ret_value = ioremap_cached(buffer->priv_phys, buffer->size); else ret_value = ioremap(buffer->priv_phys, buffer->size); if (!ret_value) { ion_cp_release_region(cp_heap); } else { if (ION_IS_CACHED(buffer->flags)) ++cp_heap->kmap_cached_count; else ++cp_heap->kmap_uncached_count; } } mutex_unlock(&cp_heap->lock); return ret_value; }
void ion_cp_heap_unmap_user(struct ion_heap *heap, struct ion_buffer *buffer) { struct ion_cp_heap *cp_heap = container_of(heap, struct ion_cp_heap, heap); mutex_lock(&cp_heap->lock); --cp_heap->umap_count; ion_cp_release_region(cp_heap); mutex_unlock(&cp_heap->lock); }
void ion_cp_heap_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer) { struct ion_cp_heap *cp_heap = container_of(heap, struct ion_cp_heap, heap); __arch_iounmap(buffer->vaddr); buffer->vaddr = NULL; mutex_lock(&cp_heap->lock); if (ION_IS_CACHED(buffer->flags)) --cp_heap->kmap_cached_count; else --cp_heap->kmap_uncached_count; ion_cp_release_region(cp_heap); mutex_unlock(&cp_heap->lock); return; }
void ion_cp_heap_unmap_kernel(struct ion_heap *heap, struct ion_buffer *buffer) { struct ion_cp_heap *cp_heap = container_of(heap, struct ion_cp_heap, heap); if (cp_heap->reusable) unmap_kernel_range((unsigned long)buffer->vaddr, buffer->size); else __arm_iounmap(buffer->vaddr); buffer->vaddr = NULL; mutex_lock(&cp_heap->lock); if (ION_IS_CACHED(buffer->flags)) --cp_heap->kmap_cached_count; else --cp_heap->kmap_uncached_count; ion_cp_release_region(cp_heap); mutex_unlock(&cp_heap->lock); return; }