aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@rpsys.net>2007-02-10 09:10:33 -0500
committerRichard Purdie <rpurdie@rpsys.net>2007-02-20 03:38:46 -0500
commit37ce69a57ff217a4ca0871e9ee5aa58c052b7d86 (patch)
tree21cdbb8c988eed585437bb502ca15c2998ea7fbc
parentb5c6916b3118d4301dc2f8cf8d33f13e5324a3a5 (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.c55
-rw-r--r--drivers/video/aty/atyfb_base.c49
-rw-r--r--drivers/video/aty/radeon_backlight.c29
-rw-r--r--drivers/video/aty/radeon_base.c3
-rw-r--r--drivers/video/fbsysfs.c14
-rw-r--r--drivers/video/nvidia/nv_backlight.c40
-rw-r--r--drivers/video/nvidia/nvidia.c3
-rw-r--r--drivers/video/riva/fbdev.c50
-rw-r--r--include/linux/fb.h9
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
1698static struct backlight_properties aty128_bl_data; 1698static struct backlight_properties aty128_bl_data;
1699 1699
1700/* Call with fb_info->bl_mutex held */
1701static int aty128_bl_get_level_brightness(struct aty128fb_par *par, 1700static 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 */ 1727static int aty128_bl_update_status(struct backlight_device *bd)
1728static 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
1781static 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
1794static int aty128_bl_get_brightness(struct backlight_device *bd) 1780static 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
1805static void aty128_bl_set_power(struct fb_info *info, int power) 1791static 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
1817static void aty128_bl_init(struct aty128fb_par *par) 1799static 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
1867static void aty128_bl_exit(struct aty128fb_par *par) 1847static 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
2117static struct backlight_properties aty_bl_data; 2117static struct backlight_properties aty_bl_data;
2118 2118
2119/* Call with fb_info->bl_mutex held */
2120static int aty_bl_get_level_brightness(struct atyfb_par *par, int level) 2119static 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 */ 2136static int aty_bl_update_status(struct backlight_device *bd)
2137static 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
2162static 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
2175static int aty_bl_get_brightness(struct backlight_device *bd) 2161static 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
2232static void aty_bl_exit(struct atyfb_par *par) 2216static 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 {
29static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata, 29static 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
217void radeonfb_bl_exit(struct radeonfb_info *rinfo) 211void 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}
564EXPORT_SYMBOL_GPL(fb_bl_default_curve); 568EXPORT_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
31static struct backlight_properties nvidia_bl_data; 31static struct backlight_properties nvidia_bl_data;
32 32
33/* Call with fb_info->bl_mutex held */
34static int nvidia_bl_get_level_brightness(struct nvidia_par *par, 33static 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 */ 53static int nvidia_bl_update_status(struct backlight_device *bd)
54static 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
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
101static int nvidia_bl_get_brightness(struct backlight_device *bd) 87static 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:
162void nvidia_bl_exit(struct nvidia_par *par) 146void 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
283static struct backlight_properties riva_bl_data; 283static struct backlight_properties riva_bl_data;
284 284
285/* Call with fb_info->bl_mutex held */
286static int riva_bl_get_level_brightness(struct riva_par *par, 285static 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 */ 305static int riva_bl_update_status(struct backlight_device *bd)
306static 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
331static 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
344static int riva_bl_get_brightness(struct backlight_device *bd) 330static 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
405static void riva_bl_exit(struct riva_par *par) 389static 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
431static inline void riva_bl_init(struct riva_par *par) {} 406static inline void riva_bl_init(struct riva_par *par) {}
432static inline void riva_bl_exit(struct riva_par *par) {} 407static 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