Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

backlight: Add suspend/resume support to the backlight core

Add suspend/resume support to the backlight core and enable use of it
by appropriate drivers.

Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>

+63 -33
+34
drivers/video/backlight/backlight.c
··· 40 40 if (!bd->ops->check_fb || 41 41 bd->ops->check_fb(evdata->info)) { 42 42 bd->props.fb_blank = *(int *)evdata->data; 43 + if (bd->props.fb_blank == FB_BLANK_UNBLANK) 44 + bd->props.state &= ~BL_CORE_FBBLANK; 45 + else 46 + bd->props.state |= BL_CORE_FBBLANK; 43 47 backlight_update_status(bd); 44 48 } 45 49 mutex_unlock(&bd->ops_lock); ··· 169 165 170 166 static struct class *backlight_class; 171 167 168 + static int backlight_suspend(struct device *dev, pm_message_t state) 169 + { 170 + struct backlight_device *bd = to_backlight_device(dev); 171 + 172 + if (bd->ops->options & BL_CORE_SUSPENDRESUME) { 173 + mutex_lock(&bd->ops_lock); 174 + bd->props.state |= BL_CORE_SUSPENDED; 175 + backlight_update_status(bd); 176 + mutex_unlock(&bd->ops_lock); 177 + } 178 + 179 + return 0; 180 + } 181 + 182 + static int backlight_resume(struct device *dev) 183 + { 184 + struct backlight_device *bd = to_backlight_device(dev); 185 + 186 + if (bd->ops->options & BL_CORE_SUSPENDRESUME) { 187 + mutex_lock(&bd->ops_lock); 188 + bd->props.state &= ~BL_CORE_SUSPENDED; 189 + backlight_update_status(bd); 190 + mutex_unlock(&bd->ops_lock); 191 + } 192 + 193 + return 0; 194 + } 195 + 172 196 static void bl_device_release(struct device *dev) 173 197 { 174 198 struct backlight_device *bd = to_backlight_device(dev); ··· 313 281 } 314 282 315 283 backlight_class->dev_attrs = bl_device_attributes; 284 + backlight_class->suspend = backlight_suspend; 285 + backlight_class->resume = backlight_resume; 316 286 return 0; 317 287 } 318 288
+12 -33
drivers/video/backlight/corgi_bl.c
··· 24 24 static struct backlight_device *corgi_backlight_device; 25 25 static struct generic_bl_info *bl_machinfo; 26 26 27 - static unsigned long corgibl_flags; 28 - #define CORGIBL_SUSPENDED 0x01 29 - #define CORGIBL_BATTLOW 0x02 27 + /* Flag to signal when the battery is low */ 28 + #define CORGIBL_BATTLOW BL_CORE_DRIVER1 30 29 31 30 static int corgibl_send_intensity(struct backlight_device *bd) 32 31 { ··· 33 34 34 35 if (bd->props.power != FB_BLANK_UNBLANK) 35 36 intensity = 0; 36 - if (bd->props.fb_blank != FB_BLANK_UNBLANK) 37 + if (bd->props.state & BL_CORE_FBBLANK) 37 38 intensity = 0; 38 - if (corgibl_flags & CORGIBL_SUSPENDED) 39 + if (bd->props.state & BL_CORE_SUSPENDED) 39 40 intensity = 0; 40 - if (corgibl_flags & CORGIBL_BATTLOW) 41 + if (bd->props.state & CORGIBL_BATTLOW) 41 42 intensity &= bl_machinfo->limit_mask; 42 43 43 44 bl_machinfo->set_bl_intensity(intensity); ··· 50 51 return 0; 51 52 } 52 53 53 - #ifdef CONFIG_PM 54 - static int corgibl_suspend(struct platform_device *pdev, pm_message_t state) 55 - { 56 - struct backlight_device *bd = platform_get_drvdata(pdev); 57 - 58 - corgibl_flags |= CORGIBL_SUSPENDED; 59 - backlight_update_status(bd); 60 - return 0; 61 - } 62 - 63 - static int corgibl_resume(struct platform_device *pdev) 64 - { 65 - struct backlight_device *bd = platform_get_drvdata(pdev); 66 - 67 - corgibl_flags &= ~CORGIBL_SUSPENDED; 68 - backlight_update_status(bd); 69 - return 0; 70 - } 71 - #else 72 - #define corgibl_suspend NULL 73 - #define corgibl_resume NULL 74 - #endif 75 - 76 54 static int corgibl_get_intensity(struct backlight_device *bd) 77 55 { 78 56 return corgibl_intensity; ··· 61 85 */ 62 86 void corgibl_limit_intensity(int limit) 63 87 { 88 + struct backlight_device *bd = corgi_backlight_device; 89 + 90 + mutex_lock(&bd->ops_lock); 64 91 if (limit) 65 - corgibl_flags |= CORGIBL_BATTLOW; 92 + bd->props.state |= CORGIBL_BATTLOW; 66 93 else 67 - corgibl_flags &= ~CORGIBL_BATTLOW; 94 + bd->props.state &= ~CORGIBL_BATTLOW; 68 95 backlight_update_status(corgi_backlight_device); 96 + mutex_unlock(&bd->ops_lock); 69 97 } 70 98 EXPORT_SYMBOL(corgibl_limit_intensity); 71 99 72 100 73 101 static struct backlight_ops corgibl_ops = { 102 + .options = BL_CORE_SUSPENDRESUME, 74 103 .get_brightness = corgibl_get_intensity, 75 104 .update_status = corgibl_send_intensity, 76 105 }; ··· 125 144 static struct platform_driver corgibl_driver = { 126 145 .probe = corgibl_probe, 127 146 .remove = corgibl_remove, 128 - .suspend = corgibl_suspend, 129 - .resume = corgibl_resume, 130 147 .driver = { 131 148 .name = "generic-bl", 132 149 },
+1
drivers/video/backlight/mbp_nvidia_bl.c
··· 70 70 } 71 71 72 72 static struct backlight_ops mbp_ops = { 73 + .options = BL_CORE_SUSPENDRESUME, 73 74 .get_brightness = mbp_get_intensity, 74 75 .update_status = mbp_send_intensity, 75 76 };
+16
include/linux/backlight.h
··· 31 31 struct fb_info; 32 32 33 33 struct backlight_ops { 34 + unsigned int options; 35 + 36 + #define BL_CORE_SUSPENDRESUME (1 << 0) 37 + 34 38 /* Notify the backlight driver some property has changed */ 35 39 int (*update_status)(struct backlight_device *); 36 40 /* Return the current backlight brightness (accounting for power, ··· 55 51 modes; 4: full off), see FB_BLANK_XXX */ 56 52 int power; 57 53 /* FB Blanking active? (values as for power) */ 54 + /* Due to be removed, please use (state & BL_CORE_FBBLANK) */ 58 55 int fb_blank; 56 + /* Flags used to signal drivers of state changes */ 57 + /* Upper 4 bits are reserved for driver internal use */ 58 + unsigned int state; 59 + 60 + #define BL_CORE_SUSPENDED (1 << 0) /* backlight is suspended */ 61 + #define BL_CORE_FBBLANK (1 << 1) /* backlight is under an fb blank event */ 62 + #define BL_CORE_DRIVER4 (1 << 28) /* reserved for driver specific use */ 63 + #define BL_CORE_DRIVER3 (1 << 29) /* reserved for driver specific use */ 64 + #define BL_CORE_DRIVER2 (1 << 30) /* reserved for driver specific use */ 65 + #define BL_CORE_DRIVER1 (1 << 31) /* reserved for driver specific use */ 66 + 59 67 }; 60 68 61 69 struct backlight_device {