ion: Switch map/unmap dma api to sg_tables
Switch these api's from scatterlists to sg_tables Signed-off-by: Rebecca Schultz Zavin <rebecca@android.com> [jstultz: modified patch to apply to staging directory] Signed-off-by: John Stultz <john.stultz@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
0f3cbb59ec
commit
4d5ca3299f
4 changed files with 53 additions and 53 deletions
|
@ -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,
|
||||||
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)
|
||||||
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,10 +169,10 @@ 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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ion_unmap_dma() - destroy a dma mapping for a handle
|
* ion_unmap_dma() - destroy a dma mapping for a handle
|
||||||
|
|
|
@ -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);
|
||||||
* @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 {
|
||||||
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 {
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
|
|
Loading…
Add table
Reference in a new issue