diff options
author | Michael Hanselmann <linux-kernel@hansmi.ch> | 2006-07-10 07:44:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-10 16:24:20 -0400 |
commit | e01af0384f54023b4548b7742952da2ffcafd4cd (patch) | |
tree | 6ffd14821a0a1fedbf4430c5df7fa60822f4809f | |
parent | 58d383a6222d66be9483598c51bae34e7d3c2c37 (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>
-rw-r--r-- | arch/powerpc/platforms/powermac/backlight.c | 31 | ||||
-rw-r--r-- | drivers/macintosh/Kconfig | 5 | ||||
-rw-r--r-- | drivers/video/aty/aty128fb.c | 66 | ||||
-rw-r--r-- | drivers/video/aty/atyfb_base.c | 53 | ||||
-rw-r--r-- | drivers/video/chipsfb.c | 3 | ||||
-rw-r--r-- | drivers/video/nvidia/nv_backlight.c | 32 | ||||
-rw-r--r-- | drivers/video/nvidia/nv_proto.h | 2 | ||||
-rw-r--r-- | drivers/video/nvidia/nvidia.c | 11 | ||||
-rw-r--r-- | drivers/video/riva/fbdev.c | 44 | ||||
-rw-r--r-- | include/asm-powerpc/backlight.h | 12 |
10 files changed, 162 insertions, 97 deletions
diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c index 69f65e215a5c..74eed6b74cd6 100644 --- a/arch/powerpc/platforms/powermac/backlight.c +++ b/arch/powerpc/platforms/powermac/backlight.c | |||
@@ -15,6 +15,15 @@ | |||
15 | 15 | ||
16 | #define OLD_BACKLIGHT_MAX 15 | 16 | #define OLD_BACKLIGHT_MAX 15 |
17 | 17 | ||
18 | static void pmac_backlight_key_worker(void *data); | ||
19 | static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker, NULL); | ||
20 | |||
21 | /* Although this variable is used in interrupt context, it makes no sense to | ||
22 | * protect it. No user is able to produce enough key events per second and | ||
23 | * notice the errors that might happen. | ||
24 | */ | ||
25 | static int pmac_backlight_key_queued; | ||
26 | |||
18 | /* Protect the pmac_backlight variable */ | 27 | /* Protect the pmac_backlight variable */ |
19 | DEFINE_MUTEX(pmac_backlight_mutex); | 28 | DEFINE_MUTEX(pmac_backlight_mutex); |
20 | 29 | ||
@@ -71,7 +80,7 @@ int pmac_backlight_curve_lookup(struct fb_info *info, int value) | |||
71 | return level; | 80 | return level; |
72 | } | 81 | } |
73 | 82 | ||
74 | static void pmac_backlight_key(int direction) | 83 | static void pmac_backlight_key_worker(void *data) |
75 | { | 84 | { |
76 | mutex_lock(&pmac_backlight_mutex); | 85 | mutex_lock(&pmac_backlight_mutex); |
77 | if (pmac_backlight) { | 86 | if (pmac_backlight) { |
@@ -82,7 +91,8 @@ static void pmac_backlight_key(int direction) | |||
82 | props = pmac_backlight->props; | 91 | props = pmac_backlight->props; |
83 | 92 | ||
84 | brightness = props->brightness + | 93 | brightness = props->brightness + |
85 | ((direction?-1:1) * (props->max_brightness / 15)); | 94 | ((pmac_backlight_key_queued?-1:1) * |
95 | (props->max_brightness / 15)); | ||
86 | 96 | ||
87 | if (brightness < 0) | 97 | if (brightness < 0) |
88 | brightness = 0; | 98 | brightness = 0; |
@@ -97,14 +107,13 @@ static void pmac_backlight_key(int direction) | |||
97 | mutex_unlock(&pmac_backlight_mutex); | 107 | mutex_unlock(&pmac_backlight_mutex); |
98 | } | 108 | } |
99 | 109 | ||
100 | void pmac_backlight_key_up() | 110 | void pmac_backlight_key(int direction) |
101 | { | 111 | { |
102 | pmac_backlight_key(0); | 112 | /* we can receive multiple interrupts here, but the scheduled work |
103 | } | 113 | * will run only once, with the last value |
104 | 114 | */ | |
105 | void pmac_backlight_key_down() | 115 | pmac_backlight_key_queued = direction; |
106 | { | 116 | schedule_work(&pmac_backlight_key_work); |
107 | pmac_backlight_key(1); | ||
108 | } | 117 | } |
109 | 118 | ||
110 | int pmac_backlight_set_legacy_brightness(int brightness) | 119 | int pmac_backlight_set_legacy_brightness(int brightness) |
@@ -157,3 +166,7 @@ int pmac_backlight_get_legacy_brightness() | |||
157 | 166 | ||
158 | return result; | 167 | return result; |
159 | } | 168 | } |
169 | |||
170 | EXPORT_SYMBOL_GPL(pmac_backlight); | ||
171 | EXPORT_SYMBOL_GPL(pmac_backlight_mutex); | ||
172 | EXPORT_SYMBOL_GPL(pmac_has_backlight_type); | ||
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 54f3f6b94efc..f5fe7fb4b3ad 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig | |||
@@ -113,7 +113,10 @@ config PMAC_MEDIABAY | |||
113 | 113 | ||
114 | config PMAC_BACKLIGHT | 114 | config PMAC_BACKLIGHT |
115 | bool "Backlight control for LCD screens" | 115 | bool "Backlight control for LCD screens" |
116 | depends on ADB_PMU && (BROKEN || !PPC64) | 116 | depends on ADB_PMU && FB = y && (BROKEN || !PPC64) |
117 | select FB_BACKLIGHT | ||
118 | select BACKLIGHT_CLASS_DEVICE | ||
119 | select BACKLIGHT_LCD_SUPPORT | ||
117 | help | 120 | help |
118 | Say Y here to enable Macintosh specific extensions of the generic | 121 | Say Y here to enable Macintosh specific extensions of the generic |
119 | backlight code. With this enabled, the brightness keys on older | 122 | backlight code. With this enabled, the brightness keys on older |
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); | |||
455 | static void wait_for_fifo(u16 entries, struct aty128fb_par *par); | 455 | static void wait_for_fifo(u16 entries, struct aty128fb_par *par); |
456 | static void wait_for_idle(struct aty128fb_par *par); | 456 | static void wait_for_idle(struct aty128fb_par *par); |
457 | static u32 depth_to_dst(u32 depth); | 457 | static u32 depth_to_dst(u32 depth); |
458 | static 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 | ||
1703 | static struct backlight_properties aty128_bl_data; | 1690 | static struct backlight_properties aty128_bl_data; |
1704 | 1691 | ||
1692 | /* Call with fb_info->bl_mutex held */ | ||
1705 | static int aty128_bl_get_level_brightness(struct aty128fb_par *par, | 1693 | static 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 | ||
1733 | static int aty128_bl_update_status(struct backlight_device *bd) | 1719 | /* Call with fb_info->bl_mutex held */ |
1720 | static 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 | ||
1773 | static 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 | |||
1786 | static int aty128_bl_get_brightness(struct backlight_device *bd) | 1786 | static 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 | ||
1798 | static 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 | |||
1798 | static void aty128_bl_init(struct aty128fb_par *par) | 1808 | static 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 | ||
2130 | static struct backlight_properties aty_bl_data; | 2130 | static struct backlight_properties aty_bl_data; |
2131 | 2131 | ||
2132 | /* Call with fb_info->bl_mutex held */ | ||
2132 | static int aty_bl_get_level_brightness(struct atyfb_par *par, int level) | 2133 | static 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 | ||
2150 | static int aty_bl_update_status(struct backlight_device *bd) | 2149 | /* Call with fb_info->bl_mutex held */ |
2150 | static 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 | ||
2175 | static 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 | |||
2175 | static int aty_bl_get_brightness(struct backlight_device *bd) | 2188 | static 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 | ||
2200 | static 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 | |||
2187 | static void aty_bl_init(struct atyfb_par *par) | 2210 | static 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 | ||
30 | static struct backlight_properties nvidia_bl_data; | 31 | static struct backlight_properties nvidia_bl_data; |
31 | 32 | ||
33 | /* Call with fb_info->bl_mutex held */ | ||
32 | static int nvidia_bl_get_level_brightness(struct nvidia_par *par, | 34 | static 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 | ||
53 | static int nvidia_bl_update_status(struct backlight_device *bd) | 53 | /* Call with fb_info->bl_mutex held */ |
54 | static 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 | ||
88 | static 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 | |||
87 | static int nvidia_bl_get_brightness(struct backlight_device *bd) | 101 | static 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 | ||
113 | void 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 | |||
99 | void nvidia_bl_init(struct nvidia_par *par) | 123 | void 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 |
69 | extern void nvidia_bl_init(struct nvidia_par *par); | 69 | extern void nvidia_bl_init(struct nvidia_par *par); |
70 | extern void nvidia_bl_exit(struct nvidia_par *par); | 70 | extern void nvidia_bl_exit(struct nvidia_par *par); |
71 | extern void nvidia_bl_set_power(struct fb_info *info, int power); | ||
71 | #else | 72 | #else |
72 | static inline void nvidia_bl_init(struct nvidia_par *par) {} | 73 | static inline void nvidia_bl_init(struct nvidia_par *par) {} |
73 | static inline void nvidia_bl_exit(struct nvidia_par *par) {} | 74 | static inline void nvidia_bl_exit(struct nvidia_par *par) {} |
75 | static 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 | ||
281 | static struct backlight_properties riva_bl_data; | 282 | static struct backlight_properties riva_bl_data; |
282 | 283 | ||
284 | /* Call with fb_info->bl_mutex held */ | ||
283 | static int riva_bl_get_level_brightness(struct riva_par *par, | 285 | static 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 | ||
304 | static int riva_bl_update_status(struct backlight_device *bd) | 304 | /* Call with fb_info->bl_mutex held */ |
305 | static 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 | ||
330 | static 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 | |||
329 | static int riva_bl_get_brightness(struct backlight_device *bd) | 343 | static 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 | ||
355 | static 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 | |||
341 | static void riva_bl_init(struct riva_par *par) | 365 | static 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 |
419 | static inline void riva_bl_init(struct riva_par *par) {} | 443 | static inline void riva_bl_init(struct riva_par *par) {} |
420 | static inline void riva_bl_exit(struct riva_par *par) {} | 444 | static inline void riva_bl_exit(struct riva_par *par) {} |
445 | static 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 | ||
diff --git a/include/asm-powerpc/backlight.h b/include/asm-powerpc/backlight.h index a5e9e656e332..58d4b6f8d827 100644 --- a/include/asm-powerpc/backlight.h +++ b/include/asm-powerpc/backlight.h | |||
@@ -16,13 +16,19 @@ | |||
16 | extern struct backlight_device *pmac_backlight; | 16 | extern struct backlight_device *pmac_backlight; |
17 | extern struct mutex pmac_backlight_mutex; | 17 | extern struct mutex pmac_backlight_mutex; |
18 | 18 | ||
19 | extern void pmac_backlight_calc_curve(struct fb_info*); | ||
20 | extern int pmac_backlight_curve_lookup(struct fb_info *info, int value); | 19 | extern int pmac_backlight_curve_lookup(struct fb_info *info, int value); |
21 | 20 | ||
22 | extern int pmac_has_backlight_type(const char *type); | 21 | extern int pmac_has_backlight_type(const char *type); |
23 | 22 | ||
24 | extern void pmac_backlight_key_up(void); | 23 | extern void pmac_backlight_key(int direction); |
25 | extern void pmac_backlight_key_down(void); | 24 | static inline void pmac_backlight_key_up(void) |
25 | { | ||
26 | pmac_backlight_key(0); | ||
27 | } | ||
28 | static inline void pmac_backlight_key_down(void) | ||
29 | { | ||
30 | pmac_backlight_key(1); | ||
31 | } | ||
26 | 32 | ||
27 | extern int pmac_backlight_set_legacy_brightness(int brightness); | 33 | extern int pmac_backlight_set_legacy_brightness(int brightness); |
28 | extern int pmac_backlight_get_legacy_brightness(void); | 34 | extern int pmac_backlight_get_legacy_brightness(void); |