Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=37ce69a57ff217a4ca0871e9ee5aa58c052b7d86
Commit:     37ce69a57ff217a4ca0871e9ee5aa58c052b7d86
Parent:     b5c6916b3118d4301dc2f8cf8d33f13e5324a3a5
Author:     Richard Purdie <[EMAIL PROTECTED]>
AuthorDate: Sat Feb 10 14:10:33 2007 +0000
Committer:  Richard Purdie <[EMAIL PROTECTED]>
CommitDate: Tue Feb 20 08:38:46 2007 +0000

    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 <[EMAIL PROTECTED]>
---
 drivers/video/aty/aty128fb.c         |   55 +++++++--------------------------
 drivers/video/aty/atyfb_base.c       |   49 +++++++-----------------------
 drivers/video/aty/radeon_backlight.c |   29 +++++-------------
 drivers/video/aty/radeon_base.c      |    3 +-
 drivers/video/fbsysfs.c              |   14 +++++---
 drivers/video/nvidia/nv_backlight.c  |   40 +++++-------------------
 drivers/video/nvidia/nvidia.c        |    3 +-
 drivers/video/riva/fbdev.c           |   50 ++++++++-----------------------
 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 1c77cfb..ef3e786 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1697,7 +1697,6 @@ static int __devinit aty128fb_setup(char *options)
 
 static struct backlight_properties aty128_bl_data;
 
-/* Call with fb_info->bl_mutex held */
 static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
                int level)
 {
@@ -1705,6 +1704,7 @@ static int aty128_bl_get_level_brightness(struct 
aty128fb_par *par,
        int atylevel;
 
        /* Get and convert the value */
+       /* No locking of bl_curve since we read a single value */
        atylevel = MAX_LEVEL -
                (info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL);
 
@@ -1724,8 +1724,7 @@ static int aty128_bl_get_level_brightness(struct 
aty128fb_par *par,
 /* That one prevents proper CRT output with LCD off */
 #undef BACKLIGHT_DAC_OFF
 
-/* Call with fb_info->bl_mutex held */
-static int __aty128_bl_update_status(struct backlight_device *bd)
+static int aty128_bl_update_status(struct backlight_device *bd)
 {
        struct aty128fb_par *par = class_get_devdata(&bd->class_dev);
        unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
@@ -1778,19 +1777,6 @@ static int __aty128_bl_update_status(struct 
backlight_device *bd)
        return 0;
 }
 
-static int aty128_bl_update_status(struct backlight_device *bd)
-{
-       struct aty128fb_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 = __aty128_bl_update_status(bd);
-       mutex_unlock(&info->bl_mutex);
-
-       return ret;
-}
-
 static int aty128_bl_get_brightness(struct backlight_device *bd)
 {
        return bd->props->brightness;
@@ -1804,14 +1790,10 @@ static struct backlight_properties aty128_bl_data = {
 
 static void aty128_bl_set_power(struct fb_info *info, int power)
 {
-       mutex_lock(&info->bl_mutex);
-
        if (info->bl_dev) {
                info->bl_dev->props->power = power;
-               __aty128_bl_update_status(info->bl_dev);
+               backlight_update_status(info->bl_dev);
        }
-
-       mutex_unlock(&info->bl_mutex);
 }
 
 static void aty128_bl_init(struct aty128fb_par *par)
@@ -1838,12 +1820,10 @@ static void aty128_bl_init(struct aty128fb_par *par)
                goto error;
        }
 
-       mutex_lock(&info->bl_mutex);
        info->bl_dev = bd;
        fb_bl_default_curve(info, 0,
                 63 * FB_BACKLIGHT_MAX / MAX_LEVEL,
                219 * FB_BACKLIGHT_MAX / MAX_LEVEL);
-       mutex_unlock(&info->bl_mutex);
 
        bd->props->brightness = aty128_bl_data.max_brightness;
        bd->props->power = FB_BLANK_UNBLANK;
@@ -1864,31 +1844,19 @@ error:
        return;
 }
 
-static void aty128_bl_exit(struct aty128fb_par *par)
+static void aty128_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);
-               info->bl_dev = NULL;
+               backlight_device_unregister(bd);
 
                printk("aty128: Backlight unloaded\n");
        }
-       mutex_unlock(&info->bl_mutex);
-
-#ifdef CONFIG_PMAC_BACKLIGHT
-       mutex_unlock(&pmac_backlight_mutex);
-#endif
 }
 #endif /* CONFIG_FB_ATY128_BACKLIGHT */
 
@@ -2175,11 +2143,12 @@ static void __devexit aty128_remove(struct pci_dev 
*pdev)
 
        par = info->par;
 
