aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Gaignard <benjamin.gaignard@linaro.org>2014-11-24 11:47:03 +0530
committerSumit Semwal <sumit.semwal@linaro.org>2014-11-24 12:12:05 +0530
commit8a0d63917ec9917f8c6284c5faf643ae4b9efaa6 (patch)
tree418b4ad48c65aa1415c5ad787a8af5ec184a5eaa
parentb8b410dcca7ba9767ae44079e32ce2f25ba1968c (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.c66
-rw-r--r--drivers/cenalloc/cenalloc.h5
-rw-r--r--drivers/cenalloc/cenalloc_priv.h6
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;