浏览代码

[PATCH] atyfb, rivafb: minor fixes

aty128fb: return an error in the unlikely event that we cannot calculate
some key PLL info

rivafb:
* call CalcStateExt() directly, rather than via function pointers, since
  CalcStateExt() is the only value ever assigned to ->CalcStateExt().
* propagate error return back from CalcVClock() through callers

Signed-off-by: Jeff Garzik <jeff@garzik.org>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Jeff Garzik 18 年之前
父节点
当前提交
fd717689f4
共有 4 个文件被更改,包括 43 次插入11 次删除
  1. 5 0
      drivers/video/aty/aty128fb.c
  2. 17 5
      drivers/video/riva/fbdev.c
  3. 5 5
      drivers/video/riva/riva_hw.c
  4. 16 1
      drivers/video/riva/riva_hw.h

+ 5 - 0
drivers/video/aty/aty128fb.c

@@ -1333,6 +1333,8 @@ static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
 	if (vclk * 12 < c.ppll_min)
 	if (vclk * 12 < c.ppll_min)
 		vclk = c.ppll_min/12;
 		vclk = c.ppll_min/12;
 
 
+	pll->post_divider = -1;
+
 	/* now, find an acceptable divider */
 	/* now, find an acceptable divider */
 	for (i = 0; i < sizeof(post_dividers); i++) {
 	for (i = 0; i < sizeof(post_dividers); i++) {
 		output_freq = post_dividers[i] * vclk;
 		output_freq = post_dividers[i] * vclk;
@@ -1342,6 +1344,9 @@ static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
 		}
 		}
 	}
 	}
 
 
+	if (pll->post_divider < 0)
+		return -EINVAL;
+
 	/* calculate feedback divider */
 	/* calculate feedback divider */
 	n = c.ref_divider * output_freq;
 	n = c.ref_divider * output_freq;
 	d = c.ref_clk;
 	d = c.ref_clk;

+ 17 - 5
drivers/video/riva/fbdev.c

@@ -740,11 +740,12 @@ static void riva_load_state(struct riva_par *par, struct riva_regs *regs)
  * CALLED FROM:
  * CALLED FROM:
  * rivafb_set_par()
  * rivafb_set_par()
  */
  */
-static void riva_load_video_mode(struct fb_info *info)
+static int riva_load_video_mode(struct fb_info *info)
 {
 {
 	int bpp, width, hDisplaySize, hDisplay, hStart,
 	int bpp, width, hDisplaySize, hDisplay, hStart,
 	    hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;
 	    hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;
 	int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd;
 	int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd;
+	int rc;
 	struct riva_par *par = info->par;
 	struct riva_par *par = info->par;
 	struct riva_regs newmode;
 	struct riva_regs newmode;
 	
 	
@@ -850,8 +851,10 @@ static void riva_load_video_mode(struct fb_info *info)
 	else
 	else
 		newmode.misc_output |= 0x80;	
 		newmode.misc_output |= 0x80;	
 
 
-	par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width,
-				  hDisplaySize, height, dotClock);
+	rc = CalcStateExt(&par->riva, &newmode.ext, bpp, width,
+			  hDisplaySize, height, dotClock);
+	if (rc)
+		goto out;
 
 
 	newmode.ext.scale = NV_RD32(par->riva.PRAMDAC, 0x00000848) &
 	newmode.ext.scale = NV_RD32(par->riva.PRAMDAC, 0x00000848) &
 		0xfff000ff;
 		0xfff000ff;
@@ -883,8 +886,12 @@ static void riva_load_video_mode(struct fb_info *info)
 	par->current_state = newmode;
 	par->current_state = newmode;
 	riva_load_state(par, &par->current_state);
 	riva_load_state(par, &par->current_state);
 	par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */
 	par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */
+
+out:
 	rivafb_blank(FB_BLANK_UNBLANK, info);
 	rivafb_blank(FB_BLANK_UNBLANK, info);
 	NVTRACE_LEAVE();
 	NVTRACE_LEAVE();
+
+	return rc;
 }
 }
 
 
 static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
 static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
@@ -1252,12 +1259,15 @@ static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 static int rivafb_set_par(struct fb_info *info)
 static int rivafb_set_par(struct fb_info *info)
 {
 {
 	struct riva_par *par = info->par;
 	struct riva_par *par = info->par;
+	int rc = 0;
 
 
 	NVTRACE_ENTER();
 	NVTRACE_ENTER();
 	/* vgaHWunlock() + riva unlock (0x7F) */
 	/* vgaHWunlock() + riva unlock (0x7F) */
 	CRTCout(par, 0x11, 0xFF);
 	CRTCout(par, 0x11, 0xFF);
 	par->riva.LockUnlock(&par->riva, 0);
 	par->riva.LockUnlock(&par->riva, 0);
-	riva_load_video_mode(info);
+	rc = riva_load_video_mode(info);
+	if (rc)
+		goto out;
 	if(!(info->flags & FBINFO_HWACCEL_DISABLED))
 	if(!(info->flags & FBINFO_HWACCEL_DISABLED))
 		riva_setup_accel(info);
 		riva_setup_accel(info);
 	
 	
@@ -1270,8 +1280,10 @@ static int rivafb_set_par(struct fb_info *info)
 		info->pixmap.scan_align = 1;
 		info->pixmap.scan_align = 1;
 	else
 	else
 		info->pixmap.scan_align = 4;
 		info->pixmap.scan_align = 4;
+
+out:
 	NVTRACE_LEAVE();
 	NVTRACE_LEAVE();
-	return 0;
+	return rc;
 }
 }
 
 
 /**
 /**

+ 5 - 5
drivers/video/riva/riva_hw.c

@@ -1227,7 +1227,7 @@ static int CalcVClock
  * Calculate extended mode parameters (SVGA) and save in a 
  * Calculate extended mode parameters (SVGA) and save in a 
  * mode state structure.
  * mode state structure.
  */
  */