+       unregister_framebuffer(info);
+
 #ifdef CONFIG_FB_ATY128_BACKLIGHT
-       aty128_bl_exit(par);
+       aty128_bl_exit(info->bl_dev);
 #endif
 
-       unregister_framebuffer(info);
 #ifdef CONFIG_MTRR
        if (par->mtrr.vram_valid)
                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 3b65293..6646228 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)
 
 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 @@ static int aty_bl_get_level_brightness(struct atyfb_par 
*par, int level)
        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 @@ static int __aty_bl_update_status(struct 
backlight_device *bd)
        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 @@ static void aty_bl_init(struct atyfb_par *par)
                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 @@ error:
        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 @@ static void __devexit atyfb_remove(struct fb_info *info)
        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);
diff --git a/drivers/video/aty/radeon_backlight.c 
b/drivers/video/aty/radeon_backlight.c
index 9cfceca..f94e461 100644
--- a/drivers/video/aty/radeon_backlight.c
+++ b/drivers/video/aty/radeon_backlight.c
@@ -29,17 +29,13 @@ struct radeon_bl_privdata {
 static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata,
                int level)
 {
-       struct fb_info *info = pdata->rinfo->info;
        int rlevel;
 
-       mutex_lock(&info->bl_mutex);
-
        /* Get and convert the value */
+       /* No locking of bl_curve since we read a single value */
        rlevel = pdata->rinfo->info->bl_curve[level] *
                 FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL;
 
-       mutex_unlock(&info->bl_mutex);
-
        if (rlevel < 0)
                rlevel = 0;
        else if (rlevel > MAX_RADEON_LEVEL)
@@ -187,12 +183,10 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
                machine_is_compatible("PowerBook6,5");
 #endif
 
-       mutex_lock(&rinfo->info->bl_mutex);
        rinfo->info->bl_dev = bd;
        fb_bl_default_curve(rinfo->info, 0,
                 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL,
                217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL);
-       mutex_unlock(&rinfo->info->bl_mutex);
 
        bd->props->brightness = radeon_bl_data.max_brightness;
        bd->props->power = FB_BLANK_UNBLANK;
@@ -216,29 +210,22 @@ error:
 
 void radeonfb_bl_exit(struct radeonfb_info *rinfo)
 {
-#ifdef CONFIG_PMAC_BACKLIGHT
-       mutex_lock(&pmac_backlight_mutex);
-#endif
+       struct backlight_device *bd = rinfo->info->bl_dev;
 
-       mutex_lock(&rinfo->info->bl_mutex);
-       if (rinfo->info->bl_dev) {
+       if (bd) {
                struct radeon_bl_privdata *pdata;
 
 #ifdef CONFIG_PMAC_BACKLIGHT
-               if (pmac_backlight == rinfo->info->bl_dev)
+               mutex_lock(&pmac_backlight_mutex);
+               if (pmac_backlight == bd)
                        pmac_backlight = NULL;
+               mutex_unlock(&pmac_backlight_mutex);
 #endif
-
-               pdata = class_get_devdata(&rinfo->info->bl_dev->class_dev);
-               backlight_device_unregister(rinfo->info->bl_dev);
+               pdata = class_get_devdata(&bd->class_dev);
+               backlight_device_unregister(bd);
                kfree(pdata);
                rinfo->info->bl_dev = NULL;
 
                printk("radeonfb: Backlight unloaded\n");
        }
-       mutex_unlock(&rinfo->info->bl_mutex);
-
-#ifdef CONFIG_PMAC_BACKLIGHT
-       mutex_unlock(&pmac_backlight_mutex);
-#endif
 }
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 0ed577e..7e228ad 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)
         if (!rinfo)
                 return;
 
-       radeonfb_bl_exit(rinfo);
        radeonfb_pm_exit(rinfo);
 
        if (rinfo->mon1_EDID)
@@ -2420,6 +2419,8 @@ static void __devexit radeonfb_pci_unregister (struct 
pci_dev *pdev)
 
         unregister_framebuffer(info);
 
+        radeonfb_bl_exit(rinfo);
+
         iounmap(rinfo->mmio_base);
         iounmap(rinfo->fb_base);
  
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 818fb09..40c80c8 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)
        info->device = dev;
 
 #ifdef CONFIG_FB_BACKLIGHT
-       mutex_init(&info->bl_mutex);
+       mutex_init(&info->bl_curve_mutex);
 #endif
 
        return info;
