|
@@ -14,6 +14,59 @@
|
|
|
#include <linux/err.h>
|
|
|
#include <linux/fb.h>
|
|
|
|
|
|
+
|
|
|
+#if defined(CONFIG_FB) || (defined(CONFIG_FB_MODULE) && \
|
|
|
+ defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE))
|
|
|
+/* This callback gets called when something important happens inside a
|
|
|
+ * framebuffer driver. We're looking if that important event is blanking,
|
|
|
+ * and if it is, we're switching backlight power as well ...
|
|
|
+ */
|
|
|
+static int fb_notifier_callback(struct notifier_block *self,
|
|
|
+ unsigned long event, void *data)
|
|
|
+{
|
|
|
+ struct backlight_device *bd;
|
|
|
+ struct fb_event *evdata = data;
|
|
|
+
|
|
|
+ /* If we aren't interested in this event, skip it immediately ... */
|
|
|
+ if (event != FB_EVENT_BLANK)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ bd = container_of(self, struct backlight_device, fb_notif);
|
|
|
+ down(&bd->sem);
|
|
|
+ if (bd->props)
|
|
|
+ if (!bd->props->check_fb ||
|
|
|
+ bd->props->check_fb(evdata->info)) {
|
|
|
+ bd->props->fb_blank = *(int *)evdata->data;
|
|
|
+ if (likely(bd->props && bd->props->update_status))
|
|
|
+ bd->props->update_status(bd);
|
|
|
+ }
|
|
|
+ up(&bd->sem);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int backlight_register_fb(struct backlight_device *bd)
|
|
|
+{
|
|
|
+ memset(&bd->fb_notif, 0, sizeof(bd->fb_notif));
|
|
|
+ bd->fb_notif.notifier_call = fb_notifier_callback;
|
|
|
+
|
|
|
+ return fb_register_client(&bd->fb_notif);
|
|
|
+}
|
|
|
+
|
|
|
+static void backlight_unregister_fb(struct backlight_device *bd)
|
|
|
+{
|
|
|
+ fb_unregister_client(&bd->fb_notif);
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline int backlight_register_fb(struct backlight_device *bd)
|
|
|
+{
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static inline void backlight_unregister_fb(struct backlight_device *bd)
|
|
|
+{
|
|
|
+}
|
|
|
+#endif /* CONFIG_FB */
|
|
|
+
|
|
|
static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
|
|
|
{
|
|
|
int rc = -ENXIO;
|
|
@@ -151,33 +204,6 @@ static const struct class_device_attribute bl_class_device_attributes[] = {
|
|
|
DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
|
|
|
};
|
|
|
|
|
|
-/* This callback gets called when something important happens inside a
|
|
|
- * framebuffer driver. We're looking if that important event is blanking,
|
|
|
- * and if it is, we're switching backlight power as well ...
|
|
|
- */
|
|
|
-static int fb_notifier_callback(struct notifier_block *self,
|
|
|
- unsigned long event, void *data)
|
|
|
-{
|
|
|
- struct backlight_device *bd;
|
|
|
- struct fb_event *evdata =(struct fb_event *)data;
|
|
|
-
|
|
|
- /* If we aren't interested in this event, skip it immediately ... */
|
|
|
- if (event != FB_EVENT_BLANK)
|
|
|
- return 0;
|
|
|
-
|
|
|
- bd = container_of(self, struct backlight_device, fb_notif);
|
|
|
- down(&bd->sem);
|
|
|
- if (bd->props)
|
|
|
- if (!bd->props->check_fb ||
|
|
|
- bd->props->check_fb(evdata->info)) {
|
|
|
- bd->props->fb_blank = *(int *)evdata->data;
|
|
|
- if (likely(bd->props && bd->props->update_status))
|
|
|
- bd->props->update_status(bd);
|
|
|
- }
|
|
|
- up(&bd->sem);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* backlight_device_register - create and register a new object of
|
|
|
* backlight_device class.
|
|
@@ -215,10 +241,7 @@ error: kfree(new_bd);
|
|
|
return ERR_PTR(rc);
|
|
|
}
|
|
|
|
|
|
- memset(&new_bd->fb_notif, 0, sizeof(new_bd->fb_notif));
|
|
|
- new_bd->fb_notif.notifier_call = fb_notifier_callback;
|
|
|
-
|
|
|
- rc = fb_register_client(&new_bd->fb_notif);
|
|
|
+ rc = backlight_register_fb(new_bd);
|
|
|
if (unlikely(rc))
|
|
|
goto error;
|
|
|
|
|
@@ -268,7 +291,7 @@ void backlight_device_unregister(struct backlight_device *bd)
|
|
|
bd->props = NULL;
|
|
|
up(&bd->sem);
|
|
|
|
|
|
- fb_unregister_client(&bd->fb_notif);
|
|
|
+ backlight_unregister_fb(bd);
|
|
|
|
|
|
class_device_unregister(&bd->class_dev);
|
|
|
}
|