-static void CalcStateExt
+int CalcStateExt
 (
 (
     RIVA_HW_INST  *chip,
     RIVA_HW_INST  *chip,
     RIVA_HW_STATE *state,
     RIVA_HW_STATE *state,
@@ -1249,7 +1249,8 @@ static void CalcStateExt
      * Extended RIVA registers.
      * Extended RIVA registers.
      */
      */
     pixelDepth = (bpp + 1)/8;
     pixelDepth = (bpp + 1)/8;
-    CalcVClock(dotClock, &VClk, &m, &n, &p, chip);
+    if (!CalcVClock(dotClock, &VClk, &m, &n, &p, chip))
+    	return -EINVAL;
 
 
     switch (chip->Architecture)
     switch (chip->Architecture)
     {
     {
@@ -1327,6 +1328,8 @@ static void CalcStateExt
     state->pitch1   =
     state->pitch1   =
     state->pitch2   =
     state->pitch2   =
     state->pitch3   = pixelDepth * width;
     state->pitch3   = pixelDepth * width;
+
+    return 0;
 }
 }
 /*
 /*
  * Load fixed function state and pre-calculated/stored state.
  * Load fixed function state and pre-calculated/stored state.
@@ -2026,7 +2029,6 @@ static void nv3GetConfig
      */
      */
     chip->Busy            = nv3Busy;
     chip->Busy            = nv3Busy;
     chip->ShowHideCursor  = ShowHideCursor;
     chip->ShowHideCursor  = ShowHideCursor;
-    chip->CalcStateExt    = CalcStateExt;
     chip->LoadStateExt    = LoadStateExt;
     chip->LoadStateExt    = LoadStateExt;
     chip->UnloadStateExt  = UnloadStateExt;
     chip->UnloadStateExt  = UnloadStateExt;
     chip->SetStartAddress = SetStartAddress3;
     chip->SetStartAddress = SetStartAddress3;
@@ -2084,7 +2086,6 @@ static void nv4GetConfig
      */
      */
     chip->Busy            = nv4Busy;
     chip->Busy            = nv4Busy;
     chip->ShowHideCursor  = ShowHideCursor;
     chip->ShowHideCursor  = ShowHideCursor;
-    chip->CalcStateExt    = CalcStateExt;
     chip->LoadStateExt    = LoadStateExt;
     chip->LoadStateExt    = LoadStateExt;
     chip->UnloadStateExt  = UnloadStateExt;
     chip->UnloadStateExt  = UnloadStateExt;
     chip->SetStartAddress = SetStartAddress;
     chip->SetStartAddress = SetStartAddress;
@@ -2186,7 +2187,6 @@ static void nv10GetConfig
      */
      */
     chip->Busy            = nv10Busy;
     chip->Busy            = nv10Busy;
     chip->ShowHideCursor  = ShowHideCursor;
     chip->ShowHideCursor  = ShowHideCursor;
-    chip->CalcStateExt    = CalcStateExt;
     chip->LoadStateExt    = LoadStateExt;
     chip->LoadStateExt    = LoadStateExt;
     chip->UnloadStateExt  = UnloadStateExt;
     chip->UnloadStateExt  = UnloadStateExt;
     chip->SetStartAddress = SetStartAddress;
     chip->SetStartAddress = SetStartAddress;

+ 16 - 1
drivers/video/riva/riva_hw.h

@@ -463,7 +463,6 @@ typedef struct _riva_hw_inst
      * Common chip functions.
      * Common chip functions.
      */
      */
     int  (*Busy)(struct _riva_hw_inst *);
     int  (*Busy)(struct _riva_hw_inst *);
-    void (*CalcStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *,int,int,int,int,int);
     void (*LoadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
     void (*LoadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
     void (*UnloadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
     void (*UnloadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
     void (*SetStartAddress)(struct _riva_hw_inst *,U032);
     void (*SetStartAddress)(struct _riva_hw_inst *,U032);
@@ -528,6 +527,22 @@ typedef struct _riva_hw_state
     U032 pitch2;
     U032 pitch2;
     U032 pitch3;
     U032 pitch3;
 } RIVA_HW_STATE;
 } RIVA_HW_STATE;
+
+/*
+ * function prototypes
+ */
+
+extern int CalcStateExt
+(
+    RIVA_HW_INST  *chip,
+    RIVA_HW_STATE *state,
+    int            bpp,
+    int            width,
+    int            hDisplaySize,
+    int            height,
+    int            dotClock
+);
+
 /*
 /*
  * External routines.
  * External routines.
  */
  */