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>
This commit is contained in:
committed by
Lee Jones
parent
93e41f968d
commit
7e3711eb87
@@ -42,6 +42,7 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
|
||||
|
||||
info->device = dev;
|
||||
info->fbcon_rotate_hint = -1;
|
||||
info->blank = FB_BLANK_UNBLANK;
|
||||
|
||||
#if IS_ENABLED(CONFIG_FB_BACKLIGHT)
|
||||
mutex_init(&info->bl_curve_mutex);
|
||||
|
||||
@@ -341,6 +341,7 @@ EXPORT_SYMBOL(fb_set_var);
|
||||
|
||||
int fb_blank(struct fb_info *info, int blank)
|
||||
{
|
||||
int old_blank = info->blank;
|
||||
struct fb_event event;
|
||||
int ret;
|
||||
|
||||
@@ -353,13 +354,19 @@ int fb_blank(struct fb_info *info, int blank)
|
||||
event.info = info;
|
||||
event.data = ␣
|
||||
|
||||
info->blank = blank;
|
||||
|
||||
ret = info->fbops->fb_blank(blank, info);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err;
|
||||
|
||||
fb_notifier_call_chain(FB_EVENT_BLANK, &event);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
info->blank = old_blank;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(fb_blank);
|
||||
|
||||
@@ -408,6 +415,14 @@ static int do_register_framebuffer(struct fb_info *fb_info)
|
||||
mutex_init(&fb_info->lock);
|
||||
mutex_init(&fb_info->mm_lock);
|
||||
|
||||
/*
|
||||
* With an fb_blank callback present, we assume that the
|
||||
* display is blank, so that fb_blank() enables it on the
|
||||
* first modeset.
|
||||
*/
|
||||
if (fb_info->fbops->fb_blank)
|
||||
fb_info->blank = FB_BLANK_POWERDOWN;
|
||||
|
||||
fb_device_create(fb_info);
|
||||
|
||||
if (fb_info->pixmap.addr == NULL) {
|
||||
|
||||
@@ -242,11 +242,11 @@ static ssize_t store_blank(struct device *device,
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_blank(struct device *device,
|
||||
struct device_attribute *attr, char *buf)
|
||||
static ssize_t show_blank(struct device *device, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
// struct fb_info *fb_info = dev_get_drvdata(device);
|
||||
return 0;
|
||||
struct fb_info *fb_info = dev_get_drvdata(device);
|
||||
|
||||
return sysfs_emit(buf, "%d\n", fb_info->blank);
|
||||
}
|
||||
|
||||
static ssize_t store_console(struct device *device,
|
||||
|
||||
@@ -472,6 +472,8 @@ struct fb_info {
|
||||
struct list_head modelist; /* mode list */
|
||||
struct fb_videomode *mode; /* current mode */
|
||||
|
||||
int blank; /* current blanking; see FB_BLANK_ constants */
|
||||
|
||||
#if IS_ENABLED(CONFIG_FB_BACKLIGHT)
|
||||
/* assigned backlight device */
|
||||
/* set before framebuffer registration,
|
||||
|
||||
Reference in New Issue
Block a user