* Locking fixes for powermac backlight infrastructure
@ 2006-07-08 12:06 Michael Hanselmann
0 siblings, 0 replies; only message in thread
From: Michael Hanselmann @ 2006-07-08 12:06 UTC (permalink / raw)
To: akpm; +Cc: benh, johannes, aris, linux-fbdev-devel, linux-kernel
This patch fixes locking issues in the new powermac backlight
infrastructure as reported by Aristeu S. Rozanski F. <aris@valeta.org>.
It also fixes the wrong calculation of backlight values in some of the
drivers.
Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch>
Acked-by: René Nussbaumer <linux-kernel@killerfox.forkbomb.ch>
---
diff -Nrup --exclude-from linux-exclude-from linux-2.6.18-rc1.orig/drivers/video/aty/aty128fb.c linux-2.6.18-rc1/drivers/video/aty/aty128fb.c
--- linux-2.6.18-rc1.orig/drivers/video/aty/aty128fb.c 2006-07-08 12:27:09.000000000 +0200
+++ linux-2.6.18-rc1/drivers/video/aty/aty128fb.c 2006-07-08 12:28:32.000000000 +0200
@@ -456,6 +456,7 @@ static void do_wait_for_fifo(u16 entries
static void wait_for_fifo(u16 entries, struct aty128fb_par *par);
static void wait_for_idle(struct aty128fb_par *par);
static u32 depth_to_dst(u32 depth);
+static void aty128_bl_set_power(struct fb_info *info, int power);
#define BIOS_IN8(v) (readb(bios + (v)))
#define BIOS_IN16(v) (readb(bios + (v)) | \
@@ -1258,25 +1259,11 @@ static void aty128_set_lcd_enable(struct
reg &= ~LVDS_DISPLAY_DIS;
aty_st_le32(LVDS_GEN_CNTL, reg);
#ifdef CONFIG_FB_ATY128_BACKLIGHT
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
- down(&info->bl_dev->sem);
- info->bl_dev->props->update_status(info->bl_dev);
- up(&info->bl_dev->sem);
- }
- mutex_unlock(&info->bl_mutex);
+ aty128_bl_set_power(info, FB_BLANK_UNBLANK);
#endif
} else {
#ifdef CONFIG_FB_ATY128_BACKLIGHT
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
- down(&info->bl_dev->sem);
- info->bl_dev->props->brightness = 0;
- info->bl_dev->props->power = FB_BLANK_POWERDOWN;
- info->bl_dev->props->update_status(info->bl_dev);
- up(&info->bl_dev->sem);
- }
- mutex_unlock(&info->bl_mutex);
+ aty128_bl_set_power(info, FB_BLANK_POWERDOWN);
#endif
reg = aty_ld_le32(LVDS_GEN_CNTL);
reg |= LVDS_DISPLAY_DIS;
@@ -1703,6 +1690,7 @@ static int __devinit aty128fb_setup(char
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)
{
@@ -1710,10 +1698,8 @@ static int aty128_bl_get_level_brightnes
int atylevel;
/* Get and convert the value */
- mutex_lock(&info->bl_mutex);
atylevel = MAX_LEVEL -
(info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL);
- mutex_unlock(&info->bl_mutex);
if (atylevel < 0)
atylevel = 0;
@@ -1731,7 +1717,8 @@ static int aty128_bl_get_level_brightnes
/* That one prevents proper CRT output with LCD off */
#undef BACKLIGHT_DAC_OFF
-static int aty128_bl_update_status(struct backlight_device *bd)
+/* Call with fb_info->bl_mutex held */
+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);
@@ -1784,6 +1771,19 @@ static int aty128_bl_update_status(struc
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;
@@ -1796,6 +1796,16 @@ static struct backlight_properties aty12
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
};
+static void aty128_bl_set_power(struct fb_info *info, int power)
+{
+ mutex_lock(&info->bl_mutex);
+ up(&info->bl_dev->sem);
+ info->bl_dev->props->power = power;
+ __aty128_bl_update_status(info->bl_dev);
+ down(&info->bl_dev->sem);
+ mutex_unlock(&info->bl_mutex);
+}
+
static void aty128_bl_init(struct aty128fb_par *par)
{
struct fb_info *info = pci_get_drvdata(par->pdev);
@@ -2198,12 +2208,8 @@ static int aty128fb_blank(int blank, str
return 0;
#ifdef CONFIG_FB_ATY128_BACKLIGHT
- if (machine_is(powermac) && blank) {
- down(&fb->bl_dev->sem);
- fb->bl_dev->props->power = FB_BLANK_POWERDOWN;
- fb->bl_dev->props->update_status(fb->bl_dev);
- up(&fb->bl_dev->sem);
- }
+ if (machine_is(powermac) && blank)
+ aty128_bl_set_power(fb, FB_BLANK_POWERDOWN);
#endif
if (blank & FB_BLANK_VSYNC_SUSPEND)
@@ -2219,14 +2225,12 @@ static int aty128fb_blank(int blank, str
aty128_set_crt_enable(par, par->crt_on && !blank);
aty128_set_lcd_enable(par, par->lcd_on && !blank);
}
+
#ifdef CONFIG_FB_ATY128_BACKLIGHT
- if (machine_is(powermac) && !blank) {
- down(&fb->bl_dev->sem);
- fb->bl_dev->props->power = FB_BLANK_UNBLANK;
- fb->bl_dev->props->update_status(fb->bl_dev);
- up(&fb->bl_dev->sem);
- }
+ if (machine_is(powermac) && !blank)
+ aty128_bl_set_power(fb, FB_BLANK_UNBLANK);
#endif
+
return 0;
}
diff -Nrup --exclude-from linux-exclude-from linux-2.6.18-rc1.orig/drivers/video/aty/atyfb_base.c linux-2.6.18-rc1/drivers/video/aty/atyfb_base.c
--- linux-2.6.18-rc1.orig/drivers/video/aty/atyfb_base.c 2006-07-08 12:27:09.000000000 +0200
+++ linux-2.6.18-rc1/drivers/video/aty/atyfb_base.c 2006-07-08 12:28:32.000000000 +0200
@@ -2129,15 +2129,14 @@ static int atyfb_pci_resume(struct pci_d
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 */
- mutex_lock(&info->bl_mutex);
atylevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
- mutex_unlock(&info->bl_mutex);
if (atylevel < 0)
atylevel = 0;
@@ -2147,7 +2146,8 @@ static int aty_bl_get_level_brightness(s
return atylevel;
}
-static int aty_bl_update_status(struct backlight_device *bd)
+/* Call with fb_info->bl_mutex held */
+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);
@@ -2172,6 +2172,19 @@ static int aty_bl_update_status(struct b
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;
@@ -2184,6 +2197,16 @@ static struct backlight_properties aty_b
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
};
+static void aty_bl_set_power(struct fb_info *info, int power)
+{
+ mutex_lock(&info->bl_mutex);
+ up(&info->bl_dev->sem);
+ info->bl_dev->props->power = power;
+ __aty_bl_update_status(info->bl_dev);
+ down(&info->bl_dev->sem);
+ mutex_unlock(&info->bl_mutex);
+}
+
static void aty_bl_init(struct atyfb_par *par)
{
struct fb_info *info = pci_get_drvdata(par->pdev);
@@ -2790,16 +2813,8 @@ static int atyfb_blank(int blank, struct
return 0;
#ifdef CONFIG_PMAC_BACKLIGHT
- if (machine_is(powermac) && blank > FB_BLANK_NORMAL) {
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
- down(&info->bl_dev->sem);
- info->bl_dev->props->power = FB_BLANK_POWERDOWN;
- info->bl_dev->props->update_status(info->bl_dev);
- up(&info->bl_dev->sem);
- }
- mutex_unlock(&info->bl_mutex);
- }
+ if (machine_is(powermac) && blank > FB_BLANK_NORMAL)
+ aty_bl_set_power(info, FB_BLANK_POWERDOWN);
#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
if (par->lcd_table && blank > FB_BLANK_NORMAL &&
(aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
@@ -2830,16 +2845,8 @@ static int atyfb_blank(int blank, struct
aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
#ifdef CONFIG_PMAC_BACKLIGHT
- if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) {
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
- down(&info->bl_dev->sem);
- info->bl_dev->props->power = FB_BLANK_UNBLANK;
- info->bl_dev->props->update_status(info->bl_dev);
- up(&info->bl_dev->sem);
- }
- mutex_unlock(&info->bl_mutex);
- }
+ if (machine_is(powermac) && blank <= FB_BLANK_NORMAL)
+ aty_bl_set_power(info, FB_BLANK_UNBLANK);
#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
(aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
diff -Nrup --exclude-from linux-exclude-from linux-2.6.18-rc1.orig/drivers/video/chipsfb.c linux-2.6.18-rc1/drivers/video/chipsfb.c
--- linux-2.6.18-rc1.orig/drivers/video/chipsfb.c 2006-07-08 12:27:08.000000000 +0200
+++ linux-2.6.18-rc1/drivers/video/chipsfb.c 2006-07-08 12:28:32.000000000 +0200
@@ -150,12 +150,11 @@ static int chipsfb_blank(int blank, stru
mutex_lock(&pmac_backlight_mutex);
if (pmac_backlight) {
- down(&pmac_backlight->sem);
-
/* used to disable backlight only for blank > 1, but it seems
* useful at blank = 1 too (saves battery, extends backlight
* life)
*/
+ down(&pmac_backlight->sem);
if (blank)
pmac_backlight->props->power = FB_BLANK_POWERDOWN;
else
diff -Nrup --exclude-from linux-exclude-from linux-2.6.18-rc1.orig/drivers/video/nvidia/nv_backlight.c linux-2.6.18-rc1/drivers/video/nvidia/nv_backlight.c
--- linux-2.6.18-rc1.orig/drivers/video/nvidia/nv_backlight.c 2006-07-08 12:27:09.000000000 +0200
+++ linux-2.6.18-rc1/drivers/video/nvidia/nv_backlight.c 2006-07-08 12:28:32.000000000 +0200
@@ -26,9 +26,11 @@
*/
#define MIN_LEVEL 0x158
#define MAX_LEVEL 0x534
+#define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
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)
{
@@ -36,9 +38,7 @@ static int nvidia_bl_get_level_brightnes
int nlevel;
/* Get and convert the value */
- mutex_lock(&info->bl_mutex);
- nlevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
- mutex_unlock(&info->bl_mutex);
+ nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
if (nlevel < 0)
nlevel = 0;
@@ -50,7 +50,8 @@ static int nvidia_bl_get_level_brightnes
return nlevel;
}
-static int nvidia_bl_update_status(struct backlight_device *bd)
+/* Call with fb_info->bl_mutex held */
+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;
@@ -84,6 +85,19 @@ static int nvidia_bl_update_status(struc
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;
@@ -96,6 +110,16 @@ static struct backlight_properties nvidi
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
};
+void nvidia_bl_set_power(struct fb_info *info, int power)
+{
+ mutex_lock(&info->bl_mutex);
+ up(&info->bl_dev->sem);
+ info->bl_dev->props->power = power;
+ __nvidia_bl_update_status(info->bl_dev);
+ down(&info->bl_dev->sem);
+ mutex_unlock(&info->bl_mutex);
+}
+
void nvidia_bl_init(struct nvidia_par *par)
{
struct fb_info *info = pci_get_drvdata(par->pci_dev);
diff -Nrup --exclude-from linux-exclude-from linux-2.6.18-rc1.orig/drivers/video/nvidia/nvidia.c linux-2.6.18-rc1/drivers/video/nvidia/nvidia.c
--- linux-2.6.18-rc1.orig/drivers/video/nvidia/nvidia.c 2006-07-08 12:27:09.000000000 +0200
+++ linux-2.6.18-rc1/drivers/video/nvidia/nvidia.c 2006-07-08 12:28:32.000000000 +0200
@@ -933,16 +933,7 @@ static int nvidiafb_blank(int blank, str
NVWriteSeq(par, 0x01, tmp);
NVWriteCrtc(par, 0x1a, vesa);
-#ifdef CONFIG_FB_NVIDIA_BACKLIGHT
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
- down(&info->bl_dev->sem);
- info->bl_dev->props->power = blank;
- info->bl_dev->props->update_status(info->bl_dev);
- up(&info->bl_dev->sem);
- }
- mutex_unlock(&info->bl_mutex);
-#endif
+ nvidia_bl_set_power(info, blank);
NVTRACE_LEAVE();
diff -Nrup --exclude-from linux-exclude-from linux-2.6.18-rc1.orig/drivers/video/nvidia/nv_proto.h linux-2.6.18-rc1/drivers/video/nvidia/nv_proto.h
--- linux-2.6.18-rc1.orig/drivers/video/nvidia/nv_proto.h 2006-07-08 12:27:09.000000000 +0200
+++ linux-2.6.18-rc1/drivers/video/nvidia/nv_proto.h 2006-07-08 12:28:32.000000000 +0200
@@ -68,9 +68,11 @@ extern u8 byte_rev[256];
#ifdef CONFIG_FB_NVIDIA_BACKLIGHT
extern void nvidia_bl_init(struct nvidia_par *par);
extern void nvidia_bl_exit(struct nvidia_par *par);
+extern void nvidia_bl_set_power(struct fb_info *info, int power);
#else
static inline void nvidia_bl_init(struct nvidia_par *par) {}
static inline void nvidia_bl_exit(struct nvidia_par *par) {}
+static inline void nvidia_bl_set_power(struct fb_info *info, int power) {}
#endif
#endif /* __NV_PROTO_H__ */
diff -Nrup --exclude-from linux-exclude-from linux-2.6.18-rc1.orig/drivers/video/riva/fbdev.c linux-2.6.18-rc1/drivers/video/riva/fbdev.c
--- linux-2.6.18-rc1.orig/drivers/video/riva/fbdev.c 2006-07-08 12:27:08.000000000 +0200
+++ linux-2.6.18-rc1/drivers/video/riva/fbdev.c 2006-07-08 12:28:32.000000000 +0200
@@ -278,9 +278,11 @@ static const struct riva_regs reg_templa
*/
#define MIN_LEVEL 0x158
#define MAX_LEVEL 0x534
+#define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX)
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)
{
@@ -288,9 +290,7 @@ static int riva_bl_get_level_brightness(
int nlevel;
/* Get and convert the value */
- mutex_lock(&info->bl_mutex);
- nlevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_LEVEL;
- mutex_unlock(&info->bl_mutex);
+ nlevel = MIN_LEVEL + info->bl_curve[level] * LEVEL_STEP;
if (nlevel < 0)
nlevel = 0;
@@ -302,7 +302,8 @@ static int riva_bl_get_level_brightness(
return nlevel;
}
-static int riva_bl_update_status(struct backlight_device *bd)
+/* Call with fb_info->bl_mutex held */
+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;
@@ -327,6 +328,19 @@ static int riva_bl_update_status(struct
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;
@@ -339,6 +353,16 @@ static struct backlight_properties riva_
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
};
+static void riva_bl_set_power(struct fb_info *info, int power)
+{
+ mutex_lock(&info->bl_mutex);
+ up(&info->bl_dev->sem);
+ info->bl_dev->props->power = power;
+ __riva_bl_update_status(info->bl_dev);
+ down(&info->bl_dev->sem);
+ mutex_unlock(&info->bl_mutex);
+}
+
static void riva_bl_init(struct riva_par *par)
{
struct fb_info *info = pci_get_drvdata(par->pdev);
@@ -419,6 +443,7 @@ static void riva_bl_exit(struct riva_par
#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_set_power(struct fb_info *info, int power) {}
#endif /* CONFIG_FB_RIVA_BACKLIGHT */
/* ------------------------------------------------------------------------- *
@@ -1337,16 +1362,7 @@ static int rivafb_blank(int blank, struc
SEQout(par, 0x01, tmp);
CRTCout(par, 0x1a, vesa);
-#ifdef CONFIG_FB_RIVA_BACKLIGHT
- mutex_lock(&info->bl_mutex);
- if (info->bl_dev) {
- down(&info->bl_dev->sem);
- info->bl_dev->props->power = blank;
- info->bl_dev->props->update_status(info->bl_dev);
- up(&info->bl_dev->sem);
- }
- mutex_unlock(&info->bl_mutex);
-#endif
+ riva_bl_set_power(info, blank);
NVTRACE_LEAVE();
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Linux-fbdev-devel mailing list
Linux-fbdev-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-fbdev-devel
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2006-07-08 12:06 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-08 12:06 Locking fixes for powermac backlight infrastructure Michael Hanselmann
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.