summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorMandar padmawar <mpadmawar@nvidia.com>2014-05-29 23:28:18 -0700
committerMandar padmawar <mpadmawar@nvidia.com>2014-05-29 23:28:18 -0700
commitabf9c41277d27ad35cb2dc036dd9c427e8d316e7 (patch)
tree7a7502259b67a5ef54a168099165ffa19159aa22 /drivers/video
parenta39d4a70d52df4a9d4a74c818880b73d684db8c7 (diff)
parent75c1032e7b6215de41e451a01033a342372105d4 (diff)
Merge commit 'refs/changes/16/411516/5' of ssh://git-master:12001/linux-3.10 into promotion_build
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/adf/adf.c22
-rw-r--r--drivers/video/adf/adf_fbdev.c36
-rw-r--r--drivers/video/adf/adf_fops.c4
-rw-r--r--drivers/video/adf/adf_fops32.h2
-rw-r--r--drivers/video/adf/adf_memblock.c17
5 files changed, 62 insertions, 19 deletions
diff --git a/drivers/video/adf/adf.c b/drivers/video/adf/adf.c
index 933e74ac8098..231881c2b355 100644
--- a/drivers/video/adf/adf.c
+++ b/drivers/video/adf/adf.c
@@ -2,6 +2,8 @@
* Copyright (C) 2013 Google, Inc.
* adf_modeinfo_{set_name,set_vrefresh} modified from
* drivers/gpu/drm/drm_modes.c
+ * adf_format_validate_yuv modified from framebuffer_check in
+ * drivers/gpu/drm/drm_crtc.c
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -492,6 +494,7 @@ static void adf_obj_destroy(struct adf_obj *obj, struct idr *idr)
struct adf_event_refcount *refcount =
container_of(node, struct adf_event_refcount,
node);
+ rb_erase(&refcount->node, &obj->event_refcount);
kfree(refcount);
node = rb_first(&obj->event_refcount);
}
@@ -920,6 +923,7 @@ done:
return ret;
}
+EXPORT_SYMBOL(adf_attachment_allow);
/**
* adf_obj_type_str - string representation of an adf_obj_type
@@ -1070,6 +1074,7 @@ int adf_format_validate_yuv(struct adf_device *dev, struct adf_buffer *buf,
u32 width = buf->w / (i != 0 ? hsub : 1);
u32 height = buf->h / (i != 0 ? vsub : 1);
u8 cpp = adf_format_plane_cpp(buf->format, i);
+ u32 last_line_size;
if (buf->pitch[i] < (u64) width * cpp) {
dev_err(&dev->base.dev, "plane %u pitch is shorter than buffer width (pitch = %u, width = %u, bpp = %u)\n",
@@ -1077,8 +1082,21 @@ int adf_format_validate_yuv(struct adf_device *dev, struct adf_buffer *buf,
return -EINVAL;
}
- if ((u64) height * buf->pitch[i] + buf->offset[i] >
- buf->dma_bufs[i]->size) {
+ switch (dev->ops->quirks.buffer_padding) {
+ case ADF_BUFFER_PADDED_TO_PITCH:
+ last_line_size = buf->pitch[i];
+ break;
+
+ case ADF_BUFFER_UNPADDED:
+ last_line_size = width * cpp;
+ break;
+
+ default:
+ BUG();
+ }
+
+ if ((u64) (height - 1) * buf->pitch[i] + last_line_size +
+ buf->offset[i] > buf->dma_bufs[i]->size) {
dev_err(&dev->base.dev, "plane %u buffer too small (height = %u, pitch = %u, offset = %u, size = %zu)\n",
i, height, buf->pitch[i],
buf->offset[i], buf->dma_bufs[i]->size);
diff --git a/drivers/video/adf/adf_fbdev.c b/drivers/video/adf/adf_fbdev.c
index cac34d14cbc2..9d3c245850af 100644
--- a/drivers/video/adf/adf_fbdev.c
+++ b/drivers/video/adf/adf_fbdev.c
@@ -356,18 +356,25 @@ int adf_fbdev_open(struct fb_info *info, int user)
struct adf_fbdev *fbdev = info->par;
int ret;
- if (!fbdev->open) {
+ mutex_lock(&fbdev->refcount_lock);
+
+ if (unlikely(fbdev->refcount == UINT_MAX)) {
+ ret = -EMFILE;
+ goto done;
+ }
+
+ if (!fbdev->refcount) {
struct drm_mode_modeinfo mode;
struct fb_videomode fbmode;
struct adf_device *dev = adf_interface_parent(fbdev->intf);
ret = adf_device_attach(dev, fbdev->eng, fbdev->intf);
if (ret < 0 && ret != -EALREADY)
- return ret;
+ goto done;
ret = adf_fb_alloc(fbdev);
if (ret < 0)
- return ret;
+ goto done;
adf_interface_current_mode(fbdev->intf, &mode);
adf_modeinfo_to_fb_videomode(&mode, &fbmode);
@@ -379,13 +386,15 @@ int adf_fbdev_open(struct fb_info *info, int user)
ret = adf_fbdev_post(fbdev);
if (ret < 0) {
- if (!fbdev->open)
+ if (!fbdev->refcount)
adf_fb_destroy(fbdev);
- return ret;
+ goto done;
}
- fbdev->open = true;
- return 0;
+ fbdev->refcount++;
+done:
+ mutex_unlock(&fbdev->refcount_lock);
+ return ret;
}
EXPORT_SYMBOL(adf_fbdev_open);
@@ -395,8 +404,12 @@ EXPORT_SYMBOL(adf_fbdev_open);
int adf_fbdev_release(struct fb_info *info, int user)
{
struct adf_fbdev *fbdev = info->par;
- adf_fb_destroy(fbdev);
- fbdev->open = false;
+ mutex_lock(&fbdev->refcount_lock);
+ BUG_ON(!fbdev->refcount);
+ fbdev->refcount--;
+ if (!fbdev->refcount)
+ adf_fb_destroy(fbdev);
+ mutex_unlock(&fbdev->refcount_lock);
return 0;
}
EXPORT_SYMBOL(adf_fbdev_release);
@@ -601,6 +614,7 @@ int adf_fbdev_init(struct adf_fbdev *fbdev, struct adf_interface *interface,
dev_err(dev, "allocating framebuffer device failed\n");
return -ENOMEM;
}
+ mutex_init(&fbdev->refcount_lock);
fbdev->default_xres_virtual = xres_virtual;
fbdev->default_yres_virtual = yres_virtual;
fbdev->default_format = format;
@@ -644,8 +658,8 @@ EXPORT_SYMBOL(adf_fbdev_init);
void adf_fbdev_destroy(struct adf_fbdev *fbdev)
{
unregister_framebuffer(fbdev->info);
- if (WARN_ON(fbdev->open))
- adf_fb_destroy(fbdev);
+ BUG_ON(fbdev->refcount);
+ mutex_destroy(&fbdev->refcount_lock);
framebuffer_release(fbdev->info);
}
EXPORT_SYMBOL(adf_fbdev_destroy);
diff --git a/drivers/video/adf/adf_fops.c b/drivers/video/adf/adf_fops.c
index abec58ea2ed8..7fbf33e1cb39 100644
--- a/drivers/video/adf/adf_fops.c
+++ b/drivers/video/adf/adf_fops.c
@@ -187,7 +187,7 @@ static int adf_buffer_import(struct adf_device *dev,
buf->dma_bufs[i] = dma_buf_get(user_buf.fd[i]);
if (IS_ERR(buf->dma_bufs[i])) {
ret = PTR_ERR(buf->dma_bufs[i]);
- dev_err(&dev->base.dev, "importing dma_buf fd %llu failed: %d\n",
+ dev_err(&dev->base.dev, "importing dma_buf fd %d failed: %d\n",
user_buf.fd[i], ret);
buf->dma_bufs[i] = NULL;
goto done;
@@ -200,7 +200,7 @@ static int adf_buffer_import(struct adf_device *dev,
if (user_buf.acquire_fence >= 0) {
buf->acquire_fence = sync_fence_fdget(user_buf.acquire_fence);
if (!buf->acquire_fence) {
- dev_err(&dev->base.dev, "getting fence fd %lld failed\n",
+ dev_err(&dev->base.dev, "getting fence fd %d failed\n",
user_buf.acquire_fence);
ret = -EINVAL;
goto done;
diff --git a/drivers/video/adf/adf_fops32.h b/drivers/video/adf/adf_fops32.h
index 53d43f010208..64034ce33a6b 100644
--- a/drivers/video/adf/adf_fops32.h
+++ b/drivers/video/adf/adf_fops32.h
@@ -25,7 +25,7 @@ struct adf_post_config32 {
compat_size_t custom_data_size;
compat_uptr_t custom_data;
- __s64 complete_fence;
+ __s32 complete_fence;
};
struct adf_device_data32 {
diff --git a/drivers/video/adf/adf_memblock.c b/drivers/video/adf/adf_memblock.c
index 3c99f27388db..e73a7d59f1e6 100644
--- a/drivers/video/adf/adf_memblock.c
+++ b/drivers/video/adf/adf_memblock.c
@@ -28,7 +28,7 @@ static struct sg_table *adf_memblock_map(struct dma_buf_attachment *attach,
unsigned long pfn = PFN_DOWN(pdata->base);
struct page *page = pfn_to_page(pfn);
struct sg_table *table;
- int ret;
+ int nents, ret;
table = kzalloc(sizeof(*table), GFP_KERNEL);
if (!table)
@@ -36,12 +36,21 @@ static struct sg_table *adf_memblock_map(struct dma_buf_attachment *attach,
ret = sg_alloc_table(table, 1, GFP_KERNEL);
if (ret < 0)
- goto err;
+ goto err_alloc;
sg_set_page(table->sgl, page, attach->dmabuf->size, 0);
+
+ nents = dma_map_sg(attach->dev, table->sgl, 1, direction);
+ if (!nents) {
+ ret = -EINVAL;
+ goto err_map;
+ }
+
return table;
-err:
+err_map:
+ sg_free_table(table);
+err_alloc:
kfree(table);
return ERR_PTR(ret);
}
@@ -49,6 +58,7 @@ err:
static void adf_memblock_unmap(struct dma_buf_attachment *attach,
struct sg_table *table, enum dma_data_direction direction)
{
+ dma_unmap_sg(attach->dev, table->sgl, 1, direction);
sg_free_table(table);
}
@@ -147,3 +157,4 @@ struct dma_buf *adf_memblock_export(phys_addr_t base, size_t size, int flags)
return buf;
}
+EXPORT_SYMBOL(adf_memblock_export);