]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Fix fbdev pixmap locking
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Sun, 15 Feb 2004 01:32:22 +0000 (17:32 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Sun, 15 Feb 2004 01:32:22 +0000 (17:32 -0800)
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 :)

drivers/video/console/fbcon.c
drivers/video/fbmem.c
drivers/video/softcursor.c
include/linux/fb.h

index 50fe17ea95dd21676da845aeb12cdc7742291f9a..c2d6237f7f095e046e307709c2ac7f4c018d9e95 100644 (file)
@@ -354,8 +354,6 @@ static void putcs_unaligned(struct vc_data *vc, struct fb_info *info,
                info->fbops->fb_imageblit(info, image);
                image->dx += cnt * vc->vc_font.width;
                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,
                info->fbops->fb_imageblit(info, image);
                image->dx += cnt * vc->vc_font.width;
                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,
        move_buf_aligned(info, dst, src, pitch, width, image.height);
 
        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,
index 4dea35376d2c20f08131730142f285ff0d4bce01..9fa0f4b9a38e79c3802f2ac3411d96708d619406 100644 (file)
@@ -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 align = info->pixmap.buf_align - 1;
-       u32 offset, count = 1000;
+       struct fb_pixmap *buf = &info->pixmap;
+       u32 align = buf->buf_align - 1, offset;
 
-       spin_lock(&info->pixmap.lock);
-       offset = info->pixmap.offset + align;
+       /* If IO mapped, we need to sync before access, no sharing of
+        * 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;
-       if (offset + size > info->pixmap.size) {
-               while (atomic_read(&info->pixmap.count) && count--);
-               if (info->fbops->fb_sync && 
-                   info->pixmap.flags & FB_PIXMAP_SYNC)
+       if (offset + size > buf->size) {
+               /* We do not fit. In order to be able to re-use the buffer,
+                * we must ensure no asynchronous DMA'ing or whatever operation
+                * is in progress, we sync for that.
+                */
+               if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
                        info->fbops->fb_sync(info);
                offset = 0;
        }
-       info->pixmap.offset = offset + size;
-       atomic_inc(&info->pixmap.count);        
-       smp_mb__after_atomic_inc();
-       spin_unlock(&info->pixmap.lock);
+       buf->offset = offset + size;
+
        return offset;
 }
 
@@ -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)) {
                image.dx = x;
                info->fbops->fb_imageblit(info, &image);
-               //atomic_dec(&info->pixmap.count);
-               //smp_mb__after_atomic_dec();
        }
        
        if (palette != NULL)
@@ -1254,7 +1261,6 @@ register_framebuffer(struct fb_info *fb_info)
                fb_info->pixmap.outbuf = sys_outbuf;
        if (fb_info->pixmap.inbuf == NULL)
                fb_info->pixmap.inbuf = sys_inbuf;
-       spin_lock_init(&fb_info->pixmap.lock);
 
        registered_fb[i] = fb_info;
 
index 7ac5a923542a9a10bf4f0bc99525790c59c14881..85fde8f5085755fdd988a9b118d5709cde66050e 100644 (file)
@@ -74,8 +74,6 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
        info->cursor.image.data = dst;
        
        info->fbops->fb_imageblit(info, &info->cursor.image);
-       atomic_dec(&info->pixmap.count);
-       smp_mb__after_atomic_dec();
        return 0;
 }
 
index b4a8f5c48312748b0b90759f10cacb444e7b05e1..32d119d0d0ea018f8a7ebdb0027cb86d4d2fb648 100644 (file)
@@ -363,8 +363,6 @@ struct fb_pixmap {
                                          /* access methods                */
        void (*outbuf)(u8 *dst, u8 *addr, unsigned int size); 
        u8   (*inbuf) (u8 *addr);
-       spinlock_t lock;                  /* spinlock                      */
-       atomic_t count;
 };
 
     /*