Commit 4d5ca329 authored by Rebecca Schultz Zavin's avatar Rebecca Schultz Zavin Committed by Greg Kroah-Hartman

ion: Switch map/unmap dma api to sg_tables

Switch these api's from scatterlists to sg_tables
Signed-off-by: default avatarRebecca Schultz Zavin <rebecca@android.com>
[jstultz: modified patch to apply to staging directory]
Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 0f3cbb59
...@@ -445,11 +445,11 @@ void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle) ...@@ -445,11 +445,11 @@ void *ion_map_kernel(struct ion_client *client, struct ion_handle *handle)
return vaddr; return vaddr;
} }
struct scatterlist *ion_map_dma(struct ion_client *client, struct sg_table *ion_map_dma(struct ion_client *client,
struct ion_handle *handle) struct ion_handle *handle)
{ {
struct ion_buffer *buffer; struct ion_buffer *buffer;
struct scatterlist *sglist; struct sg_table *table;
mutex_lock(&client->lock); mutex_lock(&client->lock);
if (!ion_handle_validate(client, handle)) { if (!ion_handle_validate(client, handle)) {
...@@ -469,16 +469,16 @@ struct scatterlist *ion_map_dma(struct ion_client *client, ...@@ -469,16 +469,16 @@ struct scatterlist *ion_map_dma(struct ion_client *client,
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
if (_ion_map(&buffer->dmap_cnt, &handle->dmap_cnt)) { if (_ion_map(&buffer->dmap_cnt, &handle->dmap_cnt)) {
sglist = buffer->heap->ops->map_dma(buffer->heap, buffer); table = buffer->heap->ops->map_dma(buffer->heap, buffer);
if (IS_ERR_OR_NULL(sglist)) if (IS_ERR_OR_NULL(table))
_ion_unmap(&buffer->dmap_cnt, &handle->dmap_cnt); _ion_unmap(&buffer->dmap_cnt, &handle->dmap_cnt);
buffer->sglist = sglist; buffer->sg_table = table;
} else { } else {
sglist = buffer->sglist; table = buffer->sg_table;
} }
mutex_unlock(&buffer->lock); mutex_unlock(&buffer->lock);
mutex_unlock(&client->lock); mutex_unlock(&client->lock);
return sglist; return table;
} }
void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle) void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle)
...@@ -505,7 +505,7 @@ void ion_unmap_dma(struct ion_client *client, struct ion_handle *handle) ...@@ -505,7 +505,7 @@ void ion_unmap_dma(struct ion_client *client, struct ion_handle *handle)
mutex_lock(&buffer->lock); mutex_lock(&buffer->lock);
if (_ion_unmap(&buffer->dmap_cnt, &handle->dmap_cnt)) { if (_ion_unmap(&buffer->dmap_cnt, &handle->dmap_cnt)) {
buffer->heap->ops->unmap_dma(buffer->heap, buffer); buffer->heap->ops->unmap_dma(buffer->heap, buffer);
buffer->sglist = NULL; buffer->sg_table = NULL;
} }
mutex_unlock(&buffer->lock); mutex_unlock(&buffer->lock);
mutex_unlock(&client->lock); mutex_unlock(&client->lock);
......
...@@ -169,9 +169,9 @@ void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle); ...@@ -169,9 +169,9 @@ void ion_unmap_kernel(struct ion_client *client, struct ion_handle *handle);
* @client: the client * @client: the client
* @handle: handle to map * @handle: handle to map
* *
* Return an sglist describing the given handle * Return an sg_table describing the given handle
*/ */
struct scatterlist *ion_map_dma(struct ion_client *client, struct sg_table *ion_map_dma(struct ion_client *client,
struct ion_handle *handle); struct ion_handle *handle);
/** /**
......
...@@ -24,18 +24,6 @@ ...@@ -24,18 +24,6 @@
#include "ion.h" #include "ion.h"
struct ion_mapping;
struct ion_dma_mapping {
struct kref ref;
struct scatterlist *sglist;
};
struct ion_kernel_mapping {
struct kref ref;
void *vaddr;
};
struct ion_buffer *ion_handle_buffer(struct ion_handle *handle); struct ion_buffer *ion_handle_buffer(struct ion_handle *handle);
/** /**
...@@ -54,7 +42,7 @@ struct ion_buffer *ion_handle_buffer(struct ion_handle *handle); ...@@ -54,7 +42,7 @@ struct ion_buffer *ion_handle_buffer(struct ion_handle *handle);
* @kmap_cnt: number of times the buffer is mapped to the kernel * @kmap_cnt: number of times the buffer is mapped to the kernel
* @vaddr: the kenrel mapping if kmap_cnt is not zero * @vaddr: the kenrel mapping if kmap_cnt is not zero
* @dmap_cnt: number of times the buffer is mapped for dma * @dmap_cnt: number of times the buffer is mapped for dma
* @sglist: the scatterlist for the buffer is dmap_cnt is not zero * @sg_table: the sg table for the buffer if dmap_cnt is not zero
*/ */
struct ion_buffer { struct ion_buffer {
struct kref ref; struct kref ref;
...@@ -71,7 +59,7 @@ struct ion_buffer { ...@@ -71,7 +59,7 @@ struct ion_buffer {
int kmap_cnt; int kmap_cnt;
void *vaddr; void *vaddr;
int dmap_cnt; int dmap_cnt;
struct scatterlist *sglist; struct sg_table *sg_table;
}; };
/** /**
...@@ -93,7 +81,7 @@ struct ion_heap_ops { ...@@ -93,7 +81,7 @@ struct ion_heap_ops {
void (*free) (struct ion_buffer *buffer); void (*free) (struct ion_buffer *buffer);
int (*phys) (struct ion_heap *heap, struct ion_buffer *buffer, int (*phys) (struct ion_heap *heap, struct ion_buffer *buffer,
ion_phys_addr_t *addr, size_t *len); ion_phys_addr_t *addr, size_t *len);
struct scatterlist *(*map_dma) (struct ion_heap *heap, struct sg_table *(*map_dma) (struct ion_heap *heap,
struct ion_buffer *buffer); struct ion_buffer *buffer);
void (*unmap_dma) (struct ion_heap *heap, struct ion_buffer *buffer); void (*unmap_dma) (struct ion_heap *heap, struct ion_buffer *buffer);
void * (*map_kernel) (struct ion_heap *heap, struct ion_buffer *buffer); void * (*map_kernel) (struct ion_heap *heap, struct ion_buffer *buffer);
......
...@@ -38,40 +38,46 @@ void ion_system_heap_free(struct ion_buffer *buffer) ...@@ -38,40 +38,46 @@ void ion_system_heap_free(struct ion_buffer *buffer)
vfree(buffer->priv_virt); vfree(buffer->priv_virt);
} }
struct scatterlist *ion_system_heap_map_dma(struct ion_heap *heap, struct sg_table *ion_system_heap_map_dma(struct ion_heap *heap,
struct ion_buffer *buffer) struct ion_buffer *buffer)
{ {
struct scatterlist *sglist; struct sg_table *table;
struct page *page; struct scatterlist *sg;
int i; int i;
int npages = PAGE_ALIGN(buffer->size) / PAGE_SIZE; int npages = PAGE_ALIGN(buffer->size) / PAGE_SIZE;
void *vaddr = buffer->priv_virt; void *vaddr = buffer->priv_virt;
int ret;
sglist = vmalloc(npages * sizeof(struct scatterlist)); table = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
if (!sglist) if (!table)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
memset(sglist, 0, npages * sizeof(struct scatterlist)); ret = sg_alloc_table(table, npages, GFP_KERNEL);
sg_init_table(sglist, npages); if (ret)
for (i = 0; i < npages; i++) { goto err0;
for_each_sg(table->sgl, sg, table->nents, i) {
struct page *page;
page = vmalloc_to_page(vaddr); page = vmalloc_to_page(vaddr);
if (!page) if (!page) {
goto end; ret = -ENOMEM;
sg_set_page(&sglist[i], page, PAGE_SIZE, 0); goto err1;
}
sg_set_page(sg, page, PAGE_SIZE, 0);
vaddr += PAGE_SIZE; vaddr += PAGE_SIZE;
} }
/* XXX do cache maintenance for dma? */ return table;
return sglist; err1:
end: sg_free_table(table);
vfree(sglist); err0:
return NULL; kfree(table);
return ERR_PTR(ret);
} }
void ion_system_heap_unmap_dma(struct ion_heap *heap, void ion_system_heap_unmap_dma(struct ion_heap *heap,
struct ion_buffer *buffer) struct ion_buffer *buffer)
{ {
/* XXX undo cache maintenance for dma? */ if (buffer->sg_table)
if (buffer->sglist) sg_free_table(buffer->sg_table);
vfree(buffer->sglist); kfree(buffer->sg_table);
} }
void *ion_system_heap_map_kernel(struct ion_heap *heap, void *ion_system_heap_map_kernel(struct ion_heap *heap,
...@@ -144,17 +150,23 @@ static int ion_system_contig_heap_phys(struct ion_heap *heap, ...@@ -144,17 +150,23 @@ static int ion_system_contig_heap_phys(struct ion_heap *heap,
return 0; return 0;
} }
struct scatterlist *ion_system_contig_heap_map_dma(struct ion_heap *heap, struct sg_table *ion_system_contig_heap_map_dma(struct ion_heap *heap,
struct ion_buffer *buffer) struct ion_buffer *buffer)
{ {
struct scatterlist *sglist; struct sg_table *table;
int ret;
sglist = vmalloc(sizeof(struct scatterlist)); table = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
if (!sglist) if (!table)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
sg_init_table(sglist, 1); ret = sg_alloc_table(table, 1, GFP_KERNEL);
sg_set_page(sglist, virt_to_page(buffer->priv_virt), buffer->size, 0); if (ret) {
return sglist; kfree(table);
return ERR_PTR(ret);
}
sg_set_page(table->sgl, virt_to_page(buffer->priv_virt), buffer->size,
0);
return table;
} }
int ion_system_contig_heap_map_user(struct ion_heap *heap, int ion_system_contig_heap_map_user(struct ion_heap *heap,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment