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/linux | |
| 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/linux')
| -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); |
