diff options
author | Richard Purdie <rpurdie@rpsys.net> | 2007-02-10 09:10:33 -0500 |
---|---|---|
committer | Richard Purdie <rpurdie@rpsys.net> | 2007-02-20 03:38:46 -0500 |
commit | 37ce69a57ff217a4ca0871e9ee5aa58c052b7d86 (patch) | |
tree | 21cdbb8c988eed585437bb502ca15c2998ea7fbc | |
parent | b5c6916b3118d4301dc2f8cf8d33f13e5324a3a5 (diff) |
backlight: Rework backlight/fb interaction simplifying, lots
fb_info->bl_mutex is badly thought out and the backlight class doesn't
need it if the framebuffer/backlight register/unregister order is
consistent, particularly after the backlight locking fixes.
Fix the drivers to use the order:
backlight_device_register()
register_framebuffer()
unregister_framebuffer()
backlight_device_unregister()
and turn bl_mutex into a lock for the bl_curve data only.
Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
-rw-r--r-- | drivers/video/aty/aty128fb.c | 55 | ||||
-rw-r--r-- | drivers/video/aty/atyfb_base.c | 49 | ||||
-rw-r--r-- | drivers/video/aty/radeon_backlight.c | 29 | ||||
-rw-r--r-- | drivers/video/aty/radeon_base.c | 3 | ||||
-rw-r--r-- | drivers/video/fbsysfs.c | 14 | ||||
-rw-r--r-- | drivers/video/nvidia/nv_backlight.c | 40 | ||||
-rw-r--r-- | drivers/video/nvidia/nvidia.c | 3 | ||||
-rw-r--r-- | drivers/video/riva/fbdev.c | 50 | ||||
-rw-r--r-- | include/linux/fb.h | 9 |
9 files changed, 68 insertions, 184 deletions
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index 1c77cfb8e683..ef3e7861c27a 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c | |||
@@ -1697,7 +1697,6 @@ static int __devinit aty128fb_setup(char *options) | |||
1697 | 1697 | ||
1698 | static struct backlight_properties aty128_bl_data; | 1698 | static struct backlight_properties aty128_bl_data; |
1699 | 1699 | ||
1700 | /* Call with fb_info->bl_mutex held */ | ||
1701 | static int aty128_bl_get_level_brightness(struct aty128fb_par *par, | 1700 | static int aty128_bl_get_level_brightness(struct aty128fb_par *par, |
1702 | int level) | 1701 | int level) |
1703 | { | 1702 | { |
@@ -1705,6 +1704,7 @@ static int aty128_bl_get_level_brightness(struct aty128fb_par *par, | |||
1705 | int atylevel; | 1704 | int atylevel; |
1706 | 1705 | ||
1707 | /* Get and convert the value */ | 1706 | /* Get and convert the value */ |
1707 | /* No locking of bl_curve since we read a single value */ | ||
1708 | atylevel = MAX_LEVEL - | 1708 | atylevel = MAX_LEVEL - |
1709 | (info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL); | 1709 | (info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL); |
1710 | 1710 | ||
@@ -1724,8 +1724,7 @@ static int aty128_bl_get_level_brightness(struct aty128fb_par *par, | |||
1724 | /* That one prevents proper CRT output with LCD off */ | 1724 | /* That one prevents proper CRT output with LCD off */ |
1725 | #undef BACKLIGHT_DAC_OFF | 1725 | #undef BACKLIGHT_DAC_OFF |
1726 | 1726 | ||
1727 | /* Call with fb_info->bl_mutex held */ | 1727 | static int aty128_bl_update_status(struct backlight_device *bd) |
1728 | static int __aty128_bl_update_status(struct backlight_device *bd) | ||
1729 | { | 1728 | { |
1730 | struct aty128fb_par *par = class_get_devdata(&bd->class_dev); | 1729 | struct aty128fb_par *par = class_get_devdata(&bd->class_dev); |
1731 | unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL); | 1730 | unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL); |
@@ -1778,19 +1777,6 @@ static int __aty128_bl_update_status(struct backlight_device *bd) | |||
1778 | return 0; | 1777 | return 0; |
1779 | } | 1778 | } |
1780 | 1779 | ||
1781 | static int aty128_bl_update_status(struct backlight_device *bd) | ||
1782 | { | ||
1783 | struct aty128fb_par *par = class_get_devdata(&bd->class_dev); | ||
1784 | struct fb_info *info = pci_get_drvdata(par->pdev); | ||
1785 | int ret; | ||
1786 | |||
1787 | mutex_lock(&info->bl_mutex); | ||
1788 | ret = __aty128_bl_update_status(bd); | ||
1789 | mutex_unlock(&info->bl_mutex); | ||
1790 | |||
1791 | return ret; | ||
1792 | } | ||
1793 | |||
1794 | static int aty128_bl_get_brightness(struct backlight_device *bd) | 1780 | static int aty128_bl_get_brightness(struct backlight_device *bd) |
1795 | { | 1781 | { |
1796 | return bd->props->brightness; | 1782 | return bd->props->brightness; |
@@ -1804,14 +1790,10 @@ static struct backlight_properties aty128_bl_data = { | |||
1804 | 1790 | ||
1805 | static void aty128_bl_set_power(struct fb_info *info, int power) | 1791 | static void aty128_bl_set_power(struct fb_info *info, int power) |
1806 | { | 1792 | { |
1807 | mutex_lock(&info->bl_mutex); | ||
1808 | |||
1809 | if (info->bl_dev) { | 1793 | if (info->bl_dev) { |
1810 | info->bl_dev->props->power = power; | 1794 | info->bl_dev->props->power = power; |
1811 | __aty128_bl_update_status(info->bl_dev); | 1795 | backlight_update_status(info->bl_dev); |
1812 | } | 1796 | } |
1813 | |||
1814 | mutex_unlock(&info->bl_mutex); | ||
1815 | } | 1797 | } |
1816 | 1798 | ||
1817 | static void aty128_bl_init(struct aty128fb_par *par) | 1799 | static void aty128_bl_init(struct aty128fb_par *par) |
@@ -1838,12 +1820,10 @@ static void aty128_bl_init(struct aty128fb_par *par) | |||
1838 | goto error; | 1820 | goto error; |
1839 | } | 1821 | } |
1840 | 1822 | ||
1841 | mutex_lock(&info->bl_mutex); | ||
1842 | info->bl_dev = bd; | 1823 | info->bl_dev = bd; |
1843 | fb_bl_default_curve(info, 0, | 1824 | fb_bl_default_curve(info, 0, |
1844 | 63 * FB_BACKLIGHT_MAX / MAX_LEVEL, | 1825 | 63 * FB_BACKLIGHT_MAX / MAX_LEVEL, |
1845 | 219 * FB_BACKLIGHT_MAX / MAX_LEVEL); | 1826 | 219 * FB_BACKLIGHT_MAX / MAX_LEVEL); |
1846 | mutex_unlock(&info->bl_mutex); | ||
1847 | 1827 | ||
1848 | bd->props->brightness = aty128_bl_data.max_brightness; | 1828 | bd->props->brightness = aty128_bl_data.max_brightness; |
1849 | bd->props->power = FB_BLANK_UNBLANK; | 1829 | bd->props->power = FB_BLANK_UNBLANK; |
@@ -1864,31 +1844,19 @@ error: | |||
1864 | return; | 1844 | return; |
1865 | } | 1845 | } |
1866 | 1846 | ||
1867 | static void aty128_bl_exit(struct aty128fb_par *par) | 1847 | static void aty128_bl_exit(struct backlight_device *bd) |
1868 | { | 1848 | { |
1869 | struct fb_info *info = pci_get_drvdata(par->pdev); | 1849 | if (bd) { |
1870 | |||
1871 | #ifdef CONFIG_PMAC_BACKLIGHT | 1850 | #ifdef CONFIG_PMAC_BACKLIGHT |
1872 | mutex_lock(&pmac_backlight_mutex); | 1851 | mutex_lock(&pmac_backlight_mutex); |
1873 | #endif | 1852 | if (pmac_backlight == bd) |
1874 | |||
1875 | mutex_lock(&info->bl_mutex); | ||
1876 | if (info->bl_dev) { | ||
1877 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
1878 | if (pmac_backlight == info->bl_dev) | ||
1879 | pmac_backlight = NULL; | 1853 | pmac_backlight = NULL; |
1854 | mutex_unlock(&pmac_backlight_mutex); | ||
1880 | #endif | 1855 | #endif |
1881 | 1856 | backlight_device_unregister(bd); | |
1882 | backlight_device_unregister(info->bl_dev); | ||
1883 | info->bl_dev = NULL; | ||
1884 | 1857 | ||
1885 | printk("aty128: Backlight unloaded\n"); | 1858 | printk("aty128: Backlight unloaded\n"); |
1886 | } | 1859 | } |
1887 | mutex_unlock(&info->bl_mutex); | ||
1888 | |||
1889 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
1890 | mutex_unlock(&pmac_backlight_mutex); | ||
1891 | #endif | ||
1892 | } | 1860 | } |
1893 | #endif /* CONFIG_FB_ATY128_BACKLIGHT */ | 1861 | #endif /* CONFIG_FB_ATY128_BACKLIGHT */ |
1894 | 1862 | ||
@@ -2175,11 +2143,12 @@ static void __devexit aty128_remove(struct pci_dev *pdev) | |||
2175 | 2143 | ||
2176 | par = info->par; | 2144 | par = info->par; |
2177 | 2145 | ||
2146 | unregister_framebuffer(info); | ||
2147 | |||
2178 | #ifdef CONFIG_FB_ATY128_BACKLIGHT | 2148 | #ifdef CONFIG_FB_ATY128_BACKLIGHT |
2179 | aty128_bl_exit(par); | 2149 | aty128_bl_exit(info->bl_dev); |
2180 | #endif | 2150 | #endif |
2181 | 2151 | ||
2182 | unregister_framebuffer(info); | ||
2183 | #ifdef CONFIG_MTRR | 2152 | #ifdef CONFIG_MTRR |
2184 | if (par->mtrr.vram_valid) | 2153 | if (par->mtrr.vram_valid) |
2185 | mtrr_del(par->mtrr.vram, info->fix.smem_start, | 2154 | mtrr_del(par->mtrr.vram, info->fix.smem_start, |
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 3b6529392359..66462286e704 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -2116,13 +2116,13 @@ static int atyfb_pci_resume(struct pci_dev *pdev) | |||
2116 | 2116 | ||
2117 | static struct backlight_properties aty_bl_data; | 2117 | static struct backlight_properties aty_bl_data; |
2118 | 2118 | ||
2119 | /* Call with fb_info->bl_mutex held */ | ||
2120 | static int aty_bl_get_level_brightness(struct atyfb_par *par, int level) | 2119 | static int aty_bl_get_level_brightness(struct atyfb_par *par, int level) |
2121 | { | 2120 | { |
2122 | struct fb_info *info = pci_get_drvdata(par->pdev); | 2121 | struct fb_info *info = pci_get_drvdata(par->pdev); |
2123 | int atylevel; | 2122 | int atylevel; |
2124 | 2123 | ||
2125 | /* Get and convert the value */ | 2124 | /* Get and convert the value */ |
2125 | /* No locking of bl_curve since we read a single value */ | ||
2126 | atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL; | 2126 | atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL; |
2127 | 2127 | ||
2128 | if (atylevel < 0) | 2128 | if (atylevel < 0) |
@@ -2133,8 +2133,7 @@ static int aty_bl_get_level_brightness(struct atyfb_par *par, int level) | |||
2133 | return atylevel; | 2133 | return atylevel; |
2134 | } | 2134 | } |
2135 | 2135 | ||
2136 | /* Call with fb_info->bl_mutex held */ | 2136 | static int aty_bl_update_status(struct backlight_device *bd) |
2137 | static int __aty_bl_update_status(struct backlight_device *bd) | ||
2138 | { | 2137 | { |
2139 | struct atyfb_par *par = class_get_devdata(&bd->class_dev); | 2138 | struct atyfb_par *par = class_get_devdata(&bd->class_dev); |
2140 | unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par); | 2139 | unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par); |
@@ -2159,19 +2158,6 @@ static int __aty_bl_update_status(struct backlight_device *bd) | |||
2159 | return 0; | 2158 | return 0; |
2160 | } | 2159 | } |
2161 | 2160 | ||
2162 | static int aty_bl_update_status(struct backlight_device *bd) | ||
2163 | { | ||
2164 | struct atyfb_par *par = class_get_devdata(&bd->class_dev); | ||
2165 | struct fb_info *info = pci_get_drvdata(par->pdev); | ||
2166 | int ret; | ||
2167 | |||
2168 | mutex_lock(&info->bl_mutex); | ||
2169 | ret = __aty_bl_update_status(bd); | ||
2170 | mutex_unlock(&info->bl_mutex); | ||
2171 | |||
2172 | return ret; | ||
2173 | } | ||
2174 | |||
2175 | static int aty_bl_get_brightness(struct backlight_device *bd) | 2161 | static int aty_bl_get_brightness(struct backlight_device *bd) |
2176 | { | 2162 | { |
2177 | return bd->props->brightness; | 2163 | return bd->props->brightness; |
@@ -2203,12 +2189,10 @@ static void aty_bl_init(struct atyfb_par *par) | |||
2203 | goto error; | 2189 | goto error; |
2204 | } | 2190 | } |
2205 | 2191 | ||
2206 | mutex_lock(&info->bl_mutex); | ||
2207 | info->bl_dev = bd; | 2192 | info->bl_dev = bd; |
2208 | fb_bl_default_curve(info, 0, | 2193 | fb_bl_default_curve(info, 0, |
2209 | 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL, | 2194 | 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL, |
2210 | 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); | 2195 | 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); |
2211 | mutex_unlock(&info->bl_mutex); | ||
2212 | 2196 | ||
2213 | bd->props->brightness = aty_bl_data.max_brightness; | 2197 | bd->props->brightness = aty_bl_data.max_brightness; |
2214 | bd->props->power = FB_BLANK_UNBLANK; | 2198 | bd->props->power = FB_BLANK_UNBLANK; |
@@ -2229,30 +2213,19 @@ error: | |||
2229 | return; | 2213 | return; |
2230 | } | 2214 | } |
2231 | 2215 | ||
2232 | static void aty_bl_exit(struct atyfb_par *par) | 2216 | static void aty_bl_exit(struct backlight_device *bd) |
2233 | { | 2217 | { |
2234 | struct fb_info *info = pci_get_drvdata(par->pdev); | 2218 | if (bd) { |
2235 | |||
2236 | #ifdef CONFIG_PMAC_BACKLIGHT | 2219 | #ifdef CONFIG_PMAC_BACKLIGHT |
2237 | mutex_lock(&pmac_backlight_mutex); | 2220 | mutex_lock(&pmac_backlight_mutex); |
2238 | #endif | 2221 | if (pmac_backlight == bd) |
2239 | |||
2240 | mutex_lock(&info->bl_mutex); | ||
2241 | if (info->bl_dev) { | ||
2242 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
2243 | if (pmac_backlight == info->bl_dev) | ||
2244 | pmac_backlight = NULL; | 2222 | pmac_backlight = NULL; |
2223 | mutex_unlock(&pmac_backlight_mutex); | ||
2245 | #endif | 2224 | #endif |
2246 | 2225 | backlight_device_unregister(bd); | |
2247 | backlight_device_unregister(info->bl_dev); | ||
2248 | 2226 | ||
2249 | printk("aty: Backlight unloaded\n"); | 2227 | printk("aty: Backlight unloaded\n"); |
2250 | } | 2228 | } |
2251 | mutex_unlock(&info->bl_mutex); | ||
2252 | |||
2253 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
2254 | mutex_unlock(&pmac_backlight_mutex); | ||
2255 | #endif | ||
2256 | } | 2229 | } |
2257 | 2230 | ||
2258 | #endif /* CONFIG_FB_ATY_BACKLIGHT */ | 2231 | #endif /* CONFIG_FB_ATY_BACKLIGHT */ |
@@ -3705,13 +3678,13 @@ static void __devexit atyfb_remove(struct fb_info *info) | |||
3705 | aty_set_crtc(par, &saved_crtc); | 3678 | aty_set_crtc(par, &saved_crtc); |
3706 | par->pll_ops->set_pll(info, &saved_pll); | 3679 | par->pll_ops->set_pll(info, &saved_pll); |
3707 | 3680 | ||
3681 | unregister_framebuffer(info); | ||
3682 | |||
3708 | #ifdef CONFIG_FB_ATY_BACKLIGHT | 3683 | #ifdef CONFIG_FB_ATY_BACKLIGHT |
3709 | if (M64_HAS(MOBIL_BUS)) | 3684 | if (M64_HAS(MOBIL_BUS)) |
3710 | aty_bl_exit(par); | 3685 | aty_bl_exit(info->bl_dev); |
3711 | #endif | 3686 | #endif |
3712 | 3687 | ||
3713 | unregister_framebuffer(info); | ||
3714 | |||
3715 | #ifdef CONFIG_MTRR | 3688 | #ifdef CONFIG_MTRR |
3716 | if (par->mtrr_reg >= 0) { | 3689 | if (par->mtrr_reg >= 0) { |
3717 | mtrr_del(par->mtrr_reg, 0, 0); | 3690 | mtrr_del(par->mtrr_reg, 0, 0); |
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index 9cfcecac8b5e..f94e4616788d 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c | |||
@@ -29,17 +29,13 @@ struct radeon_bl_privdata { | |||
29 | static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata, | 29 | static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata, |
30 | int level) | 30 | int level) |
31 | { | 31 | { |
32 | struct fb_info *info = pdata->rinfo->info; | ||
33 | int rlevel; | 32 | int rlevel; |
34 | 33 | ||
35 | mutex_lock(&info->bl_mutex); | ||
36 | |||
37 | /* Get and convert the value */ | 34 | /* Get and convert the value */ |
35 | /* No locking of bl_curve since we read a single value */ | ||
38 | rlevel = pdata->rinfo->info->bl_curve[level] * | 36 | rlevel = pdata->rinfo->info->bl_curve[level] * |
39 | FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL; | 37 | FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL; |
40 | 38 | ||
41 | mutex_unlock(&info->bl_mutex); | ||
42 | |||
43 | if (rlevel < 0) | 39 | if (rlevel < 0) |
44 | rlevel = 0; | 40 | rlevel = 0; |
45 | else if (rlevel > MAX_RADEON_LEVEL) | 41 | else if (rlevel > MAX_RADEON_LEVEL) |
@@ -187,12 +183,10 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo) | |||
187 | machine_is_compatible("PowerBook6,5"); | 183 | machine_is_compatible("PowerBook6,5"); |
188 | #endif | 184 | #endif |
189 | 185 | ||
190 | mutex_lock(&rinfo->info->bl_mutex); | ||
191 | rinfo->info->bl_dev = bd; | 186 | rinfo->info->bl_dev = bd; |
192 | fb_bl_default_curve(rinfo->info, 0, | 187 | fb_bl_default_curve(rinfo->info, 0, |
193 | 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL, | 188 | 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL, |
194 | 217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL); | 189 | 217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL); |
195 | mutex_unlock(&rinfo->info->bl_mutex); | ||
196 | 190 | ||
197 | bd->props->brightness = radeon_bl_data.max_brightness; | 191 | bd->props->brightness = radeon_bl_data.max_brightness; |
198 | bd->props->power = FB_BLANK_UNBLANK; | 192 | bd->props->power = FB_BLANK_UNBLANK; |
@@ -216,29 +210,22 @@ error: | |||
216 | 210 | ||
217 | void radeonfb_bl_exit(struct radeonfb_info *rinfo) | 211 | void radeonfb_bl_exit(struct radeonfb_info *rinfo) |
218 | { | 212 | { |
219 | #ifdef CONFIG_PMAC_BACKLIGHT | 213 | struct backlight_device *bd = rinfo->info->bl_dev; |
220 | mutex_lock(&pmac_backlight_mutex); | ||
221 | #endif | ||
222 | 214 | ||
223 | mutex_lock(&rinfo->info->bl_mutex); | 215 | if (bd) { |
224 | if (rinfo->info->bl_dev) { | ||
225 | struct radeon_bl_privdata *pdata; | 216 | struct radeon_bl_privdata *pdata; |
226 | 217 | ||
227 | #ifdef CONFIG_PMAC_BACKLIGHT | 218 | #ifdef CONFIG_PMAC_BACKLIGHT |
228 | if (pmac_backlight == rinfo->info->bl_dev) | 219 | mutex_lock(&pmac_backlight_mutex); |
220 | if (pmac_backlight == bd) | ||
229 | pmac_backlight = NULL; | 221 | pmac_backlight = NULL; |
222 | mutex_unlock(&pmac_backlight_mutex); | ||
230 | #endif | 223 | #endif |
231 | 224 | pdata = class_get_devdata(&bd->class_dev); | |
232 | pdata = class_get_devdata(&rinfo->info->bl_dev->class_dev); | 225 | backlight_device_unregister(bd); |
233 | backlight_device_unregister(rinfo->info->bl_dev); | ||
234 | kfree(pdata); | 226 | kfree(pdata); |
235 | rinfo->info->bl_dev = NULL; | 227 | rinfo->info->bl_dev = NULL; |
236 | 228 | ||
237 | printk("radeonfb: Backlight unloaded\n"); | 229 | printk("radeonfb: Backlight unloaded\n"); |
238 | } | 230 | } |
239 | mutex_unlock(&rinfo->info->bl_mutex); | ||
240 | |||
241 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
242 | mutex_unlock(&pmac_backlight_mutex); | ||
243 | #endif | ||
244 | } | 231 | } |
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 0ed577e7cc21..7e228aded4c2 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c | |||
@@ -2393,7 +2393,6 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev) | |||
2393 | if (!rinfo) | 2393 | if (!rinfo) |
2394 | return; | 2394 | return; |
2395 | 2395 | ||
2396 | radeonfb_bl_exit(rinfo); | ||
2397 | radeonfb_pm_exit(rinfo); | 2396 | radeonfb_pm_exit(rinfo); |
2398 | 2397 | ||
2399 | if (rinfo->mon1_EDID) | 2398 | if (rinfo->mon1_EDID) |
@@ -2420,6 +2419,8 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev) | |||
2420 | 2419 | ||
2421 | unregister_framebuffer(info); | 2420 | unregister_framebuffer(info); |
2422 | 2421 | ||
2422 | radeonfb_bl_exit(rinfo); | ||
2423 | |||
2423 | iounmap(rinfo->mmio_base); | 2424 | iounmap(rinfo->mmio_base); |
2424 | iounmap(rinfo->fb_base); | 2425 | iounmap(rinfo->fb_base); |
2425 | 2426 | ||
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 818fb09105f9..40c80c8190e2 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c | |||
@@ -59,7 +59,7 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev) | |||
59 | info->device = dev; | 59 | info->device = dev; |
60 | 60 | ||
61 | #ifdef CONFIG_FB_BACKLIGHT | 61 | #ifdef CONFIG_FB_BACKLIGHT |
62 | mutex_init(&info->bl_mutex); | 62 | mutex_init(&info->bl_curve_mutex); |
63 | #endif | 63 | #endif |
64 | 64 | ||
65 | return info; | 65 | return info; |
@@ -445,10 +445,10 @@ static ssize_t store_bl_curve(struct device *device, | |||
445 | /* If there has been an error in the input data, we won't | 445 | /* If there has been an error in the input data, we won't |
446 | * reach this loop. | 446 | * reach this loop. |
447 | */ | 447 | */ |
448 | mutex_lock(&fb_info->bl_mutex); | 448 | mutex_lock(&fb_info->bl_curve_mutex); |
449 | for (i = 0; i < FB_BACKLIGHT_LEVELS; ++i) | 449 | for (i = 0; i < FB_BACKLIGHT_LEVELS; ++i) |
450 | fb_info->bl_curve[i] = tmp_curve[i]; | 450 | fb_info->bl_curve[i] = tmp_curve[i]; |
451 | mutex_unlock(&fb_info->bl_mutex); | 451 | mutex_unlock(&fb_info->bl_curve_mutex); |
452 | 452 | ||
453 | return count; | 453 | return count; |
454 | } | 454 | } |
@@ -466,7 +466,7 @@ static ssize_t show_bl_curve(struct device *device, | |||
466 | if (!fb_info || !fb_info->bl_dev) | 466 | if (!fb_info || !fb_info->bl_dev) |
467 | return -ENODEV; | 467 | return -ENODEV; |
468 | 468 | ||
469 | mutex_lock(&fb_info->bl_mutex); | 469 | mutex_lock(&fb_info->bl_curve_mutex); |
470 | for (i = 0; i < FB_BACKLIGHT_LEVELS; i += 8) | 470 | for (i = 0; i < FB_BACKLIGHT_LEVELS; i += 8) |
471 | len += snprintf(&buf[len], PAGE_SIZE, | 471 | len += snprintf(&buf[len], PAGE_SIZE, |
472 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | 472 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", |
@@ -478,7 +478,7 @@ static ssize_t show_bl_curve(struct device *device, | |||
478 | fb_info->bl_curve[i + 5], | 478 | fb_info->bl_curve[i + 5], |
479 | fb_info->bl_curve[i + 6], | 479 | fb_info->bl_curve[i + 6], |
480 | fb_info->bl_curve[i + 7]); | 480 | fb_info->bl_curve[i + 7]); |
481 | mutex_unlock(&fb_info->bl_mutex); | 481 | mutex_unlock(&fb_info->bl_curve_mutex); |
482 | 482 | ||
483 | return len; | 483 | return len; |
484 | } | 484 | } |
@@ -552,6 +552,8 @@ void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 max) | |||
552 | { | 552 | { |
553 | unsigned int i, flat, count, range = (max - min); | 553 | unsigned int i, flat, count, range = (max - min); |
554 | 554 | ||
555 | mutex_lock(&fb_info->bl_curve_mutex); | ||
556 | |||
555 | fb_info->bl_curve[0] = off; | 557 | fb_info->bl_curve[0] = off; |
556 | 558 | ||
557 | for (flat = 1; flat < (FB_BACKLIGHT_LEVELS / 16); ++flat) | 559 | for (flat = 1; flat < (FB_BACKLIGHT_LEVELS / 16); ++flat) |
@@ -560,6 +562,8 @@ void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 max) | |||
560 | count = FB_BACKLIGHT_LEVELS * 15 / 16; | 562 | count = FB_BACKLIGHT_LEVELS * 15 / 16; |
561 | for (i = 0; i < count; ++i) | 563 | for (i = 0; i < count; ++i) |
562 | fb_info->bl_curve[flat + i] = min + (range * (i + 1) / count); | 564 | fb_info->bl_curve[flat + i] = min + (range * (i + 1) / count); |
565 | |||
566 | mutex_unlock(&fb_info->bl_curve_mutex); | ||
563 | } | 567 | } |
564 | EXPORT_SYMBOL_GPL(fb_bl_default_curve); | 568 | EXPORT_SYMBOL_GPL(fb_bl_default_curve); |
565 | #endif | 569 | #endif |
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c index 695b6bf54d92..2bebfeeb4f1d 100644 --- a/drivers/video/nvidia/nv_backlight.c +++ b/drivers/video/nvidia/nv_backlight.c | |||
@@ -30,7 +30,6 @@ | |||
30 | 30 | ||
31 | static struct backlight_properties nvidia_bl_data; | 31 | static struct backlight_properties nvidia_bl_data; |
32 | 32 | ||
33 | /* Call with fb_info->bl_mutex held */ | ||
34 | static int nvidia_bl_get_level_brightness(struct nvidia_par *par, | 33 | static int nvidia_bl_get_level_brightness(struct nvidia_par *par, |
35 | int level) | 34 | int level) |
36 | { | 35 | { |
@@ -38,6 +37,7 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par *par, | |||
38 | int nlevel; | 37 | int nlevel; |
39 | 38 | ||
40 | /* Get and convert the value */ | 39 | /* Get and convert the value */ |
40 | /* No locking of bl_curve since we read a single value */ | ||
41 | nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP; | 41 | nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP; |
42 | 42 | ||
43 | if (nlevel < 0) | 43 | if (nlevel < 0) |
@@ -50,8 +50,7 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par *par, | |||
50 | return nlevel; | 50 | return nlevel; |
51 | } | 51 | } |
52 | 52 | ||
53 | /* Call with fb_info->bl_mutex held */ | 53 | static int nvidia_bl_update_status(struct backlight_device *bd) |
54 | static int __nvidia_bl_update_status(struct backlight_device *bd) | ||
55 | { | 54 | { |
56 | struct nvidia_par *par = class_get_devdata(&bd->class_dev); | 55 | struct nvidia_par *par = class_get_devdata(&bd->class_dev); |
57 | u32 tmp_pcrt, tmp_pmc, fpcontrol; | 56 | u32 tmp_pcrt, tmp_pmc, fpcontrol; |
@@ -85,19 +84,6 @@ static int __nvidia_bl_update_status(struct backlight_device *bd) | |||
85 | return 0; | 84 | return 0; |
86 | } | 85 | } |
87 | 86 | ||
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 | |||
101 | static int nvidia_bl_get_brightness(struct backlight_device *bd) | 87 | static int nvidia_bl_get_brightness(struct backlight_device *bd) |
102 | { | 88 | { |
103 | return bd->props->brightness; | 89 | return bd->props->brightness; |
@@ -133,12 +119,10 @@ void nvidia_bl_init(struct nvidia_par *par) | |||
133 | goto error; | 119 | goto error; |
134 | } | 120 | } |
135 | 121 | ||
136 | mutex_lock(&info->bl_mutex); | ||
137 | info->bl_dev = bd; | 122 | info->bl_dev = bd; |
138 | fb_bl_default_curve(info, 0, | 123 | fb_bl_default_curve(info, 0, |
139 | 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL, | 124 | 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL, |
140 | 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL); | 125 | 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL); |
141 | mutex_unlock(&info->bl_mutex); | ||
142 | 126 | ||
143 | bd->props->brightness = nvidia_bl_data.max_brightness; | 127 | bd->props->brightness = nvidia_bl_data.max_brightness; |
144 | bd->props->power = FB_BLANK_UNBLANK; | 128 | bd->props->power = FB_BLANK_UNBLANK; |
@@ -162,25 +146,17 @@ error: | |||
162 | void nvidia_bl_exit(struct nvidia_par *par) | 146 | void nvidia_bl_exit(struct nvidia_par *par) |
163 | { | 147 | { |
164 | struct fb_info *info = pci_get_drvdata(par->pci_dev); | 148 | struct fb_info *info = pci_get_drvdata(par->pci_dev); |
149 | struct backlight_device *bd = info->bl_dev; | ||
165 | 150 | ||
151 | if (bd) { | ||
166 | #ifdef CONFIG_PMAC_BACKLIGHT | 152 | #ifdef CONFIG_PMAC_BACKLIGHT |
167 | mutex_lock(&pmac_backlight_mutex); | 153 | mutex_lock(&pmac_backlight_mutex); |
168 | #endif | 154 | if (pmac_backlight == bd) |
169 | |||
170 | mutex_lock(&info->bl_mutex); | ||
171 | if (info->bl_dev) { | ||
172 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
173 | if (pmac_backlight == info->bl_dev) | ||
174 | pmac_backlight = NULL; | 155 | pmac_backlight = NULL; |
156 | mutex_unlock(&pmac_backlight_mutex); | ||
175 | #endif | 157 | #endif |
176 | 158 | backlight_device_unregister(bd); | |
177 | backlight_device_unregister(info->bl_dev); | ||
178 | 159 | ||
179 | printk("nvidia: Backlight unloaded\n"); | 160 | printk("nvidia: Backlight unloaded\n"); |
180 | } | 161 | } |
181 | mutex_unlock(&info->bl_mutex); | ||
182 | |||
183 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
184 | mutex_unlock(&pmac_backlight_mutex); | ||
185 | #endif | ||
186 | } | 162 | } |
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 64f59119c422..c18e9557ca30 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
@@ -1350,9 +1350,10 @@ static void __devexit nvidiafb_remove(struct pci_dev *pd) | |||
1350 | 1350 | ||
1351 | NVTRACE_ENTER(); | 1351 | NVTRACE_ENTER(); |
1352 | 1352 | ||
1353 | unregister_framebuffer(info); | ||
1354 | |||
1353 | nvidia_bl_exit(par); | 1355 | nvidia_bl_exit(par); |
1354 | 1356 | ||
1355 | unregister_framebuffer(info); | ||
1356 | #ifdef CONFIG_MTRR | 1357 | #ifdef CONFIG_MTRR |
1357 | if (par->mtrr.vram_valid) | 1358 | if (par->mtrr.vram_valid) |
1358 | mtrr_del(par->mtrr.vram, info->fix.smem_start, | 1359 | mtrr_del(par->mtrr.vram, info->fix.smem_start, |
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 9e7d3fcde207..ab00350907dd 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c | |||
@@ -282,7 +282,6 @@ static const struct riva_regs reg_template = { | |||
282 | 282 | ||
283 | static struct backlight_properties riva_bl_data; | 283 | static struct backlight_properties riva_bl_data; |
284 | 284 | ||
285 | /* Call with fb_info->bl_mutex held */ | ||
286 | static int riva_bl_get_level_brightness(struct riva_par *par, | 285 | static int riva_bl_get_level_brightness(struct riva_par *par, |
287 | int level) | 286 | int level) |
288 | { | 287 | { |
@@ -290,6 +289,7 @@ static int riva_bl_get_level_brightness(struct riva_par *par, | |||
290 | int nlevel; | 289 | int nlevel; |
291 | 290 | ||
292 | /* Get and convert the value */ | 291 | /* Get and convert the value */ |
292 | /* No locking on bl_curve since accessing a single value */ | ||
293 | nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP; | 293 | nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP; |
294 | 294 | ||
295 | if (nlevel < 0) | 295 | if (nlevel < 0) |
@@ -302,8 +302,7 @@ static int riva_bl_get_level_brightness(struct riva_par *par, | |||
302 | return nlevel; | 302 | return nlevel; |
303 | } | 303 | } |
304 | 304 | ||
305 | /* Call with fb_info->bl_mutex held */ | 305 | static int riva_bl_update_status(struct backlight_device *bd) |
306 | static int __riva_bl_update_status(struct backlight_device *bd) | ||
307 | { | 306 | { |
308 | struct riva_par *par = class_get_devdata(&bd->class_dev); | 307 | struct riva_par *par = class_get_devdata(&bd->class_dev); |
309 | U032 tmp_pcrt, tmp_pmc; | 308 | U032 tmp_pcrt, tmp_pmc; |
@@ -328,19 +327,6 @@ static int __riva_bl_update_status(struct backlight_device *bd) | |||
328 | return 0; | 327 | return 0; |
329 | } | 328 | } |
330 | 329 | ||
331 | static int riva_bl_update_status(struct backlight_device *bd) | ||
332 | { | ||
333 | struct riva_par *par = class_get_devdata(&bd->class_dev); | ||
334 | struct fb_info *info = pci_get_drvdata(par->pdev); | ||
335 | int ret; | ||
336 | |||
337 | mutex_lock(&info->bl_mutex); | ||
338 | ret = __riva_bl_update_status(bd); | ||
339 | mutex_unlock(&info->bl_mutex); | ||
340 | |||
341 | return ret; | ||
342 | } | ||
343 | |||
344 | static int riva_bl_get_brightness(struct backlight_device *bd) | 330 | static int riva_bl_get_brightness(struct backlight_device *bd) |
345 | { | 331 | { |
346 | return bd->props->brightness; | 332 | return bd->props->brightness; |
@@ -376,12 +362,10 @@ static void riva_bl_init(struct riva_par *par) | |||
376 | goto error; | 362 | goto error; |
377 | } | 363 | } |
378 | 364 | ||
379 | mutex_lock(&info->bl_mutex); | ||
380 | info->bl_dev = bd; | 365 | info->bl_dev = bd; |
381 | fb_bl_default_curve(info, 0, | 366 | fb_bl_default_curve(info, 0, |
382 | MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL, | 367 | MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL, |
383 | FB_BACKLIGHT_MAX); | 368 | FB_BACKLIGHT_MAX); |
384 | mutex_unlock(&info->bl_mutex); | ||
385 | 369 | ||
386 | bd->props->brightness = riva_bl_data.max_brightness; | 370 | bd->props->brightness = riva_bl_data.max_brightness; |
387 | bd->props->power = FB_BLANK_UNBLANK; | 371 | bd->props->power = FB_BLANK_UNBLANK; |
@@ -402,34 +386,25 @@ error: | |||
402 | return; | 386 | return; |
403 | } | 387 | } |
404 | 388 | ||
405 | static void riva_bl_exit(struct riva_par *par) | 389 | static void riva_bl_exit(struct fb_info *info) |
406 | { | 390 | { |
407 | struct fb_info *info = pci_get_drvdata(par->pdev); | 391 | struct backlight_device *bd = info->bl_dev; |
408 | 392 | ||
393 | if (bd) { | ||
409 | #ifdef CONFIG_PMAC_BACKLIGHT | 394 | #ifdef CONFIG_PMAC_BACKLIGHT |
410 | mutex_lock(&pmac_backlight_mutex); | 395 | mutex_lock(&pmac_backlight_mutex); |
411 | #endif | 396 | if (pmac_backlight == bd) |
412 | |||
413 | mutex_lock(&info->bl_mutex); | ||
414 | if (info->bl_dev) { | ||
415 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
416 | if (pmac_backlight == info->bl_dev) | ||
417 | pmac_backlight = NULL; | 397 | pmac_backlight = NULL; |
398 | mutex_unlock(&pmac_backlight_mutex); | ||
418 | #endif | 399 | #endif |
419 | 400 | backlight_device_unregister(bd); | |
420 | backlight_device_unregister(info->bl_dev); | ||
421 | 401 | ||
422 | printk("riva: Backlight unloaded\n"); | 402 | printk("riva: Backlight unloaded\n"); |
423 | } | 403 | } |
424 | mutex_unlock(&info->bl_mutex); | ||
425 | |||
426 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
427 | mutex_unlock(&pmac_backlight_mutex); | ||
428 | #endif | ||
429 | } | 404 | } |
430 | #else | 405 | #else |
431 | static inline void riva_bl_init(struct riva_par *par) {} | 406 | static inline void riva_bl_init(struct riva_par *par) {} |
432 | static inline void riva_bl_exit(struct riva_par *par) {} | 407 | static inline void riva_bl_exit(struct fb_info *info) {} |
433 | #endif /* CONFIG_FB_RIVA_BACKLIGHT */ | 408 | #endif /* CONFIG_FB_RIVA_BACKLIGHT */ |
434 | 409 | ||
435 | /* ------------------------------------------------------------------------- * | 410 | /* ------------------------------------------------------------------------- * |
@@ -2146,14 +2121,15 @@ static void __exit rivafb_remove(struct pci_dev *pd) | |||
2146 | 2121 | ||
2147 | NVTRACE_ENTER(); | 2122 | NVTRACE_ENTER(); |
2148 | 2123 | ||
2149 | riva_bl_exit(par); | ||
2150 | |||
2151 | #ifdef CONFIG_FB_RIVA_I2C | 2124 | #ifdef CONFIG_FB_RIVA_I2C |
2152 | riva_delete_i2c_busses(par); | 2125 | riva_delete_i2c_busses(par); |
2153 | kfree(par->EDID); | 2126 | kfree(par->EDID); |
2154 | #endif | 2127 | #endif |
2155 | 2128 | ||
2156 | unregister_framebuffer(info); | 2129 | unregister_framebuffer(info); |
2130 | |||
2131 | riva_bl_exit(info); | ||
2132 | |||
2157 | #ifdef CONFIG_MTRR | 2133 | #ifdef CONFIG_MTRR |
2158 | if (par->mtrr.vram_valid) | 2134 | if (par->mtrr.vram_valid) |
2159 | mtrr_del(par->mtrr.vram, info->fix.smem_start, | 2135 | mtrr_del(par->mtrr.vram, info->fix.smem_start, |
diff --git a/include/linux/fb.h b/include/linux/fb.h index bf7158b59b25..be913ec87169 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h | |||
@@ -769,16 +769,13 @@ struct fb_info { | |||
769 | struct fb_videomode *mode; /* current mode */ | 769 | struct fb_videomode *mode; /* current mode */ |
770 | 770 | ||
771 | #ifdef CONFIG_FB_BACKLIGHT | 771 | #ifdef CONFIG_FB_BACKLIGHT |
772 | /* Lock ordering: | ||
773 | * bl_mutex (protects bl_dev and bl_curve) | ||
774 | * bl_dev->sem (backlight class) | ||
775 | */ | ||
776 | struct mutex bl_mutex; | ||
777 | |||
778 | /* assigned backlight device */ | 772 | /* assigned backlight device */ |
773 | /* set before framebuffer registration, | ||
774 | remove after unregister */ | ||
779 | struct backlight_device *bl_dev; | 775 | struct backlight_device *bl_dev; |
780 | 776 | ||
781 | /* Backlight level curve */ | 777 | /* Backlight level curve */ |
778 | struct mutex bl_curve_mutex; | ||
782 | u8 bl_curve[FB_BACKLIGHT_LEVELS]; | 779 | u8 bl_curve[FB_BACKLIGHT_LEVELS]; |
783 | #endif | 780 | #endif |
784 | 781 | ||