Merge tag 'backlight-for-linus-3.15' of git://git.kernel.org/pub/scm/linux/kernel...
[linux.git] / drivers / video / backlight / backlight.c
index 20b276e1f894465a140165c2f90a44f479e37597..bd2172c2d650705a5e9e03fe4a251aefccc7b789 100644 (file)
@@ -34,13 +34,15 @@ static const char *const backlight_types[] = {
                           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 ...
+ * and if it is and necessary, 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;
+       int node = evdata->info->node;
+       int fb_blank = 0;
 
        /* If we aren't interested in this event, skip it immediately ... */
        if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK)
@@ -51,12 +53,24 @@ static int fb_notifier_callback(struct notifier_block *self,
        if (bd->ops)
                if (!bd->ops->check_fb ||
                    bd->ops->check_fb(bd, evdata->info)) {
-                       bd->props.fb_blank = *(int *)evdata->data;
-                       if (bd->props.fb_blank == FB_BLANK_UNBLANK)
-                               bd->props.state &= ~BL_CORE_FBBLANK;
-                       else
-                               bd->props.state |= BL_CORE_FBBLANK;
-                       backlight_update_status(bd);
+                       fb_blank = *(int *)evdata->data;
+                       if (fb_blank == FB_BLANK_UNBLANK &&
+                           !bd->fb_bl_on[node]) {
+                               bd->fb_bl_on[node] = true;
+                               if (!bd->use_count++) {
+                                       bd->props.state &= ~BL_CORE_FBBLANK;
+                                       bd->props.fb_blank = FB_BLANK_UNBLANK;
+                                       backlight_update_status(bd);
+                               }
+                       } else if (fb_blank != FB_BLANK_UNBLANK &&
+                                  bd->fb_bl_on[node]) {
+                               bd->fb_bl_on[node] = false;
+                               if (!(--bd->use_count)) {
+                                       bd->props.state |= BL_CORE_FBBLANK;
+                                       bd->props.fb_blank = fb_blank;
+                                       backlight_update_status(bd);
+                               }
+                       }
                }
        mutex_unlock(&bd->ops_lock);
        return 0;