diff options
author | Benjamin Gaignard <benjamin.gaignard@linaro.org> | 2014-11-24 11:47:03 +0530 |
---|---|---|
committer | Sumit Semwal <sumit.semwal@linaro.org> | 2014-11-24 12:12:05 +0530 |
commit | 8a0d63917ec9917f8c6284c5faf643ae4b9efaa6 (patch) | |
tree | 418b4ad48c65aa1415c5ad787a8af5ec184a5eaa | |
parent | b8b410dcca7ba9767ae44079e32ce2f25ba1968c (diff) |
cenalloc: some improvements.
Remove struct cenalloc_device * from exported functions prototype,
instead use global cenalloc_dev.
Add k{un}map_atomic dma_buf_ops functions.
Do fixes to avoid segfault when allocator has not been set.
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
-rw-r--r-- | drivers/cenalloc/cenalloc.c | 66 | ||||
-rw-r--r-- | drivers/cenalloc/cenalloc.h | 5 | ||||
-rw-r--r-- | drivers/cenalloc/cenalloc_priv.h | 6 |
3 files changed, 41 insertions, 36 deletions
diff --git a/drivers/cenalloc/cenalloc.c b/drivers/cenalloc/cenalloc.c index e52d081334c0..786084a2621a 100644 --- a/drivers/cenalloc/cenalloc.c +++ b/drivers/cenalloc/cenalloc.c @@ -38,6 +38,8 @@ #include "cenalloc.h" #include "cenalloc_priv.h" +extern struct cenalloc_allocator system_contig; + /* * Constraints-aware allocator framework helper is meant to facilitate * deferred allocation of backing storage for dma-buf buffers. @@ -65,9 +67,9 @@ struct cenalloc_device { struct rw_semaphore lock; struct plist_head allocators; - }; +static struct cenalloc_device cenalloc_dev; /* this function should only be called while dev->buffer_lock is held */ static void cenalloc_buffer_add(struct cenalloc_device *dev, @@ -106,8 +108,7 @@ static bool is_cenalloc_buffer(struct dma_buf *dmabuf); * on success, pointer to the associated dma_buf; * error if dma-buf cannot be exported or if it is out of memory. */ -struct dma_buf *cenalloc_buffer_create(struct cenalloc_device *dev, - unsigned long len, +struct dma_buf *cenalloc_buffer_create(unsigned long len, unsigned long align, unsigned long flags) { @@ -121,7 +122,7 @@ struct dma_buf *cenalloc_buffer_create(struct cenalloc_device *dev, buffer->flags = flags; kref_init(&buffer->ref); - buffer->dev = dev; + buffer->dev = &cenalloc_dev; buffer->size = len; buffer->align = align; @@ -135,9 +136,9 @@ struct dma_buf *cenalloc_buffer_create(struct cenalloc_device *dev, mutex_init(&buffer->lock); - mutex_lock(&dev->buffer_lock); - cenalloc_buffer_add(dev, buffer); - mutex_unlock(&dev->buffer_lock); + mutex_lock(&cenalloc_dev.buffer_lock); + cenalloc_buffer_add(&cenalloc_dev, buffer); + mutex_unlock(&cenalloc_dev.buffer_lock); return dmabuf; @@ -150,10 +151,15 @@ EXPORT_SYMBOL_GPL(cenalloc_buffer_create); static void cenalloc_buffer_destroy(struct cenalloc_buffer *buffer) { + if (!buffer->allocator) + goto no_allocator; + if (WARN_ON(buffer->kmap_cnt > 0)) buffer->allocator->ops->unmap_kernel(buffer->allocator, buffer); buffer->allocator->ops->unmap_dma(buffer->allocator, buffer); buffer->allocator->ops->free(buffer); + +no_allocator: kfree(buffer); } @@ -296,7 +302,7 @@ static int cenalloc_find_allocator(struct cenalloc_device *dev, static struct sg_table *cenalloc_buffer_first_alloc( struct cenalloc_buffer *buffer) { - struct cenalloc_allocator *allocator = buffer->allocator; + struct cenalloc_allocator *allocator; struct sg_table *table; int num_pages = PAGE_ALIGN(buffer->size) / PAGE_SIZE; @@ -311,6 +317,8 @@ static struct sg_table *cenalloc_buffer_first_alloc( return ERR_PTR(-ENODEV); } + allocator = buffer->allocator; + ret = allocator->ops->allocate(allocator, buffer, buffer->size, buffer->align, buffer->flags); if (ret) @@ -383,24 +391,20 @@ static struct sg_table *cenalloc_map_dma_buf(struct dma_buf_attachment *attach, { struct dma_buf *dmabuf = attach->dmabuf; struct cenalloc_buffer *buffer = dmabuf->priv; - struct sg_table *table = NULL; if (!buffer->sg_table) { down_read(&(buffer->dev->lock)); - table = cenalloc_buffer_first_alloc(buffer); + buffer->sg_table = cenalloc_buffer_first_alloc(buffer); up_read(&(buffer->dev->lock)); - if (IS_ERR(table)) - return table; + if (IS_ERR(buffer->sg_table)) + return buffer->sg_table; } mutex_lock(&buffer->lock); - buffer->sg_table = table; - cenalloc_buffer_sync_for_device(buffer, attach->dev, direction); mutex_unlock(&buffer->lock); return buffer->sg_table; - } static void cenalloc_unmap_dma_buf(struct dma_buf_attachment *attachment, @@ -410,7 +414,8 @@ static void cenalloc_unmap_dma_buf(struct dma_buf_attachment *attachment, struct dma_buf *dmabuf = attachment->dmabuf; struct cenalloc_buffer *buffer = dmabuf->priv; - buffer->allocator->ops->unmap_dma(buffer->allocator, buffer); + if (buffer->allocator) + buffer->allocator->ops->unmap_dma(buffer->allocator, buffer); } static int cenalloc_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) @@ -514,6 +519,8 @@ static struct dma_buf_ops ca_dma_buf_ops = { .end_cpu_access = cenalloc_dma_buf_end_cpu_access, .kmap = cenalloc_dma_buf_kmap, .kunmap = cenalloc_dma_buf_kunmap, + .kmap_atomic = cenalloc_dma_buf_kmap, + .kunmap_atomic = cenalloc_dma_buf_kunmap, }; static bool is_cenalloc_buffer(struct dma_buf *dmabuf) @@ -521,15 +528,14 @@ static bool is_cenalloc_buffer(struct dma_buf *dmabuf) return(dmabuf->ops == &ca_dma_buf_ops); } -static int cenalloc_buffer_getfd(struct cenalloc_device *dev, - unsigned long len, +static int cenalloc_buffer_getfd(unsigned long len, unsigned long align, unsigned long flags) { struct dma_buf *dmabuf; int fd; - dmabuf = cenalloc_buffer_create(dev, len, align, flags); + dmabuf = cenalloc_buffer_create(len, align, flags); if (IS_ERR(dmabuf)) return PTR_ERR(dmabuf); @@ -543,9 +549,6 @@ static int cenalloc_buffer_getfd(struct cenalloc_device *dev, static long cenalloc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - - struct cenalloc_device *dev = filp->private_data; - int ret = 0; int fd = 0; @@ -560,8 +563,7 @@ static long cenalloc_ioctl(struct file *filp, unsigned int cmd, unsigned long ar switch (cmd) { case CA_IOC_CREATE: { - fd = cenalloc_buffer_getfd(dev, data.len, - data.align, data.flags); + fd = cenalloc_buffer_getfd(data.len, data.align, data.flags); if (fd < 0) return -ENOMEM; @@ -613,8 +615,7 @@ static const struct file_operations cenalloc_fops = { * Adds an allocator to the cenalloc_device; This should be called at * platform initialization time, for all allocators for the platform. */ -void cenalloc_device_add_allocator(struct cenalloc_device *dev, - struct cenalloc_allocator *allocator) +void cenalloc_device_add_allocator(struct cenalloc_allocator *allocator) { if (!allocator->ops->allocate || !allocator->ops->free || @@ -622,14 +623,14 @@ void cenalloc_device_add_allocator(struct cenalloc_device *dev, pr_err("%s: can not add allocator with invalid ops struct.\n", __func__); - allocator->dev = dev; - down_write(&dev->lock); + allocator->dev = &cenalloc_dev; + down_write(&cenalloc_dev.lock); /* use negative allocator->id to reverse the priority -- when traversing the list later attempt higher id numbers first */ plist_node_init(&allocator->node, -allocator->id); - plist_add(&allocator->node, &dev->allocators); + plist_add(&allocator->node, &cenalloc_dev.allocators); - up_write(&dev->lock); + up_write(&cenalloc_dev.lock); } EXPORT_SYMBOL_GPL(cenalloc_device_add_allocator); @@ -643,6 +644,7 @@ static struct cenalloc_device cenalloc_dev = { .dev.parent = NULL, }; +#if 0 /* * TODO: this mechanism of getting a cenalloc device isn't the best, * Need to have a better way of getting handle to device. @@ -652,6 +654,7 @@ struct cenalloc_device *cenalloc_get_device(void) return &cenalloc_dev; } EXPORT_SYMBOL_GPL(cenalloc_get_device); +#endif static int __init cenalloc_device_init(void) { @@ -667,6 +670,9 @@ static int __init cenalloc_device_init(void) mutex_init(&cenalloc_dev.buffer_lock); init_rwsem(&cenalloc_dev.lock); plist_head_init(&cenalloc_dev.allocators); + + cenalloc_device_add_allocator(&system_contig); + return ret; } diff --git a/drivers/cenalloc/cenalloc.h b/drivers/cenalloc/cenalloc.h index c1d3a0e5ade8..6e2a13d5fe68 100644 --- a/drivers/cenalloc/cenalloc.h +++ b/drivers/cenalloc/cenalloc.h @@ -29,6 +29,7 @@ #include "uapi/cenalloc.h" +#if 0 struct cenalloc_device; /** @@ -39,6 +40,7 @@ struct cenalloc_device; * TODO: might need to have a better way of getting this device. */ const struct cenalloc_device *cenalloc_get_device(void); +#endif /** * cenalloc_buffer_create: @@ -55,8 +57,7 @@ const struct cenalloc_device *cenalloc_get_device(void); * @flags: flags for the buffer, if any * */ -struct dma_buf *cenalloc_buffer_create(struct cenalloc_device *dev, - unsigned long len, +struct dma_buf *cenalloc_buffer_create(unsigned long len, unsigned long align, unsigned long flags); diff --git a/drivers/cenalloc/cenalloc_priv.h b/drivers/cenalloc/cenalloc_priv.h index 31f5e5941e0c..f5115132ab4f 100644 --- a/drivers/cenalloc/cenalloc_priv.h +++ b/drivers/cenalloc/cenalloc_priv.h @@ -54,8 +54,8 @@ #define CENALLOC_ALLOCATOR_SYSTEM_CONTIG_MASK \ (1 << CENALLOC_ALLOCATOR_SYSTEM_CONTIG) - struct cenalloc_device; + /** * struct cenalloc_buffer - metadata for a particular buffer * @node: node in the cenalloc_device buffers tree @@ -172,11 +172,9 @@ struct cenalloc_allocator { /** * cenalloc_device_add_allocator - adds an allocator to the cenalloc device - * @dev: the device * @allocator: the allocator to add */ -void cenalloc_device_add_allocator(struct cenalloc_device *dev, - struct cenalloc_allocator *allocator); +void cenalloc_device_add_allocator(struct cenalloc_allocator *allocator); /** * TODO: add some helpers for common allocator operations on buffers; |