Commit 7b377012 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Linus Torvalds

[PATCH] Fix fbdev pixmap locking

This removes the broken locking code in the pixmaps, and rewrite the
buffer access function to properly call fb_sync when needed.  The old
broken loocking is useless as we are covered by the console semaphore in
all cases hopefully (except if I missed one :)
parent 29d6f8c4
...@@ -354,8 +354,6 @@ static void putcs_unaligned(struct vc_data *vc, struct fb_info *info, ...@@ -354,8 +354,6 @@ static void putcs_unaligned(struct vc_data *vc, struct fb_info *info,
info->fbops->fb_imageblit(info, image); info->fbops->fb_imageblit(info, image);
image->dx += cnt * vc->vc_font.width; image->dx += cnt * vc->vc_font.width;
count -= cnt; count -= cnt;
atomic_dec(&info->pixmap.count);
smp_mb__after_atomic_dec();
} }
} }
...@@ -394,8 +392,6 @@ static void putcs_aligned(struct vc_data *vc, struct fb_info *info, ...@@ -394,8 +392,6 @@ static void putcs_aligned(struct vc_data *vc, struct fb_info *info,
info->fbops->fb_imageblit(info, image); info->fbops->fb_imageblit(info, image);
image->dx += cnt * vc->vc_font.width; image->dx += cnt * vc->vc_font.width;
count -= cnt; count -= cnt;
atomic_dec(&info->pixmap.count);
smp_mb__after_atomic_dec();
} }
} }
...@@ -466,8 +462,6 @@ static void accel_putc(struct vc_data *vc, struct fb_info *info, ...@@ -466,8 +462,6 @@ static void accel_putc(struct vc_data *vc, struct fb_info *info,
move_buf_aligned(info, dst, src, pitch, width, image.height); move_buf_aligned(info, dst, src, pitch, width, image.height);
info->fbops->fb_imageblit(info, &image); info->fbops->fb_imageblit(info, &image);
atomic_dec(&info->pixmap.count);
smp_mb__after_atomic_dec();
} }
void accel_putcs(struct vc_data *vc, struct fb_info *info, void accel_putcs(struct vc_data *vc, struct fb_info *info,
......
...@@ -464,23 +464,32 @@ void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch, ...@@ -464,23 +464,32 @@ void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
*/ */
u32 fb_get_buffer_offset(struct fb_info *info, u32 size) u32 fb_get_buffer_offset(struct fb_info *info, u32 size)
{ {
u32 align = info->pixmap.buf_align - 1; struct fb_pixmap *buf = &info->pixmap;
u32 offset, count = 1000; u32 align = buf->buf_align - 1, offset;
spin_lock(&info->pixmap.lock); /* If IO mapped, we need to sync before access, no sharing of
offset = info->pixmap.offset + align; * the pixmap is done
*/
if (buf->flags & FB_PIXMAP_IO) {
if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
info->fbops->fb_sync(info);
return 0;
}
/* See if we fit in the remaining pixmap space */
offset = buf->offset + align;
offset &= ~align; offset &= ~align;
if (offset + size > info->pixmap.size) { if (offset + size > buf->size) {
while (atomic_read(&info->pixmap.count) && count--); /* We do not fit. In order to be able to re-use the buffer,
if (info->fbops->fb_sync && * we must ensure no asynchronous DMA'ing or whatever operation
info->pixmap.flags & FB_PIXMAP_SYNC) * is in progress, we sync for that.
*/
if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
info->fbops->fb_sync(info); info->fbops->fb_sync(info);
offset = 0; offset = 0;
} }
info->pixmap.offset = offset + size; buf->offset = offset + size;
atomic_inc(&info->pixmap.count);
smp_mb__after_atomic_inc();
spin_unlock(&info->pixmap.lock);
return offset; return offset;
} }
...@@ -733,8 +742,6 @@ int fb_show_logo(struct fb_info *info) ...@@ -733,8 +742,6 @@ int fb_show_logo(struct fb_info *info)
x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) { x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) {
image.dx = x; image.dx = x;
info->fbops->fb_imageblit(info, &image); info->fbops->fb_imageblit(info, &image);
//atomic_dec(&info->pixmap.count);
//smp_mb__after_atomic_dec();
} }
if (palette != NULL) if (palette != NULL)
...@@ -1254,7 +1261,6 @@ register_framebuffer(struct fb_info *fb_info) ...@@ -1254,7 +1261,6 @@ register_framebuffer(struct fb_info *fb_info)
fb_info->pixmap.outbuf = sys_outbuf; fb_info->pixmap.outbuf = sys_outbuf;
if (fb_info->pixmap.inbuf == NULL) if (fb_info->pixmap.inbuf == NULL)
fb_info->pixmap.inbuf = sys_inbuf; fb_info->pixmap.inbuf = sys_inbuf;
spin_lock_init(&fb_info->pixmap.lock);
registered_fb[i] = fb_info; registered_fb[i] = fb_info;
......
...@@ -74,8 +74,6 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) ...@@ -74,8 +74,6 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
info->cursor.image.data = dst; info->cursor.image.data = dst;
info->fbops->fb_imageblit(info, &info->cursor.image); info->fbops->fb_imageblit(info, &info->cursor.image);
atomic_dec(&info->pixmap.count);
smp_mb__after_atomic_dec();
return 0; return 0;
} }
......
...@@ -363,8 +363,6 @@ struct fb_pixmap { ...@@ -363,8 +363,6 @@ struct fb_pixmap {
/* access methods */ /* access methods */
void (*outbuf)(u8 *dst, u8 *addr, unsigned int size); void (*outbuf)(u8 *dst, u8 *addr, unsigned int size);
u8 (*inbuf) (u8 *addr); u8 (*inbuf) (u8 *addr);
spinlock_t lock; /* spinlock */
atomic_t count;
}; };
/* /*
......
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