@@ -445,10 +445,10 @@ static ssize_t store_bl_curve(struct device *device,
        /* If there has been an error in the input data, we won't
         * reach this loop.
         */
-       mutex_lock(&fb_info->bl_mutex);
+       mutex_lock(&fb_info->bl_curve_mutex);
        for (i = 0; i < FB_BACKLIGHT_LEVELS; ++i)
                fb_info->bl_curve[i] = tmp_curve[i];
-       mutex_unlock(&fb_info->bl_mutex);
+       mutex_unlock(&fb_info->bl_curve_mutex);
 
        return count;
 }
@@ -466,7 +466,7 @@ static ssize_t show_bl_curve(struct device *device,
        if (!fb_info || !fb_info->bl_dev)
                return -ENODEV;
 
-       mutex_lock(&fb_info->bl_mutex);
+       mutex_lock(&fb_info->bl_curve_mutex);
        for (i = 0; i < FB_BACKLIGHT_LEVELS; i += 8)
                len += snprintf(&buf[len], PAGE_SIZE,
                                "%02x %02x %02x %02x %02x %02x %02x %02x\n",
@@ -478,7 +478,7 @@ static ssize_t show_bl_curve(struct device *device,
                                fb_info->bl_curve[i + 5],
                                fb_info->bl_curve[i + 6],
                                fb_info->bl_curve[i + 7]);
-       mutex_unlock(&fb_info->bl_mutex);
+       mutex_unlock(&fb_info->bl_curve_mutex);
 
        return len;
 }
@@ -552,6 +552,8 @@ void fb_bl_default_curve(struct fb_info *fb_info, u8 off, 
u8 min, u8 max)
 {
        unsigned int i, flat, count, range = (max - min);
 
+       mutex_lock(&fb_info->bl_curve_mutex);
+
        fb_info->bl_curve[0] = off;
 
        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)
        count = FB_BACKLIGHT_LEVELS * 15 / 16;
        for (i = 0; i < count; ++i)
                fb_info->bl_curve[flat + i] = min + (range * (i + 1) / count);
+
+       mutex_unlock(&fb_info->bl_curve_mutex);
 }
 EXPORT_SYMBOL_GPL(fb_bl_default_curve);
 #endif
diff --git a/drivers/video/nvidia/nv_backlight.c 
b/drivers/video/nvidia/nv_backlight.c
index 695b6bf..2bebfee 100644
--- a/drivers/video/nvidia/nv_backlight.c
+++ b/drivers/video/nvidia/nv_backlight.c
@@ -30,7 +30,6 @@
 
 static struct backlight_properties nvidia_bl_data;
 
-/* Call with fb_info->bl_mutex held */
 static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
                int level)
 {
@@ -38,6 +37,7 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par 
*par,
        int nlevel;
 
        /* Get and convert the value */
+       /* No locking of bl_curve since we read a single value */
        nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
 
        if (nlevel < 0)
@@ -50,8 +50,7 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par 
*par,
        return nlevel;
 }
 
-/* Call with fb_info->bl_mutex held */
-static int __nvidia_bl_update_status(struct backlight_device *bd)
+static int nvidia_bl_update_status(struct backlight_device *bd)
 {
        struct nvidia_par *par = class_get_devdata(&bd->class_dev);
        u32 tmp_pcrt, tmp_pmc, fpcontrol;
@@ -85,19 +84,6 @@ static int __nvidia_bl_update_status(struct backlight_device 
*bd)
        return 0;
 }
 
-static int nvidia_bl_update_status(struct backlight_device *bd)
-{
-       struct nvidia_par *par = class_get_devdata(&bd->class_dev);
-       struct fb_info *info = pci_get_drvdata(par->pci_dev);
-       int ret;
-
-       mutex_lock(&info->bl_mutex);
-       ret = __nvidia_bl_update_status(bd);
-       mutex_unlock(&info->bl_mutex);
-
-       return ret;
-}
-
 static int nvidia_bl_get_brightness(struct backlight_device *bd)
 {
        return bd->props->brightness;
@@ -133,12 +119,10 @@ void nvidia_bl_init(struct nvidia_par *par)
                goto error;
        }
 
-       mutex_lock(&info->bl_mutex);
        info->bl_dev = bd;
        fb_bl_default_curve(info, 0,
                0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL,
                0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
-       mutex_unlock(&info->bl_mutex);
 
        bd->props->brightness = nvidia_bl_data.max_brightness;
        bd->props->power = FB_BLANK_UNBLANK;
@@ -162,25 +146,17 @@ error:
 void nvidia_bl_exit(struct nvidia_par *par)
 {
        struct fb_info *info = pci_get_drvdata(par->pci_dev);
+       struct backlight_device *bd = info->bl_dev;
 
+       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("nvidia: Backlight unloaded\n");
        }
-       mutex_unlock(&info->bl_mutex);
-
-#ifdef CONFIG_PMAC_BACKLIGHT
-       mutex_unlock(&pmac_backlight_mutex);
-#endif
 }
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 64f5911..c18e955 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)
 
        NVTRACE_ENTER();
 
+       unregister_framebuffer(info);
+
        nvidia_bl_exit(par);
 
-       unregister_framebuffer(info);
 #ifdef CONFIG_MTRR
        if (par->mtrr.vram_valid)
                mtrr_del(par->mtrr.vram, info->fix.smem_start,
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 9e7d3fc..ab00350 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -282,7 +282,6 @@ static const struct riva_regs reg_template = {
 
 static struct backlight_properties riva_bl_data;
 
-/* Call with fb_info->bl_mutex held */
 static int riva_bl_get_level_brightness(struct riva_par *par,
                int level)
 {
@@ -290,6 +289,7 @@ static int riva_bl_get_level_brightness(struct riva_par 
*par,
        int nlevel;
 
        /* Get and convert the value */
+       /* No locking on bl_curve since accessing a single value */
        nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
 
        if (nlevel < 0)
@@ -302,8 +302,7 @@ static int riva_bl_get_level_brightness(struct riva_par 
*par,
        return nlevel;
 }
 
-/* Call with fb_info->bl_mutex held */
-static int __riva_bl_update_status(struct backlight_device *bd)
+static int riva_bl_update_status(struct backlight_device *bd)
 {
        struct riva_par *par = class_get_devdata(&bd->class_dev);
        U032 tmp_pcrt, tmp_pmc;
@@ -328,19 +327,6 @@ static int __riva_bl_update_status(struct backlight_device 
*bd)
        return 0;
 }
 
-static int riva_bl_update_status(struct backlight_device *bd)
-{
-       struct riva_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 = __riva_bl_update_status(bd);
-       mutex_unlock(&info->bl_mutex);
-
-       return ret;
-}
-
 static int riva_bl_get_brightness(struct backlight_device *bd)
 {
        return bd->props->brightness;
@@ -376,12 +362,10 @@ static void riva_bl_init(struct riva_par *par)
                goto error;
        }
 
-       mutex_lock(&info->bl_mutex);
        info->bl_dev = bd;
        fb_bl_default_curve(info, 0,
                MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL,
                FB_BACKLIGHT_MAX);
-       mutex_unlock(&info->bl_mutex);
 
        bd->props->brightness = riva_bl_data.max_brightness;
        bd->props->power = FB_BLANK_UNBLANK;
@@ -402,34 +386,25 @@ error:
        return;
 }
 
-static void riva_bl_exit(struct riva_par *par)
+static void riva_bl_exit(struct fb_info *info)
 {
-       struct fb_info *info = pci_get_drvdata(par->pdev);
+       struct backlight_device *bd = info->bl_dev;
 
+       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("riva: Backlight unloaded\n");
        }
-       mutex_unlock(&info->bl_mutex);
-
-#ifdef CONFIG_PMAC_BACKLIGHT
-       mutex_unlock(&pmac_backlight_mutex);
-#endif
 }
 #else
 static inline void riva_bl_init(struct riva_par *par) {}
-static inline void riva_bl_exit(struct riva_par *par) {}
+static inline void riva_bl_exit(struct fb_info *info) {}
 #endif /* CONFIG_FB_RIVA_BACKLIGHT */
 
 /* ------------------------------------------------------------------------- *
@@ -2146,14 +2121,15 @@ static void __exit rivafb_remove(struct pci_dev *pd)
        
        NVTRACE_ENTER();
 
-       riva_bl_exit(par);
-
 #ifdef CONFIG_FB_RIVA_I2C
        riva_delete_i2c_busses(par);
        kfree(par->EDID);
 #endif
 
        unregister_framebuffer(info);
+
+       riva_bl_exit(info);
+
 #ifdef CONFIG_MTRR
        if (par->mtrr.vram_valid)
                mtrr_del(par->mtrr.vram, info->fix.smem_start,
diff --git a/include/linux/fb.h b/include/linux/fb.h
index bf7158b..be913ec 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -769,16 +769,13 @@ struct fb_info {
        struct fb_videomode *mode;      /* current mode */
 
 #ifdef CONFIG_FB_BACKLIGHT
-       /* Lock ordering:
-        * bl_mutex (protects bl_dev and bl_curve)
-        *   bl_dev->sem (backlight class)
-        */
-       struct mutex bl_mutex;
-
        /* assigned backlight device */
+       /* set before framebuffer registration, 
+          remove after unregister */
        struct backlight_device *bl_dev;
 
        /* Backlight level curve */
+       struct mutex bl_curve_mutex;    
        u8 bl_curve[FB_BACKLIGHT_LEVELS];
 #endif
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to