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>
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 3b65293..6646228 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2116,13 +2116,13 @@
static struct backlight_properties aty_bl_data;
-/* Call with fb_info->bl_mutex held */
static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
{
struct fb_info *info = pci_get_drvdata(par->pdev);
int atylevel;
/* Get and convert the value */
+ /* No locking of bl_curve since we read a single value */
atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
if (atylevel < 0)
@@ -2133,8 +2133,7 @@
return atylevel;
}
-/* Call with fb_info->bl_mutex held */
-static int __aty_bl_update_status(struct backlight_device *bd)
+static int aty_bl_update_status(struct backlight_device *bd)
{
struct atyfb_par *par = class_get_devdata(&bd->class_dev);
unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par);
@@ -2159,19 +2158,6 @@
return 0;
}
-static int aty_bl_update_status(struct backlight_device *bd)
-{
- struct atyfb_par *par = class_get_devdata(&bd->class_dev);
- struct fb_info *info = pci_get_drvdata(par->pdev);
- int ret;
-
- mutex_lock(&info->bl_mutex);
- ret = __aty_bl_update_status(bd);
- mutex_unlock(&info->bl_mutex);
-
- return ret;
-}
-
static int aty_bl_get_brightness(struct backlight_device *bd)
{
return bd->props->brightness;
@@ -2203,12 +2189,10 @@
goto error;
}
- mutex_lock(&info->bl_mutex);
info->bl_dev = bd;
fb_bl_default_curve(info, 0,
0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
- mutex_unlock(&info->bl_mutex);
bd->props->brightness = aty_bl_data.max_brightness;
bd->props->power = FB_BLANK_UNBLANK;
@@ -2229,30 +2213,19 @@
return;
}
-static void aty_bl_exit(struct atyfb_par *par)
+static void aty_bl_exit(struct backlight_device *bd)
{
- struct fb_info *info = pci_get_drvdata(par->pdev);
-
+ if (bd) {
#ifdef CONFIG_PMAC_BACKLIGHT
- mutex_lock(&pmac_backlight_mutex);
-#endif
-
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
-#ifdef CONFIG_PMAC_BACKLIGHT
- if (pmac_backlight == info->bl_dev)
+ mutex_lock(&pmac_backlight_mutex);
+ if (pmac_backlight == bd)
pmac_backlight = NULL;
+ mutex_unlock(&pmac_backlight_mutex);
#endif
-
- backlight_device_unregister(info->bl_dev);
+ backlight_device_unregister(bd);
printk("aty: Backlight unloaded\n");
}
- mutex_unlock(&info->bl_mutex);
-
-#ifdef CONFIG_PMAC_BACKLIGHT
- mutex_unlock(&pmac_backlight_mutex);
-#endif
}
#endif /* CONFIG_FB_ATY_BACKLIGHT */
@@ -3705,13 +3678,13 @@
aty_set_crtc(par, &saved_crtc);
par->pll_ops->set_pll(info, &saved_pll);
+ unregister_framebuffer(info);
+
#ifdef CONFIG_FB_ATY_BACKLIGHT
if (M64_HAS(MOBIL_BUS))
- aty_bl_exit(par);
+ aty_bl_exit(info->bl_dev);
#endif
- unregister_framebuffer(info);
-
#ifdef CONFIG_MTRR
if (par->mtrr_reg >= 0) {
mtrr_del(par->mtrr_reg, 0, 0);