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 /drivers/video/aty | |
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>
Diffstat (limited to 'drivers/video/aty')
-rw-r--r-- | drivers/video/aty/aty128fb.c | 66 | ||||
-rw-r--r-- | drivers/video/aty/atyfb_base.c | 53 |
2 files changed, 65 insertions, 54 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); | |||
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)) { |