Commit 37ce69a5 authored by Richard Purdie's avatar Richard Purdie

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: default avatarRichard Purdie <rpurdie@rpsys.net>
parent b5c6916b
...@@ -1697,7 +1697,6 @@ static int __devinit aty128fb_setup(char *options) ...@@ -1697,7 +1697,6 @@ static int __devinit aty128fb_setup(char *options)
static struct backlight_properties aty128_bl_data; 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, static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
int level) int level)
{ {
...@@ -1705,6 +1704,7 @@ static int aty128_bl_get_level_brightness(struct aty128fb_par *par, ...@@ -1705,6 +1704,7 @@ static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
int atylevel; int atylevel;
/* Get and convert the value */ /* Get and convert the value */
/* No locking of bl_curve since we read a single value */
atylevel = MAX_LEVEL - atylevel = MAX_LEVEL -
(info->bl_curve[level] * FB_BACKLIGHT_MAX / 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, ...@@ -1724,8 +1724,7 @@ static int aty128_bl_get_level_brightness(struct aty128fb_par *par,
/* That one prevents proper CRT output with LCD off */ /* That one prevents proper CRT output with LCD off */
#undef BACKLIGHT_DAC_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); struct aty128fb_par *par = class_get_devdata(&bd->class_dev);
unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL); unsigned int reg = aty_ld_le32(LVDS_GEN_CNTL);
...@@ -1778,19 +1777,6 @@ static int __aty128_bl_update_status(struct backlight_device *bd) ...@@ -1778,19 +1777,6 @@ static int __aty128_bl_update_status(struct backlight_device *bd)
return 0; 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) static int aty128_bl_get_brightness(struct backlight_device *bd)
{ {
return bd->props->brightness; return bd->props->brightness;
...@@ -1804,14 +1790,10 @@ static struct backlight_properties aty128_bl_data = { ...@@ -1804,14 +1790,10 @@ static struct backlight_properties aty128_bl_data = {
static void aty128_bl_set_power(struct fb_info *info, int power) static void aty128_bl_set_power(struct fb_info *info, int power)
{ {
mutex_lock(&info->bl_mutex);
if (info->bl_dev) { if (info->bl_dev) {
info->bl_dev->props->power = power; 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) static void aty128_bl_init(struct aty128fb_par *par)
...@@ -1838,12 +1820,10 @@ static void aty128_bl_init(struct aty128fb_par *par) ...@@ -1838,12 +1820,10 @@ static void aty128_bl_init(struct aty128fb_par *par)
goto error; goto error;
} }
mutex_lock(&info->bl_mutex);
info->bl_dev = bd; info->bl_dev = bd;
fb_bl_default_curve(info, 0, fb_bl_default_curve(info, 0,
63 * FB_BACKLIGHT_MAX / MAX_LEVEL, 63 * FB_BACKLIGHT_MAX / MAX_LEVEL,
219 * 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->brightness = aty128_bl_data.max_brightness;
bd->props->power = FB_BLANK_UNBLANK; bd->props->power = FB_BLANK_UNBLANK;
...@@ -1864,31 +1844,19 @@ static void aty128_bl_init(struct aty128fb_par *par) ...@@ -1864,31 +1844,19 @@ static void aty128_bl_init(struct aty128fb_par *par)
return; 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 #ifdef CONFIG_PMAC_BACKLIGHT
mutex_lock(&pmac_backlight_mutex); mutex_lock(&pmac_backlight_mutex);
#endif if (pmac_backlight == bd)
mutex_lock(&info->bl_mutex);
if (info->bl_dev) {
#ifdef CONFIG_PMAC_BACKLIGHT
if (pmac_backlight == info->bl_dev)
pmac_backlight = NULL; pmac_backlight = NULL;
mutex_unlock(&pmac_backlight_mutex);
#endif #endif
backlight_device_unregister(bd);
backlight_device_unregister(info->bl_dev);
info->bl_dev = NULL;
printk("aty128: Backlight unloaded\n"); 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 */ #endif /* CONFIG_FB_ATY128_BACKLIGHT */
...@@ -2175,11 +2143,12 @@ static void __devexit aty128_remove(struct pci_dev *pdev) ...@@ -2175,11 +2143,12 @@ static void __devexit aty128_remove(struct pci_dev *pdev)
par = info->par; par = info->par;
unregister_framebuffer(info);
#ifdef CONFIG_FB_ATY128_BACKLIGHT #ifdef CONFIG_FB_ATY128_BACKLIGHT
aty128_bl_exit(par); aty128_bl_exit(info->bl_dev);
#endif #endif
unregister_framebuffer(info);
#ifdef CONFIG_MTRR #ifdef CONFIG_MTRR
if (par->mtrr.vram_valid) if (par->mtrr.vram_valid)
mtrr_del(par->mtrr.vram, info->fix.smem_start, mtrr_del(par->mtrr.vram, info->fix.smem_start,
......
...@@ -2116,13 +2116,13 @@ static int atyfb_pci_resume(struct pci_dev *pdev) ...@@ -2116,13 +2116,13 @@ static int atyfb_pci_resume(struct pci_dev *pdev)
static struct backlight_properties aty_bl_data; 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) static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
{ {
struct fb_info *info = pci_get_drvdata(par->pdev); struct fb_info *info = pci_get_drvdata(par->pdev);
int atylevel; int atylevel;
/* Get and convert the value */ /* 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; atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
if (atylevel < 0) if (atylevel < 0)
...@@ -2133,8 +2133,7 @@ static int aty_bl_get_level_brightness(struct atyfb_par *par, int level) ...@@ -2133,8 +2133,7 @@ static int aty_bl_get_level_brightness(struct atyfb_par *par, int level)
return atylevel; 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); struct atyfb_par *par = class_get_devdata(&bd->class_dev);
unsigned int reg = aty_ld_lcd(LCD_MISC_CNTL, par); 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,19 +2158,6 @@ static int __aty_bl_update_status(struct backlight_device *bd)
return 0; 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) static int aty_bl_get_brightness(struct backlight_device *bd)
{ {
return bd->props->brightness; return bd->props->brightness;
...@@ -2203,12 +2189,10 @@ static void aty_bl_init(struct atyfb_par *par) ...@@ -2203,12 +2189,10 @@ static void aty_bl_init(struct atyfb_par *par)
goto error; goto error;
} }
mutex_lock(&info->bl_mutex);
info->bl_dev = bd; info->bl_dev = bd;
fb_bl_default_curve(info, 0, fb_bl_default_curve(info, 0,
0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL, 0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
0xFF * 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->brightness = aty_bl_data.max_brightness;
bd->props->power = FB_BLANK_UNBLANK; bd->props->power = FB_BLANK_UNBLANK;
...@@ -2229,30 +2213,19 @@ static void aty_bl_init(struct atyfb_par *par) ...@@ -2229,30 +2213,19 @@ static void aty_bl_init(struct atyfb_par *par)
return; 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 #ifdef CONFIG_PMAC_BACKLIGHT
mutex_lock(&pmac_backlight_mutex); mutex_lock(&pmac_backlight_mutex);
#endif if (pmac_backlight == bd)
mutex_lock(&info->bl_mutex);
if (info->bl_dev) {
#ifdef CONFIG_PMAC_BACKLIGHT
if (pmac_backlight == info->bl_dev)
pmac_backlight = NULL; pmac_backlight = NULL;
mutex_unlock(&pmac_backlight_mutex);
#endif #endif
backlight_device_unregister(bd);
backlight_device_unregister(info->bl_dev);
printk("aty: Backlight unloaded\n"); 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 */ #endif /* CONFIG_FB_ATY_BACKLIGHT */
...@@ -3705,13 +3678,13 @@ static void __devexit atyfb_remove(struct fb_info *info) ...@@ -3705,13 +3678,13 @@ static void __devexit atyfb_remove(struct fb_info *info)
aty_set_crtc(par, &saved_crtc); aty_set_crtc(par, &saved_crtc);
par->pll_ops->set_pll(info, &saved_pll); par->pll_ops->set_pll(info, &saved_pll);
unregister_framebuffer(info);
#ifdef CONFIG_FB_ATY_BACKLIGHT #ifdef CONFIG_FB_ATY_BACKLIGHT
if (M64_HAS(MOBIL_BUS)) if (M64_HAS(MOBIL_BUS))
aty_bl_exit(par); aty_bl_exit(info->bl_dev);
#endif #endif
unregister_framebuffer(info);
#ifdef CONFIG_MTRR #ifdef CONFIG_MTRR
if (par->mtrr_reg >= 0) { if (par->mtrr_reg >= 0) {
mtrr_del(par->mtrr_reg, 0, 0); mtrr_del(par->mtrr_reg, 0, 0);
......
...@@ -29,17 +29,13 @@ struct radeon_bl_privdata { ...@@ -29,17 +29,13 @@ struct radeon_bl_privdata {
static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata, static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata,
int level) int level)
{ {
struct fb_info *info = pdata->rinfo->info;
int rlevel; int rlevel;
mutex_lock(&info->bl_mutex);
/* Get and convert the value */ /* Get and convert the value */
/* No locking of bl_curve since we read a single value */
rlevel = pdata->rinfo->info->bl_curve[level] * rlevel = pdata->rinfo->info->bl_curve[level] *
FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL; FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL;
mutex_unlock(&info->bl_mutex);
if (rlevel < 0) if (rlevel < 0)
rlevel = 0; rlevel = 0;
else if (rlevel > MAX_RADEON_LEVEL) else if (rlevel > MAX_RADEON_LEVEL)
...@@ -187,12 +183,10 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo) ...@@ -187,12 +183,10 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
machine_is_compatible("PowerBook6,5"); machine_is_compatible("PowerBook6,5");
#endif #endif
mutex_lock(&rinfo->info->bl_mutex);
rinfo->info->bl_dev = bd; rinfo->info->bl_dev = bd;
fb_bl_default_curve(rinfo->info, 0, fb_bl_default_curve(rinfo->info, 0,
63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL, 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL,
217 * 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->brightness = radeon_bl_data.max_brightness;
bd->props->power = FB_BLANK_UNBLANK; bd->props->power = FB_BLANK_UNBLANK;
...@@ -216,29 +210,22 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo) ...@@ -216,29 +210,22 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
void radeonfb_bl_exit(struct radeonfb_info *rinfo) void radeonfb_bl_exit(struct radeonfb_info *rinfo)
{ {
#ifdef CONFIG_PMAC_BACKLIGHT struct backlight_device *bd = rinfo->info->bl_dev;
mutex_lock(&pmac_backlight_mutex);
#endif
mutex_lock(&rinfo->info->bl_mutex); if (bd) {
if (rinfo->info->bl_dev) {
struct radeon_bl_privdata *pdata; struct radeon_bl_privdata *pdata;
#ifdef CONFIG_PMAC_BACKLIGHT #ifdef CONFIG_PMAC_BACKLIGHT
if (pmac_backlight == rinfo->info->bl_dev) mutex_lock(&pmac_backlight_mutex);
if (pmac_backlight == bd)
pmac_backlight = NULL; pmac_backlight = NULL;
mutex_unlock(&pmac_backlight_mutex);
#endif #endif
pdata = class_get_devdata(&bd->class_dev);
pdata = class_get_devdata(&rinfo->info->bl_dev->class_dev); backlight_device_unregister(bd);
backlight_device_unregister(rinfo->info->bl_dev);
kfree(pdata); kfree(pdata);
rinfo->info->bl_dev = NULL; rinfo->info->bl_dev = NULL;
printk("radeonfb: Backlight unloaded\n"); printk("radeonfb: Backlight unloaded\n");
} }
mutex_unlock(&rinfo->info->bl_mutex);
#ifdef CONFIG_PMAC_BACKLIGHT
mutex_unlock(&pmac_backlight_mutex);
#endif
} }
...@@ -2393,7 +2393,6 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev) ...@@ -2393,7 +2393,6 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
if (!rinfo) if (!rinfo)
return; return;
radeonfb_bl_exit(rinfo);
radeonfb_pm_exit(rinfo); radeonfb_pm_exit(rinfo);
if (rinfo->mon1_EDID) if (rinfo->mon1_EDID)
...@@ -2420,6 +2419,8 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev) ...@@ -2420,6 +2419,8 @@ static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
unregister_framebuffer(info); unregister_framebuffer(info);
radeonfb_bl_exit(rinfo);
iounmap(rinfo->mmio_base); iounmap(rinfo->mmio_base);
iounmap(rinfo->fb_base); iounmap(rinfo->fb_base);
......
...@@ -59,7 +59,7 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev) ...@@ -59,7 +59,7 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
info->device = dev; info->device = dev;
#ifdef CONFIG_FB_BACKLIGHT #ifdef CONFIG_FB_BACKLIGHT
mutex_init(&info->bl_mutex); mutex_init(&info->bl_curve_mutex);
#endif #endif
return info; return info;
...@@ -445,10 +445,10 @@ static ssize_t store_bl_curve(struct device *device, ...@@ -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 /* If there has been an error in the input data, we won't
* reach this loop. * reach this loop.
*/ */
mutex_lock(&fb_info->bl_mutex); mutex_lock(&fb_info->bl_curve_mutex);
for (i = 0; i < FB_BACKLIGHT_LEVELS; ++i) for (i = 0; i < FB_BACKLIGHT_LEVELS; ++i)
fb_info->bl_curve[i] = tmp_curve[i]; fb_info->bl_curve[i] = tmp_curve[i];
mutex_unlock(&fb_info->bl_mutex); mutex_unlock(&fb_info->bl_curve_mutex);
return count; return count;
} }
...@@ -466,7 +466,7 @@ static ssize_t show_bl_curve(struct device *device, ...@@ -466,7 +466,7 @@ static ssize_t show_bl_curve(struct device *device,
if (!fb_info || !fb_info->bl_dev) if (!fb_info || !fb_info->bl_dev)
return -ENODEV; return -ENODEV;
mutex_lock(&fb_info->bl_mutex); mutex_lock(&fb_info->bl_curve_mutex);
for (i = 0; i < FB_BACKLIGHT_LEVELS; i += 8) for (i = 0; i < FB_BACKLIGHT_LEVELS; i += 8)
len += snprintf(&buf[len], PAGE_SIZE, len += snprintf(&buf[len], PAGE_SIZE,
"%02x %02x %02x %02x %02x %02x %02x %02x\n", "%02x %02x %02x %02x %02x %02x %02x %02x\n",
...@@ -478,7 +478,7 @@ static ssize_t show_bl_curve(struct device *device, ...@@ -478,7 +478,7 @@ static ssize_t show_bl_curve(struct device *device,
fb_info->bl_curve[i + 5], fb_info->bl_curve[i + 5],
fb_info->bl_curve[i + 6], fb_info->bl_curve[i + 6],
fb_info->bl_curve[i + 7]); fb_info->bl_curve[i + 7]);
mutex_unlock(&fb_info->bl_mutex); mutex_unlock(&fb_info->bl_curve_mutex);
return len; return len;
} }
...@@ -552,6 +552,8 @@ void fb_bl_default_curve(struct fb_info *fb_info, u8 off, u8 min, u8 max) ...@@ -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); unsigned int i, flat, count, range = (max - min);
mutex_lock(&fb_info->bl_curve_mutex);
fb_info->bl_curve[0] = off; fb_info->bl_curve[0] = off;
for (flat = 1; flat < (FB_BACKLIGHT_LEVELS / 16); ++flat) 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,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; count = FB_BACKLIGHT_LEVELS * 15 / 16;
for (i = 0; i < count; ++i) for (i = 0; i < count; ++i)
fb_info->bl_curve[flat + i] = min + (range * (i + 1) / count); 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); EXPORT_SYMBOL_GPL(fb_bl_default_curve);
#endif #endif
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
static struct backlight_properties nvidia_bl_data; 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, static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
int level) int level)
{ {
...@@ -38,6 +37,7 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par *par, ...@@ -38,6 +37,7 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
int nlevel; int nlevel;
/* Get and convert the value */ /* 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; nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
if (nlevel < 0) if (nlevel < 0)
...@@ -50,8 +50,7 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par *par, ...@@ -50,8 +50,7 @@ static int nvidia_bl_get_level_brightness(struct nvidia_par *par,
return nlevel; 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); struct nvidia_par *par = class_get_devdata(&bd->class_dev);
u32 tmp_pcrt, tmp_pmc, fpcontrol; u32 tmp_pcrt, tmp_pmc, fpcontrol;
...@@ -85,19 +84,6 @@ static int __nvidia_bl_update_status(struct backlight_device *bd) ...@@ -85,19 +84,6 @@ static int __nvidia_bl_update_status(struct backlight_device *bd)
return 0; 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) static int nvidia_bl_get_brightness(struct backlight_device *bd)
{ {
return bd->props->brightness; return bd->props->brightness;
...@@ -133,12 +119,10 @@ void nvidia_bl_init(struct nvidia_par *par) ...@@ -133,12 +119,10 @@ void nvidia_bl_init(struct nvidia_par *par)
goto error; goto error;
} }
mutex_lock(&info->bl_mutex);
info->bl_dev = bd; info->bl_dev = bd;
fb_bl_default_curve(info, 0, fb_bl_default_curve(info, 0,
0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL, 0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL,
0x534 * 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->brightness = nvidia_bl_data.max_brightness;
bd->props->power = FB_BLANK_UNBLANK; bd->props->power = FB_BLANK_UNBLANK;
...@@ -162,25 +146,17 @@ void nvidia_bl_init(struct nvidia_par *par) ...@@ -162,25 +146,17 @@ void nvidia_bl_init(struct nvidia_par *par)
void nvidia_bl_exit(struct nvidia_par *par) void nvidia_bl_exit(struct nvidia_par *par)
{ {
struct fb_info *info = pci_get_drvdata(par->pci_dev); struct fb_info *info = pci_get_drvdata(par->pci_dev);
struct backlight_device *bd = info->bl_dev;
if (bd) {
#ifdef CONFIG_PMAC_BACKLIGHT #ifdef CONFIG_PMAC_BACKLIGHT
mutex_lock(&pmac_backlight_mutex); mutex_lock(&pmac_backlight_mutex);
#endif if (pmac_backlight == bd)
mutex_lock(&info->bl_mutex);
if (info->bl_dev) {
#ifdef CONFIG_PMAC_BACKLIGHT
if (pmac_backlight == info->bl_dev)
pmac_backlight = NULL; pmac_backlight = NULL;
mutex_unlock(&pmac_backlight_mutex);
#endif #endif
backlight_device_unregister(bd);
backlight_device_unregister(info->bl_dev);
printk("nvidia: Backlight unloaded\n"); printk("nvidia: Backlight unloaded\n");
} }
mutex_unlock(&info->bl_mutex);
#ifdef CONFIG_PMAC_BACKLIGHT
mutex_unlock(&pmac_backlight_mutex);
#endif
} }
...@@ -1350,9 +1350,10 @@ static void __devexit nvidiafb_remove(struct pci_dev *pd) ...@@ -1350,9 +1350,10 @@ static void __devexit nvidiafb_remove(struct pci_dev *pd)
NVTRACE_ENTER(); NVTRACE_ENTER();
unregister_framebuffer(info);
nvidia_bl_exit(par); nvidia_bl_exit(par);
unregister_framebuffer(info);
#ifdef CONFIG_MTRR #ifdef CONFIG_MTRR
if (par->mtrr.vram_valid) if (par->mtrr.vram_valid)
mtrr_del(par->mtrr.vram, info->fix.smem_start, mtrr_del(par->mtrr.vram, info->fix.smem_start,
......
...@@ -282,7 +282,6 @@ static const struct riva_regs reg_template = { ...@@ -282,7 +282,6 @@ static const struct riva_regs reg_template = {
static struct backlight_properties riva_bl_data; 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, static int riva_bl_get_level_brightness(struct riva_par *par,
int level) int level)
{ {
...@@ -290,6 +289,7 @@ static int riva_bl_get_level_brightness(struct riva_par *par, ...@@ -290,6 +289,7 @@ static int riva_bl_get_level_brightness(struct riva_par *par,
int nlevel; int nlevel;
/* Get and convert the value */ /* Get and convert the value */
/* No locking on bl_curve since accessing a single value */
nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP; nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
if (nlevel < 0) if (nlevel < 0)
...@@ -302,8 +302,7 @@ static int riva_bl_get_level_brightness(struct riva_par *par, ...@@ -302,8 +302,7 @@ static int riva_bl_get_level_brightness(struct riva_par *par,
return nlevel; 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); struct riva_par *par = class_get_devdata(&bd->class_dev);
U032 tmp_pcrt, tmp_pmc; U032 tmp_pcrt, tmp_pmc;
...@@ -328,19 +327,6 @@ static int __riva_bl_update_status(struct backlight_device *bd) ...@@ -328,19 +327,6 @@ static int __riva_bl_update_status(struct backlight_device *bd)
return 0; 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) static int riva_bl_get_brightness(struct backlight_device *bd)
{ {
return bd->props->brightness; return bd->props->brightness;
...@@ -376,12 +362,10 @@ static void riva_bl_init(struct riva_par *par) ...@@ -376,12 +362,10 @@ static void riva_bl_init(struct riva_par *par)
goto error; goto error;
} }
mutex_lock(&info->bl_mutex);
info->bl_dev = bd; info->bl_dev = bd;
fb_bl_default_curve(info, 0, fb_bl_default_curve(info, 0,
MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL, MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL,
FB_BACKLIGHT_MAX); FB_BACKLIGHT_MAX);
mutex_unlock(&info->bl_mutex);
bd->props->brightness = riva_bl_data.max_brightness; bd->props->brightness = riva_bl_data.max_brightness;
bd->props->power = FB_BLANK_UNBLANK; bd->props->power = FB_BLANK_UNBLANK;
...@@ -402,34 +386,25 @@ static void riva_bl_init(struct riva_par *par) ...@@ -402,34 +386,25 @@ static void riva_bl_init(struct riva_par *par)
return; 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 #ifdef CONFIG_PMAC_BACKLIGHT
mutex_lock(&pmac_backlight_mutex); mutex_lock(&pmac_backlight_mutex);
#endif if (pmac_backlight == bd)
mutex_lock(&info->bl_mutex);
if (info->bl_dev) {
#ifdef CONFIG_PMAC_BACKLIGHT
if (pmac_backlight == info->bl_dev)
pmac_backlight = NULL; pmac_backlight = NULL;
mutex_unlock(&pmac_backlight_mutex);
#endif #endif
backlight_device_unregister(bd);
backlight_device_unregister(info->bl_dev);
printk("riva: Backlight unloaded\n"); printk("riva: Backlight unloaded\n");
} }
mutex_unlock(&info->bl_mutex);
#ifdef CONFIG_PMAC_BACKLIGHT
mutex_unlock(&pmac_backlight_mutex);
#endif
} }
#else #else
static inline void riva_bl_init(struct riva_par *par) {} 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 */ #endif /* CONFIG_FB_RIVA_BACKLIGHT */
/* ------------------------------------------------------------------------- * /* ------------------------------------------------------------------------- *
...@@ -2146,14 +2121,15 @@ static void __exit rivafb_remove(struct pci_dev *pd) ...@@ -2146,14 +2121,15 @@ static void __exit rivafb_remove(struct pci_dev *pd)
NVTRACE_ENTER(); NVTRACE_ENTER();
riva_bl_exit(par);
#ifdef CONFIG_FB_RIVA_I2C #ifdef CONFIG_FB_RIVA_I2C
riva_delete_i2c_busses(par); riva_delete_i2c_busses(par);
kfree(par->EDID); kfree(par->EDID);
#endif #endif
unregister_framebuffer(info); unregister_framebuffer(info);
riva_bl_exit(info);
#ifdef CONFIG_MTRR #ifdef CONFIG_MTRR
if (par->mtrr.vram_valid) if (par->mtrr.vram_valid)
mtrr_del(par->mtrr.vram, info->fix.smem_start, mtrr_del(par->mtrr.vram, info->fix.smem_start,
......
...@@ -769,16 +769,13 @@ struct fb_info { ...@@ -769,16 +769,13 @@ struct fb_info {
struct fb_videomode *mode; /* current mode */ struct fb_videomode *mode; /* current mode */
#ifdef CONFIG_FB_BACKLIGHT #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 */ /* assigned backlight device */
/* set before framebuffer registration,
remove after unregister */
struct backlight_device *bl_dev; struct backlight_device *bl_dev;
/* Backlight level curve */ /* Backlight level curve */
struct mutex bl_curve_mutex;
u8 bl_curve[FB_BACKLIGHT_LEVELS]; u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment