gpu: ion: Add callbacks to enable SMI voting in ION.
This change is part of the move from PMEM to ION. ION needs an SMI
voting interface smiliar to PMEM's.
Change-Id: I18888f46198848694fb7e1e0d2671074bf51d7c9
Signed-off-by: Alex Bird <alexbird@codeaurora.org>
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index 71dea89..7c542b8 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -33,6 +33,10 @@
ion_phys_addr_t base;
unsigned long allocated_bytes;
unsigned long total_size;
+ void (*request_region)(void *);
+ void (*release_region)(void *);
+ atomic_t map_count;
+ void *bus_id;
};
ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap,
@@ -128,6 +132,12 @@
struct ion_buffer *buffer,
unsigned long flags)
{
+ struct ion_carveout_heap *carveout_heap =
+ container_of(heap, struct ion_carveout_heap, heap);
+
+ if (atomic_inc_return(&carveout_heap->map_count) == 1)
+ carveout_heap->request_region(carveout_heap->bus_id);
+
if (ION_IS_CACHED(flags))
return ioremap_cached(buffer->priv_phys, buffer->size);
else
@@ -137,14 +147,27 @@
void ion_carveout_heap_unmap_kernel(struct ion_heap *heap,
struct ion_buffer *buffer)
{
+ struct ion_carveout_heap *carveout_heap =
+ container_of(heap, struct ion_carveout_heap, heap);
+
__arch_iounmap(buffer->vaddr);
buffer->vaddr = NULL;
+
+ if (atomic_dec_and_test(&carveout_heap->map_count))
+ carveout_heap->release_region(carveout_heap->bus_id);
+
return;
}
int ion_carveout_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
struct vm_area_struct *vma, unsigned long flags)
{
+ struct ion_carveout_heap *carveout_heap =
+ container_of(heap, struct ion_carveout_heap, heap);
+
+ if (atomic_inc_return(&carveout_heap->map_count) == 1)
+ carveout_heap->request_region(carveout_heap->bus_id);
+
if (ION_IS_CACHED(flags))
return remap_pfn_range(vma, vma->vm_start,
__phys_to_pfn(buffer->priv_phys) + vma->vm_pgoff,
@@ -157,6 +180,16 @@
pgprot_noncached(vma->vm_page_prot));
}
+void ion_carveout_heap_unmap_user(struct ion_heap *heap,
+ struct ion_buffer *buffer)
+{
+ struct ion_carveout_heap *carveout_heap =
+ container_of(heap, struct ion_carveout_heap, heap);
+
+ if (atomic_dec_and_test(&carveout_heap->map_count))
+ carveout_heap->release_region(carveout_heap->bus_id);
+}
+
int ion_carveout_cache_ops(struct ion_heap *heap, struct ion_buffer *buffer,
void *vaddr, unsigned int offset, unsigned int length,
unsigned int cmd)
@@ -205,6 +238,7 @@
.phys = ion_carveout_heap_phys,
.map_user = ion_carveout_heap_map_user,
.map_kernel = ion_carveout_heap_map_kernel,
+ .unmap_user = ion_carveout_heap_unmap_user,
.unmap_kernel = ion_carveout_heap_unmap_kernel,
.map_dma = ion_carveout_heap_map_dma,
.unmap_dma = ion_carveout_heap_unmap_dma,
@@ -238,6 +272,9 @@
carveout_heap->heap.type = ION_HEAP_TYPE_CARVEOUT;
carveout_heap->allocated_bytes = 0;
carveout_heap->total_size = heap_data->size;
+ carveout_heap->bus_id = heap_data->setup_region();
+ carveout_heap->request_region = heap_data->request_region;
+ carveout_heap->release_region = heap_data->release_region;
return &carveout_heap->heap;
}
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index 888b599..ac51854 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -86,6 +86,7 @@
* @map_kernel map memory to the kernel
* @unmap_kernel unmap memory to the kernel
* @map_user map memory to userspace
+ * @unmap_user unmap memory to userspace
*/
struct ion_heap_ops {
int (*allocate) (struct ion_heap *heap,
@@ -102,6 +103,7 @@
void (*unmap_kernel) (struct ion_heap *heap, struct ion_buffer *buffer);
int (*map_user) (struct ion_heap *mapper, struct ion_buffer *buffer,
struct vm_area_struct *vma, unsigned long flags);
+ void (*unmap_user) (struct ion_heap *mapper, struct ion_buffer *buffer);
int (*cache_op)(struct ion_heap *heap, struct ion_buffer *buffer,
void *vaddr, unsigned int offset,
unsigned int length, unsigned int cmd);
diff --git a/include/linux/ion.h b/include/linux/ion.h
index 89ac992..a7f3de5 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -99,6 +99,11 @@
* @name: used for debug purposes
* @base: base address of heap in physical memory if applicable
* @size: size of the heap in bytes if applicable
+ * @request_region: function to be called when the number of allocations goes
+ * from 0 -> 1
+ * @release_region: function to be called when the number of allocations goes
+ * from 1 -> 0
+ * @setup_region: function to be called upon ion registration
*
* Provided by the board file.
*/
@@ -109,6 +114,9 @@
ion_phys_addr_t base;
size_t size;
enum ion_memory_types memory_type;
+ void (*request_region)(void *);
+ void (*release_region)(void *);
+ void *(*setup_region)(void);
};
/**