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>
This commit is contained in:
@@ -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,
|
|||||||
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,
|
|||||||
/* 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)
|
|||||||
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 = {
|
|||||||
|
|
||||||
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)
|
|||||||
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 @@ error:
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@ error:
|
|||||||
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)
|
|||||||
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 {
|
|||||||
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)
|
|||||||
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 @@ error:
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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,
|
|||||||
/* 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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
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 @@
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@ error:
|
|||||||
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)
|
|||||||
|
|
||||||
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 = {
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@ error:
|
|||||||
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)
|
|||||||
|
|
||||||
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 {
|
|||||||
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
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user