summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/omapdrm/omap_fb.c
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2015-06-04 10:56:33 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2015-06-12 22:52:51 +0300
commitf524ab7c070b39f4c8bd76fede6cacd17057ebc3 (patch)
tree023c263bb84ca62c897de1d75875a5ca5ba36283 /drivers/gpu/drm/omapdrm/omap_fb.c
parent794a65ffba77f63ecfc7d23ca6406cc23deab202 (diff)
downloadlinux-f524ab7c070b39f4c8bd76fede6cacd17057ebc3.tar.xz
drm: omapdrm: add lock for fb pinning
Before atomic modesetting omap_framebuffer_pin() and omap_framebuffer_unpin() were always called with modesetting locks taken. With atomic modesetting support this is no longer the case, and we need locking to protect the pin_count and the paddr, as multiple threads may pin the same fb concurrently. This patch adds a mutex to struct omap_framebuffer, and uses it in omap_framebuffer_pin() and omap_framebuffer_unpin(). Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_fb.c')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fb.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index e505140a8782..0b967e76df1a 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -89,6 +89,8 @@ struct omap_framebuffer {
int pin_count;
const struct format *format;
struct plane planes[4];
+ /* lock for pinning (pin_count and planes.paddr) */
+ struct mutex lock;
};
static int omap_framebuffer_create_handle(struct drm_framebuffer *fb,
@@ -250,8 +252,11 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb)
struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
int ret, i, n = drm_format_num_planes(fb->pixel_format);
+ mutex_lock(&omap_fb->lock);
+
if (omap_fb->pin_count > 0) {
omap_fb->pin_count++;
+ mutex_unlock(&omap_fb->lock);
return 0;
}
@@ -265,6 +270,8 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb)
omap_fb->pin_count++;
+ mutex_unlock(&omap_fb->lock);
+
return 0;
fail:
@@ -274,6 +281,8 @@ fail:
plane->paddr = 0;
}
+ mutex_unlock(&omap_fb->lock);
+
return ret;
}
@@ -283,10 +292,14 @@ int omap_framebuffer_unpin(struct drm_framebuffer *fb)
struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
int ret, i, n = drm_format_num_planes(fb->pixel_format);
+ mutex_lock(&omap_fb->lock);
+
omap_fb->pin_count--;
- if (omap_fb->pin_count > 0)
+ if (omap_fb->pin_count > 0) {
+ mutex_unlock(&omap_fb->lock);
return 0;
+ }
for (i = 0; i < n; i++) {
struct plane *plane = &omap_fb->planes[i];
@@ -296,9 +309,12 @@ int omap_framebuffer_unpin(struct drm_framebuffer *fb)
plane->paddr = 0;
}
+ mutex_unlock(&omap_fb->lock);
+
return 0;
fail:
+ mutex_unlock(&omap_fb->lock);
return ret;
}
@@ -411,6 +427,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
fb = &omap_fb->base;
omap_fb->format = format;
+ mutex_init(&omap_fb->lock);
for (i = 0; i < n; i++) {
struct plane *plane = &omap_fb->planes[i];