From bb2c941b3131437185e79c8f2a16469876664572 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 8 Dec 2025 20:39:22 +0100 Subject: [PATCH 01/11] efi: sysfb_efi: Replace open coded swap with the macro Replace the open coded width height swap with the standard macro. Signed-off-by: Tvrtko Ursulin Suggested-by: Thomas Zimmermann Cc: Thomas Zimmermann Cc: Ard Biesheuvel Cc: Melissa Wen Cc: linux-efi@vger.kernel.org Reviewed-by: Thomas Zimmermann Tested-by: Melissa Wen # v3 Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/sysfb_efi.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c index 1e509595ac03..1d8b6966731c 100644 --- a/drivers/firmware/efi/sysfb_efi.c +++ b/drivers/firmware/efi/sysfb_efi.c @@ -357,10 +357,7 @@ __init void sysfb_apply_efi_quirks(void) if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI && dmi_check_system(efifb_dmi_swap_width_height)) { - u16 temp = screen_info.lfb_width; - - screen_info.lfb_width = screen_info.lfb_height; - screen_info.lfb_height = temp; + swap(screen_info.lfb_width, screen_info.lfb_height); screen_info.lfb_linelength = 4 * screen_info.lfb_width; } } From 449b87e81f3561bd907d3b9a31cf69590132a2df Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 8 Dec 2025 20:39:23 +0100 Subject: [PATCH 02/11] efi: sysfb_efi: Fix lfb_linelength calculation when applying quirks PIXEL_BIT_MASK formats can have either less or more than four bytes per pixel so lets fix the lfb_linelenght calculation when applying the swapped width and height quirks. Signed-off-by: Tvrtko Ursulin Suggested-by: Thomas Zimmermann Cc: Thomas Zimmermann Cc: Ard Biesheuvel Cc: Melissa Wen Cc: linux-efi@vger.kernel.org Tested-by: Melissa Wen # v3 Reviewed-by: Thomas Zimmermann Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/sysfb_efi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c index 1d8b6966731c..60495eb3441c 100644 --- a/drivers/firmware/efi/sysfb_efi.c +++ b/drivers/firmware/efi/sysfb_efi.c @@ -357,8 +357,11 @@ __init void sysfb_apply_efi_quirks(void) if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI && dmi_check_system(efifb_dmi_swap_width_height)) { + u32 bpp = __screen_info_lfb_bits_per_pixel(&screen_info); + swap(screen_info.lfb_width, screen_info.lfb_height); - screen_info.lfb_linelength = 4 * screen_info.lfb_width; + screen_info.lfb_linelength = bpp * screen_info.lfb_width / + BITS_PER_BYTE; } } From 7f2f1fd6fc050be874afa9eb52a0ff974f379869 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 8 Dec 2025 20:39:24 +0100 Subject: [PATCH 03/11] efi: sysfb_efi: Convert swap width and height quirk to a callback Convert the swapping of width and height quirk to a callback. Signed-off-by: Tvrtko Ursulin Suggested-by: Ard Biesheuvel Cc: Thomas Zimmermann Cc: Ard Biesheuvel Cc: Melissa Wen Cc: linux-efi@vger.kernel.org Reviewed-by: Thomas Zimmermann Tested-by: Melissa Wen # v3 [ardb: use local var to refer to screen_info] Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/sysfb_efi.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c index 60495eb3441c..dc4d70b7737c 100644 --- a/drivers/firmware/efi/sysfb_efi.c +++ b/drivers/firmware/efi/sysfb_efi.c @@ -231,6 +231,17 @@ static const struct dmi_system_id efifb_dmi_system_table[] __initconst = { {}, }; +static int __init efifb_swap_width_height(const struct dmi_system_id *id) +{ + struct screen_info *si = &screen_info; + u32 bpp = __screen_info_lfb_bits_per_pixel(si); + + swap(si->lfb_width, si->lfb_height); + si->lfb_linelength = bpp * si->lfb_width / BITS_PER_BYTE; + + return 1; +} + /* * Some devices have a portrait LCD but advertise a landscape resolution (and * pitch). We simply swap width and height for these devices so that we can @@ -248,6 +259,7 @@ static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = { DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "MIIX 310-10ICR"), DMI_EXACT_MATCH(DMI_BIOS_VERSION, "1HCN44WW"), }, + .callback = efifb_swap_width_height, }, { /* Lenovo MIIX 320-10ICR with 800x1280 portrait screen */ @@ -256,6 +268,7 @@ static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = { DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), }, + .callback = efifb_swap_width_height, }, { /* Lenovo D330 with 800x1280 or 1200x1920 portrait screen */ @@ -264,6 +277,7 @@ static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = { DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"), }, + .callback = efifb_swap_width_height, }, { /* Lenovo IdeaPad Duet 3 10IGL5 with 1200x1920 portrait screen */ @@ -272,6 +286,7 @@ static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = { DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Duet 3 10IGL5"), }, + .callback = efifb_swap_width_height, }, { /* Lenovo Yoga Book X91F / X91L */ @@ -280,6 +295,7 @@ static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = { /* Non exact match to match F + L versions */ DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"), }, + .callback = efifb_swap_width_height, }, {}, }; @@ -355,14 +371,8 @@ __init void sysfb_apply_efi_quirks(void) !(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS)) dmi_check_system(efifb_dmi_system_table); - if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI && - dmi_check_system(efifb_dmi_swap_width_height)) { - u32 bpp = __screen_info_lfb_bits_per_pixel(&screen_info); - - swap(screen_info.lfb_width, screen_info.lfb_height); - screen_info.lfb_linelength = bpp * screen_info.lfb_width / - BITS_PER_BYTE; - } + if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) + dmi_check_system(efifb_dmi_swap_width_height); } __init void sysfb_set_efifb_fwnode(struct platform_device *pd) From c7c7eb5ed5a3896e57019f7b33e3b7dcb4ab73b4 Mon Sep 17 00:00:00 2001 From: Tvrtko Ursulin Date: Mon, 8 Dec 2025 20:39:25 +0100 Subject: [PATCH 04/11] efi: sysfb_efi: Fix efidrmfb and simpledrmfb on Valve Steam Deck Valve Steam Deck has a 800x1280 portrait screen installed in a landscape orientation. The firmware offers a software-rotated 1280x800 mode, which GRUB can be made to switch to when displaying a boot menu. If this mode was selected frame buffer drivers will see this fake mode and fbcon rendering will be corrupted. Let us therefore add a selective quirk inside the current "swap with and height" handling, which will detect this exact mode and fix it up back to the native one. This will allow the DRM-based framebuffer drivers to detect the correct mode, apply the existing panel orientation quirk, and render the console in landscape mode with no corruption. Signed-off-by: Tvrtko Ursulin Cc: Thomas Zimmermann Cc: Ard Biesheuvel Cc: Melissa Wen Cc: linux-efi@vger.kernel.org Tested-by: Melissa Wen # v3 Reviewed-by: Thomas Zimmermann [ardb: use local var to refer to screen_info] Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/sysfb_efi.c | 47 ++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c index dc4d70b7737c..aea94a75b575 100644 --- a/drivers/firmware/efi/sysfb_efi.c +++ b/drivers/firmware/efi/sysfb_efi.c @@ -242,6 +242,33 @@ static int __init efifb_swap_width_height(const struct dmi_system_id *id) return 1; } +struct efifb_mode_fixup { + unsigned int width; + unsigned int height; + unsigned int linelength; +}; + +static int __init +efifb_check_and_swap_width_height(const struct dmi_system_id *id) +{ + const struct efifb_mode_fixup *data = id->driver_data; + struct screen_info *si = &screen_info; + + if (data->width == si->lfb_width && data->height == si->lfb_height) { + swap(si->lfb_width, si->lfb_height); + si->lfb_linelength = data->linelength; + si->lfb_size = data->linelength * data->width; + } + + return 1; +} + +static const struct efifb_mode_fixup efifb_steamdeck_mode_fixup __initconst = { + .width = 1280, + .height = 800, + .linelength = 3328, +}; + /* * Some devices have a portrait LCD but advertise a landscape resolution (and * pitch). We simply swap width and height for these devices so that we can @@ -297,6 +324,26 @@ static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = { }, .callback = efifb_swap_width_height, }, + { + /* Valve Steam Deck (Jupiter) */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), + }, + .callback = efifb_check_and_swap_width_height, + .driver_data = (void *)&efifb_steamdeck_mode_fixup, + }, + { + /* Valve Steam Deck (Galileo) */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galileo"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), + }, + .callback = efifb_check_and_swap_width_height, + .driver_data = (void *)&efifb_steamdeck_mode_fixup, + }, {}, }; From b868070fbc023b254ac46607970612e059efdcd3 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 26 Nov 2025 17:03:18 +0100 Subject: [PATCH 05/11] efi: earlycon: Reduce number of references to global screen_info Replace usage of global screen_info with local pointers. This will later reduce churn when screen_info is being moved. Signed-off-by: Thomas Zimmermann Reviewed-by: Richard Lyu Acked-by: Arnd Bergmann Acked-by: Ard Biesheuvel Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/earlycon.c | 40 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/firmware/efi/earlycon.c b/drivers/firmware/efi/earlycon.c index d18a1a5de144..42e3a173dac1 100644 --- a/drivers/firmware/efi/earlycon.c +++ b/drivers/firmware/efi/earlycon.c @@ -32,12 +32,13 @@ static void *efi_fb; */ static int __init efi_earlycon_remap_fb(void) { + const struct screen_info *si = &screen_info; + /* bail if there is no bootconsole or it was unregistered already */ if (!earlycon_console || !console_is_registered(earlycon_console)) return 0; - efi_fb = memremap(fb_base, screen_info.lfb_size, - fb_wb ? MEMREMAP_WB : MEMREMAP_WC); + efi_fb = memremap(fb_base, si->lfb_size, fb_wb ? MEMREMAP_WB : MEMREMAP_WC); return efi_fb ? 0 : -ENOMEM; } @@ -71,12 +72,12 @@ static __ref void efi_earlycon_unmap(void *addr, unsigned long len) early_memunmap(addr, len); } -static void efi_earlycon_clear_scanline(unsigned int y) +static void efi_earlycon_clear_scanline(unsigned int y, const struct screen_info *si) { unsigned long *dst; u16 len; - len = screen_info.lfb_linelength; + len = si->lfb_linelength; dst = efi_earlycon_map(y*len, len); if (!dst) return; @@ -85,7 +86,7 @@ static void efi_earlycon_clear_scanline(unsigned int y) efi_earlycon_unmap(dst, len); } -static void efi_earlycon_scroll_up(void) +static void efi_earlycon_scroll_up(const struct screen_info *si) { unsigned long *dst, *src; u16 maxlen = 0; @@ -99,8 +100,8 @@ static void efi_earlycon_scroll_up(void) } maxlen *= 4; - len = screen_info.lfb_linelength; - height = screen_info.lfb_height; + len = si->lfb_linelength; + height = si->lfb_height; for (i = 0; i < height - font->height; i++) { dst = efi_earlycon_map(i*len, len); @@ -120,7 +121,8 @@ static void efi_earlycon_scroll_up(void) } } -static void efi_earlycon_write_char(u32 *dst, unsigned char c, unsigned int h) +static void efi_earlycon_write_char(u32 *dst, unsigned char c, unsigned int h, + const struct screen_info *si) { const u32 color_black = 0x00000000; const u32 color_white = 0x00ffffff; @@ -145,13 +147,12 @@ static void efi_earlycon_write_char(u32 *dst, unsigned char c, unsigned int h) static void efi_earlycon_write(struct console *con, const char *str, unsigned int num) { - struct screen_info *si; + const struct screen_info *si = &screen_info; u32 cur_efi_x = efi_x; unsigned int len; const char *s; void *dst; - si = &screen_info; len = si->lfb_linelength; while (num) { @@ -174,7 +175,7 @@ efi_earlycon_write(struct console *con, const char *str, unsigned int num) x = efi_x; while (n-- > 0) { - efi_earlycon_write_char(dst + x*4, *s, h); + efi_earlycon_write_char(dst + x * 4, *s, h, si); x += font->width; s++; } @@ -207,10 +208,10 @@ efi_earlycon_write(struct console *con, const char *str, unsigned int num) cur_line_y = (cur_line_y + 1) % max_line_y; efi_y -= font->height; - efi_earlycon_scroll_up(); + efi_earlycon_scroll_up(si); for (i = 0; i < font->height; i++) - efi_earlycon_clear_scanline(efi_y + i); + efi_earlycon_clear_scanline(efi_y + i, si); } } } @@ -226,22 +227,21 @@ void __init efi_earlycon_reprobe(void) static int __init efi_earlycon_setup(struct earlycon_device *device, const char *opt) { - struct screen_info *si; + const struct screen_info *si = &screen_info; u16 xres, yres; u32 i; fb_wb = opt && !strcmp(opt, "ram"); - if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) { + if (si->orig_video_isVGA != VIDEO_TYPE_EFI) { fb_probed = true; return -ENODEV; } - fb_base = screen_info.lfb_base; - if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) - fb_base |= (u64)screen_info.ext_lfb_base << 32; + fb_base = si->lfb_base; + if (si->capabilities & VIDEO_CAPABILITY_64BIT_BASE) + fb_base |= (u64)si->ext_lfb_base << 32; - si = &screen_info; xres = si->lfb_width; yres = si->lfb_height; @@ -266,7 +266,7 @@ static int __init efi_earlycon_setup(struct earlycon_device *device, efi_y -= font->height; for (i = 0; i < (yres - efi_y) / font->height; i++) - efi_earlycon_scroll_up(); + efi_earlycon_scroll_up(si); device->con->write = efi_earlycon_write; earlycon_console = device->con; From 54bdafd7780850803385d6faf33034a0fa7cd4cc Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 26 Nov 2025 17:03:19 +0100 Subject: [PATCH 06/11] efi: sysfb_efi: Reduce number of references to global screen_info Replace usage of global screen_info with local pointers. This will later reduce churn when screen_info is being moved. Signed-off-by: Thomas Zimmermann Reviewed-by: Richard Lyu Acked-by: Arnd Bergmann Acked-by: Ard Biesheuvel Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/sysfb_efi.c | 73 +++++++++++++++++-------------- drivers/firmware/sysfb.c | 4 +- drivers/firmware/sysfb_simplefb.c | 2 +- include/linux/sysfb.h | 9 ++-- 4 files changed, 47 insertions(+), 41 deletions(-) diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c index aea94a75b575..c074cbccd91b 100644 --- a/drivers/firmware/efi/sysfb_efi.c +++ b/drivers/firmware/efi/sysfb_efi.c @@ -92,7 +92,7 @@ void efifb_setup_from_dmi(struct screen_info *si, const char *opt) }) #ifdef CONFIG_EFI -static int __init efifb_set_system(const struct dmi_system_id *id) +static int __init efifb_set_system(struct screen_info *si, const struct dmi_system_id *id) { struct efifb_dmi_info *info = id->driver_data; @@ -101,14 +101,14 @@ static int __init efifb_set_system(const struct dmi_system_id *id) return 0; /* Trust the bootloader over the DMI tables */ - if (screen_info.lfb_base == 0) { + if (si->lfb_base == 0) { #if defined(CONFIG_PCI) struct pci_dev *dev = NULL; int found_bar = 0; #endif if (info->base) { - screen_info.lfb_base = choose_value(info->base, - screen_info.lfb_base, OVERRIDE_BASE, + si->lfb_base = choose_value(info->base, + si->lfb_base, OVERRIDE_BASE, info->flags); #if defined(CONFIG_PCI) @@ -135,49 +135,53 @@ static int __init efifb_set_system(const struct dmi_system_id *id) start = pci_resource_start(dev, i); end = pci_resource_end(dev, i); - if (screen_info.lfb_base >= start && - screen_info.lfb_base < end) { + if (si->lfb_base >= start && si->lfb_base < end) { found_bar = 1; break; } } } if (!found_bar) - screen_info.lfb_base = 0; + si->lfb_base = 0; #endif } } - if (screen_info.lfb_base) { - screen_info.lfb_linelength = choose_value(info->stride, - screen_info.lfb_linelength, OVERRIDE_STRIDE, + if (si->lfb_base) { + si->lfb_linelength = choose_value(info->stride, + si->lfb_linelength, OVERRIDE_STRIDE, info->flags); - screen_info.lfb_width = choose_value(info->width, - screen_info.lfb_width, OVERRIDE_WIDTH, + si->lfb_width = choose_value(info->width, + si->lfb_width, OVERRIDE_WIDTH, info->flags); - screen_info.lfb_height = choose_value(info->height, - screen_info.lfb_height, OVERRIDE_HEIGHT, + si->lfb_height = choose_value(info->height, + si->lfb_height, OVERRIDE_HEIGHT, info->flags); - if (screen_info.orig_video_isVGA == 0) - screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; + if (si->orig_video_isVGA == 0) + si->orig_video_isVGA = VIDEO_TYPE_EFI; } else { - screen_info.lfb_linelength = 0; - screen_info.lfb_width = 0; - screen_info.lfb_height = 0; - screen_info.orig_video_isVGA = 0; + si->lfb_linelength = 0; + si->lfb_width = 0; + si->lfb_height = 0; + si->orig_video_isVGA = 0; return 0; } printk(KERN_INFO "efifb: dmi detected %s - framebuffer at 0x%08x " "(%dx%d, stride %d)\n", id->ident, - screen_info.lfb_base, screen_info.lfb_width, - screen_info.lfb_height, screen_info.lfb_linelength); + si->lfb_base, si->lfb_width, + si->lfb_height, si->lfb_linelength); return 1; } +static int __init efifb_set_system_callback(const struct dmi_system_id *id) +{ + return efifb_set_system(&screen_info, id); +} + #define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \ { \ - efifb_set_system, \ + efifb_set_system_callback, \ name, \ { \ DMI_MATCH(DMI_BIOS_VENDOR, vendor), \ @@ -347,12 +351,13 @@ static const struct dmi_system_id efifb_dmi_swap_width_height[] __initconst = { {}, }; -static bool efifb_overlaps_pci_range(const struct of_pci_range *range) +static bool efifb_overlaps_pci_range(const struct screen_info *si, + const struct of_pci_range *range) { - u64 fb_base = screen_info.lfb_base; + u64 fb_base = si->lfb_base; - if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) - fb_base |= (u64)(unsigned long)screen_info.ext_lfb_base << 32; + if (si->capabilities & VIDEO_CAPABILITY_64BIT_BASE) + fb_base |= (u64)(unsigned long)si->ext_lfb_base << 32; return fb_base >= range->cpu_addr && fb_base < (range->cpu_addr + range->size); @@ -374,7 +379,7 @@ static struct device_node *find_pci_overlap_node(void) } for_each_of_pci_range(&parser, &range) - if (efifb_overlaps_pci_range(&range)) + if (efifb_overlaps_pci_range(&screen_info, &range)) return np; } return NULL; @@ -412,19 +417,19 @@ static const struct fwnode_operations efifb_fwnode_ops = { static struct fwnode_handle efifb_fwnode; -__init void sysfb_apply_efi_quirks(void) +__init void sysfb_apply_efi_quirks(struct screen_info *si) { - if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || - !(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS)) + if (si->orig_video_isVGA != VIDEO_TYPE_EFI || + !(si->capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS)) dmi_check_system(efifb_dmi_system_table); - if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) + if (si->orig_video_isVGA == VIDEO_TYPE_EFI) dmi_check_system(efifb_dmi_swap_width_height); } -__init void sysfb_set_efifb_fwnode(struct platform_device *pd) +__init void sysfb_set_efifb_fwnode(const struct screen_info *si, struct platform_device *pd) { - if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI && IS_ENABLED(CONFIG_PCI)) { + if (si->orig_video_isVGA == VIDEO_TYPE_EFI && IS_ENABLED(CONFIG_PCI)) { fwnode_init(&efifb_fwnode, &efifb_fwnode_ops); pd->dev.fwnode = &efifb_fwnode; } diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c index 889e5b05c739..916b28538a29 100644 --- a/drivers/firmware/sysfb.c +++ b/drivers/firmware/sysfb.c @@ -155,7 +155,7 @@ static __init int sysfb_init(void) if (disabled) goto unlock_mutex; - sysfb_apply_efi_quirks(); + sysfb_apply_efi_quirks(si); parent = sysfb_parent_dev(si); if (IS_ERR(parent)) { @@ -200,7 +200,7 @@ static __init int sysfb_init(void) pd->dev.parent = parent; - sysfb_set_efifb_fwnode(pd); + sysfb_set_efifb_fwnode(si, pd); ret = platform_device_add_data(pd, si, sizeof(*si)); if (ret) diff --git a/drivers/firmware/sysfb_simplefb.c b/drivers/firmware/sysfb_simplefb.c index 592d8a644619..71f542e37732 100644 --- a/drivers/firmware/sysfb_simplefb.c +++ b/drivers/firmware/sysfb_simplefb.c @@ -117,7 +117,7 @@ __init struct platform_device *sysfb_create_simplefb(const struct screen_info *s pd->dev.parent = parent; - sysfb_set_efifb_fwnode(pd); + sysfb_set_efifb_fwnode(si, pd); ret = platform_device_add_resources(pd, &res, 1); if (ret) diff --git a/include/linux/sysfb.h b/include/linux/sysfb.h index b449665c686a..8527a50a5290 100644 --- a/include/linux/sysfb.h +++ b/include/linux/sysfb.h @@ -82,16 +82,17 @@ static inline bool sysfb_handles_screen_info(void) #ifdef CONFIG_EFI extern struct efifb_dmi_info efifb_dmi_list[]; -void sysfb_apply_efi_quirks(void); -void sysfb_set_efifb_fwnode(struct platform_device *pd); +void sysfb_apply_efi_quirks(struct screen_info *si); +void sysfb_set_efifb_fwnode(const struct screen_info *si, struct platform_device *pd); #else /* CONFIG_EFI */ -static inline void sysfb_apply_efi_quirks(void) +static inline void sysfb_apply_efi_quirks(struct screen_info *si) { } -static inline void sysfb_set_efifb_fwnode(struct platform_device *pd) +static inline void sysfb_set_efifb_fwnode(const struct screen_info *si, + struct platform_device *pd) { } From b945922619b77b95a48f254582ed86f33d24f560 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 26 Nov 2025 17:03:20 +0100 Subject: [PATCH 07/11] sysfb: Add struct sysfb_display_info Add struct sysfb_display_info to wrap display-related state. For now it contains only the screen's video mode. Later EDID will be added as well. This struct will be helpful for passing display state to sysfb drivers or from the EFI stub library. Signed-off-by: Thomas Zimmermann Acked-by: Arnd Bergmann Acked-by: Ard Biesheuvel Reviewed-by: Richard Lyu Signed-off-by: Ard Biesheuvel --- include/linux/sysfb.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/sysfb.h b/include/linux/sysfb.h index 8527a50a5290..8b37247528bf 100644 --- a/include/linux/sysfb.h +++ b/include/linux/sysfb.h @@ -8,6 +8,7 @@ */ #include +#include #include #include @@ -60,6 +61,10 @@ struct efifb_dmi_info { int flags; }; +struct sysfb_display_info { + struct screen_info screen; +}; + #ifdef CONFIG_SYSFB void sysfb_disable(struct device *dev); From a41e0ab394e42c7c09ddd8155d2cc3ca17bdce55 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 26 Nov 2025 17:03:21 +0100 Subject: [PATCH 08/11] sysfb: Replace screen_info with sysfb_primary_display Replace the global screen_info with sysfb_primary_display of type struct sysfb_display_info. Adapt all users of screen_info. Instances of screen_info are defined for x86, loongarch and EFI, with only one instance compiled into a specific build. Replace all of them with sysfb_primary_display. All existing users of screen_info are updated by pointing them to sysfb_primary_display.screen instead. This introduces some churn to the code, but has no impact on functionality. Boot parameters and EFI config tables are unchanged. They transfer screen_info as before. The logic in EFI's alloc_screen_info() changes slightly, as it now returns the screen field of sysfb_primary_display. Signed-off-by: Thomas Zimmermann Acked-by: Arnd Bergmann Acked-by: Ard Biesheuvel Acked-by: Bjorn Helgaas # drivers/pci/ Reviewed-by: Richard Lyu Signed-off-by: Ard Biesheuvel --- arch/arm64/kernel/image-vars.h | 2 +- arch/loongarch/kernel/efi.c | 15 +++++++------ arch/loongarch/kernel/image-vars.h | 2 +- arch/riscv/kernel/image-vars.h | 2 +- arch/x86/kernel/kexec-bzimage64.c | 4 +++- arch/x86/kernel/setup.c | 10 +++++---- arch/x86/video/video-common.c | 4 ++-- drivers/firmware/efi/earlycon.c | 8 +++---- drivers/firmware/efi/efi-init.c | 22 +++++++++---------- drivers/firmware/efi/libstub/efi-stub-entry.c | 18 ++++++++++----- drivers/firmware/efi/sysfb_efi.c | 8 +++---- drivers/firmware/sysfb.c | 6 ++--- drivers/hv/vmbus_drv.c | 6 ++--- drivers/pci/vgaarb.c | 4 ++-- drivers/video/screen_info_pci.c | 5 +++-- include/linux/screen_info.h | 2 -- include/linux/sysfb.h | 5 +++-- 17 files changed, 68 insertions(+), 55 deletions(-) diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h index 85bc629270bd..d7b0d12b1015 100644 --- a/arch/arm64/kernel/image-vars.h +++ b/arch/arm64/kernel/image-vars.h @@ -38,7 +38,7 @@ PROVIDE(__efistub__end = _end); PROVIDE(__efistub___inittext_end = __inittext_end); PROVIDE(__efistub__edata = _edata); #if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB) -PROVIDE(__efistub_screen_info = screen_info); +PROVIDE(__efistub_sysfb_primary_display = sysfb_primary_display); #endif PROVIDE(__efistub__ctype = _ctype); diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c index 52c21c895318..95fb535daf1c 100644 --- a/arch/loongarch/kernel/efi.c +++ b/arch/loongarch/kernel/efi.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include @@ -75,11 +75,11 @@ bool efi_poweroff_required(void) unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR; #if defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON) -struct screen_info screen_info __section(".data"); -EXPORT_SYMBOL_GPL(screen_info); +struct sysfb_display_info sysfb_primary_display __section(".data"); +EXPORT_SYMBOL_GPL(sysfb_primary_display); #endif -static void __init init_screen_info(void) +static void __init init_primary_display(void) { struct screen_info *si; @@ -91,11 +91,12 @@ static void __init init_screen_info(void) pr_err("Could not map screen_info config table\n"); return; } - screen_info = *si; + sysfb_primary_display.screen = *si; memset(si, 0, sizeof(*si)); early_memunmap(si, sizeof(*si)); - memblock_reserve(__screen_info_lfb_base(&screen_info), screen_info.lfb_size); + memblock_reserve(__screen_info_lfb_base(&sysfb_primary_display.screen), + sysfb_primary_display.screen.lfb_size); } void __init efi_init(void) @@ -129,7 +130,7 @@ void __init efi_init(void) set_bit(EFI_CONFIG_TABLES, &efi.flags); if (IS_ENABLED(CONFIG_EFI_EARLYCON) || IS_ENABLED(CONFIG_SYSFB)) - init_screen_info(); + init_primary_display(); if (boot_memmap == EFI_INVALID_TABLE_ADDR) return; diff --git a/arch/loongarch/kernel/image-vars.h b/arch/loongarch/kernel/image-vars.h index 41ddcf56d21c..e557ebd46c2b 100644 --- a/arch/loongarch/kernel/image-vars.h +++ b/arch/loongarch/kernel/image-vars.h @@ -12,7 +12,7 @@ __efistub_kernel_entry = kernel_entry; __efistub_kernel_asize = kernel_asize; __efistub_kernel_fsize = kernel_fsize; #if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB) -__efistub_screen_info = screen_info; +__efistub_sysfb_primary_display = sysfb_primary_display; #endif #endif diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h index 3df30dd1c458..3bd9d06a8b8f 100644 --- a/arch/riscv/kernel/image-vars.h +++ b/arch/riscv/kernel/image-vars.h @@ -29,7 +29,7 @@ __efistub__end = _end; __efistub__edata = _edata; __efistub___init_text_end = __init_text_end; #if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB) -__efistub_screen_info = screen_info; +__efistub_sysfb_primary_display = sysfb_primary_display; #endif #endif diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c index c3244ac680d1..7508d0ccc740 100644 --- a/arch/x86/kernel/kexec-bzimage64.c +++ b/arch/x86/kernel/kexec-bzimage64.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -303,7 +304,8 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params, params->hdr.hardware_subarch = boot_params.hdr.hardware_subarch; /* Copying screen_info will do? */ - memcpy(¶ms->screen_info, &screen_info, sizeof(struct screen_info)); + memcpy(¶ms->screen_info, &sysfb_primary_display.screen, + sizeof(sysfb_primary_display.screen)); /* Fill in memsize later */ params->screen_info.ext_mem_k = 0; diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 1b2edd07a3e1..675e4b9deb1f 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -211,8 +212,9 @@ arch_initcall(init_x86_sysctl); /* * Setup options */ -struct screen_info screen_info; -EXPORT_SYMBOL(screen_info); + +struct sysfb_display_info sysfb_primary_display; +EXPORT_SYMBOL(sysfb_primary_display); #if defined(CONFIG_FIRMWARE_EDID) struct edid_info edid_info; EXPORT_SYMBOL_GPL(edid_info); @@ -526,7 +528,7 @@ static void __init parse_setup_data(void) static void __init parse_boot_params(void) { ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev); - screen_info = boot_params.screen_info; + sysfb_primary_display.screen = boot_params.screen_info; #if defined(CONFIG_FIRMWARE_EDID) edid_info = boot_params.edid_info; #endif @@ -1254,7 +1256,7 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) if (!efi_enabled(EFI_BOOT) || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY)) - vgacon_register_screen(&screen_info); + vgacon_register_screen(&sysfb_primary_display.screen); #endif #endif x86_init.oem.banner(); diff --git a/arch/x86/video/video-common.c b/arch/x86/video/video-common.c index e0aeee99bc99..152789f00fcd 100644 --- a/arch/x86/video/video-common.c +++ b/arch/x86/video/video-common.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include @@ -29,7 +29,7 @@ EXPORT_SYMBOL(pgprot_framebuffer); bool video_is_primary_device(struct device *dev) { #ifdef CONFIG_SCREEN_INFO - struct screen_info *si = &screen_info; + struct screen_info *si = &sysfb_primary_display.screen; struct resource res[SCREEN_INFO_MAX_RESOURCES]; ssize_t i, numres; #endif diff --git a/drivers/firmware/efi/earlycon.c b/drivers/firmware/efi/earlycon.c index 42e3a173dac1..3d060d59968c 100644 --- a/drivers/firmware/efi/earlycon.c +++ b/drivers/firmware/efi/earlycon.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include @@ -32,7 +32,7 @@ static void *efi_fb; */ static int __init efi_earlycon_remap_fb(void) { - const struct screen_info *si = &screen_info; + const struct screen_info *si = &sysfb_primary_display.screen; /* bail if there is no bootconsole or it was unregistered already */ if (!earlycon_console || !console_is_registered(earlycon_console)) @@ -147,7 +147,7 @@ static void efi_earlycon_write_char(u32 *dst, unsigned char c, unsigned int h, static void efi_earlycon_write(struct console *con, const char *str, unsigned int num) { - const struct screen_info *si = &screen_info; + const struct screen_info *si = &sysfb_primary_display.screen; u32 cur_efi_x = efi_x; unsigned int len; const char *s; @@ -227,7 +227,7 @@ void __init efi_earlycon_reprobe(void) static int __init efi_earlycon_setup(struct earlycon_device *device, const char *opt) { - const struct screen_info *si = &screen_info; + const struct screen_info *si = &sysfb_primary_display.screen; u16 xres, yres; u32 i; diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c index a65c2d5b9e7b..d1d418a34407 100644 --- a/drivers/firmware/efi/efi-init.c +++ b/drivers/firmware/efi/efi-init.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include @@ -57,15 +57,15 @@ static phys_addr_t __init efi_to_phys(unsigned long addr) extern __weak const efi_config_table_type_t efi_arch_tables[]; /* - * x86 defines its own screen_info and uses it even without EFI, - * everything else can get it from here. + * x86 defines its own instance of sysfb_primary_display and uses + * it even without EFI, everything else can get them from here. */ #if !defined(CONFIG_X86) && (defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON)) -struct screen_info screen_info __section(".data"); -EXPORT_SYMBOL_GPL(screen_info); +struct sysfb_display_info sysfb_primary_display __section(".data"); +EXPORT_SYMBOL_GPL(sysfb_primary_display); #endif -static void __init init_screen_info(void) +static void __init init_primary_display(void) { struct screen_info *si; @@ -75,13 +75,13 @@ static void __init init_screen_info(void) pr_err("Could not map screen_info config table\n"); return; } - screen_info = *si; + sysfb_primary_display.screen = *si; memset(si, 0, sizeof(*si)); early_memunmap(si, sizeof(*si)); - if (memblock_is_map_memory(screen_info.lfb_base)) - memblock_mark_nomap(screen_info.lfb_base, - screen_info.lfb_size); + if (memblock_is_map_memory(sysfb_primary_display.screen.lfb_base)) + memblock_mark_nomap(sysfb_primary_display.screen.lfb_base, + sysfb_primary_display.screen.lfb_size); if (IS_ENABLED(CONFIG_EFI_EARLYCON)) efi_earlycon_reprobe(); @@ -274,5 +274,5 @@ void __init efi_init(void) if (IS_ENABLED(CONFIG_X86) || IS_ENABLED(CONFIG_SYSFB) || IS_ENABLED(CONFIG_EFI_EARLYCON)) - init_screen_info(); + init_primary_display(); } diff --git a/drivers/firmware/efi/libstub/efi-stub-entry.c b/drivers/firmware/efi/libstub/efi-stub-entry.c index a6c049835190..401ecbbdf331 100644 --- a/drivers/firmware/efi/libstub/efi-stub-entry.c +++ b/drivers/firmware/efi/libstub/efi-stub-entry.c @@ -1,13 +1,18 @@ // SPDX-License-Identifier: GPL-2.0-only #include -#include +#include #include #include "efistub.h" -static unsigned long screen_info_offset; +static unsigned long kernel_image_offset; + +static void *kernel_image_addr(void *addr) +{ + return addr + kernel_image_offset; +} struct screen_info *alloc_screen_info(void) { @@ -16,8 +21,11 @@ struct screen_info *alloc_screen_info(void) if (IS_ENABLED(CONFIG_X86) || IS_ENABLED(CONFIG_EFI_EARLYCON) || - IS_ENABLED(CONFIG_SYSFB)) - return (void *)&screen_info + screen_info_offset; + IS_ENABLED(CONFIG_SYSFB)) { + struct sysfb_display_info *dpy = kernel_image_addr(&sysfb_primary_display); + + return &dpy->screen; + } return NULL; } @@ -73,7 +81,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, return status; } - screen_info_offset = image_addr - (unsigned long)image->image_base; + kernel_image_offset = image_addr - (unsigned long)image->image_base; status = efi_stub_common(handle, image, image_addr, cmdline_ptr); diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c index c074cbccd91b..4c3986ddcd54 100644 --- a/drivers/firmware/efi/sysfb_efi.c +++ b/drivers/firmware/efi/sysfb_efi.c @@ -176,7 +176,7 @@ static int __init efifb_set_system(struct screen_info *si, const struct dmi_syst static int __init efifb_set_system_callback(const struct dmi_system_id *id) { - return efifb_set_system(&screen_info, id); + return efifb_set_system(&sysfb_primary_display.screen, id); } #define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \ @@ -237,7 +237,7 @@ static const struct dmi_system_id efifb_dmi_system_table[] __initconst = { static int __init efifb_swap_width_height(const struct dmi_system_id *id) { - struct screen_info *si = &screen_info; + struct screen_info *si = &sysfb_primary_display.screen; u32 bpp = __screen_info_lfb_bits_per_pixel(si); swap(si->lfb_width, si->lfb_height); @@ -256,7 +256,7 @@ static int __init efifb_check_and_swap_width_height(const struct dmi_system_id *id) { const struct efifb_mode_fixup *data = id->driver_data; - struct screen_info *si = &screen_info; + struct screen_info *si = &sysfb_primary_display.screen; if (data->width == si->lfb_width && data->height == si->lfb_height) { swap(si->lfb_width, si->lfb_height); @@ -379,7 +379,7 @@ static struct device_node *find_pci_overlap_node(void) } for_each_of_pci_range(&parser, &range) - if (efifb_overlaps_pci_range(&screen_info, &range)) + if (efifb_overlaps_pci_range(&sysfb_primary_display.screen, &range)) return np; } return NULL; diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c index 916b28538a29..1f671f9219b0 100644 --- a/drivers/firmware/sysfb.c +++ b/drivers/firmware/sysfb.c @@ -66,7 +66,7 @@ static bool sysfb_unregister(void) */ void sysfb_disable(struct device *dev) { - struct screen_info *si = &screen_info; + struct screen_info *si = &sysfb_primary_display.screen; struct device *parent; mutex_lock(&disable_lock); @@ -92,7 +92,7 @@ EXPORT_SYMBOL_GPL(sysfb_disable); */ bool sysfb_handles_screen_info(void) { - const struct screen_info *si = &screen_info; + const struct screen_info *si = &sysfb_primary_display.screen; return !!screen_info_video_type(si); } @@ -141,7 +141,7 @@ static struct device *sysfb_parent_dev(const struct screen_info *si) static __init int sysfb_init(void) { - struct screen_info *si = &screen_info; + struct screen_info *si = &sysfb_primary_display.screen; struct device *parent; unsigned int type; struct simplefb_platform_data mode; diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index a53af6fe81a6..9c937190be81 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -2340,8 +2340,8 @@ static void __maybe_unused vmbus_reserve_fb(void) if (efi_enabled(EFI_BOOT)) { /* Gen2 VM: get FB base from EFI framebuffer */ if (IS_ENABLED(CONFIG_SYSFB)) { - start = screen_info.lfb_base; - size = max_t(__u32, screen_info.lfb_size, 0x800000); + start = sysfb_primary_display.screen.lfb_base; + size = max_t(__u32, sysfb_primary_display.screen.lfb_size, 0x800000); } } else { /* Gen1 VM: get FB base from PCI */ diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c index 436fa7f4c387..805be9ea4a34 100644 --- a/drivers/pci/vgaarb.c +++ b/drivers/pci/vgaarb.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include @@ -557,7 +557,7 @@ EXPORT_SYMBOL(vga_put); static bool vga_is_firmware_default(struct pci_dev *pdev) { #if defined CONFIG_X86 - return pdev == screen_info_pci_dev(&screen_info); + return pdev == screen_info_pci_dev(&sysfb_primary_display.screen); #else return false; #endif diff --git a/drivers/video/screen_info_pci.c b/drivers/video/screen_info_pci.c index 66bfc1d0a6dc..8f34d8a74f09 100644 --- a/drivers/video/screen_info_pci.c +++ b/drivers/video/screen_info_pci.c @@ -4,6 +4,7 @@ #include #include #include +#include static struct pci_dev *screen_info_lfb_pdev; static size_t screen_info_lfb_bar; @@ -26,7 +27,7 @@ static bool __screen_info_relocation_is_valid(const struct screen_info *si, stru void screen_info_apply_fixups(void) { - struct screen_info *si = &screen_info; + struct screen_info *si = &sysfb_primary_display.screen; if (screen_info_lfb_pdev) { struct resource *pr = &screen_info_lfb_pdev->resource[screen_info_lfb_bar]; @@ -75,7 +76,7 @@ static void screen_info_fixup_lfb(struct pci_dev *pdev) .flags = IORESOURCE_MEM, }; const struct resource *pr; - const struct screen_info *si = &screen_info; + const struct screen_info *si = &sysfb_primary_display.screen; if (screen_info_lfb_pdev) return; // already found diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h index 1690706206e8..c022403c599a 100644 --- a/include/linux/screen_info.h +++ b/include/linux/screen_info.h @@ -151,6 +151,4 @@ static inline struct pci_dev *screen_info_pci_dev(const struct screen_info *si) } #endif -extern struct screen_info screen_info; - #endif /* _SCREEN_INFO_H */ diff --git a/include/linux/sysfb.h b/include/linux/sysfb.h index 8b37247528bf..e8bde392c690 100644 --- a/include/linux/sysfb.h +++ b/include/linux/sysfb.h @@ -8,11 +8,10 @@ */ #include +#include #include #include -#include - struct device; struct platform_device; struct screen_info; @@ -65,6 +64,8 @@ struct sysfb_display_info { struct screen_info screen; }; +extern struct sysfb_display_info sysfb_primary_display; + #ifdef CONFIG_SYSFB void sysfb_disable(struct device *dev); From 08e583ad68577ff5135d2b6fad1d3b4b400074a5 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 26 Nov 2025 17:03:22 +0100 Subject: [PATCH 09/11] sysfb: Pass sysfb_primary_display to devices Instead of screen_info, store a copy of sysfb_primary_display as device data. Pick it up in drivers. Later changes will add additional data to the display info, such as EDID information. Signed-off-by: Thomas Zimmermann Acked-by: Arnd Bergmann Acked-by: Ard Biesheuvel Reviewed-by: Richard Lyu Signed-off-by: Ard Biesheuvel --- drivers/firmware/sysfb.c | 5 +++-- drivers/gpu/drm/sysfb/efidrm.c | 9 ++++++--- drivers/gpu/drm/sysfb/vesadrm.c | 9 ++++++--- drivers/video/fbdev/efifb.c | 10 ++++++---- drivers/video/fbdev/vesafb.c | 10 ++++++---- drivers/video/fbdev/vga16fb.c | 8 +++++--- 6 files changed, 32 insertions(+), 19 deletions(-) diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c index 1f671f9219b0..8833582c1883 100644 --- a/drivers/firmware/sysfb.c +++ b/drivers/firmware/sysfb.c @@ -141,7 +141,8 @@ static struct device *sysfb_parent_dev(const struct screen_info *si) static __init int sysfb_init(void) { - struct screen_info *si = &sysfb_primary_display.screen; + struct sysfb_display_info *dpy = &sysfb_primary_display; + struct screen_info *si = &dpy->screen; struct device *parent; unsigned int type; struct simplefb_platform_data mode; @@ -202,7 +203,7 @@ static __init int sysfb_init(void) sysfb_set_efifb_fwnode(si, pd); - ret = platform_device_add_data(pd, si, sizeof(*si)); + ret = platform_device_add_data(pd, dpy, sizeof(*dpy)); if (ret) goto err; diff --git a/drivers/gpu/drm/sysfb/efidrm.c b/drivers/gpu/drm/sysfb/efidrm.c index 1b683d55d6ea..29533ae8fbbf 100644 --- a/drivers/gpu/drm/sysfb/efidrm.c +++ b/drivers/gpu/drm/sysfb/efidrm.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -141,6 +141,7 @@ static const struct drm_mode_config_funcs efidrm_mode_config_funcs = { static struct efidrm_device *efidrm_device_create(struct drm_driver *drv, struct platform_device *pdev) { + const struct sysfb_display_info *dpy; const struct screen_info *si; const struct drm_format_info *format; int width, height, stride; @@ -160,9 +161,11 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv, size_t nformats; int ret; - si = dev_get_platdata(&pdev->dev); - if (!si) + dpy = dev_get_platdata(&pdev->dev); + if (!dpy) return ERR_PTR(-ENODEV); + si = &dpy->screen; + if (screen_info_video_type(si) != VIDEO_TYPE_EFI) return ERR_PTR(-ENODEV); diff --git a/drivers/gpu/drm/sysfb/vesadrm.c b/drivers/gpu/drm/sysfb/vesadrm.c index 7b7b5ba26317..16fc223f8c5b 100644 --- a/drivers/gpu/drm/sysfb/vesadrm.c +++ b/drivers/gpu/drm/sysfb/vesadrm.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -391,6 +391,7 @@ static const struct drm_mode_config_funcs vesadrm_mode_config_funcs = { static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv, struct platform_device *pdev) { + const struct sysfb_display_info *dpy; const struct screen_info *si; const struct drm_format_info *format; int width, height, stride; @@ -410,9 +411,11 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv, size_t nformats; int ret; - si = dev_get_platdata(&pdev->dev); - if (!si) + dpy = dev_get_platdata(&pdev->dev); + if (!dpy) return ERR_PTR(-ENODEV); + si = &dpy->screen; + if (screen_info_video_type(si) != VIDEO_TYPE_VLFB) return ERR_PTR(-ENODEV); diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c index 0e1bd3dba255..47ebc0107209 100644 --- a/drivers/video/fbdev/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include