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 /include | |
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>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/backlight.h | 26 | ||||
-rw-r--r-- | include/linux/lcd.h | 26 |
2 files changed, 52 insertions, 0 deletions
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); |