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>
This commit is contained in:
		
					parent
					
						
							
								9be1df98bc
							
						
					
				
			
			
				commit
				
					
						c835ee7f41
					
				
			
		
					 4 changed files with 63 additions and 33 deletions
				
			
		|  | @ -40,6 +40,10 @@ static int fb_notifier_callback(struct notifier_block *self, | |||
| 		if (!bd->ops->check_fb || | ||||
| 		    bd->ops->check_fb(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); | ||||
| 		} | ||||
| 	mutex_unlock(&bd->ops_lock); | ||||
|  | @ -165,6 +169,34 @@ static ssize_t backlight_show_actual_brightness(struct device *dev, | |||
| 
 | ||||
| static struct class *backlight_class; | ||||
| 
 | ||||
| static int backlight_suspend(struct device *dev, pm_message_t state) | ||||
| { | ||||
| 	struct backlight_device *bd = to_backlight_device(dev); | ||||
| 
 | ||||
| 	if (bd->ops->options & BL_CORE_SUSPENDRESUME) { | ||||
| 		mutex_lock(&bd->ops_lock); | ||||
| 		bd->props.state |= BL_CORE_SUSPENDED; | ||||
| 		backlight_update_status(bd); | ||||
| 		mutex_unlock(&bd->ops_lock); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int backlight_resume(struct device *dev) | ||||
| { | ||||
| 	struct backlight_device *bd = to_backlight_device(dev); | ||||
| 
 | ||||
| 	if (bd->ops->options & BL_CORE_SUSPENDRESUME) { | ||||
| 		mutex_lock(&bd->ops_lock); | ||||
| 		bd->props.state &= ~BL_CORE_SUSPENDED; | ||||
| 		backlight_update_status(bd); | ||||
| 		mutex_unlock(&bd->ops_lock); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void bl_device_release(struct device *dev) | ||||
| { | ||||
| 	struct backlight_device *bd = to_backlight_device(dev); | ||||
|  | @ -281,6 +313,8 @@ static int __init backlight_class_init(void) | |||
| 	} | ||||
| 
 | ||||
| 	backlight_class->dev_attrs = bl_device_attributes; | ||||
| 	backlight_class->suspend = backlight_suspend; | ||||
| 	backlight_class->resume = backlight_resume; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -24,9 +24,8 @@ static struct backlight_properties corgibl_data; | |||
| static struct backlight_device *corgi_backlight_device; | ||||
| static struct generic_bl_info *bl_machinfo; | ||||
| 
 | ||||
| static unsigned long corgibl_flags; | ||||
| #define CORGIBL_SUSPENDED     0x01 | ||||
| #define CORGIBL_BATTLOW       0x02 | ||||
| /* Flag to signal when the battery is low */ | ||||
| #define CORGIBL_BATTLOW       BL_CORE_DRIVER1 | ||||
| 
 | ||||
| static int corgibl_send_intensity(struct backlight_device *bd) | ||||
| { | ||||
|  | @ -34,11 +33,11 @@ static int corgibl_send_intensity(struct backlight_device *bd) | |||
| 
 | ||||
| 	if (bd->props.power != FB_BLANK_UNBLANK) | ||||
| 		intensity = 0; | ||||
| 	if (bd->props.fb_blank != FB_BLANK_UNBLANK) | ||||
| 	if (bd->props.state & BL_CORE_FBBLANK) | ||||
| 		intensity = 0; | ||||
| 	if (corgibl_flags & CORGIBL_SUSPENDED) | ||||
| 	if (bd->props.state & BL_CORE_SUSPENDED) | ||||
| 		intensity = 0; | ||||
| 	if (corgibl_flags & CORGIBL_BATTLOW) | ||||
| 	if (bd->props.state & CORGIBL_BATTLOW) | ||||
| 		intensity &= bl_machinfo->limit_mask; | ||||
| 
 | ||||
| 	bl_machinfo->set_bl_intensity(intensity); | ||||
|  | @ -51,29 +50,6 @@ static int corgibl_send_intensity(struct backlight_device *bd) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_PM | ||||
| static int corgibl_suspend(struct platform_device *pdev, pm_message_t state) | ||||
| { | ||||
| 	struct backlight_device *bd = platform_get_drvdata(pdev); | ||||
| 
 | ||||
| 	corgibl_flags |= CORGIBL_SUSPENDED; | ||||
| 	backlight_update_status(bd); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int corgibl_resume(struct platform_device *pdev) | ||||
| { | ||||
| 	struct backlight_device *bd = platform_get_drvdata(pdev); | ||||
| 
 | ||||
| 	corgibl_flags &= ~CORGIBL_SUSPENDED; | ||||
| 	backlight_update_status(bd); | ||||
| 	return 0; | ||||
| } | ||||
| #else | ||||
| #define corgibl_suspend	NULL | ||||
| #define corgibl_resume	NULL | ||||
| #endif | ||||
| 
 | ||||
| static int corgibl_get_intensity(struct backlight_device *bd) | ||||
| { | ||||
| 	return corgibl_intensity; | ||||
|  | @ -85,16 +61,21 @@ static int corgibl_get_intensity(struct backlight_device *bd) | |||
|  */ | ||||
| void corgibl_limit_intensity(int limit) | ||||
| { | ||||
| 	struct backlight_device *bd = corgi_backlight_device; | ||||
| 
 | ||||
| 	mutex_lock(&bd->ops_lock); | ||||
| 	if (limit) | ||||
| 		corgibl_flags |= CORGIBL_BATTLOW; | ||||
| 		bd->props.state |= CORGIBL_BATTLOW; | ||||
| 	else | ||||
| 		corgibl_flags &= ~CORGIBL_BATTLOW; | ||||
| 		bd->props.state &= ~CORGIBL_BATTLOW; | ||||
| 	backlight_update_status(corgi_backlight_device); | ||||
| 	mutex_unlock(&bd->ops_lock); | ||||
| } | ||||
| EXPORT_SYMBOL(corgibl_limit_intensity); | ||||
| 
 | ||||
| 
 | ||||
| static struct backlight_ops corgibl_ops = { | ||||
| 	.options = BL_CORE_SUSPENDRESUME, | ||||
| 	.get_brightness = corgibl_get_intensity, | ||||
| 	.update_status  = corgibl_send_intensity, | ||||
| }; | ||||
|  | @ -144,8 +125,6 @@ static int corgibl_remove(struct platform_device *pdev) | |||
| static struct platform_driver corgibl_driver = { | ||||
| 	.probe		= corgibl_probe, | ||||
| 	.remove		= corgibl_remove, | ||||
| 	.suspend	= corgibl_suspend, | ||||
| 	.resume		= corgibl_resume, | ||||
| 	.driver		= { | ||||
| 		.name	= "generic-bl", | ||||
| 	}, | ||||
|  |  | |||
|  | @ -70,6 +70,7 @@ static int mbp_get_intensity(struct backlight_device *bd) | |||
| } | ||||
| 
 | ||||
| static struct backlight_ops mbp_ops = { | ||||
| 	.options = BL_CORE_SUSPENDRESUME, | ||||
| 	.get_brightness = mbp_get_intensity, | ||||
| 	.update_status  = mbp_send_intensity, | ||||
| }; | ||||
|  |  | |||
|  | @ -31,6 +31,10 @@ struct backlight_device; | |||
| struct fb_info; | ||||
| 
 | ||||
| struct backlight_ops { | ||||
| 	unsigned int options; | ||||
| 
 | ||||
| #define BL_CORE_SUSPENDRESUME	(1 << 0) | ||||
| 
 | ||||
| 	/* Notify the backlight driver some property has changed */ | ||||
| 	int (*update_status)(struct backlight_device *); | ||||
| 	/* Return the current backlight brightness (accounting for power,
 | ||||
|  | @ -51,7 +55,19 @@ struct backlight_properties { | |||
| 	   modes; 4: full off), see FB_BLANK_XXX */ | ||||
| 	int power; | ||||
| 	/* FB Blanking active? (values as for power) */ | ||||
| 	/* Due to be removed, please use (state & BL_CORE_FBBLANK) */ | ||||
| 	int fb_blank; | ||||
| 	/* Flags used to signal drivers of state changes */ | ||||
| 	/* Upper 4 bits are reserved for driver internal use */ | ||||
| 	unsigned int state; | ||||
| 
 | ||||
| #define BL_CORE_SUSPENDED	(1 << 0)	/* backlight is suspended */ | ||||
| #define BL_CORE_FBBLANK		(1 << 1)	/* backlight is under an fb blank event */ | ||||
| #define BL_CORE_DRIVER4		(1 << 28)	/* reserved for driver specific use */ | ||||
| #define BL_CORE_DRIVER3		(1 << 29)	/* reserved for driver specific use */ | ||||
| #define BL_CORE_DRIVER2		(1 << 30)	/* reserved for driver specific use */ | ||||
| #define BL_CORE_DRIVER1		(1 << 31)	/* reserved for driver specific use */ | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| struct backlight_device { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Richard Purdie
				Richard Purdie