diff options
Diffstat (limited to 'drivers/video/backlight')
-rw-r--r-- | drivers/video/backlight/backlight.c | 87 | ||||
-rw-r--r-- | drivers/video/backlight/lcd.c | 78 |
2 files changed, 104 insertions, 61 deletions
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index f439a588394a..1dac9e743427 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
@@ -14,6 +14,59 @@ | |||
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/fb.h> | 15 | #include <linux/fb.h> |
16 | 16 | ||
17 | |||
18 | #if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \ | ||
19 | defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)) | ||
20 | /* This callback gets called when something important happens inside a | ||
21 | * framebuffer driver. We're looking if that important event is blanking, | ||
22 | * and if it is, we're switching backlight power as well ... | ||
23 | */ | ||
24 | static int fb_notifier_callback(struct notifier_block *self, | ||
25 | unsigned long event, void *data) | ||
26 | { | ||
27 | struct backlight_device *bd; | ||
28 | struct fb_event *evdata = data; | ||
29 | |||
30 | /* If we aren't interested in this event, skip it immediately ... */ | ||
31 | if (event != FB_EVENT_BLANK) | ||
32 | return 0; | ||
33 | |||
34 | bd = container_of(self, struct backlight_device, fb_notif); | ||
35 | down(&bd->sem); | ||
36 | if (bd->props) | ||
37 | if (!bd->props->check_fb || | ||
38 | bd->props->check_fb(evdata->info)) { | ||
39 | bd->props->fb_blank = *(int *)evdata->data; | ||
40 | if (likely(bd->props && bd->props->update_status)) | ||
41 | bd->props->update_status(bd); | ||
42 | } | ||
43 | up(&bd->sem); | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | static int backlight_register_fb(struct backlight_device *bd) | ||
48 | { | ||
49 | memset(&bd->fb_notif, 0, sizeof(bd->fb_notif)); | ||
50 | bd->fb_notif.notifier_call = fb_notifier_callback; | ||
51 | |||
52 | return fb_register_client(&bd->fb_notif); | ||
53 | } | ||
54 | |||
55 | static void backlight_unregister_fb(struct backlight_device *bd) | ||
56 | { | ||
57 | fb_unregister_client(&bd->fb_notif); | ||
58 | } | ||
59 | #else | ||
60 | static inline int backlight_register_fb(struct backlight_device *bd) | ||
61 | { | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static inline void backlight_unregister_fb(struct backlight_device *bd) | ||
66 | { | ||
67 | } | ||
68 | #endif /* CONFIG_FB */ | ||
69 | |||
17 | static ssize_t backlight_show_power(struct class_device *cdev, char *buf) | 70 | static ssize_t backlight_show_power(struct class_device *cdev, char *buf) |
18 | { | 71 | { |
19 | int rc = -ENXIO; | 72 | int rc = -ENXIO; |
@@ -151,33 +204,6 @@ static const struct class_device_attribute bl_class_device_attributes[] = { | |||
151 | DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), | 204 | DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), |
152 | }; | 205 | }; |
153 | 206 | ||
154 | /* This callback gets called when something important happens inside a | ||
155 | * framebuffer driver. We're looking if that important event is blanking, | ||
156 | * and if it is, we're switching backlight power as well ... | ||
157 | */ | ||
158 | static int fb_notifier_callback(struct notifier_block *self, | ||
159 | unsigned long event, void *data) | ||
160 | { | ||
161 | struct backlight_device *bd; | ||
162 | struct fb_event *evdata =(struct fb_event *)data; | ||
163 | |||
164 | /* If we aren't interested in this event, skip it immediately ... */ | ||
165 | if (event != FB_EVENT_BLANK) | ||
166 | return 0; | ||
167 | |||
168 | bd = container_of(self, struct backlight_device, fb_notif); | ||
169 | down(&bd->sem); | ||
170 | if (bd->props) | ||
171 | if (!bd->props->check_fb || | ||
172 | bd->props->check_fb(evdata->info)) { | ||
173 | bd->props->fb_blank = *(int *)evdata->data; | ||
174 | if (likely(bd->props && bd->props->update_status)) | ||
175 | bd->props->update_status(bd); | ||
176 | } | ||
177 | up(&bd->sem); | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | /** | 207 | /** |
182 | * backlight_device_register - create and register a new object of | 208 | * backlight_device_register - create and register a new object of |
183 | * backlight_device class. | 209 | * backlight_device class. |
@@ -215,10 +241,7 @@ error: kfree(new_bd); | |||
215 | return ERR_PTR(rc); | 241 | return ERR_PTR(rc); |
216 | } | 242 | } |
217 | 243 | ||
218 | memset(&new_bd->fb_notif, 0, sizeof(new_bd->fb_notif)); | 244 | rc = backlight_register_fb(new_bd); |
219 | new_bd->fb_notif.notifier_call = fb_notifier_callback; | ||
220 | |||
221 | rc = fb_register_client(&new_bd->fb_notif); | ||
222 | if (unlikely(rc)) | 245 | if (unlikely(rc)) |
223 | goto error; | 246 | goto error; |
224 | 247 | ||
@@ -268,7 +291,7 @@ void backlight_device_unregister(struct backlight_device *bd) | |||
268 | bd->props = NULL; | 291 | bd->props = NULL; |
269 | up(&bd->sem); | 292 | up(&bd->sem); |
270 | 293 | ||
271 | fb_unregister_client(&bd->fb_notif); | 294 | backlight_unregister_fb(bd); |
272 | 295 | ||
273 | class_device_unregister(&bd->class_dev); | 296 | class_device_unregister(&bd->class_dev); |
274 | } | 297 | } |
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 58c37d489107..f6e041627edb 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c | |||
@@ -14,6 +14,53 @@ | |||
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/fb.h> | 15 | #include <linux/fb.h> |
16 | 16 | ||
17 | #if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \ | ||
18 | defined(CONFIG_LCD_CLASS_DEVICE_MODULE)) | ||
19 | /* This callback gets called when something important happens inside a | ||
20 | * framebuffer driver. We're looking if that important event is blanking, | ||
21 | * and if it is, we're switching lcd power as well ... | ||
22 | */ | ||
23 | static int fb_notifier_callback(struct notifier_block *self, | ||
24 | unsigned long event, void *data) | ||
25 | { | ||
26 | struct lcd_device *ld; | ||
27 | struct fb_event *evdata = data; | ||
28 | |||
29 | /* If we aren't interested in this event, skip it immediately ... */ | ||
30 | if (event != FB_EVENT_BLANK) | ||
31 | return 0; | ||
32 | |||
33 | ld = container_of(self, struct lcd_device, fb_notif); | ||
34 | down(&ld->sem); | ||
35 | if (ld->props) | ||
36 | if (!ld->props->check_fb || ld->props->check_fb(evdata->info)) | ||
37 | ld->props->set_power(ld, *(int *)evdata->data); | ||
38 | up(&ld->sem); | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static int lcd_register_fb(struct lcd_device *ld) | ||
43 | { | ||
44 | memset(&ld->fb_notif, 0, sizeof(&ld->fb_notif)); | ||
45 | ld->fb_notif.notifier_call = fb_notifier_callback; | ||
46 | return fb_register_client(&ld->fb_notif); | ||
47 | } | ||
48 | |||
49 | static void lcd_unregister_fb(struct lcd_device *ld) | ||
50 | { | ||
51 | fb_unregister_client(&ld->fb_notif); | ||
52 | } | ||
53 | #else | ||
54 | static int lcd_register_fb(struct lcd_device *ld) | ||
55 | { | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static inline void lcd_unregister_fb(struct lcd_device *ld) | ||
60 | { | ||
61 | } | ||
62 | #endif /* CONFIG_FB */ | ||
63 | |||
17 | static ssize_t lcd_show_power(struct class_device *cdev, char *buf) | 64 | static ssize_t lcd_show_power(struct class_device *cdev, char *buf) |
18 | { | 65 | { |
19 | int rc; | 66 | int rc; |
@@ -127,29 +174,6 @@ static const struct class_device_attribute lcd_class_device_attributes[] = { | |||
127 | DECLARE_ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL), | 174 | DECLARE_ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL), |
128 | }; | 175 | }; |
129 | 176 | ||
130 | /* This callback gets called when something important happens inside a | ||
131 | * framebuffer driver. We're looking if that important event is blanking, | ||
132 | * and if it is, we're switching lcd power as well ... | ||
133 | */ | ||
134 | static int fb_notifier_callback(struct notifier_block *self, | ||
135 | unsigned long event, void *data) | ||
136 | { | ||
137 | struct lcd_device *ld; | ||
138 | struct fb_event *evdata =(struct fb_event *)data; | ||
139 | |||
140 | /* If we aren't interested in this event, skip it immediately ... */ | ||
141 | if (event != FB_EVENT_BLANK) | ||
142 | return 0; | ||
143 | |||
144 | ld = container_of(self, struct lcd_device, fb_notif); | ||
145 | down(&ld->sem); | ||
146 | if (ld->props) | ||
147 | if (!ld->props->check_fb || ld->props->check_fb(evdata->info)) | ||
148 | ld->props->set_power(ld, *(int *)evdata->data); | ||
149 | up(&ld->sem); | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | /** | 177 | /** |
154 | * lcd_device_register - register a new object of lcd_device class. | 178 | * lcd_device_register - register a new object of lcd_device class. |
155 | * @name: the name of the new object(must be the same as the name of the | 179 | * @name: the name of the new object(must be the same as the name of the |
@@ -186,10 +210,8 @@ error: kfree(new_ld); | |||
186 | return ERR_PTR(rc); | 210 | return ERR_PTR(rc); |
187 | } | 211 | } |
188 | 212 | ||
189 | memset(&new_ld->fb_notif, 0, sizeof(new_ld->fb_notif)); | 213 | rc = lcd_register_fb(new_ld); |
190 | new_ld->fb_notif.notifier_call = fb_notifier_callback; | ||
191 | 214 | ||
192 | rc = fb_register_client(&new_ld->fb_notif); | ||
193 | if (unlikely(rc)) | 215 | if (unlikely(rc)) |
194 | goto error; | 216 | goto error; |
195 | 217 | ||
@@ -232,9 +254,7 @@ void lcd_device_unregister(struct lcd_device *ld) | |||
232 | down(&ld->sem); | 254 | down(&ld->sem); |
233 | ld->props = NULL; | 255 | ld->props = NULL; |
234 | up(&ld->sem); | 256 | up(&ld->sem); |
235 | 257 | lcd_unregister_fb(ld); | |
236 | fb_unregister_client(&ld->fb_notif); | ||
237 | |||
238 | class_device_unregister(&ld->class_dev); | 258 | class_device_unregister(&ld->class_dev); |
239 | } | 259 | } |
240 | EXPORT_SYMBOL(lcd_device_unregister); | 260 | EXPORT_SYMBOL(lcd_device_unregister); |