diff options
author | Richard Purdie <rpurdie@rpsys.net> | 2007-02-08 17:25:09 -0500 |
---|---|---|
committer | Richard Purdie <rpurdie@rpsys.net> | 2007-02-20 03:38:45 -0500 |
commit | 28ee086d5b36aab2931f6740e409bb0fb6c65e5f (patch) | |
tree | 0a308c80affcc39c2c869f29f1109e5ee9d6140f | |
parent | a8db3c1948eb30cd6988b5b96b654f591e6280b1 (diff) |
backlight: Fix external uses of backlight internal semaphore
backlight_device->sem has a very specific use as documented in the
header file. The external users of this are using it for a different
reason, to serialise access to the update_status() method.
backlight users were supposed to implement their own internal
serialisation of update_status() if needed but everyone is doing
things differently and incorrectly. Therefore add a global mutex to
take care of serialisation for everyone, once and for all.
Locking for get_brightness remains optional since most users don't
need it.
Also update the lcd class in a similar way.
Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
-rw-r--r-- | arch/powerpc/kernel/traps.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/backlight.c | 19 | ||||
-rw-r--r-- | drivers/macintosh/via-pmu-backlight.c | 4 | ||||
-rw-r--r-- | drivers/misc/asus-laptop.c | 20 | ||||
-rw-r--r-- | drivers/usb/misc/appledisplay.c | 6 | ||||
-rw-r--r-- | drivers/video/aty/aty128fb.c | 6 | ||||
-rw-r--r-- | drivers/video/aty/atyfb_base.c | 6 | ||||
-rw-r--r-- | drivers/video/aty/radeon_backlight.c | 4 | ||||
-rw-r--r-- | drivers/video/backlight/backlight.c | 10 | ||||
-rw-r--r-- | drivers/video/backlight/lcd.c | 1 | ||||
-rw-r--r-- | drivers/video/chipsfb.c | 8 | ||||
-rw-r--r-- | drivers/video/nvidia/nv_backlight.c | 6 | ||||
-rw-r--r-- | drivers/video/riva/fbdev.c | 6 | ||||
-rw-r--r-- | include/linux/backlight.h | 26 | ||||
-rw-r--r-- | include/linux/lcd.h | 26 |
15 files changed, 76 insertions, 76 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index dcc6f159fd94..35ce07b6a5bc 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -107,12 +107,10 @@ int die(const char *str, struct pt_regs *regs, long err) | |||
107 | if (machine_is(powermac) && pmac_backlight) { | 107 | if (machine_is(powermac) && pmac_backlight) { |
108 | struct backlight_properties *props; | 108 | struct backlight_properties *props; |
109 | 109 | ||
110 | down(&pmac_backlight->sem); | ||
111 | props = pmac_backlight->props; | 110 | props = pmac_backlight->props; |
112 | props->brightness = props->max_brightness; | 111 | props->brightness = props->max_brightness; |
113 | props->power = FB_BLANK_UNBLANK; | 112 | props->power = FB_BLANK_UNBLANK; |
114 | props->update_status(pmac_backlight); | 113 | backlight_update_status(pmac_backlight); |
115 | up(&pmac_backlight->sem); | ||
116 | } | 114 | } |
117 | mutex_unlock(&pmac_backlight_mutex); | 115 | mutex_unlock(&pmac_backlight_mutex); |
118 | #endif | 116 | #endif |
diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c index c3a89414ddc0..1be358c1448a 100644 --- a/arch/powerpc/platforms/powermac/backlight.c +++ b/arch/powerpc/platforms/powermac/backlight.c | |||
@@ -37,7 +37,9 @@ static int pmac_backlight_set_legacy_queued; | |||
37 | */ | 37 | */ |
38 | static atomic_t kernel_backlight_disabled = ATOMIC_INIT(0); | 38 | static atomic_t kernel_backlight_disabled = ATOMIC_INIT(0); |
39 | 39 | ||
40 | /* Protect the pmac_backlight variable */ | 40 | /* Protect the pmac_backlight variable below. |
41 | You should hold this lock when using the pmac_backlight pointer to | ||
42 | prevent its potential removal. */ | ||
41 | DEFINE_MUTEX(pmac_backlight_mutex); | 43 | DEFINE_MUTEX(pmac_backlight_mutex); |
42 | 44 | ||
43 | /* Main backlight storage | 45 | /* Main backlight storage |
@@ -49,9 +51,6 @@ DEFINE_MUTEX(pmac_backlight_mutex); | |||
49 | * internal display, it doesn't matter. Other backlight drivers can be used | 51 | * internal display, it doesn't matter. Other backlight drivers can be used |
50 | * independently. | 52 | * independently. |
51 | * | 53 | * |
52 | * Lock ordering: | ||
53 | * pmac_backlight_mutex (global, main backlight) | ||
54 | * pmac_backlight->sem (backlight class) | ||
55 | */ | 54 | */ |
56 | struct backlight_device *pmac_backlight; | 55 | struct backlight_device *pmac_backlight; |
57 | 56 | ||
@@ -104,7 +103,6 @@ static void pmac_backlight_key_worker(struct work_struct *work) | |||
104 | struct backlight_properties *props; | 103 | struct backlight_properties *props; |
105 | int brightness; | 104 | int brightness; |
106 | 105 | ||
107 | down(&pmac_backlight->sem); | ||
108 | props = pmac_backlight->props; | 106 | props = pmac_backlight->props; |
109 | 107 | ||
110 | brightness = props->brightness + | 108 | brightness = props->brightness + |
@@ -117,9 +115,7 @@ static void pmac_backlight_key_worker(struct work_struct *work) | |||
117 | brightness = props->max_brightness; | 115 | brightness = props->max_brightness; |
118 | 116 | ||
119 | props->brightness = brightness; | 117 | props->brightness = brightness; |
120 | props->update_status(pmac_backlight); | 118 | backlight_update_status(pmac_backlight); |
121 | |||
122 | up(&pmac_backlight->sem); | ||
123 | } | 119 | } |
124 | mutex_unlock(&pmac_backlight_mutex); | 120 | mutex_unlock(&pmac_backlight_mutex); |
125 | } | 121 | } |
@@ -145,7 +141,6 @@ static int __pmac_backlight_set_legacy_brightness(int brightness) | |||
145 | if (pmac_backlight) { | 141 | if (pmac_backlight) { |
146 | struct backlight_properties *props; | 142 | struct backlight_properties *props; |
147 | 143 | ||
148 | down(&pmac_backlight->sem); | ||
149 | props = pmac_backlight->props; | 144 | props = pmac_backlight->props; |
150 | props->brightness = brightness * | 145 | props->brightness = brightness * |
151 | (props->max_brightness + 1) / | 146 | (props->max_brightness + 1) / |
@@ -156,8 +151,7 @@ static int __pmac_backlight_set_legacy_brightness(int brightness) | |||
156 | else if (props->brightness < 0) | 151 | else if (props->brightness < 0) |
157 | props->brightness = 0; | 152 | props->brightness = 0; |
158 | 153 | ||
159 | props->update_status(pmac_backlight); | 154 | backlight_update_status(pmac_backlight); |
160 | up(&pmac_backlight->sem); | ||
161 | 155 | ||
162 | error = 0; | 156 | error = 0; |
163 | } | 157 | } |
@@ -196,14 +190,11 @@ int pmac_backlight_get_legacy_brightness() | |||
196 | if (pmac_backlight) { | 190 | if (pmac_backlight) { |
197 | struct backlight_properties *props; | 191 | struct backlight_properties *props; |
198 | 192 | ||
199 | down(&pmac_backlight->sem); | ||
200 | props = pmac_backlight->props; | 193 | props = pmac_backlight->props; |
201 | 194 | ||
202 | result = props->brightness * | 195 | result = props->brightness * |
203 | (OLD_BACKLIGHT_MAX + 1) / | 196 | (OLD_BACKLIGHT_MAX + 1) / |
204 | (props->max_brightness + 1); | 197 | (props->max_brightness + 1); |
205 | |||
206 | up(&pmac_backlight->sem); | ||
207 | } | 198 | } |
208 | mutex_unlock(&pmac_backlight_mutex); | 199 | mutex_unlock(&pmac_backlight_mutex); |
209 | 200 | ||
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c index db8bcc35bc03..7ba2042b2dd0 100644 --- a/drivers/macintosh/via-pmu-backlight.c +++ b/drivers/macintosh/via-pmu-backlight.c | |||
@@ -166,11 +166,9 @@ void __init pmu_backlight_init() | |||
166 | pmu_backlight_data.max_brightness / 15); | 166 | pmu_backlight_data.max_brightness / 15); |
167 | } | 167 | } |
168 | 168 | ||
169 | down(&bd->sem); | ||
170 | bd->props->brightness = level; | 169 | bd->props->brightness = level; |
171 | bd->props->power = FB_BLANK_UNBLANK; | 170 | bd->props->power = FB_BLANK_UNBLANK; |
172 | bd->props->update_status(bd); | 171 | backlight_update_status(bd); |
173 | up(&bd->sem); | ||
174 | 172 | ||
175 | mutex_lock(&pmac_backlight_mutex); | 173 | mutex_lock(&pmac_backlight_mutex); |
176 | if (!pmac_backlight) | 174 | if (!pmac_backlight) |
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index d15ee5e34201..7ace5b9a3d28 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c | |||
@@ -348,13 +348,8 @@ static void lcd_blank(int blank) | |||
348 | struct backlight_device *bd = asus_backlight_device; | 348 | struct backlight_device *bd = asus_backlight_device; |
349 | 349 | ||
350 | if (bd) { | 350 | if (bd) { |
351 | down(&bd->sem); | 351 | bd->props->power = blank; |
352 | if (likely(bd->props)) { | 352 | backlight_update_status(bd); |
353 | bd->props->power = blank; | ||
354 | if (likely(bd->props->update_status)) | ||
355 | bd->props->update_status(bd); | ||
356 | } | ||
357 | up(&bd->sem); | ||
358 | } | 353 | } |
359 | } | 354 | } |
360 | 355 | ||
@@ -1028,14 +1023,9 @@ static int asus_backlight_init(struct device *dev) | |||
1028 | 1023 | ||
1029 | asus_backlight_device = bd; | 1024 | asus_backlight_device = bd; |
1030 | 1025 | ||
1031 | down(&bd->sem); | 1026 | bd->props->brightness = read_brightness(NULL); |
1032 | if (likely(bd->props)) { | 1027 | bd->props->power = FB_BLANK_UNBLANK; |
1033 | bd->props->brightness = read_brightness(NULL); | 1028 | backlight_update_status(bd); |
1034 | bd->props->power = FB_BLANK_UNBLANK; | ||
1035 | if (likely(bd->props->update_status)) | ||
1036 | bd->props->update_status(bd); | ||
1037 | } | ||
1038 | up(&bd->sem); | ||
1039 | } | 1029 | } |
1040 | return 0; | 1030 | return 0; |
1041 | } | 1031 | } |
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 416cde5893af..cd2c5574cf93 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c | |||
@@ -189,11 +189,9 @@ static void appledisplay_work(struct work_struct *work) | |||
189 | container_of(work, struct appledisplay, work.work); | 189 | container_of(work, struct appledisplay, work.work); |
190 | int retval; | 190 | int retval; |
191 | 191 | ||
192 | up(&pdata->bd->sem); | ||
193 | retval = appledisplay_bl_get_brightness(pdata->bd); | 192 | retval = appledisplay_bl_get_brightness(pdata->bd); |
194 | if (retval >= 0) | 193 | if (retval >= 0) |
195 | pdata->bd->props->brightness = retval; | 194 | pdata->bd->props->brightness = retval; |
196 | down(&pdata->bd->sem); | ||
197 | 195 | ||
198 | /* Poll again in about 125ms if there's still a button pressed */ | 196 | /* Poll again in about 125ms if there's still a button pressed */ |
199 | if (pdata->button_pressed) | 197 | if (pdata->button_pressed) |
@@ -288,9 +286,7 @@ static int appledisplay_probe(struct usb_interface *iface, | |||
288 | } | 286 | } |
289 | 287 | ||
290 | /* Try to get brightness */ | 288 | /* Try to get brightness */ |
291 | up(&pdata->bd->sem); | ||
292 | brightness = appledisplay_bl_get_brightness(pdata->bd); | 289 | brightness = appledisplay_bl_get_brightness(pdata->bd); |
293 | down(&pdata->bd->sem); | ||
294 | 290 | ||
295 | if (brightness < 0) { | 291 | if (brightness < 0) { |
296 | retval = brightness; | 292 | retval = brightness; |
@@ -299,9 +295,7 @@ static int appledisplay_probe(struct usb_interface *iface, | |||
299 | } | 295 | } |
300 | 296 | ||
301 | /* Set brightness in backlight device */ | 297 | /* Set brightness in backlight device */ |
302 | up(&pdata->bd->sem); | ||
303 | pdata->bd->props->brightness = brightness; | 298 | pdata->bd->props->brightness = brightness; |
304 | down(&pdata->bd->sem); | ||
305 | 299 | ||
306 | /* save our data pointer in the interface device */ | 300 | /* save our data pointer in the interface device */ |
307 | usb_set_intfdata(iface, pdata); | 301 | usb_set_intfdata(iface, pdata); |
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index 1fa211c0d7bb..5d8f73b2b66f 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c | |||
@@ -1807,10 +1807,8 @@ static void aty128_bl_set_power(struct fb_info *info, int power) | |||
1807 | mutex_lock(&info->bl_mutex); | 1807 | mutex_lock(&info->bl_mutex); |
1808 | 1808 | ||
1809 | if (info->bl_dev) { | 1809 | if (info->bl_dev) { |
1810 | down(&info->bl_dev->sem); | ||
1811 | info->bl_dev->props->power = power; | 1810 | info->bl_dev->props->power = power; |
1812 | __aty128_bl_update_status(info->bl_dev); | 1811 | __aty128_bl_update_status(info->bl_dev); |
1813 | up(&info->bl_dev->sem); | ||
1814 | } | 1812 | } |
1815 | 1813 | ||
1816 | mutex_unlock(&info->bl_mutex); | 1814 | mutex_unlock(&info->bl_mutex); |
@@ -1847,11 +1845,9 @@ static void aty128_bl_init(struct aty128fb_par *par) | |||
1847 | 219 * FB_BACKLIGHT_MAX / MAX_LEVEL); | 1845 | 219 * FB_BACKLIGHT_MAX / MAX_LEVEL); |
1848 | mutex_unlock(&info->bl_mutex); | 1846 | mutex_unlock(&info->bl_mutex); |
1849 | 1847 | ||
1850 | down(&bd->sem); | ||
1851 | bd->props->brightness = aty128_bl_data.max_brightness; | 1848 | bd->props->brightness = aty128_bl_data.max_brightness; |
1852 | bd->props->power = FB_BLANK_UNBLANK; | 1849 | bd->props->power = FB_BLANK_UNBLANK; |
1853 | bd->props->update_status(bd); | 1850 | backlight_update_status(bd); |
1854 | up(&bd->sem); | ||
1855 | 1851 | ||
1856 | #ifdef CONFIG_PMAC_BACKLIGHT | 1852 | #ifdef CONFIG_PMAC_BACKLIGHT |
1857 | mutex_lock(&pmac_backlight_mutex); | 1853 | mutex_lock(&pmac_backlight_mutex); |
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 5ea5a00e58a3..23deb3566020 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c | |||
@@ -2188,10 +2188,8 @@ static void aty_bl_set_power(struct fb_info *info, int power) | |||
2188 | mutex_lock(&info->bl_mutex); | 2188 | mutex_lock(&info->bl_mutex); |
2189 | 2189 | ||
2190 | if (info->bl_dev) { | 2190 | if (info->bl_dev) { |
2191 | down(&info->bl_dev->sem); | ||
2192 | info->bl_dev->props->power = power; | 2191 | info->bl_dev->props->power = power; |
2193 | __aty_bl_update_status(info->bl_dev); | 2192 | __aty_bl_update_status(info->bl_dev); |
2194 | up(&info->bl_dev->sem); | ||
2195 | } | 2193 | } |
2196 | 2194 | ||
2197 | mutex_unlock(&info->bl_mutex); | 2195 | mutex_unlock(&info->bl_mutex); |
@@ -2224,11 +2222,9 @@ static void aty_bl_init(struct atyfb_par *par) | |||
2224 | 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); | 2222 | 0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL); |
2225 | mutex_unlock(&info->bl_mutex); | 2223 | mutex_unlock(&info->bl_mutex); |
2226 | 2224 | ||
2227 | down(&bd->sem); | ||
2228 | bd->props->brightness = aty_bl_data.max_brightness; | 2225 | bd->props->brightness = aty_bl_data.max_brightness; |
2229 | bd->props->power = FB_BLANK_UNBLANK; | 2226 | bd->props->power = FB_BLANK_UNBLANK; |
2230 | bd->props->update_status(bd); | 2227 | backlight_update_status(bd); |
2231 | up(&bd->sem); | ||
2232 | 2228 | ||
2233 | #ifdef CONFIG_PMAC_BACKLIGHT | 2229 | #ifdef CONFIG_PMAC_BACKLIGHT |
2234 | mutex_lock(&pmac_backlight_mutex); | 2230 | mutex_lock(&pmac_backlight_mutex); |
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index 8b66df6f199a..9cfcecac8b5e 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c | |||
@@ -194,11 +194,9 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo) | |||
194 | 217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL); | 194 | 217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL); |
195 | mutex_unlock(&rinfo->info->bl_mutex); | 195 | mutex_unlock(&rinfo->info->bl_mutex); |
196 | 196 | ||
197 | down(&bd->sem); | ||
198 | bd->props->brightness = radeon_bl_data.max_brightness; | 197 | bd->props->brightness = radeon_bl_data.max_brightness; |
199 | bd->props->power = FB_BLANK_UNBLANK; | 198 | bd->props->power = FB_BLANK_UNBLANK; |
200 | bd->props->update_status(bd); | 199 | backlight_update_status(bd); |
201 | up(&bd->sem); | ||
202 | 200 | ||
203 | #ifdef CONFIG_PMAC_BACKLIGHT | 201 | #ifdef CONFIG_PMAC_BACKLIGHT |
204 | mutex_lock(&pmac_backlight_mutex); | 202 | mutex_lock(&pmac_backlight_mutex); |
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 7a85be4d2b0a..347081daf7a4 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
@@ -37,8 +37,7 @@ static int fb_notifier_callback(struct notifier_block *self, | |||
37 | if (!bd->props->check_fb || | 37 | if (!bd->props->check_fb || |
38 | bd->props->check_fb(evdata->info)) { | 38 | bd->props->check_fb(evdata->info)) { |
39 | bd->props->fb_blank = *(int *)evdata->data; | 39 | bd->props->fb_blank = *(int *)evdata->data; |
40 | if (bd->props && bd->props->update_status) | 40 | backlight_update_status(bd); |
41 | bd->props->update_status(bd); | ||
42 | } | 41 | } |
43 | up(&bd->sem); | 42 | up(&bd->sem); |
44 | return 0; | 43 | return 0; |
@@ -97,8 +96,7 @@ static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, | |||
97 | if (bd->props) { | 96 | if (bd->props) { |
98 | pr_debug("backlight: set power to %d\n", power); | 97 | pr_debug("backlight: set power to %d\n", power); |
99 | bd->props->power = power; | 98 | bd->props->power = power; |
100 | if (bd->props->update_status) | 99 | backlight_update_status(bd); |
101 | bd->props->update_status(bd); | ||
102 | rc = count; | 100 | rc = count; |
103 | } | 101 | } |
104 | up(&bd->sem); | 102 | up(&bd->sem); |
@@ -140,8 +138,7 @@ static ssize_t backlight_store_brightness(struct class_device *cdev, const char | |||
140 | pr_debug("backlight: set brightness to %d\n", | 138 | pr_debug("backlight: set brightness to %d\n", |
141 | brightness); | 139 | brightness); |
142 | bd->props->brightness = brightness; | 140 | bd->props->brightness = brightness; |
143 | if (bd->props->update_status) | 141 | backlight_update_status(bd); |
144 | bd->props->update_status(bd); | ||
145 | rc = count; | 142 | rc = count; |
146 | } | 143 | } |
147 | } | 144 | } |
@@ -230,6 +227,7 @@ struct backlight_device *backlight_device_register(const char *name, | |||
230 | if (!new_bd) | 227 | if (!new_bd) |
231 | return ERR_PTR(-ENOMEM); | 228 | return ERR_PTR(-ENOMEM); |
232 | 229 | ||
230 | mutex_init(&new_bd->update_lock); | ||
233 | init_MUTEX(&new_bd->sem); | 231 | init_MUTEX(&new_bd->sem); |
234 | new_bd->props = bp; | 232 | new_bd->props = bp; |
235 | memset(&new_bd->class_dev, 0, sizeof(new_bd->class_dev)); | 233 | memset(&new_bd->class_dev, 0, sizeof(new_bd->class_dev)); |
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 959024812abc..1e1e61a4b5da 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c | |||
@@ -198,6 +198,7 @@ struct lcd_device *lcd_device_register(const char *name, void *devdata, | |||
198 | return ERR_PTR(-ENOMEM); | 198 | return ERR_PTR(-ENOMEM); |
199 | 199 | ||
200 | init_MUTEX(&new_ld->sem); | 200 | init_MUTEX(&new_ld->sem); |
201 | mutex_init(&new_ld->update_lock); | ||
201 | new_ld->props = lp; | 202 | new_ld->props = lp; |
202 | memset(&new_ld->class_dev, 0, sizeof(new_ld->class_dev)); | 203 | memset(&new_ld->class_dev, 0, sizeof(new_ld->class_dev)); |
203 | new_ld->class_dev.class = &lcd_class; | 204 | new_ld->class_dev.class = &lcd_class; |
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c index 73cb426bf2d7..9a656bc6295c 100644 --- a/drivers/video/chipsfb.c +++ b/drivers/video/chipsfb.c | |||
@@ -153,13 +153,11 @@ static int chipsfb_blank(int blank, struct fb_info *info) | |||
153 | * useful at blank = 1 too (saves battery, extends backlight | 153 | * useful at blank = 1 too (saves battery, extends backlight |
154 | * life) | 154 | * life) |
155 | */ | 155 | */ |
156 | down(&pmac_backlight->sem); | ||
157 | if (blank) | 156 | if (blank) |
158 | pmac_backlight->props->power = FB_BLANK_POWERDOWN; | 157 | pmac_backlight->props->power = FB_BLANK_POWERDOWN; |
159 | else | 158 | else |
160 | pmac_backlight->props->power = FB_BLANK_UNBLANK; | 159 | pmac_backlight->props->power = FB_BLANK_UNBLANK; |
161 | pmac_backlight->props->update_status(pmac_backlight); | 160 | backlight_update_status(pmac_backlight); |
162 | up(&pmac_backlight->sem); | ||
163 | } | 161 | } |
164 | 162 | ||
165 | mutex_unlock(&pmac_backlight_mutex); | 163 | mutex_unlock(&pmac_backlight_mutex); |
@@ -415,10 +413,8 @@ chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) | |||
415 | /* turn on the backlight */ | 413 | /* turn on the backlight */ |
416 | mutex_lock(&pmac_backlight_mutex); | 414 | mutex_lock(&pmac_backlight_mutex); |
417 | if (pmac_backlight) { | 415 | if (pmac_backlight) { |
418 | down(&pmac_backlight->sem); | ||
419 | pmac_backlight->props->power = FB_BLANK_UNBLANK; | 416 | pmac_backlight->props->power = FB_BLANK_UNBLANK; |
420 | pmac_backlight->props->update_status(pmac_backlight); | 417 | backlight_update_status(pmac_backlight); |
421 | up(&pmac_backlight->sem); | ||
422 | } | 418 | } |
423 | mutex_unlock(&pmac_backlight_mutex); | 419 | mutex_unlock(&pmac_backlight_mutex); |
424 | #endif /* CONFIG_PMAC_BACKLIGHT */ | 420 | #endif /* CONFIG_PMAC_BACKLIGHT */ |
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c index 4254c090dc4b..f5e42d0bd0da 100644 --- a/drivers/video/nvidia/nv_backlight.c +++ b/drivers/video/nvidia/nv_backlight.c | |||
@@ -114,10 +114,8 @@ void nvidia_bl_set_power(struct fb_info *info, int power) | |||
114 | mutex_lock(&info->bl_mutex); | 114 | mutex_lock(&info->bl_mutex); |
115 | 115 | ||
116 | if (info->bl_dev) { | 116 | if (info->bl_dev) { |
117 | down(&info->bl_dev->sem); | ||
118 | info->bl_dev->props->power = power; | 117 | info->bl_dev->props->power = power; |
119 | __nvidia_bl_update_status(info->bl_dev); | 118 | __nvidia_bl_update_status(info->bl_dev); |
120 | up(&info->bl_dev->sem); | ||
121 | } | 119 | } |
122 | 120 | ||
123 | mutex_unlock(&info->bl_mutex); | 121 | mutex_unlock(&info->bl_mutex); |
@@ -154,11 +152,9 @@ void nvidia_bl_init(struct nvidia_par *par) | |||
154 | 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL); | 152 | 0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL); |
155 | mutex_unlock(&info->bl_mutex); | 153 | mutex_unlock(&info->bl_mutex); |
156 | 154 | ||
157 | down(&bd->sem); | ||
158 | bd->props->brightness = nvidia_bl_data.max_brightness; | 155 | bd->props->brightness = nvidia_bl_data.max_brightness; |
159 | bd->props->power = FB_BLANK_UNBLANK; | 156 | bd->props->power = FB_BLANK_UNBLANK; |
160 | bd->props->update_status(bd); | 157 | backlight_update_status(bd); |
161 | up(&bd->sem); | ||
162 | 158 | ||
163 | #ifdef CONFIG_PMAC_BACKLIGHT | 159 | #ifdef CONFIG_PMAC_BACKLIGHT |
164 | mutex_lock(&pmac_backlight_mutex); | 160 | mutex_lock(&pmac_backlight_mutex); |
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index fd825711bb63..b70d18f7fcd9 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c | |||
@@ -357,10 +357,8 @@ static void riva_bl_set_power(struct fb_info *info, int power) | |||
357 | mutex_lock(&info->bl_mutex); | 357 | mutex_lock(&info->bl_mutex); |
358 | 358 | ||
359 | if (info->bl_dev) { | 359 | if (info->bl_dev) { |
360 | down(&info->bl_dev->sem); | ||
361 | info->bl_dev->props->power = power; | 360 | info->bl_dev->props->power = power; |
362 | __riva_bl_update_status(info->bl_dev); | 361 | __riva_bl_update_status(info->bl_dev); |
363 | up(&info->bl_dev->sem); | ||
364 | } | 362 | } |
365 | 363 | ||
366 | mutex_unlock(&info->bl_mutex); | 364 | mutex_unlock(&info->bl_mutex); |
@@ -397,11 +395,9 @@ static void riva_bl_init(struct riva_par *par) | |||
397 | FB_BACKLIGHT_MAX); | 395 | FB_BACKLIGHT_MAX); |
398 | mutex_unlock(&info->bl_mutex); | 396 | mutex_unlock(&info->bl_mutex); |
399 | 397 | ||
400 | down(&bd->sem); | ||
401 | bd->props->brightness = riva_bl_data.max_brightness; | 398 | bd->props->brightness = riva_bl_data.max_brightness; |
402 | bd->props->power = FB_BLANK_UNBLANK; | 399 | bd->props->power = FB_BLANK_UNBLANK; |
403 | bd->props->update_status(bd); | 400 | backlight_update_status(bd); |
404 | up(&bd->sem); | ||
405 | 401 | ||
406 | #ifdef CONFIG_PMAC_BACKLIGHT | 402 | #ifdef CONFIG_PMAC_BACKLIGHT |
407 | mutex_lock(&pmac_backlight_mutex); | 403 | mutex_lock(&pmac_backlight_mutex); |
diff --git a/include/linux/backlight.h b/include/linux/backlight.h index 287c62d956f2..d1426b852bdf 100644 --- a/include/linux/backlight.h +++ b/include/linux/backlight.h | |||
@@ -9,8 +9,24 @@ | |||
9 | #define _LINUX_BACKLIGHT_H | 9 | #define _LINUX_BACKLIGHT_H |
10 | 10 | ||
11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
12 | #include <linux/mutex.h> | ||
12 | #include <linux/notifier.h> | 13 | #include <linux/notifier.h> |
13 | 14 | ||
15 | /* Notes on locking: | ||
16 | * | ||
17 | * backlight_device->sem is an internal backlight lock protecting the props | ||
18 | * field and no code outside the core should need to touch it. | ||
19 | * | ||
20 | * Access to update_status() is serialised by the update_lock mutex since | ||
21 | * most drivers seem to need this and historically get it wrong. | ||
22 | * | ||
23 | * Most drivers don't need locking on their get_brightness() method. | ||
24 | * If yours does, you need to implement it in the driver. You can use the | ||
25 | * update_lock mutex if appropriate. | ||
26 | * | ||
27 | * Any other use of the locks below is probably wrong. | ||
28 | */ | ||
29 | |||
14 | struct backlight_device; | 30 | struct backlight_device; |
15 | struct fb_info; | 31 | struct fb_info; |
16 | 32 | ||
@@ -44,12 +60,22 @@ struct backlight_device { | |||
44 | struct semaphore sem; | 60 | struct semaphore sem; |
45 | /* If this is NULL, the backing module is unloaded */ | 61 | /* If this is NULL, the backing module is unloaded */ |
46 | struct backlight_properties *props; | 62 | struct backlight_properties *props; |
63 | /* Serialise access to update_status method */ | ||
64 | struct mutex update_lock; | ||
47 | /* The framebuffer notifier block */ | 65 | /* The framebuffer notifier block */ |
48 | struct notifier_block fb_notif; | 66 | struct notifier_block fb_notif; |
49 | /* The class device structure */ | 67 | /* The class device structure */ |
50 | struct class_device class_dev; | 68 | struct class_device class_dev; |
51 | }; | 69 | }; |
52 | 70 | ||
71 | static inline void backlight_update_status(struct backlight_device *bd) | ||
72 | { | ||
73 | mutex_lock(&bd->update_lock); | ||
74 | if (bd->props && bd->props->update_status) | ||
75 | bd->props->update_status(bd); | ||
76 | mutex_unlock(&bd->update_lock); | ||
77 | } | ||
78 | |||
53 | extern struct backlight_device *backlight_device_register(const char *name, | 79 | extern struct backlight_device *backlight_device_register(const char *name, |
54 | struct device *dev,void *devdata,struct backlight_properties *bp); | 80 | struct device *dev,void *devdata,struct backlight_properties *bp); |
55 | extern void backlight_device_unregister(struct backlight_device *bd); | 81 | extern void backlight_device_unregister(struct backlight_device *bd); |
diff --git a/include/linux/lcd.h b/include/linux/lcd.h index 8a468f168c45..bfbf6552eb51 100644 --- a/include/linux/lcd.h +++ b/include/linux/lcd.h | |||
@@ -9,8 +9,24 @@ | |||
9 | #define _LINUX_LCD_H | 9 | #define _LINUX_LCD_H |
10 | 10 | ||
11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
12 | #include <linux/mutex.h> | ||
12 | #include <linux/notifier.h> | 13 | #include <linux/notifier.h> |
13 | 14 | ||
15 | /* Notes on locking: | ||
16 | * | ||
17 | * lcd_device->sem is an internal backlight lock protecting the props | ||
18 | * field and no code outside the core should need to touch it. | ||
19 | * | ||
20 | * Access to set_power() is serialised by the update_lock mutex since | ||
21 | * most drivers seem to need this and historically get it wrong. | ||
22 | * | ||
23 | * Most drivers don't need locking on their get_power() method. | ||
24 | * If yours does, you need to implement it in the driver. You can use the | ||
25 | * update_lock mutex if appropriate. | ||
26 | * | ||
27 | * Any other use of the locks below is probably wrong. | ||
28 | */ | ||
29 | |||
14 | struct lcd_device; | 30 | struct lcd_device; |
15 | struct fb_info; | 31 | struct fb_info; |
16 | 32 | ||
@@ -39,12 +55,22 @@ struct lcd_device { | |||
39 | struct semaphore sem; | 55 | struct semaphore sem; |
40 | /* If this is NULL, the backing module is unloaded */ | 56 | /* If this is NULL, the backing module is unloaded */ |
41 | struct lcd_properties *props; | 57 | struct lcd_properties *props; |
58 | /* Serialise access to set_power method */ | ||
59 | struct mutex update_lock; | ||
42 | /* The framebuffer notifier block */ | 60 | /* The framebuffer notifier block */ |
43 | struct notifier_block fb_notif; | 61 | struct notifier_block fb_notif; |
44 | /* The class device structure */ | 62 | /* The class device structure */ |
45 | struct class_device class_dev; | 63 | struct class_device class_dev; |
46 | }; | 64 | }; |
47 | 65 | ||
66 | static inline void lcd_set_power(struct lcd_device *ld, int power) | ||
67 | { | ||
68 | mutex_lock(&ld->update_lock); | ||
69 | if (ld->props && ld->props->set_power) | ||
70 | ld->props->set_power(ld, power); | ||
71 | mutex_unlock(&ld->update_lock); | ||
72 | } | ||
73 | |||
48 | extern struct lcd_device *lcd_device_register(const char *name, | 74 | extern struct lcd_device *lcd_device_register(const char *name, |
49 | void *devdata, struct lcd_properties *lp); | 75 | void *devdata, struct lcd_properties *lp); |
50 | extern void lcd_device_unregister(struct lcd_device *ld); | 76 | extern void lcd_device_unregister(struct lcd_device *ld); |