]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 14 May 2014 16:10:31 +0000 (18:10 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 14 May 2014 16:10:31 +0000 (18:10 +0200)
added patches:
tgafb-fix-mode-setting-with-fbset.patch

queue-3.4/series
queue-3.4/tgafb-fix-mode-setting-with-fbset.patch [new file with mode: 0644]

index e3a156505893fb47a34376fc89db6058c15a82dc..a9d5dcf0c80c1e98f89b0e50add05d80fdef0e6f 100644 (file)
@@ -6,3 +6,4 @@ net-add-net_ratelimited_function-and-net_-level-_ratelimited-macros.patch
 netfilter-can-t-fail-and-free-after-table-replacement.patch
 tracepoint-do-not-waste-memory-on-mods-with-no-tracepoints.patch
 powerpc-add-vr-save-restore-functions.patch
+tgafb-fix-mode-setting-with-fbset.patch
diff --git a/queue-3.4/tgafb-fix-mode-setting-with-fbset.patch b/queue-3.4/tgafb-fix-mode-setting-with-fbset.patch
new file mode 100644 (file)
index 0000000..8b21dd2
--- /dev/null
@@ -0,0 +1,127 @@
+From 624966589041deb32a2626ee2e176e8274581101 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Thu, 23 Jan 2014 14:42:43 -0500
+Subject: tgafb: fix mode setting with fbset
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 624966589041deb32a2626ee2e176e8274581101 upstream.
+
+Mode setting in the TGA driver is broken for these reasons:
+
+- info->fix.line_length is set just once in tgafb_init_fix function. If
+  we change videomode, info->fix.line_length is not recalculated - so
+  the video mode is changed but the screen is corrupted because of wrong
+  info->fix.line_length.
+
+- info->fix.smem_len is set in tgafb_init_fix to the size of the default
+  video mode (640x480). If we set a higher resolution,
+  info->fix.smem_len is smaller than the current screen size, preventing
+  the userspace program from mapping the framebuffer.
+
+This patch fixes it:
+
+- info->fix.line_length initialization is moved to tgafb_set_par so that
+  it is recalculated with each mode change.
+
+- info->fix.smem_len is set to a fixed value representing the real
+  amount of video ram (the values are taken from xfree86 driver).
+
+- add a check to tgafb_check_var to prevent us from setting a videomode
+  that doesn't fit into videoram.
+
+- in tgafb_register, tgafb_init_fix is moved upwards, to be called
+  before fb_find_mode (because fb_find_mode already needs the videoram
+  size set in tgafb_init_fix).
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ drivers/video/tgafb.c |   15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/drivers/video/tgafb.c
++++ b/drivers/video/tgafb.c
+@@ -192,6 +192,8 @@ tgafb_check_var(struct fb_var_screeninfo
+       if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
+               return -EINVAL;
++      if (var->xres * var->yres * (var->bits_per_pixel >> 3) > info->fix.smem_len)
++              return -EINVAL;
+       if (var->nonstd)
+               return -EINVAL;
+       if (1000000000 / var->pixclock > TGA_PLL_MAX_FREQ)
+@@ -272,6 +274,7 @@ tgafb_set_par(struct fb_info *info)
+       par->yres = info->var.yres;
+       par->pll_freq = pll_freq = 1000000000 / info->var.pixclock;
+       par->bits_per_pixel = info->var.bits_per_pixel;
++      info->fix.line_length = par->xres * (par->bits_per_pixel >> 3);
+       tga_type = par->tga_type;
+@@ -1318,6 +1321,7 @@ tgafb_init_fix(struct fb_info *info)
+       int tga_bus_tc = TGA_BUS_TC(par->dev);
+       u8 tga_type = par->tga_type;
+       const char *tga_type_name = NULL;
++      unsigned memory_size;
+       switch (tga_type) {
+       case TGA_TYPE_8PLANE:
+@@ -1325,21 +1329,25 @@ tgafb_init_fix(struct fb_info *info)
+                       tga_type_name = "Digital ZLXp-E1";
+               if (tga_bus_tc)
+                       tga_type_name = "Digital ZLX-E1";
++              memory_size = 2097152;
+               break;
+       case TGA_TYPE_24PLANE:
+               if (tga_bus_pci)
+                       tga_type_name = "Digital ZLXp-E2";
+               if (tga_bus_tc)
+                       tga_type_name = "Digital ZLX-E2";
++              memory_size = 8388608;
+               break;
+       case TGA_TYPE_24PLUSZ:
+               if (tga_bus_pci)
+                       tga_type_name = "Digital ZLXp-E3";
+               if (tga_bus_tc)
+                       tga_type_name = "Digital ZLX-E3";
++              memory_size = 16777216;
+               break;
+       default:
+               tga_type_name = "Unknown";
++              memory_size = 16777216;
+               break;
+       }
+@@ -1351,9 +1359,8 @@ tgafb_init_fix(struct fb_info *info)
+                           ? FB_VISUAL_PSEUDOCOLOR
+                           : FB_VISUAL_DIRECTCOLOR);
+-      info->fix.line_length = par->xres * (par->bits_per_pixel >> 3);
+       info->fix.smem_start = (size_t) par->tga_fb_base;
+-      info->fix.smem_len = info->fix.line_length * par->yres;
++      info->fix.smem_len = memory_size;
+       info->fix.mmio_start = (size_t) par->tga_regs_base;
+       info->fix.mmio_len = 512;
+@@ -1478,6 +1485,9 @@ tgafb_register(struct device *dev)
+               modedb_tga = &modedb_tc;
+               modedbsize_tga = 1;
+       }
++
++      tgafb_init_fix(info);
++
+       ret = fb_find_mode(&info->var, info,
+                          mode_option ? mode_option : mode_option_tga,
+                          modedb_tga, modedbsize_tga, NULL,
+@@ -1495,7 +1505,6 @@ tgafb_register(struct device *dev)
+       }
+       tgafb_set_par(info);
+-      tgafb_init_fix(info);
+       if (register_framebuffer(info) < 0) {
+               printk(KERN_ERR "tgafb: Could not register framebuffer\n");