aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorMichael Hanselmann <linux-kernel@hansmi.ch>2006-07-10 07:44:45 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-10 16:24:20 -0400
commite01af0384f54023b4548b7742952da2ffcafd4cd (patch)
tree6ffd14821a0a1fedbf4430c5df7fa60822f4809f /drivers/video
parent58d383a6222d66be9483598c51bae34e7d3c2c37 (diff)
[PATCH] powermac: Combined fixes for backlight code
This patch fixes several problems: - pmac_backlight_key() is called under interrupt context, and therefore can't use mutexes or semaphores, so defer the backlight level for later, as it's not critical (original code by Aristeu S. Rozanski F. <aris@valeta.org>). - Add exports for functions that might be called from modules - Fix Kconfig depdencies on PMAC_BACKLIGHT. - Fix locking issues on calls from inside the driver (reported by Aristeu S. Rozanski F., too) - Fix wrong calculation of backlight values in some of the drivers - Replace pmac_backlight_key_up/down by inline functions [akpm@osdl.org: fix function prototypes] Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch> Acked-by: Aristeu S. Rozanski F. <aris@valeta.org> Acked-by: Rene Nussbaumer <linux-kernel@killerfox.forkbomb.ch> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/aty/aty128fb.c66
-rw-r--r--drivers/video/aty/atyfb_base.c53
-rw-r--r--drivers/video/chipsfb.c3
-rw-r--r--drivers/video/nvidia/nv_backlight.c32
-rw-r--r--drivers/video/nvidia/nv_proto.h2
-rw-r--r--drivers/video/nvidia/nvidia.c11
-rw-r--r--drivers/video/riva/fbdev.c44
7 files changed, 127 insertions, 84 deletions
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 1006f125fcc7..c64a717e2d4b 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -455,6 +455,7 @@ static void do_wait_for_fifo(u16 entries, struct aty128fb_par *par);
455static void wait_for_fifo(u16 entries, struct aty128fb_par *par); 455static void wait_for_fifo(u16 entries, struct aty128fb_par *par);
456static void wait_for_idle(struct aty128fb_par *par); 456static void wait_for_idle(struct aty128fb_par *par);
457static u32 depth_to_dst(u32 depth); 457static u32 depth_to_dst(u32 depth);
458static void aty128_bl_set_power(struct fb_info *info, int power);
458 459
459#define BIOS_IN8(v) (readb(bios + (v))) 460#define BIOS_IN8(v) (readb(bios + (v)))
460#define BIOS_IN16(v) (readb(bios + (v)) | \ 461#define BIOS_IN16(v) (readb(bios + (v)) | \
@@ -1257,25 +1258,11 @@ static void aty128_set_lcd_enable(struct aty128fb_par *par, int on)
1257 reg &= ~LVDS_DISPLAY_DIS; 1258 reg &= ~LVDS_DISPLAY_DIS;
1258 aty_st_le32(LVDS_GEN_CNTL, reg); 1259 aty_st_le32(LVDS_GEN_CNTL, reg);
1259#ifdef CONFIG_FB_ATY128_BACKLIGHT 1260#ifdef CONFIG_FB_ATY128_BACKLIGHT
1260 mutex_lock(&info->bl_mutex); 1261 aty128_bl_set_power(info, FB_BLANK_UNBLANK);
1261 if (info->bl_dev) {
1262 down(&info->bl_dev->sem);
1263 info->bl_dev->props->update_status(info->bl_dev);
1264 up(&info->bl_dev->sem);
1265 }
1266 mutex_unlock(&info->bl_mutex);
1267#endif 1262#endif
1268 } else { 1263 } else {
1269#ifdef CONFIG_FB_ATY128_BACKLIGHT 1264#ifdef CONFIG_FB_ATY128_BACKLIGHT
1270 mutex_lock(&info->bl_mutex); 1265 aty128_bl_set_power(info, FB_BLANK_POWERDOWN);
1271 if (info->bl_dev) {
1272 down(&info->bl_dev->sem);
1273 info->bl_dev->props->brightness = 0;
1274 info->bl_dev->props->power = FB_BLANK_POWERDOWN;
1275 info->bl_dev->props->update_status(info->bl_dev);
1276 up(&info->bl_dev->sem);
1277 }
1278 mutex_unlock(&info->bl_mutex);
1279#endif 1266#endif
1280 reg = aty_ld_le32(LVDS_GEN_CNTL); 1267 reg = aty_ld_le32(LVDS_GEN_CNTL);
1281 reg |= LVDS_DISPLAY_DIS; 1268 reg |= LVDS_DISPLAY_DIS;
@@ -1702,6 +1689,7 @@ static int __devinit aty128fb_setup(char *options)
1702 1689
1703static struct backlight_properties aty128_bl_data; 1690static struct backlight_properties aty128_bl_data;
1704 1691
1692/* Call with fb_info->bl_mutex held */
1705static int aty128_bl_get_level_brightness(struct aty128fb_par *par, 1693static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
1706 int level) 1694 int level)
1707{ 1695{
@@ -1709,10 +1697,8 @@ static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
1709 int atylevel; 1697 int atylevel;
1710 1698
1711 /* Get and convert the value */ 1699 /* Get and convert the value */
1712 mutex_lock(&info->bl_mutex);
1713 atylevel = MAX_LEVEL - 1700 atylevel = MAX_LEVEL -
1714 (info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL); 1701 (info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL);
1715 mutex_unlock(&info->bl_mutex);
1716 1702
1717 if (atylevel < 0) 1703 if (atylevel < 0)
1718 atylevel = 0; 1704 atylevel = 0;
@@ -1730,7 +1716,8 @@ static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
1730/* That one prevents proper CRT output with LCD off */ 1716/* That one prevents proper CRT output with LCD off */
1731#undef BACKLIGHT_DAC_OFF 1717#undef BACKLIGHT_DAC_OFF
1732 1718
1733static int aty128_bl_update_status(struct backlight_device *bd) 1719/* Call with fb_info->bl_mutex held */
1720static int __aty128_bl_update_status(struct backlight_device *bd)
1734{ 1721{
1735 struct aty128fb_par *par = class_get_devdata(&bd->class_dev); 1722 struct aty128fb_par *par = class_get_devdata(&bd->class_dev);
1736 unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL); 1723 unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
@@ -1783,6 +1770,19 @@ static int aty128_bl_update_status(struct backlight_device *bd)
1783 return 0; 1770 return 0;
1784} 1771}
1785 1772
1773static int aty128_bl_update_status(struct backlight_device *bd)
1774{
1775 struct aty128fb_par *par = class_get_devdata(&bd->class_dev);
1776 struct fb_info *info = pci_get_drvdata(par->pdev);
1777 int ret;
1778
1779 mutex_lock(&info->bl_mutex);
1780 ret = __aty128_bl_update_status(bd);
1781 mutex_unlock(&info->bl_mutex);
1782
1783 return ret;
1784}
1785
1786static int aty128_bl_get_brightness(struct backlight_device *bd) 1786static int aty128_bl_get_brightness(struct backlight_device *bd)
1787{ 1787{
1788 return bd->props->brightness; 1788 return bd->props->brightness;
@@ -1795,6 +1795,16 @@ static struct backlight_properties aty128_bl_data = {
1795 .max_brightness = (FB_BACKLIGHT_LEVELS - 1), 1795 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
1796}; 1796};
1797 1797
1798static void aty128_bl_set_power(struct fb_info *info, int power)
1799{
1800 mutex_lock(&info->bl_mutex);
1801 up(&info->bl_dev->sem);
1802 info->bl_dev->props->power = power;
1803 __aty128_bl_update_status(info->bl_dev);
1804 down(&info->bl_dev->sem);
1805 mutex_unlock(&info->bl_mutex);
1806}
1807
1798static void aty128_bl_init(struct aty128fb_par *par) 1808static void aty128_bl_init(struct aty128fb_par *par)
1799{ 1809{
1800 struct fb_info *info = pci_get_drvdata(par->pdev); 1810 struct fb_info *info = pci_get_drvdata(par->pdev);
@@ -2197,12 +2207,8 @@ static int aty128fb_blank(int blank, struct fb_info *fb)
2197 return 0; 2207 return 0;
2198 2208
2199#ifdef CONFIG_FB_ATY128_BACKLIGHT 2209#ifdef CONFIG_FB_ATY128_BACKLIGHT
2200 if (machine_is(powermac) && blank) { 2210 if (machine_is(powermac) && blank)
2201 down(&fb->bl_dev->sem); 2211 aty128_bl_set_power(fb, FB_BLANK_POWERDOWN);
2202 fb->bl_dev->props->power = FB_BLANK_POWERDOWN;
2203 fb->bl_dev->props->update_status(fb->bl_dev);
2204 up(&fb->bl_dev->sem);
2205 }
2206#endif 2212#endif
2207 2213
2208 if (blank & FB_BLANK_VSYNC_SUSPEND) 2214 if (blank & FB_BLANK_VSYNC_SUSPEND)
@@ -2218,14 +2224,12 @@ static int aty128fb_blank(int blank, struct fb_info *fb)
2218 aty128_set_crt_enable(par, par->crt_on && !blank); 2224 aty128_set_crt_enable(par, par->crt_on && !blank);
2219 aty128_set_lcd_enable(par, par->lcd_on && !blank); 2225 aty128_set_lcd_enable(par, par->lcd_on && !blank);
2220 } 2226 }
2227
2221#ifdef CONFIG_FB_ATY128_BACKLIGHT 2228#ifdef CONFIG_FB_ATY128_BACKLIGHT
2222 if (machine_is(powermac) && !blank) { 2229 if (machine_is(powermac) && !blank)
2223 down(&fb->bl_dev->sem); 2230 aty128_bl_set_power(fb, FB_BLANK_UNBLANK);
2224 fb->bl_dev->props->power = FB_BLANK_UNBLANK;
2225 fb->bl_dev->props->update_status(fb->bl_dev);
2226 up(&fb->bl_dev->sem);
2227 }
2228#endif 2231#endif
2232
2229 return 0; 2233 return 0;
2230} 2234}
2231 2235
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 0c9706746d79..1507d19f481f 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2129,15 +2129,14 @@ static int atyfb_pci_resume(struct pci_dev *pdev)
2129 2129
2130static struct backlight_properties aty_bl_data; 2130static struct backlight_properties aty_bl_data;
2131 2131
2132/* Call with fb_info->bl_mutex held */
2132static int aty_bl_get_level_brightness(struct atyfb_par *par, int level) 2133static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
2133{ 2134{
2134 struct fb_info *info = pci_get_drvdata(par->pdev); 2135 struct fb_info *info = pci_get_drvdata(par->pdev);
2135 int atylevel; 2136 int atylevel;
2136 2137
2137 /* Get and convert the value */ 2138 /* Get and convert the value */
2138 mutex_lock(&info->bl_mutex);
2139 atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL; 2139 atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
2140 mutex_unlock(&info->bl_mutex);
2141 2140
2142 if (atylevel < 0) 2141 if (atylevel < 0)
2143 atylevel = 0; 2142 atylevel = 0;
@@ -2147,7 +2146,8 @@ static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
2147 return atylevel; 2146 return atylevel;
2148} 2147}
2149 2148
2150static int aty_bl_update_status(struct backlight_device *bd) 2149/* Call with fb_info->bl_mutex held */
2150static int __aty_bl_update_status(struct backlight_device *bd)
2151{ 2151{
2152 struct atyfb_par *par = class_get_devdata(&bd->class_dev); 2152 struct atyfb_par *par = class_get_devdata(&bd->class_dev);
2153 unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par); 2153 unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
@@ -2172,6 +2172,19 @@ static int aty_bl_update_status(struct backlight_device *bd)
2172 return 0; 2172 return 0;
2173} 2173}
2174 2174
2175static int aty_bl_update_status(struct backlight_device *bd)
2176{
2177 struct atyfb_par *par = class_get_devdata(&bd->class_dev);
2178 struct fb_info *info = pci_get_drvdata(par->pdev);
2179 int ret;
2180
2181 mutex_lock(&info->bl_mutex);
2182 ret = __aty_bl_update_status(bd);
2183 mutex_unlock(&info->bl_mutex);
2184
2185 return ret;
2186}
2187
2175static int aty_bl_get_brightness(struct backlight_device *bd) 2188static int aty_bl_get_brightness(struct backlight_device *bd)
2176{ 2189{
2177 return bd->props->brightness; 2190 return bd->props->brightness;
@@ -2184,6 +2197,16 @@ static struct backlight_properties aty_bl_data = {
2184 .max_brightness = (FB_BACKLIGHT_LEVELS - 1), 2197 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
2185}; 2198};
2186 2199
2200static void aty_bl_set_power(struct fb_info *info, int power)
2201{
2202 mutex_lock(&info->bl_mutex);
2203 up(&info->bl_dev->sem);
2204 info->bl_dev->props->power = power;
2205 __aty_bl_update_status(info->bl_dev);
2206 down(&info->bl_dev->sem);
2207 mutex_unlock(&info->bl_mutex);
2208}
2209
2187static void aty_bl_init(struct atyfb_par *par) 2210static void aty_bl_init(struct atyfb_par *par)
2188{ 2211{
2189 struct fb_info *info = pci_get_drvdata(par->pdev); 2212 struct fb_info *info = pci_get_drvdata(par->pdev);
@@ -2790,16 +2813,8 @@ static int atyfb_blank(int blank, struct fb_info *info)
2790 return 0; 2813 return 0;
2791 2814
2792#ifdef CONFIG_PMAC_BACKLIGHT 2815#ifdef CONFIG_PMAC_BACKLIGHT
2793 if (machine_is(powermac) && blank > FB_BLANK_NORMAL) { 2816 if (machine_is(powermac) && blank > FB_BLANK_NORMAL)
2794 mutex_lock(&info->bl_mutex); 2817 aty_bl_set_power(info, FB_BLANK_POWERDOWN);
2795 if (info->bl_dev) {
2796 down(&info->bl_dev->sem);
2797 info->bl_dev->props->power = FB_BLANK_POWERDOWN;
2798 info->bl_dev->props->update_status(info->bl_dev);
2799 up(&info->bl_dev->sem);
2800 }
2801 mutex_unlock(&info->bl_mutex);
2802 }
2803#elif defined(CONFIG_FB_ATY_GENERIC_LCD) 2818#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2804 if (par->lcd_table && blank > FB_BLANK_NORMAL && 2819 if (par->lcd_table && blank > FB_BLANK_NORMAL &&
2805 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { 2820 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
@@ -2830,16 +2845,8 @@ static int atyfb_blank(int blank, struct fb_info *info)
2830 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); 2845 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
2831 2846
2832#ifdef CONFIG_PMAC_BACKLIGHT 2847#ifdef CONFIG_PMAC_BACKLIGHT
2833 if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) { 2848 if (machine_is(powermac) && blank <= FB_BLANK_NORMAL)
2834 mutex_lock(&info->bl_mutex); 2849 aty_bl_set_power(info, FB_BLANK_UNBLANK);
2835 if (info->bl_dev) {
2836 down(&info->bl_dev->sem);
2837 info->bl_dev->props->power = FB_BLANK_UNBLANK;
2838 info->bl_dev->props->update_status(info->bl_dev);
2839 up(&info->bl_dev->sem);
2840 }
2841 mutex_unlock(&info->bl_mutex);
2842 }
2843#elif defined(CONFIG_FB_ATY_GENERIC_LCD) 2850#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2844 if (par->lcd_table && blank <= FB_BLANK_NORMAL && 2851 if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
2845 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { 2852 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index eba9d93ae360..73cb426bf2d7 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -149,12 +149,11 @@ static int chipsfb_blank(int blank, struct fb_info *info)
149 mutex_lock(&pmac_backlight_mutex); 149 mutex_lock(&pmac_backlight_mutex);
150 150
151 if (pmac_backlight) { 151 if (pmac_backlight) {
152 down(&pmac_backlight->sem);
153
154 /* used to disable backlight only for blank > 1, but it seems 152 /* used to disable backlight only for blank > 1, but it seems
155 * useful at blank = 1 too (saves battery, extends backlight 153 * useful at blank = 1 too (saves battery, extends backlight
156 * life) 154 * life)
157 */ 155 */
156 down(&pmac_backlight->sem);
158 if (blank) 157 if (blank)
159 pmac_backlight->props->power = FB_BLANK_POWERDOWN; 158 pmac_backlight->props->power = FB_BLANK_POWERDOWN;
160 else 159 else
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c
index 1c1c10c699c5..b45f577094ac 100644
--- a/drivers/video/nvidia/nv_backlight.c
+++ b/drivers/video/nvidia/nv_backlight.c
@@ -26,9 +26,11 @@
26 */ 26 */
27#define MIN_LEVEL 0x158 27#define MIN_LEVEL 0x158
28#define MAX_LEVEL 0x534 28#define MAX_LEVEL 0x534
29#define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
29 30
30static struct backlight_properties nvidia_bl_data; 31static struct backlight_properties nvidia_bl_data;
31 32
33/* Call with fb_info->bl_mutex held */
32static int nvidia_bl_get_level_brightness(struct nvidia_par *par, 34static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
33 int level) 35 int level)
34{ 36{
@@ -36,9 +38,7 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
36 int nlevel; 38 int nlevel;
37 39
38 /* Get and convert the value */ 40 /* Get and convert the value */
39 mutex_lock(&info->bl_mutex); 41 nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
40 nlevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
41 mutex_unlock(&info->bl_mutex);
42 42
43 if (nlevel < 0) 43 if (nlevel < 0)
44 nlevel = 0; 44 nlevel = 0;
@@ -50,7 +50,8 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
50 return nlevel; 50 return nlevel;
51} 51}
52 52
53static int nvidia_bl_update_status(struct backlight_device *bd) 53/* Call with fb_info->bl_mutex held */
54static int __nvidia_bl_update_status(struct backlight_device *bd)
54{ 55{
55 struct nvidia_par *par = class_get_devdata(&bd->class_dev); 56 struct nvidia_par *par = class_get_devdata(&bd->class_dev);
56 u32 tmp_pcrt, tmp_pmc, fpcontrol; 57 u32 tmp_pcrt, tmp_pmc, fpcontrol;
@@ -84,6 +85,19 @@ static int nvidia_bl_update_status(struct backlight_device *bd)
84 return 0; 85 return 0;
85} 86}
86 87
88static int nvidia_bl_update_status(struct backlight_device *bd)
89{
90 struct nvidia_par *par = class_get_devdata(&bd->class_dev);
91 struct fb_info *info = pci_get_drvdata(par->pci_dev);
92 int ret;
93
94 mutex_lock(&info->bl_mutex);
95 ret = __nvidia_bl_update_status(bd);
96 mutex_unlock(&info->bl_mutex);
97
98 return ret;
99}
100
87static int nvidia_bl_get_brightness(struct backlight_device *bd) 101static int nvidia_bl_get_brightness(struct backlight_device *bd)
88{ 102{
89 return bd->props->brightness; 103 return bd->props->brightness;
@@ -96,6 +110,16 @@ static struct backlight_properties nvidia_bl_data = {
96 .max_brightness = (FB_BACKLIGHT_LEVELS - 1), 110 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
97}; 111};
98 112
113void nvidia_bl_set_power(struct fb_info *info, int power)
114{
115 mutex_lock(&info->bl_mutex);
116 up(&info->bl_dev->sem);
117 info->bl_dev->props->power = power;
118 __nvidia_bl_update_status(info->bl_dev);
119 down(&info->bl_dev->sem);
120 mutex_unlock(&info->bl_mutex);
121}
122
99void nvidia_bl_init(struct nvidia_par *par) 123void nvidia_bl_init(struct nvidia_par *par)
100{ 124{
101 struct fb_info *info = pci_get_drvdata(par->pci_dev); 125 struct fb_info *info = pci_get_drvdata(par->pci_dev);
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index 6fba656cd56b..861271017655 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/nvidia/nv_proto.h
@@ -68,9 +68,11 @@ extern u8 byte_rev[256];
68#ifdef CONFIG_FB_NVIDIA_BACKLIGHT 68#ifdef CONFIG_FB_NVIDIA_BACKLIGHT
69extern void nvidia_bl_init(struct nvidia_par *par); 69extern void nvidia_bl_init(struct nvidia_par *par);
70extern void nvidia_bl_exit(struct nvidia_par *par); 70extern void nvidia_bl_exit(struct nvidia_par *par);
71extern void nvidia_bl_set_power(struct fb_info *info, int power);
71#else 72#else
72static inline void nvidia_bl_init(struct nvidia_par *par) {} 73static inline void nvidia_bl_init(struct nvidia_par *par) {}
73static inline void nvidia_bl_exit(struct nvidia_par *par) {} 74static inline void nvidia_bl_exit(struct nvidia_par *par) {}
75static inline void nvidia_bl_set_power(struct fb_info *info, int power) {}
74#endif 76#endif
75 77
76#endif /* __NV_PROTO_H__ */ 78#endif /* __NV_PROTO_H__ */
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index ef58c3825501..9f2066f0745a 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -932,16 +932,7 @@ static int nvidiafb_blank(int blank, struct fb_info *info)
932 NVWriteSeq(par, 0x01, tmp); 932 NVWriteSeq(par, 0x01, tmp);
933 NVWriteCrtc(par, 0x1a, vesa); 933 NVWriteCrtc(par, 0x1a, vesa);
934 934
935#ifdef CONFIG_FB_NVIDIA_BACKLIGHT 935 nvidia_bl_set_power(info, blank);
936 mutex_lock(&info->bl_mutex);
937 if (info->bl_dev) {
938 down(&info->bl_dev->sem);
939 info->bl_dev->props->power = blank;
940 info->bl_dev->props->update_status(info->bl_dev);
941 up(&info->bl_dev->sem);
942 }
943 mutex_unlock(&info->bl_mutex);
944#endif
945 936
946 NVTRACE_LEAVE(); 937 NVTRACE_LEAVE();
947 938
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index baf494cecc10..33dddbae5420 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -277,9 +277,11 @@ static const struct riva_regs reg_template = {
277 */ 277 */
278#define MIN_LEVEL 0x158 278#define MIN_LEVEL 0x158
279#define MAX_LEVEL 0x534 279#define MAX_LEVEL 0x534
280#define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
280 281
281static struct backlight_properties riva_bl_data; 282static struct backlight_properties riva_bl_data;
282 283
284/* Call with fb_info->bl_mutex held */
283static int riva_bl_get_level_brightness(struct riva_par *par, 285static int riva_bl_get_level_brightness(struct riva_par *par,
284 int level) 286 int level)
285{ 287{
@@ -287,9 +289,7 @@ static int riva_bl_get_level_brightness(struct riva_par *par,
287 int nlevel; 289 int nlevel;
288 290
289 /* Get and convert the value */ 291 /* Get and convert the value */
290 mutex_lock(&info->bl_mutex); 292 nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
291 nlevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
292 mutex_unlock(&info->bl_mutex);
293 293
294 if (nlevel < 0) 294 if (nlevel < 0)
295 nlevel = 0; 295 nlevel = 0;
@@ -301,7 +301,8 @@ static int riva_bl_get_level_brightness(struct riva_par *par,
301 return nlevel; 301 return nlevel;
302} 302}
303 303
304static int riva_bl_update_status(struct backlight_device *bd) 304/* Call with fb_info->bl_mutex held */
305static int __riva_bl_update_status(struct backlight_device *bd)
305{ 306{
306 struct riva_par *par = class_get_devdata(&bd->class_dev); 307 struct riva_par *par = class_get_devdata(&bd->class_dev);
307 U032 tmp_pcrt, tmp_pmc; 308 U032 tmp_pcrt, tmp_pmc;
@@ -326,6 +327,19 @@ static int riva_bl_update_status(struct backlight_device *bd)
326 return 0; 327 return 0;
327} 328}
328 329
330static int riva_bl_update_status(struct backlight_device *bd)
331{
332 struct riva_par *par = class_get_devdata(&bd->class_dev);
333 struct fb_info *info = pci_get_drvdata(par->pdev);
334 int ret;
335
336 mutex_lock(&info->bl_mutex);
337 ret = __riva_bl_update_status(bd);
338 mutex_unlock(&info->bl_mutex);
339
340 return ret;
341}
342
329static int riva_bl_get_brightness(struct backlight_device *bd) 343static int riva_bl_get_brightness(struct backlight_device *bd)
330{ 344{
331 return bd->props->brightness; 345 return bd->props->brightness;
@@ -338,6 +352,16 @@ static struct backlight_properties riva_bl_data = {
338 .max_brightness = (FB_BACKLIGHT_LEVELS - 1), 352 .max_brightness = (FB_BACKLIGHT_LEVELS - 1),
339}; 353};
340 354
355static void riva_bl_set_power(struct fb_info *info, int power)
356{
357 mutex_lock(&info->bl_mutex);
358 up(&info->bl_dev->sem);
359 info->bl_dev->props->power = power;
360 __riva_bl_update_status(info->bl_dev);
361 down(&info->bl_dev->sem);
362 mutex_unlock(&info->bl_mutex);
363}
364
341static void riva_bl_init(struct riva_par *par) 365static void riva_bl_init(struct riva_par *par)
342{ 366{
343 struct fb_info *info = pci_get_drvdata(par->pdev); 367 struct fb_info *info = pci_get_drvdata(par->pdev);
@@ -418,6 +442,7 @@ static void riva_bl_exit(struct riva_par *par)
418#else 442#else
419static inline void riva_bl_init(struct riva_par *par) {} 443static inline void riva_bl_init(struct riva_par *par) {}
420static inline void riva_bl_exit(struct riva_par *par) {} 444static inline void riva_bl_exit(struct riva_par *par) {}
445static inline void riva_bl_set_power(struct fb_info *info, int power) {}
421#endif /* CONFIG_FB_RIVA_BACKLIGHT */ 446#endif /* CONFIG_FB_RIVA_BACKLIGHT */
422 447
423/* ------------------------------------------------------------------------- * 448/* ------------------------------------------------------------------------- *
@@ -1336,16 +1361,7 @@ static int rivafb_blank(int blank, struct fb_info *info)
1336 SEQout(par, 0x01, tmp); 1361 SEQout(par, 0x01, tmp);
1337 CRTCout(par, 0x1a, vesa); 1362 CRTCout(par, 0x1a, vesa);
1338 1363
1339#ifdef CONFIG_FB_RIVA_BACKLIGHT 1364 riva_bl_set_power(info, blank);
1340 mutex_lock(&info->bl_mutex);
1341 if (info->bl_dev) {
1342 down(&info->bl_dev->sem);
1343 info->bl_dev->props->power = blank;
1344 info->bl_dev->props->update_status(info->bl_dev);
1345 up(&info->bl_dev->sem);
1346 }
1347 mutex_unlock(&info->bl_mutex);
1348#endif
1349 1365
1350 NVTRACE_LEAVE(); 1366 NVTRACE_LEAVE();
1351 1367