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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'efi-next-for-v7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi

Pull EFI updates from Ard Biesheuvel:

- Quirk the broken EFI framebuffer geometry on the Valve Steam Deck

- Capture the EDID information of the primary display also on non-x86
EFI systems when booting via the EFI stub.

* tag 'efi-next-for-v7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi:
efi: Support EDID information
sysfb: Move edid_info into sysfb_primary_display
sysfb: Pass sysfb_primary_display to devices
sysfb: Replace screen_info with sysfb_primary_display
sysfb: Add struct sysfb_display_info
efi: sysfb_efi: Reduce number of references to global screen_info
efi: earlycon: Reduce number of references to global screen_info
efi: sysfb_efi: Fix efidrmfb and simpledrmfb on Valve Steam Deck
efi: sysfb_efi: Convert swap width and height quirk to a callback
efi: sysfb_efi: Fix lfb_linelength calculation when applying quirks
efi: sysfb_efi: Replace open coded swap with the macro

+359 -252
+1 -1
arch/arm64/kernel/image-vars.h
··· 38 38 PROVIDE(__efistub___inittext_end = __inittext_end); 39 39 PROVIDE(__efistub__edata = _edata); 40 40 #if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB) 41 - PROVIDE(__efistub_screen_info = screen_info); 41 + PROVIDE(__efistub_sysfb_primary_display = sysfb_primary_display); 42 42 #endif 43 43 PROVIDE(__efistub__ctype = _ctype); 44 44
+16 -15
arch/loongarch/kernel/efi.c
··· 18 18 #include <linux/kobject.h> 19 19 #include <linux/memblock.h> 20 20 #include <linux/reboot.h> 21 - #include <linux/screen_info.h> 21 + #include <linux/sysfb.h> 22 22 #include <linux/uaccess.h> 23 23 24 24 #include <asm/early_ioremap.h> ··· 72 72 (acpi_gbl_reduced_hardware || acpi_no_s5); 73 73 } 74 74 75 - unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR; 75 + unsigned long __initdata primary_display_table = EFI_INVALID_TABLE_ADDR; 76 76 77 77 #if defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON) 78 - struct screen_info screen_info __section(".data"); 79 - EXPORT_SYMBOL_GPL(screen_info); 78 + struct sysfb_display_info sysfb_primary_display __section(".data"); 79 + EXPORT_SYMBOL_GPL(sysfb_primary_display); 80 80 #endif 81 81 82 - static void __init init_screen_info(void) 82 + static void __init init_primary_display(void) 83 83 { 84 - struct screen_info *si; 84 + struct sysfb_display_info *dpy; 85 85 86 - if (screen_info_table == EFI_INVALID_TABLE_ADDR) 86 + if (primary_display_table == EFI_INVALID_TABLE_ADDR) 87 87 return; 88 88 89 - si = early_memremap(screen_info_table, sizeof(*si)); 90 - if (!si) { 91 - pr_err("Could not map screen_info config table\n"); 89 + dpy = early_memremap(primary_display_table, sizeof(*dpy)); 90 + if (!dpy) { 91 + pr_err("Could not map primary_display config table\n"); 92 92 return; 93 93 } 94 - screen_info = *si; 95 - memset(si, 0, sizeof(*si)); 96 - early_memunmap(si, sizeof(*si)); 94 + sysfb_primary_display = *dpy; 95 + memset(dpy, 0, sizeof(*dpy)); 96 + early_memunmap(dpy, sizeof(*dpy)); 97 97 98 - memblock_reserve(__screen_info_lfb_base(&screen_info), screen_info.lfb_size); 98 + memblock_reserve(__screen_info_lfb_base(&sysfb_primary_display.screen), 99 + sysfb_primary_display.screen.lfb_size); 99 100 } 100 101 101 102 void __init efi_init(void) ··· 130 129 set_bit(EFI_CONFIG_TABLES, &efi.flags); 131 130 132 131 if (IS_ENABLED(CONFIG_EFI_EARLYCON) || IS_ENABLED(CONFIG_SYSFB)) 133 - init_screen_info(); 132 + init_primary_display(); 134 133 135 134 if (boot_memmap == EFI_INVALID_TABLE_ADDR) 136 135 return;
+1 -1
arch/loongarch/kernel/image-vars.h
··· 12 12 __efistub_kernel_asize = kernel_asize; 13 13 __efistub_kernel_fsize = kernel_fsize; 14 14 #if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB) 15 - __efistub_screen_info = screen_info; 15 + __efistub_sysfb_primary_display = sysfb_primary_display; 16 16 #endif 17 17 18 18 #endif
+1 -1
arch/riscv/kernel/image-vars.h
··· 29 29 __efistub__edata = _edata; 30 30 __efistub___init_text_end = __init_text_end; 31 31 #if defined(CONFIG_EFI_EARLYCON) || defined(CONFIG_SYSFB) 32 - __efistub_screen_info = screen_info; 32 + __efistub_sysfb_primary_display = sysfb_primary_display; 33 33 #endif 34 34 35 35 #endif
+3 -1
arch/x86/kernel/kexec-bzimage64.c
··· 20 20 #include <linux/of_fdt.h> 21 21 #include <linux/efi.h> 22 22 #include <linux/random.h> 23 + #include <linux/sysfb.h> 23 24 24 25 #include <asm/bootparam.h> 25 26 #include <asm/setup.h> ··· 304 303 params->hdr.hardware_subarch = boot_params.hdr.hardware_subarch; 305 304 306 305 /* Copying screen_info will do? */ 307 - memcpy(&params->screen_info, &screen_info, sizeof(struct screen_info)); 306 + memcpy(&params->screen_info, &sysfb_primary_display.screen, 307 + sizeof(sysfb_primary_display.screen)); 308 308 309 309 /* Fill in memsize later */ 310 310 params->screen_info.ext_mem_k = 0;
+7 -9
arch/x86/kernel/setup.c
··· 22 22 #include <linux/random.h> 23 23 #include <linux/root_dev.h> 24 24 #include <linux/static_call.h> 25 + #include <linux/sysfb.h> 25 26 #include <linux/swiotlb.h> 26 27 #include <linux/tboot.h> 27 28 #include <linux/usb/xhci-dbgp.h> ··· 212 211 /* 213 212 * Setup options 214 213 */ 215 - struct screen_info screen_info; 216 - EXPORT_SYMBOL(screen_info); 217 - #if defined(CONFIG_FIRMWARE_EDID) 218 - struct edid_info edid_info; 219 - EXPORT_SYMBOL_GPL(edid_info); 220 - #endif 214 + 215 + struct sysfb_display_info sysfb_primary_display; 216 + EXPORT_SYMBOL(sysfb_primary_display); 221 217 222 218 extern int root_mountflags; 223 219 ··· 524 526 static void __init parse_boot_params(void) 525 527 { 526 528 ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev); 527 - screen_info = boot_params.screen_info; 529 + sysfb_primary_display.screen = boot_params.screen_info; 528 530 #if defined(CONFIG_FIRMWARE_EDID) 529 - edid_info = boot_params.edid_info; 531 + sysfb_primary_display.edid = boot_params.edid_info; 530 532 #endif 531 533 #ifdef CONFIG_X86_32 532 534 apm_info.bios = boot_params.apm_bios_info; ··· 1252 1254 #ifdef CONFIG_VT 1253 1255 #if defined(CONFIG_VGA_CONSOLE) 1254 1256 if (!efi_enabled(EFI_BOOT) || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY)) 1255 - vgacon_register_screen(&screen_info); 1257 + vgacon_register_screen(&sysfb_primary_display.screen); 1256 1258 #endif 1257 1259 #endif 1258 1260 x86_init.oem.banner();
+2 -2
arch/x86/video/video-common.c
··· 9 9 10 10 #include <linux/module.h> 11 11 #include <linux/pci.h> 12 - #include <linux/screen_info.h> 12 + #include <linux/sysfb.h> 13 13 #include <linux/vgaarb.h> 14 14 15 15 #include <asm/video.h> ··· 29 29 bool video_is_primary_device(struct device *dev) 30 30 { 31 31 #ifdef CONFIG_SCREEN_INFO 32 - struct screen_info *si = &screen_info; 32 + struct screen_info *si = &sysfb_primary_display.screen; 33 33 struct resource res[SCREEN_INFO_MAX_RESOURCES]; 34 34 ssize_t i, numres; 35 35 #endif
+21 -21
drivers/firmware/efi/earlycon.c
··· 9 9 #include <linux/io.h> 10 10 #include <linux/kernel.h> 11 11 #include <linux/serial_core.h> 12 - #include <linux/screen_info.h> 12 + #include <linux/sysfb.h> 13 13 #include <linux/string.h> 14 14 15 15 #include <asm/early_ioremap.h> ··· 32 32 */ 33 33 static int __init efi_earlycon_remap_fb(void) 34 34 { 35 + const struct screen_info *si = &sysfb_primary_display.screen; 36 + 35 37 /* bail if there is no bootconsole or it was unregistered already */ 36 38 if (!earlycon_console || !console_is_registered(earlycon_console)) 37 39 return 0; 38 40 39 - efi_fb = memremap(fb_base, screen_info.lfb_size, 40 - fb_wb ? MEMREMAP_WB : MEMREMAP_WC); 41 + efi_fb = memremap(fb_base, si->lfb_size, fb_wb ? MEMREMAP_WB : MEMREMAP_WC); 41 42 42 43 return efi_fb ? 0 : -ENOMEM; 43 44 } ··· 72 71 early_memunmap(addr, len); 73 72 } 74 73 75 - static void efi_earlycon_clear_scanline(unsigned int y) 74 + static void efi_earlycon_clear_scanline(unsigned int y, const struct screen_info *si) 76 75 { 77 76 unsigned long *dst; 78 77 u16 len; 79 78 80 - len = screen_info.lfb_linelength; 79 + len = si->lfb_linelength; 81 80 dst = efi_earlycon_map(y*len, len); 82 81 if (!dst) 83 82 return; ··· 86 85 efi_earlycon_unmap(dst, len); 87 86 } 88 87 89 - static void efi_earlycon_scroll_up(void) 88 + static void efi_earlycon_scroll_up(const struct screen_info *si) 90 89 { 91 90 unsigned long *dst, *src; 92 91 u16 maxlen = 0; ··· 100 99 } 101 100 maxlen *= 4; 102 101 103 - len = screen_info.lfb_linelength; 104 - height = screen_info.lfb_height; 102 + len = si->lfb_linelength; 103 + height = si->lfb_height; 105 104 106 105 for (i = 0; i < height - font->height; i++) { 107 106 dst = efi_earlycon_map(i*len, len); ··· 121 120 } 122 121 } 123 122 124 - static void efi_earlycon_write_char(u32 *dst, unsigned char c, unsigned int h) 123 + static void efi_earlycon_write_char(u32 *dst, unsigned char c, unsigned int h, 124 + const struct screen_info *si) 125 125 { 126 126 const u32 color_black = 0x00000000; 127 127 const u32 color_white = 0x00ffffff; ··· 147 145 static void 148 146 efi_earlycon_write(struct console *con, const char *str, unsigned int num) 149 147 { 150 - struct screen_info *si; 148 + const struct screen_info *si = &sysfb_primary_display.screen; 151 149 u32 cur_efi_x = efi_x; 152 150 unsigned int len; 153 151 const char *s; 154 152 void *dst; 155 153 156 - si = &screen_info; 157 154 len = si->lfb_linelength; 158 155 159 156 while (num) { ··· 175 174 x = efi_x; 176 175 177 176 while (n-- > 0) { 178 - efi_earlycon_write_char(dst + x*4, *s, h); 177 + efi_earlycon_write_char(dst + x * 4, *s, h, si); 179 178 x += font->width; 180 179 s++; 181 180 } ··· 208 207 cur_line_y = (cur_line_y + 1) % max_line_y; 209 208 210 209 efi_y -= font->height; 211 - efi_earlycon_scroll_up(); 210 + efi_earlycon_scroll_up(si); 212 211 213 212 for (i = 0; i < font->height; i++) 214 - efi_earlycon_clear_scanline(efi_y + i); 213 + efi_earlycon_clear_scanline(efi_y + i, si); 215 214 } 216 215 } 217 216 } ··· 227 226 static int __init efi_earlycon_setup(struct earlycon_device *device, 228 227 const char *opt) 229 228 { 230 - struct screen_info *si; 229 + const struct screen_info *si = &sysfb_primary_display.screen; 231 230 u16 xres, yres; 232 231 u32 i; 233 232 234 233 fb_wb = opt && !strcmp(opt, "ram"); 235 234 236 - if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) { 235 + if (si->orig_video_isVGA != VIDEO_TYPE_EFI) { 237 236 fb_probed = true; 238 237 return -ENODEV; 239 238 } 240 239 241 - fb_base = screen_info.lfb_base; 242 - if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) 243 - fb_base |= (u64)screen_info.ext_lfb_base << 32; 240 + fb_base = si->lfb_base; 241 + if (si->capabilities & VIDEO_CAPABILITY_64BIT_BASE) 242 + fb_base |= (u64)si->ext_lfb_base << 32; 244 243 245 - si = &screen_info; 246 244 xres = si->lfb_width; 247 245 yres = si->lfb_height; 248 246 ··· 266 266 267 267 efi_y -= font->height; 268 268 for (i = 0; i < (yres - efi_y) / font->height; i++) 269 - efi_earlycon_scroll_up(); 269 + efi_earlycon_scroll_up(si); 270 270 271 271 device->con->write = efi_earlycon_write; 272 272 earlycon_console = device->con;
+19 -19
drivers/firmware/efi/efi-init.c
··· 19 19 #include <linux/of_address.h> 20 20 #include <linux/of_fdt.h> 21 21 #include <linux/platform_device.h> 22 - #include <linux/screen_info.h> 22 + #include <linux/sysfb.h> 23 23 24 24 #include <asm/efi.h> 25 25 26 - unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR; 26 + unsigned long __initdata primary_display_table = EFI_INVALID_TABLE_ADDR; 27 27 28 28 static int __init is_memory(efi_memory_desc_t *md) 29 29 { ··· 57 57 extern __weak const efi_config_table_type_t efi_arch_tables[]; 58 58 59 59 /* 60 - * x86 defines its own screen_info and uses it even without EFI, 61 - * everything else can get it from here. 60 + * x86 defines its own instance of sysfb_primary_display and uses 61 + * it even without EFI, everything else can get them from here. 62 62 */ 63 63 #if !defined(CONFIG_X86) && (defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON)) 64 - struct screen_info screen_info __section(".data"); 65 - EXPORT_SYMBOL_GPL(screen_info); 64 + struct sysfb_display_info sysfb_primary_display __section(".data"); 65 + EXPORT_SYMBOL_GPL(sysfb_primary_display); 66 66 #endif 67 67 68 - static void __init init_screen_info(void) 68 + static void __init init_primary_display(void) 69 69 { 70 - struct screen_info *si; 70 + struct sysfb_display_info *dpy; 71 71 72 - if (screen_info_table != EFI_INVALID_TABLE_ADDR) { 73 - si = early_memremap(screen_info_table, sizeof(*si)); 74 - if (!si) { 75 - pr_err("Could not map screen_info config table\n"); 72 + if (primary_display_table != EFI_INVALID_TABLE_ADDR) { 73 + dpy = early_memremap(primary_display_table, sizeof(*dpy)); 74 + if (!dpy) { 75 + pr_err("Could not map primary_display config table\n"); 76 76 return; 77 77 } 78 - screen_info = *si; 79 - memset(si, 0, sizeof(*si)); 80 - early_memunmap(si, sizeof(*si)); 78 + sysfb_primary_display = *dpy; 79 + memset(dpy, 0, sizeof(*dpy)); 80 + early_memunmap(dpy, sizeof(*dpy)); 81 81 82 - if (memblock_is_map_memory(screen_info.lfb_base)) 83 - memblock_mark_nomap(screen_info.lfb_base, 84 - screen_info.lfb_size); 82 + if (memblock_is_map_memory(sysfb_primary_display.screen.lfb_base)) 83 + memblock_mark_nomap(sysfb_primary_display.screen.lfb_base, 84 + sysfb_primary_display.screen.lfb_size); 85 85 86 86 if (IS_ENABLED(CONFIG_EFI_EARLYCON)) 87 87 efi_earlycon_reprobe(); ··· 274 274 if (IS_ENABLED(CONFIG_X86) || 275 275 IS_ENABLED(CONFIG_SYSFB) || 276 276 IS_ENABLED(CONFIG_EFI_EARLYCON)) 277 - init_screen_info(); 277 + init_primary_display(); 278 278 }
+2 -2
drivers/firmware/efi/efi.c
··· 63 63 static unsigned long __initdata rt_prop = EFI_INVALID_TABLE_ADDR; 64 64 static unsigned long __initdata initrd = EFI_INVALID_TABLE_ADDR; 65 65 66 - extern unsigned long screen_info_table; 66 + extern unsigned long primary_display_table; 67 67 68 68 struct mm_struct efi_mm = { 69 69 .mm_mt = MTREE_INIT_EXT(mm_mt, MM_MT_FLAGS, efi_mm.mmap_lock), ··· 642 642 {LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID, &efi.unaccepted, "Unaccepted" }, 643 643 #endif 644 644 #ifdef CONFIG_EFI_GENERIC_STUB 645 - {LINUX_EFI_SCREEN_INFO_TABLE_GUID, &screen_info_table }, 645 + {LINUX_EFI_PRIMARY_DISPLAY_TABLE_GUID, &primary_display_table }, 646 646 #endif 647 647 {}, 648 648 };
+1 -1
drivers/firmware/efi/libstub/Makefile
··· 80 80 $(call if_changed_rule,cc_o_c) 81 81 82 82 lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o \ 83 - screen_info.o efi-stub-entry.o 83 + primary_display.o efi-stub-entry.o 84 84 85 85 lib-$(CONFIG_ARM) += arm32-stub.o 86 86 lib-$(CONFIG_ARM64) += kaslr.o arm64.o arm64-stub.o smbios.o
+11 -6
drivers/firmware/efi/libstub/efi-stub-entry.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 3 3 #include <linux/efi.h> 4 - #include <linux/screen_info.h> 4 + #include <linux/sysfb.h> 5 5 6 6 #include <asm/efi.h> 7 7 8 8 #include "efistub.h" 9 9 10 - static unsigned long screen_info_offset; 10 + static unsigned long kernel_image_offset; 11 11 12 - struct screen_info *alloc_screen_info(void) 12 + static void *kernel_image_addr(void *addr) 13 + { 14 + return addr + kernel_image_offset; 15 + } 16 + 17 + struct sysfb_display_info *alloc_primary_display(void) 13 18 { 14 19 if (IS_ENABLED(CONFIG_ARM)) 15 - return __alloc_screen_info(); 20 + return __alloc_primary_display(); 16 21 17 22 if (IS_ENABLED(CONFIG_X86) || 18 23 IS_ENABLED(CONFIG_EFI_EARLYCON) || 19 24 IS_ENABLED(CONFIG_SYSFB)) 20 - return (void *)&screen_info + screen_info_offset; 25 + return kernel_image_addr(&sysfb_primary_display); 21 26 22 27 return NULL; 23 28 } ··· 78 73 return status; 79 74 } 80 75 81 - screen_info_offset = image_addr - (unsigned long)image->image_base; 76 + kernel_image_offset = image_addr - (unsigned long)image->image_base; 82 77 83 78 status = efi_stub_common(handle, image, image_addr, cmdline_ptr); 84 79
+27 -16
drivers/firmware/efi/libstub/efi-stub.c
··· 10 10 */ 11 11 12 12 #include <linux/efi.h> 13 - #include <linux/screen_info.h> 13 + #include <linux/sysfb.h> 14 14 #include <asm/efi.h> 15 15 16 16 #include "efistub.h" ··· 48 48 static u64 virtmap_base = EFI_RT_VIRTUAL_BASE; 49 49 static bool flat_va_mapping = (EFI_RT_VIRTUAL_OFFSET != 0); 50 50 51 - void __weak free_screen_info(struct screen_info *si) 51 + void __weak free_primary_display(struct sysfb_display_info *dpy) 52 + { } 53 + 54 + static struct sysfb_display_info *setup_primary_display(void) 52 55 { 53 - } 56 + struct sysfb_display_info *dpy; 57 + struct screen_info *screen = NULL; 58 + struct edid_info *edid = NULL; 59 + efi_status_t status; 54 60 55 - static struct screen_info *setup_graphics(void) 56 - { 57 - struct screen_info *si, tmp = {}; 58 - 59 - if (efi_setup_graphics(&tmp, NULL) != EFI_SUCCESS) 61 + dpy = alloc_primary_display(); 62 + if (!dpy) 60 63 return NULL; 64 + screen = &dpy->screen; 65 + #if defined(CONFIG_FIRMWARE_EDID) 66 + edid = &dpy->edid; 67 + #endif 61 68 62 - si = alloc_screen_info(); 63 - if (!si) 64 - return NULL; 69 + status = efi_setup_graphics(screen, edid); 70 + if (status != EFI_SUCCESS) 71 + goto err_free_primary_display; 65 72 66 - *si = tmp; 67 - return si; 73 + return dpy; 74 + 75 + err_free_primary_display: 76 + free_primary_display(dpy); 77 + return NULL; 68 78 } 69 79 70 80 static void install_memreserve_table(void) ··· 155 145 unsigned long image_addr, 156 146 char *cmdline_ptr) 157 147 { 158 - struct screen_info *si; 148 + struct sysfb_display_info *dpy; 159 149 efi_status_t status; 160 150 161 151 status = check_platform_features(); 162 152 if (status != EFI_SUCCESS) 163 153 return status; 164 154 165 - si = setup_graphics(); 155 + dpy = setup_primary_display(); 166 156 167 157 efi_retrieve_eventlog(); 168 158 ··· 182 172 183 173 status = efi_boot_kernel(handle, image, image_addr, cmdline_ptr); 184 174 185 - free_screen_info(si); 175 + free_primary_display(dpy); 176 + 186 177 return status; 187 178 } 188 179
+4 -3
drivers/firmware/efi/libstub/efistub.h
··· 36 36 37 37 struct edid_info; 38 38 struct screen_info; 39 + struct sysfb_display_info; 39 40 40 41 extern bool efi_no5lvl; 41 42 extern bool efi_nochunk; ··· 1176 1175 1177 1176 void efi_retrieve_eventlog(void); 1178 1177 1179 - struct screen_info *alloc_screen_info(void); 1180 - struct screen_info *__alloc_screen_info(void); 1181 - void free_screen_info(struct screen_info *si); 1178 + struct sysfb_display_info *alloc_primary_display(void); 1179 + struct sysfb_display_info *__alloc_primary_display(void); 1180 + void free_primary_display(struct sysfb_display_info *dpy); 1182 1181 1183 1182 void efi_cache_sync_image(unsigned long image_base, 1184 1183 unsigned long alloc_size);
+56
drivers/firmware/efi/libstub/primary_display.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/efi.h> 4 + #include <linux/sysfb.h> 5 + 6 + #include <asm/efi.h> 7 + 8 + #include "efistub.h" 9 + 10 + /* 11 + * There are two ways of populating the core kernel's sysfb_primary_display 12 + * via the stub: 13 + * 14 + * - using a configuration table, which relies on the EFI init code to 15 + * locate the table and copy the contents; or 16 + * 17 + * - by linking directly to the core kernel's copy of the global symbol. 18 + * 19 + * The latter is preferred because it makes the EFIFB earlycon available very 20 + * early, but it only works if the EFI stub is part of the core kernel image 21 + * itself. The zboot decompressor can only use the configuration table 22 + * approach. 23 + */ 24 + 25 + static efi_guid_t primary_display_guid = LINUX_EFI_PRIMARY_DISPLAY_TABLE_GUID; 26 + 27 + struct sysfb_display_info *__alloc_primary_display(void) 28 + { 29 + struct sysfb_display_info *dpy; 30 + efi_status_t status; 31 + 32 + status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY, 33 + sizeof(*dpy), (void **)&dpy); 34 + 35 + if (status != EFI_SUCCESS) 36 + return NULL; 37 + 38 + memset(dpy, 0, sizeof(*dpy)); 39 + 40 + status = efi_bs_call(install_configuration_table, 41 + &primary_display_guid, dpy); 42 + if (status == EFI_SUCCESS) 43 + return dpy; 44 + 45 + efi_bs_call(free_pool, dpy); 46 + return NULL; 47 + } 48 + 49 + void free_primary_display(struct sysfb_display_info *dpy) 50 + { 51 + if (!dpy) 52 + return; 53 + 54 + efi_bs_call(install_configuration_table, &primary_display_guid, NULL); 55 + efi_bs_call(free_pool, dpy); 56 + }
-53
drivers/firmware/efi/libstub/screen_info.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - 3 - #include <linux/efi.h> 4 - #include <linux/screen_info.h> 5 - 6 - #include <asm/efi.h> 7 - 8 - #include "efistub.h" 9 - 10 - /* 11 - * There are two ways of populating the core kernel's struct screen_info via the stub: 12 - * - using a configuration table, like below, which relies on the EFI init code 13 - * to locate the table and copy the contents; 14 - * - by linking directly to the core kernel's copy of the global symbol. 15 - * 16 - * The latter is preferred because it makes the EFIFB earlycon available very 17 - * early, but it only works if the EFI stub is part of the core kernel image 18 - * itself. The zboot decompressor can only use the configuration table 19 - * approach. 20 - */ 21 - 22 - static efi_guid_t screen_info_guid = LINUX_EFI_SCREEN_INFO_TABLE_GUID; 23 - 24 - struct screen_info *__alloc_screen_info(void) 25 - { 26 - struct screen_info *si; 27 - efi_status_t status; 28 - 29 - status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY, 30 - sizeof(*si), (void **)&si); 31 - 32 - if (status != EFI_SUCCESS) 33 - return NULL; 34 - 35 - memset(si, 0, sizeof(*si)); 36 - 37 - status = efi_bs_call(install_configuration_table, 38 - &screen_info_guid, si); 39 - if (status == EFI_SUCCESS) 40 - return si; 41 - 42 - efi_bs_call(free_pool, si); 43 - return NULL; 44 - } 45 - 46 - void free_screen_info(struct screen_info *si) 47 - { 48 - if (!si) 49 - return; 50 - 51 - efi_bs_call(install_configuration_table, &screen_info_guid, NULL); 52 - efi_bs_call(free_pool, si); 53 - }
+2 -2
drivers/firmware/efi/libstub/zboot.c
··· 26 26 // executable code loaded into memory to be safe for execution. 27 27 } 28 28 29 - struct screen_info *alloc_screen_info(void) 29 + struct sysfb_display_info *alloc_primary_display(void) 30 30 { 31 - return __alloc_screen_info(); 31 + return __alloc_primary_display(); 32 32 } 33 33 34 34 asmlinkage efi_status_t __efiapi
+103 -41
drivers/firmware/efi/sysfb_efi.c
··· 92 92 }) 93 93 94 94 #ifdef CONFIG_EFI 95 - static int __init efifb_set_system(const struct dmi_system_id *id) 95 + static int __init efifb_set_system(struct screen_info *si, const struct dmi_system_id *id) 96 96 { 97 97 struct efifb_dmi_info *info = id->driver_data; 98 98 ··· 101 101 return 0; 102 102 103 103 /* Trust the bootloader over the DMI tables */ 104 - if (screen_info.lfb_base == 0) { 104 + if (si->lfb_base == 0) { 105 105 #if defined(CONFIG_PCI) 106 106 struct pci_dev *dev = NULL; 107 107 int found_bar = 0; 108 108 #endif 109 109 if (info->base) { 110 - screen_info.lfb_base = choose_value(info->base, 111 - screen_info.lfb_base, OVERRIDE_BASE, 110 + si->lfb_base = choose_value(info->base, 111 + si->lfb_base, OVERRIDE_BASE, 112 112 info->flags); 113 113 114 114 #if defined(CONFIG_PCI) ··· 135 135 136 136 start = pci_resource_start(dev, i); 137 137 end = pci_resource_end(dev, i); 138 - if (screen_info.lfb_base >= start && 139 - screen_info.lfb_base < end) { 138 + if (si->lfb_base >= start && si->lfb_base < end) { 140 139 found_bar = 1; 141 140 break; 142 141 } 143 142 } 144 143 } 145 144 if (!found_bar) 146 - screen_info.lfb_base = 0; 145 + si->lfb_base = 0; 147 146 #endif 148 147 } 149 148 } 150 - if (screen_info.lfb_base) { 151 - screen_info.lfb_linelength = choose_value(info->stride, 152 - screen_info.lfb_linelength, OVERRIDE_STRIDE, 149 + if (si->lfb_base) { 150 + si->lfb_linelength = choose_value(info->stride, 151 + si->lfb_linelength, OVERRIDE_STRIDE, 153 152 info->flags); 154 - screen_info.lfb_width = choose_value(info->width, 155 - screen_info.lfb_width, OVERRIDE_WIDTH, 153 + si->lfb_width = choose_value(info->width, 154 + si->lfb_width, OVERRIDE_WIDTH, 156 155 info->flags); 157 - screen_info.lfb_height = choose_value(info->height, 158 - screen_info.lfb_height, OVERRIDE_HEIGHT, 156 + si->lfb_height = choose_value(info->height, 157 + si->lfb_height, OVERRIDE_HEIGHT, 159 158 info->flags); 160 - if (screen_info.orig_video_isVGA == 0) 161 - screen_info.orig_video_isVGA = VIDEO_TYPE_EFI; 159 + if (si->orig_video_isVGA == 0) 160 + si->orig_video_isVGA = VIDEO_TYPE_EFI; 162 161 } else { 163 - screen_info.lfb_linelength = 0; 164 - screen_info.lfb_width = 0; 165 - screen_info.lfb_height = 0; 166 - screen_info.orig_video_isVGA = 0; 162 + si->lfb_linelength = 0; 163 + si->lfb_width = 0; 164 + si->lfb_height = 0; 165 + si->orig_video_isVGA = 0; 167 166 return 0; 168 167 } 169 168 170 169 printk(KERN_INFO "efifb: dmi detected %s - framebuffer at 0x%08x " 171 170 "(%dx%d, stride %d)\n", id->ident, 172 - screen_info.lfb_base, screen_info.lfb_width, 173 - screen_info.lfb_height, screen_info.lfb_linelength); 171 + si->lfb_base, si->lfb_width, 172 + si->lfb_height, si->lfb_linelength); 174 173 175 174 return 1; 176 175 } 177 176 177 + static int __init efifb_set_system_callback(const struct dmi_system_id *id) 178 + { 179 + return efifb_set_system(&sysfb_primary_display.screen, id); 180 + } 181 + 178 182 #define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \ 179 183 { \ 180 - efifb_set_system, \ 184 + efifb_set_system_callback, \ 181 185 name, \ 182 186 { \ 183 187 DMI_MATCH(DMI_BIOS_VENDOR, vendor), \ ··· 235 231 {}, 236 232 }; 237 233 234 + static int __init efifb_swap_width_height(const struct dmi_system_id *id) 235 + { 236 + struct screen_info *si = &sysfb_primary_display.screen; 237 + u32 bpp = __screen_info_lfb_bits_per_pixel(si); 238 + 239 + swap(si->lfb_width, si->lfb_height); 240 + si->lfb_linelength = bpp * si->lfb_width / BITS_PER_BYTE; 241 + 242 + return 1; 243 + } 244 + 245 + struct efifb_mode_fixup { 246 + unsigned int width; 247 + unsigned int height; 248 + unsigned int linelength; 249 + }; 250 + 251 + static int __init 252 + efifb_check_and_swap_width_height(const struct dmi_system_id *id) 253 + { 254 + const struct efifb_mode_fixup *data = id->driver_data; 255 + struct screen_info *si = &sysfb_primary_display.screen; 256 + 257 + if (data->width == si->lfb_width && data->height == si->lfb_height) { 258 + swap(si->lfb_width, si->lfb_height); 259 + si->lfb_linelength = data->linelength; 260 + si->lfb_size = data->linelength * data->width; 261 + } 262 + 263 + return 1; 264 + } 265 + 266 + static const struct efifb_mode_fixup efifb_steamdeck_mode_fixup __initconst = { 267 + .width = 1280, 268 + .height = 800, 269 + .linelength = 3328, 270 + }; 271 + 238 272 /* 239 273 * Some devices have a portrait LCD but advertise a landscape resolution (and 240 274 * pitch). We simply swap width and height for these devices so that we can ··· 290 248 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "MIIX 310-10ICR"), 291 249 DMI_EXACT_MATCH(DMI_BIOS_VERSION, "1HCN44WW"), 292 250 }, 251 + .callback = efifb_swap_width_height, 293 252 }, 294 253 { 295 254 /* Lenovo MIIX 320-10ICR with 800x1280 portrait screen */ ··· 299 256 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, 300 257 "Lenovo MIIX 320-10ICR"), 301 258 }, 259 + .callback = efifb_swap_width_height, 302 260 }, 303 261 { 304 262 /* Lenovo D330 with 800x1280 or 1200x1920 portrait screen */ ··· 308 264 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, 309 265 "Lenovo ideapad D330-10IGM"), 310 266 }, 267 + .callback = efifb_swap_width_height, 311 268 }, 312 269 { 313 270 /* Lenovo IdeaPad Duet 3 10IGL5 with 1200x1920 portrait screen */ ··· 317 272 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, 318 273 "IdeaPad Duet 3 10IGL5"), 319 274 }, 275 + .callback = efifb_swap_width_height, 320 276 }, 321 277 { 322 278 /* Lenovo Yoga Book X91F / X91L */ ··· 326 280 /* Non exact match to match F + L versions */ 327 281 DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"), 328 282 }, 283 + .callback = efifb_swap_width_height, 284 + }, 285 + { 286 + /* Valve Steam Deck (Jupiter) */ 287 + .matches = { 288 + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), 289 + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"), 290 + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), 291 + }, 292 + .callback = efifb_check_and_swap_width_height, 293 + .driver_data = (void *)&efifb_steamdeck_mode_fixup, 294 + }, 295 + { 296 + /* Valve Steam Deck (Galileo) */ 297 + .matches = { 298 + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), 299 + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galileo"), 300 + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), 301 + }, 302 + .callback = efifb_check_and_swap_width_height, 303 + .driver_data = (void *)&efifb_steamdeck_mode_fixup, 329 304 }, 330 305 {}, 331 306 }; 332 307 333 - static bool efifb_overlaps_pci_range(const struct of_pci_range *range) 308 + static bool efifb_overlaps_pci_range(const struct screen_info *si, 309 + const struct of_pci_range *range) 334 310 { 335 - u64 fb_base = screen_info.lfb_base; 311 + u64 fb_base = si->lfb_base; 336 312 337 - if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) 338 - fb_base |= (u64)(unsigned long)screen_info.ext_lfb_base << 32; 313 + if (si->capabilities & VIDEO_CAPABILITY_64BIT_BASE) 314 + fb_base |= (u64)(unsigned long)si->ext_lfb_base << 32; 339 315 340 316 return fb_base >= range->cpu_addr && 341 317 fb_base < (range->cpu_addr + range->size); ··· 379 311 } 380 312 381 313 for_each_of_pci_range(&parser, &range) 382 - if (efifb_overlaps_pci_range(&range)) 314 + if (efifb_overlaps_pci_range(&sysfb_primary_display.screen, &range)) 383 315 return np; 384 316 } 385 317 return NULL; ··· 417 349 418 350 static struct fwnode_handle efifb_fwnode; 419 351 420 - __init void sysfb_apply_efi_quirks(void) 352 + __init void sysfb_apply_efi_quirks(struct screen_info *si) 421 353 { 422 - if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || 423 - !(screen_info.capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS)) 354 + if (si->orig_video_isVGA != VIDEO_TYPE_EFI || 355 + !(si->capabilities & VIDEO_CAPABILITY_SKIP_QUIRKS)) 424 356 dmi_check_system(efifb_dmi_system_table); 425 357 426 - if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI && 427 - dmi_check_system(efifb_dmi_swap_width_height)) { 428 - u16 temp = screen_info.lfb_width; 429 - 430 - screen_info.lfb_width = screen_info.lfb_height; 431 - screen_info.lfb_height = temp; 432 - screen_info.lfb_linelength = 4 * screen_info.lfb_width; 433 - } 358 + if (si->orig_video_isVGA == VIDEO_TYPE_EFI) 359 + dmi_check_system(efifb_dmi_swap_width_height); 434 360 } 435 361 436 - __init void sysfb_set_efifb_fwnode(struct platform_device *pd) 362 + __init void sysfb_set_efifb_fwnode(const struct screen_info *si, struct platform_device *pd) 437 363 { 438 - if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI && IS_ENABLED(CONFIG_PCI)) { 364 + if (si->orig_video_isVGA == VIDEO_TYPE_EFI && IS_ENABLED(CONFIG_PCI)) { 439 365 fwnode_init(&efifb_fwnode, &efifb_fwnode_ops); 440 366 pd->dev.fwnode = &efifb_fwnode; 441 367 }
+7 -6
drivers/firmware/sysfb.c
··· 66 66 */ 67 67 void sysfb_disable(struct device *dev) 68 68 { 69 - struct screen_info *si = &screen_info; 69 + struct screen_info *si = &sysfb_primary_display.screen; 70 70 struct device *parent; 71 71 72 72 mutex_lock(&disable_lock); ··· 92 92 */ 93 93 bool sysfb_handles_screen_info(void) 94 94 { 95 - const struct screen_info *si = &screen_info; 95 + const struct screen_info *si = &sysfb_primary_display.screen; 96 96 97 97 return !!screen_info_video_type(si); 98 98 } ··· 141 141 142 142 static __init int sysfb_init(void) 143 143 { 144 - struct screen_info *si = &screen_info; 144 + struct sysfb_display_info *dpy = &sysfb_primary_display; 145 + struct screen_info *si = &dpy->screen; 145 146 struct device *parent; 146 147 unsigned int type; 147 148 struct simplefb_platform_data mode; ··· 156 155 if (disabled) 157 156 goto unlock_mutex; 158 157 159 - sysfb_apply_efi_quirks(); 158 + sysfb_apply_efi_quirks(si); 160 159 161 160 parent = sysfb_parent_dev(si); 162 161 if (IS_ERR(parent)) { ··· 201 200 202 201 pd->dev.parent = parent; 203 202 204 - sysfb_set_efifb_fwnode(pd); 203 + sysfb_set_efifb_fwnode(si, pd); 205 204 206 - ret = platform_device_add_data(pd, si, sizeof(*si)); 205 + ret = platform_device_add_data(pd, dpy, sizeof(*dpy)); 207 206 if (ret) 208 207 goto err; 209 208
+1 -1
drivers/firmware/sysfb_simplefb.c
··· 117 117 118 118 pd->dev.parent = parent; 119 119 120 - sysfb_set_efifb_fwnode(pd); 120 + sysfb_set_efifb_fwnode(si, pd); 121 121 122 122 ret = platform_device_add_resources(pd, &res, 1); 123 123 if (ret)
+8 -6
drivers/gpu/drm/sysfb/efidrm.c
··· 4 4 #include <linux/efi.h> 5 5 #include <linux/limits.h> 6 6 #include <linux/platform_device.h> 7 - #include <linux/screen_info.h> 7 + #include <linux/sysfb.h> 8 8 9 9 #include <drm/clients/drm_client_setup.h> 10 10 #include <drm/drm_atomic.h> ··· 24 24 #include <drm/drm_print.h> 25 25 #include <drm/drm_probe_helper.h> 26 26 27 - #include <video/edid.h> 28 27 #include <video/pixel_format.h> 29 28 30 29 #include "drm_sysfb_helper.h" ··· 140 141 static struct efidrm_device *efidrm_device_create(struct drm_driver *drv, 141 142 struct platform_device *pdev) 142 143 { 144 + const struct sysfb_display_info *dpy; 143 145 const struct screen_info *si; 144 146 const struct drm_format_info *format; 145 147 int width, height, stride; ··· 160 160 size_t nformats; 161 161 int ret; 162 162 163 - si = dev_get_platdata(&pdev->dev); 164 - if (!si) 163 + dpy = dev_get_platdata(&pdev->dev); 164 + if (!dpy) 165 165 return ERR_PTR(-ENODEV); 166 + si = &dpy->screen; 167 + 166 168 if (screen_info_video_type(si) != VIDEO_TYPE_EFI) 167 169 return ERR_PTR(-ENODEV); 168 170 ··· 206 204 &format->format, width, height, stride); 207 205 208 206 #if defined(CONFIG_FIRMWARE_EDID) 209 - if (drm_edid_header_is_valid(edid_info.dummy) == 8) 210 - sysfb->edid = edid_info.dummy; 207 + if (drm_edid_header_is_valid(dpy->edid.dummy) == 8) 208 + sysfb->edid = dpy->edid.dummy; 211 209 #endif 212 210 sysfb->fb_mode = drm_sysfb_mode(width, height, 0, 0); 213 211 sysfb->fb_format = format;
+8 -6
drivers/gpu/drm/sysfb/vesadrm.c
··· 4 4 #include <linux/ioport.h> 5 5 #include <linux/limits.h> 6 6 #include <linux/platform_device.h> 7 - #include <linux/screen_info.h> 7 + #include <linux/sysfb.h> 8 8 9 9 #include <drm/clients/drm_client_setup.h> 10 10 #include <drm/drm_atomic.h> ··· 25 25 #include <drm/drm_print.h> 26 26 #include <drm/drm_probe_helper.h> 27 27 28 - #include <video/edid.h> 29 28 #include <video/pixel_format.h> 30 29 #include <video/vga.h> 31 30 ··· 390 391 static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv, 391 392 struct platform_device *pdev) 392 393 { 394 + const struct sysfb_display_info *dpy; 393 395 const struct screen_info *si; 394 396 const struct drm_format_info *format; 395 397 int width, height, stride; ··· 410 410 size_t nformats; 411 411 int ret; 412 412 413 - si = dev_get_platdata(&pdev->dev); 414 - if (!si) 413 + dpy = dev_get_platdata(&pdev->dev); 414 + if (!dpy) 415 415 return ERR_PTR(-ENODEV); 416 + si = &dpy->screen; 417 + 416 418 if (screen_info_video_type(si) != VIDEO_TYPE_VLFB) 417 419 return ERR_PTR(-ENODEV); 418 420 ··· 473 471 } 474 472 475 473 #if defined(CONFIG_FIRMWARE_EDID) 476 - if (drm_edid_header_is_valid(edid_info.dummy) == 8) 477 - sysfb->edid = edid_info.dummy; 474 + if (drm_edid_header_is_valid(dpy->edid.dummy) == 8) 475 + sysfb->edid = dpy->edid.dummy; 478 476 #endif 479 477 sysfb->fb_mode = drm_sysfb_mode(width, height, 0, 0); 480 478 sysfb->fb_format = format;
+3 -3
drivers/hv/vmbus_drv.c
··· 29 29 #include <linux/delay.h> 30 30 #include <linux/panic_notifier.h> 31 31 #include <linux/ptrace.h> 32 - #include <linux/screen_info.h> 32 + #include <linux/sysfb.h> 33 33 #include <linux/efi.h> 34 34 #include <linux/random.h> 35 35 #include <linux/kernel.h> ··· 2340 2340 if (efi_enabled(EFI_BOOT)) { 2341 2341 /* Gen2 VM: get FB base from EFI framebuffer */ 2342 2342 if (IS_ENABLED(CONFIG_SYSFB)) { 2343 - start = screen_info.lfb_base; 2344 - size = max_t(__u32, screen_info.lfb_size, 0x800000); 2343 + start = sysfb_primary_display.screen.lfb_base; 2344 + size = max_t(__u32, sysfb_primary_display.screen.lfb_size, 0x800000); 2345 2345 } 2346 2346 } else { 2347 2347 /* Gen1 VM: get FB base from PCI */
+2 -2
drivers/pci/vgaarb.c
··· 26 26 #include <linux/poll.h> 27 27 #include <linux/miscdevice.h> 28 28 #include <linux/slab.h> 29 - #include <linux/screen_info.h> 29 + #include <linux/sysfb.h> 30 30 #include <linux/vt.h> 31 31 #include <linux/console.h> 32 32 #include <linux/acpi.h> ··· 557 557 static bool vga_is_firmware_default(struct pci_dev *pdev) 558 558 { 559 559 #if defined CONFIG_X86 560 - return pdev == screen_info_pci_dev(&screen_info); 560 + return pdev == screen_info_pci_dev(&sysfb_primary_display.screen); 561 561 #else 562 562 return false; 563 563 #endif
+5 -3
drivers/video/Kconfig
··· 63 63 64 64 config FIRMWARE_EDID 65 65 bool "Enable firmware EDID" 66 - depends on X86 66 + depends on EFI_GENERIC_STUB || X86 67 67 help 68 68 This enables access to the EDID transferred from the firmware. 69 - On x86, this is from the VESA BIOS. DRM display drivers will 70 - be able to export the information to userspace. 69 + On EFI systems, the EDID comes from the same device as the 70 + primary GOP. On x86 with BIOS, it comes from the VESA BIOS. 71 + DRM display drivers will be able to export the information 72 + to userspace. 71 73 72 74 Also enable this if DDC/I2C transfers do not work for your driver 73 75 and if you are using nvidiafb, i810fb or savagefb.
+5 -3
drivers/video/fbdev/core/fbmon.c
··· 32 32 #include <linux/module.h> 33 33 #include <linux/pci.h> 34 34 #include <linux/slab.h> 35 - #include <video/edid.h> 35 + #include <linux/string_choices.h> 36 + #include <linux/sysfb.h> 37 + 36 38 #include <video/of_videomode.h> 37 39 #include <video/videomode.h> 40 + 38 41 #include "../edid.h" 39 - #include <linux/string_choices.h> 40 42 41 43 /* 42 44 * EDID parser ··· 1506 1504 res = &dev->resource[PCI_ROM_RESOURCE]; 1507 1505 1508 1506 if (res && res->flags & IORESOURCE_ROM_SHADOW) 1509 - edid = edid_info.dummy; 1507 + edid = sysfb_primary_display.edid.dummy; 1510 1508 1511 1509 return edid; 1512 1510 }
+6 -4
drivers/video/fbdev/efifb.c
··· 15 15 #include <linux/fb.h> 16 16 #include <linux/platform_device.h> 17 17 #include <linux/printk.h> 18 - #include <linux/screen_info.h> 18 + #include <linux/sysfb.h> 19 19 #include <video/vga.h> 20 20 #include <asm/efi.h> 21 21 #include <drm/drm_utils.h> /* For drm_get_panel_orientation_quirk */ ··· 345 345 346 346 static int efifb_probe(struct platform_device *dev) 347 347 { 348 + struct sysfb_display_info *dpy; 348 349 struct screen_info *si; 349 350 struct fb_info *info; 350 351 struct efifb_par *par; ··· 361 360 * driver. We get a copy of the attached screen_info, so that we can 362 361 * modify its values without affecting later drivers. 363 362 */ 364 - si = dev_get_platdata(&dev->dev); 365 - if (!si) 363 + dpy = dev_get_platdata(&dev->dev); 364 + if (!dpy) 366 365 return -ENODEV; 367 - si = devm_kmemdup(&dev->dev, si, sizeof(*si), GFP_KERNEL); 366 + 367 + si = devm_kmemdup(&dev->dev, &dpy->screen, sizeof(*si), GFP_KERNEL); 368 368 if (!si) 369 369 return -ENOMEM; 370 370
+6 -4
drivers/video/fbdev/vesafb.c
··· 20 20 #include <linux/ioport.h> 21 21 #include <linux/init.h> 22 22 #include <linux/platform_device.h> 23 - #include <linux/screen_info.h> 23 + #include <linux/sysfb.h> 24 24 #include <linux/io.h> 25 25 26 26 #include <video/vga.h> ··· 243 243 244 244 static int vesafb_probe(struct platform_device *dev) 245 245 { 246 + struct sysfb_display_info *dpy; 246 247 struct screen_info *si; 247 248 struct fb_info *info; 248 249 struct vesafb_par *par; ··· 258 257 * driver. We get a copy of the attached screen_info, so that we can 259 258 * modify its values without affecting later drivers. 260 259 */ 261 - si = dev_get_platdata(&dev->dev); 262 - if (!si) 260 + dpy = dev_get_platdata(&dev->dev); 261 + if (!dpy) 263 262 return -ENODEV; 264 - si = devm_kmemdup(&dev->dev, si, sizeof(*si), GFP_KERNEL); 263 + 264 + si = devm_kmemdup(&dev->dev, &dpy->screen, sizeof(*si), GFP_KERNEL); 265 265 if (!si) 266 266 return -ENOMEM; 267 267
+5 -3
drivers/video/fbdev/vga16fb.c
··· 21 21 #include <linux/ioport.h> 22 22 #include <linux/init.h> 23 23 #include <linux/platform_device.h> 24 - #include <linux/screen_info.h> 24 + #include <linux/sysfb.h> 25 25 26 26 #include <asm/io.h> 27 27 #include <video/vga.h> ··· 1305 1305 1306 1306 static int vga16fb_probe(struct platform_device *dev) 1307 1307 { 1308 + struct sysfb_display_info *dpy; 1308 1309 struct screen_info *si; 1309 1310 struct fb_info *info; 1310 1311 struct vga16fb_par *par; 1311 1312 int i; 1312 1313 int ret = 0; 1313 1314 1314 - si = dev_get_platdata(&dev->dev); 1315 - if (!si) 1315 + dpy = dev_get_platdata(&dev->dev); 1316 + if (!dpy) 1316 1317 return -ENODEV; 1318 + si = &dpy->screen; 1317 1319 1318 1320 ret = check_mode_supported(si); 1319 1321 if (ret)
+3 -2
drivers/video/screen_info_pci.c
··· 4 4 #include <linux/printk.h> 5 5 #include <linux/screen_info.h> 6 6 #include <linux/string.h> 7 + #include <linux/sysfb.h> 7 8 8 9 static struct pci_dev *screen_info_lfb_pdev; 9 10 static size_t screen_info_lfb_bar; ··· 27 26 28 27 void screen_info_apply_fixups(void) 29 28 { 30 - struct screen_info *si = &screen_info; 29 + struct screen_info *si = &sysfb_primary_display.screen; 31 30 32 31 if (screen_info_lfb_pdev) { 33 32 struct resource *pr = &screen_info_lfb_pdev->resource[screen_info_lfb_bar]; ··· 76 75 .flags = IORESOURCE_MEM, 77 76 }; 78 77 const struct resource *pr; 79 - const struct screen_info *si = &screen_info; 78 + const struct screen_info *si = &sysfb_primary_display.screen; 80 79 81 80 if (screen_info_lfb_pdev) 82 81 return; // already found
+5 -4
include/linux/efi.h
··· 406 406 #define EFI_CC_FINAL_EVENTS_TABLE_GUID EFI_GUID(0xdd4a4648, 0x2de7, 0x4665, 0x96, 0x4d, 0x21, 0xd9, 0xef, 0x5f, 0xb4, 0x46) 407 407 408 408 /* 409 - * This GUID is used to pass to the kernel proper the struct screen_info 410 - * structure that was populated by the stub based on the GOP protocol instance 411 - * associated with ConOut 409 + * This GUIDs are used to pass to the kernel proper the primary 410 + * display that has been populated by the stub based on the GOP 411 + * instance associated with ConOut. 412 412 */ 413 - #define LINUX_EFI_SCREEN_INFO_TABLE_GUID EFI_GUID(0xe03fc20a, 0x85dc, 0x406e, 0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95) 413 + #define LINUX_EFI_PRIMARY_DISPLAY_TABLE_GUID EFI_GUID(0xe03fc20a, 0x85dc, 0x406e, 0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95) 414 + 414 415 #define LINUX_EFI_ARM_CPU_STATE_TABLE_GUID EFI_GUID(0xef79e4aa, 0x3c3d, 0x4989, 0xb9, 0x02, 0x07, 0xa9, 0x43, 0xe5, 0x50, 0xd2) 415 416 #define LINUX_EFI_LOADER_ENTRY_GUID EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f) 416 417 #define LINUX_EFI_RANDOM_SEED_TABLE_GUID EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2, 0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b)
-2
include/linux/screen_info.h
··· 151 151 } 152 152 #endif 153 153 154 - extern struct screen_info screen_info; 155 - 156 154 #endif /* _SCREEN_INFO_H */
+18 -5
include/linux/sysfb.h
··· 8 8 */ 9 9 10 10 #include <linux/err.h> 11 + #include <linux/platform_data/simplefb.h> 12 + #include <linux/screen_info.h> 11 13 #include <linux/types.h> 12 14 13 - #include <linux/platform_data/simplefb.h> 15 + #include <video/edid.h> 14 16 15 17 struct device; 16 18 struct platform_device; ··· 62 60 int flags; 63 61 }; 64 62 63 + struct sysfb_display_info { 64 + struct screen_info screen; 65 + 66 + #if defined(CONFIG_FIRMWARE_EDID) 67 + struct edid_info edid; 68 + #endif 69 + }; 70 + 71 + extern struct sysfb_display_info sysfb_primary_display; 72 + 65 73 #ifdef CONFIG_SYSFB 66 74 67 75 void sysfb_disable(struct device *dev); ··· 94 82 #ifdef CONFIG_EFI 95 83 96 84 extern struct efifb_dmi_info efifb_dmi_list[]; 97 - void sysfb_apply_efi_quirks(void); 98 - void sysfb_set_efifb_fwnode(struct platform_device *pd); 85 + void sysfb_apply_efi_quirks(struct screen_info *si); 86 + void sysfb_set_efifb_fwnode(const struct screen_info *si, struct platform_device *pd); 99 87 100 88 #else /* CONFIG_EFI */ 101 89 102 - static inline void sysfb_apply_efi_quirks(void) 90 + static inline void sysfb_apply_efi_quirks(struct screen_info *si) 103 91 { 104 92 } 105 93 106 - static inline void sysfb_set_efifb_fwnode(struct platform_device *pd) 94 + static inline void sysfb_set_efifb_fwnode(const struct screen_info *si, 95 + struct platform_device *pd) 107 96 { 108 97 } 109 98
-4
include/video/edid.h
··· 4 4 5 5 #include <uapi/video/edid.h> 6 6 7 - #if defined(CONFIG_FIRMWARE_EDID) 8 - extern struct edid_info edid_info; 9 - #endif 10 - 11 7 #endif /* __linux_video_edid_h__ */