Commit f524ab7c authored by Tomi Valkeinen's avatar Tomi Valkeinen Committed by Laurent Pinchart

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: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
Acked-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
parent 794a65ff
...@@ -89,6 +89,8 @@ struct omap_framebuffer { ...@@ -89,6 +89,8 @@ struct omap_framebuffer {
int pin_count; int pin_count;
const struct format *format; const struct format *format;
struct plane planes[4]; 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, static int omap_framebuffer_create_handle(struct drm_framebuffer *fb,
...@@ -250,8 +252,11 @@ int omap_framebuffer_pin(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); struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
int ret, i, n = drm_format_num_planes(fb->pixel_format); int ret, i, n = drm_format_num_planes(fb->pixel_format);
mutex_lock(&omap_fb->lock);
if (omap_fb->pin_count > 0) { if (omap_fb->pin_count > 0) {
omap_fb->pin_count++; omap_fb->pin_count++;
mutex_unlock(&omap_fb->lock);
return 0; return 0;
} }
...@@ -265,6 +270,8 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb) ...@@ -265,6 +270,8 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb)
omap_fb->pin_count++; omap_fb->pin_count++;
mutex_unlock(&omap_fb->lock);
return 0; return 0;
fail: fail:
...@@ -274,6 +281,8 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb) ...@@ -274,6 +281,8 @@ int omap_framebuffer_pin(struct drm_framebuffer *fb)
plane->paddr = 0; plane->paddr = 0;
} }
mutex_unlock(&omap_fb->lock);
return ret; return ret;
} }
...@@ -283,10 +292,14 @@ int omap_framebuffer_unpin(struct drm_framebuffer *fb) ...@@ -283,10 +292,14 @@ int omap_framebuffer_unpin(struct drm_framebuffer *fb)
struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb); struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
int ret, i, n = drm_format_num_planes(fb->pixel_format); int ret, i, n = drm_format_num_planes(fb->pixel_format);
mutex_lock(&omap_fb->lock);
omap_fb->pin_count--; omap_fb->pin_count--;
if (omap_fb->pin_count > 0) if (omap_fb->pin_count > 0) {
mutex_unlock(&omap_fb->lock);
return 0; return 0;
}
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
struct plane *plane = &omap_fb->planes[i]; struct plane *plane = &omap_fb->planes[i];
...@@ -296,9 +309,12 @@ int omap_framebuffer_unpin(struct drm_framebuffer *fb) ...@@ -296,9 +309,12 @@ int omap_framebuffer_unpin(struct drm_framebuffer *fb)
plane->paddr = 0; plane->paddr = 0;
} }
mutex_unlock(&omap_fb->lock);
return 0; return 0;
fail: fail:
mutex_unlock(&omap_fb->lock);
return ret; return ret;
} }
...@@ -411,6 +427,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev, ...@@ -411,6 +427,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
fb = &omap_fb->base; fb = &omap_fb->base;
omap_fb->format = format; omap_fb->format = format;
mutex_init(&omap_fb->lock);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
struct plane *plane = &omap_fb->planes[i]; struct plane *plane = &omap_fb->planes[i];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment