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

fbdev: Track display blanking state

Store the display's blank status in struct fb_info.blank and track
it in fb_blank(). As an extra, the status is now available from the
sysfs blank attribute.

Support for blanking is optional. Therefore framebuffer_alloc()
initializes the state to FB_BLANK_UNBLANK (i.e., the display is
on). If the fb_blank callback has been set, register_framebuffer()
sets the state to FB_BLANK_POWERDOWN. On the first modeset, the
call to fb_blank() will update it to _UNBLANK. This is important,
as listeners to FB_EVENT_BLANK will now see the display being
switched on.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Simona Vetter <simona.vetter@ffwll.ch>
Link: https://lore.kernel.org/r/20250321095517.313713-3-tzimmermann@suse.de
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Thomas Zimmermann and committed by
Lee Jones
7e3711eb 93e41f96

+23 -5
+1
drivers/video/fbdev/core/fb_info.c
··· 42 42 43 43 info->device = dev; 44 44 info->fbcon_rotate_hint = -1; 45 + info->blank = FB_BLANK_UNBLANK; 45 46 46 47 #if IS_ENABLED(CONFIG_FB_BACKLIGHT) 47 48 mutex_init(&info->bl_curve_mutex);
+16 -1
drivers/video/fbdev/core/fbmem.c
··· 341 341 342 342 int fb_blank(struct fb_info *info, int blank) 343 343 { 344 + int old_blank = info->blank; 344 345 struct fb_event event; 345 346 int ret; 346 347 ··· 354 353 event.info = info; 355 354 event.data = &blank; 356 355 356 + info->blank = blank; 357 + 357 358 ret = info->fbops->fb_blank(blank, info); 358 359 if (ret) 359 - return ret; 360 + goto err; 360 361 361 362 fb_notifier_call_chain(FB_EVENT_BLANK, &event); 362 363 363 364 return 0; 365 + 366 + err: 367 + info->blank = old_blank; 368 + return ret; 364 369 } 365 370 EXPORT_SYMBOL(fb_blank); 366 371 ··· 414 407 refcount_set(&fb_info->count, 1); 415 408 mutex_init(&fb_info->lock); 416 409 mutex_init(&fb_info->mm_lock); 410 + 411 + /* 412 + * With an fb_blank callback present, we assume that the 413 + * display is blank, so that fb_blank() enables it on the 414 + * first modeset. 415 + */ 416 + if (fb_info->fbops->fb_blank) 417 + fb_info->blank = FB_BLANK_POWERDOWN; 417 418 418 419 fb_device_create(fb_info); 419 420
+4 -4
drivers/video/fbdev/core/fbsysfs.c
··· 242 242 return count; 243 243 } 244 244 245 - static ssize_t show_blank(struct device *device, 246 - struct device_attribute *attr, char *buf) 245 + static ssize_t show_blank(struct device *device, struct device_attribute *attr, char *buf) 247 246 { 248 - // struct fb_info *fb_info = dev_get_drvdata(device); 249 - return 0; 247 + struct fb_info *fb_info = dev_get_drvdata(device); 248 + 249 + return sysfs_emit(buf, "%d\n", fb_info->blank); 250 250 } 251 251 252 252 static ssize_t store_console(struct device *device,
+2
include/linux/fb.h
··· 472 472 struct list_head modelist; /* mode list */ 473 473 struct fb_videomode *mode; /* current mode */ 474 474 475 + int blank; /* current blanking; see FB_BLANK_ constants */ 476 + 475 477 #if IS_ENABLED(CONFIG_FB_BACKLIGHT) 476 478 /* assigned backlight device */ 477 479 /* set before framebuffer registration,