summaryrefslogtreecommitdiffstats
path: root/drivers/video/via/lcd.c
diff options
context:
space:
mode:
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2009-08-06 15:07:34 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-08-07 10:39:56 -0700
commit521594442cc62d1c2af8436a05ab5918b7730b19 (patch)
tree6def6161e8b87e13791b42636cb26ae6c389538a /drivers/video/via/lcd.c
parent4bfc44958e499af9a73f62201543b3a1f617cfeb (diff)
downloadlinux-521594442cc62d1c2af8436a05ab5918b7730b19.tar.bz2
viafb: fix rmmod bug
This fixes a bug caused by changing pointers (viafb_mode, viafb_mode1) assigned by module_param. It reduces driver complexity by not needlessly changing these vars as they are only read once and removing now superfluous code. On unpatched kernels loading viafb with viafb_mode or viafb_mode1 option used and afterwards unloading it results in: kernel BUG at mm/slub.c:2926! invalid opcode: 0000 [#1] PREEMPT last sysfs file: /sys/devices/virtual/block/loop0/removable Modules linked in: snd_hda_codec_realtek snd_hda_intel snd_hda_codec snd_hwdep snd_pcm rtl8187 snd_timer eeprom_93cx6 mmc_block snd soundcore via_sdmmc fb snd_page_alloc i2c_algo_bit i2c_viapro ehci_hcd uhci_hcd cfbcopyarea mmc_core cfbimgblt cfbfillrect video output [last unloaded: viafb] Pid: 3355, comm: rmmod Not tainted (2.6.31-rc1 #0) EIP: 0060:[<c106a759>] EFLAGS: 00010246 CPU: 0 EIP is at kfree+0x80/0xda EAX: c17c2da0 EBX: dc7edbdc ECX: 0000010f EDX: 00000000 ESI: c102c700 EDI: dc7ed8fa EBP: d703ff2c ESP: d703ff20 DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068 Process rmmod (pid: 3355, ti=d703e000 task=db1412c0 task.ti=d703e000) Stack: dc7edbdc 00000014 00000016 d703ff40 c102c700 dc7f45d4 dc7f45d4 00000880 d703ff4c c103e571 00000000 d703ffac c103e751 66616976 da140062 db89ba80 00000328 d702edf8 db89ba80 d703ff9c c105d0f0 00000200 da14f898 00000014 Call Trace: [<c102c700>] ? destroy_params+0x1e/0x2b [<c103e571>] ? free_module+0xa2/0xd7 [<c103e751>] ? sys_delete_module+0x1ab/0x1da [<c105d0f0>] ? do_munmap+0x20a/0x225 [<c10029b4>] ? sysenter_do_call+0x12/0x26 Code: 10 76 7a 8d 87 00 00 00 40 c1 e8 0c c1 e0 05 03 05 1c 87 41 c1 66 83 38 00 79 03 8b 40 0c 8b 10 84 d2 78 12 66 f7 c2 00 c0 75 04 <0f> 0b eb fe e8 6f 5a fe ff eb 47 8b 55 04 8b 58 0c 9c 5e fa 3b EIP: [<c106a759>] kfree+0x80/0xda SS:ESP 0068:d703ff20 This is caused by the current code changing the pointers assigned by module_param. During unload it tries to free the memory the pointers point at which is now part of an internal structure. The patch simply avoids changing the pointers. This is okay as they are read only once during the initialization process. Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> Cc: Scott Fang <ScottFang@viatech.com.cn> Cc: Joseph Chan <JosephChan@via.com.tw> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/via/lcd.c')
-rw-r--r--drivers/video/via/lcd.c15
1 files changed, 3 insertions, 12 deletions
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 6c7290a6a447..78c6b3387947 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -580,10 +580,7 @@ static void load_lcd_k400_patch_tbl(int set_hres, int set_vres,
int reg_num = 0;
struct io_reg *lcd_patch_reg = NULL;
- if (viaparinfo->lvds_setting_info->iga_path == IGA2)
- vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
- else
- vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
+ vmode_index = viafb_get_mode_index(set_hres, set_vres);
switch (panel_id) {
/* LCD 800x600 */
case LCD_PANEL_ID1_800X600:
@@ -761,10 +758,7 @@ static void load_lcd_p880_patch_tbl(int set_hres, int set_vres,
int reg_num = 0;
struct io_reg *lcd_patch_reg = NULL;
- if (viaparinfo->lvds_setting_info->iga_path == IGA2)
- vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
- else
- vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
+ vmode_index = viafb_get_mode_index(set_hres, set_vres);
switch (panel_id) {
case LCD_PANEL_ID5_1400X1050:
@@ -832,10 +826,7 @@ static void load_lcd_patch_regs(int set_hres, int set_vres,
{
int vmode_index;
- if (viaparinfo->lvds_setting_info->iga_path == IGA2)
- vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
- else
- vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
+ vmode_index = viafb_get_mode_index(set_hres, set_vres);
viafb_unlock_crt();