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
This commit is contained in:
Linus Torvalds
2026-02-09 20:49:19 -08:00
34 changed files with 359 additions and 252 deletions

View File

@@ -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);

View File

@@ -18,7 +18,7 @@
#include <linux/kobject.h>
#include <linux/memblock.h>
#include <linux/reboot.h>
#include <linux/screen_info.h>
#include <linux/sysfb.h>
#include <linux/uaccess.h>
#include <asm/early_ioremap.h>
@@ -72,30 +72,31 @@ bool efi_poweroff_required(void)
(acpi_gbl_reduced_hardware || acpi_no_s5);
}
unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR;
unsigned long __initdata primary_display_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;
struct sysfb_display_info *dpy;
if (screen_info_table == EFI_INVALID_TABLE_ADDR)
if (primary_display_table == EFI_INVALID_TABLE_ADDR)
return;
si = early_memremap(screen_info_table, sizeof(*si));
if (!si) {
pr_err("Could not map screen_info config table\n");
dpy = early_memremap(primary_display_table, sizeof(*dpy));
if (!dpy) {
pr_err("Could not map primary_display config table\n");
return;
}
screen_info = *si;
memset(si, 0, sizeof(*si));
early_memunmap(si, sizeof(*si));
sysfb_primary_display = *dpy;
memset(dpy, 0, sizeof(*dpy));
early_memunmap(dpy, sizeof(*dpy));
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;

View File

@@ -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

View File

@@ -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

View File

@@ -20,6 +20,7 @@
#include <linux/of_fdt.h>
#include <linux/efi.h>
#include <linux/random.h>
#include <linux/sysfb.h>
#include <asm/bootparam.h>
#include <asm/setup.h>
@@ -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(&params->screen_info, &screen_info, sizeof(struct screen_info));
memcpy(&params->screen_info, &sysfb_primary_display.screen,
sizeof(sysfb_primary_display.screen));
/* Fill in memsize later */
params->screen_info.ext_mem_k = 0;

View File

@@ -22,6 +22,7 @@
#include <linux/random.h>
#include <linux/root_dev.h>
#include <linux/static_call.h>
#include <linux/sysfb.h>
#include <linux/swiotlb.h>
#include <linux/tboot.h>
#include <linux/usb/xhci-dbgp.h>
@@ -211,12 +212,9 @@ arch_initcall(init_x86_sysctl);
/*
* Setup options
*/
struct screen_info screen_info;
EXPORT_SYMBOL(screen_info);
#if defined(CONFIG_FIRMWARE_EDID)
struct edid_info edid_info;
EXPORT_SYMBOL_GPL(edid_info);
#endif
struct sysfb_display_info sysfb_primary_display;
EXPORT_SYMBOL(sysfb_primary_display);
extern int root_mountflags;
@@ -526,9 +524,9 @@ 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;
sysfb_primary_display.edid = boot_params.edid_info;
#endif
#ifdef CONFIG_X86_32
apm_info.bios = boot_params.apm_bios_info;
@@ -1254,7 +1252,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();

View File

@@ -9,7 +9,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/screen_info.h>
#include <linux/sysfb.h>
#include <linux/vgaarb.h>
#include <asm/video.h>
@@ -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

View File

@@ -9,7 +9,7 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/serial_core.h>
#include <linux/screen_info.h>
#include <linux/sysfb.h>
#include <linux/string.h>
#include <asm/early_ioremap.h>
@@ -32,12 +32,13 @@ static void *efi_fb;
*/
static int __init efi_earlycon_remap_fb(void)
{
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))
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 = &sysfb_primary_display.screen;
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 = &sysfb_primary_display.screen;
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;

View File

@@ -19,11 +19,11 @@
#include <linux/of_address.h>
#include <linux/of_fdt.h>
#include <linux/platform_device.h>
#include <linux/screen_info.h>
#include <linux/sysfb.h>
#include <asm/efi.h>
unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR;
unsigned long __initdata primary_display_table = EFI_INVALID_TABLE_ADDR;
static int __init is_memory(efi_memory_desc_t *md)
{
@@ -57,31 +57,31 @@ 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;
struct sysfb_display_info *dpy;
if (screen_info_table != EFI_INVALID_TABLE_ADDR) {
si = early_memremap(screen_info_table, sizeof(*si));
if (!si) {
pr_err("Could not map screen_info config table\n");
if (primary_display_table != EFI_INVALID_TABLE_ADDR) {
dpy = early_memremap(primary_display_table, sizeof(*dpy));
if (!dpy) {
pr_err("Could not map primary_display config table\n");
return;
}
screen_info = *si;
memset(si, 0, sizeof(*si));
early_memunmap(si, sizeof(*si));
sysfb_primary_display = *dpy;
memset(dpy, 0, sizeof(*dpy));
early_memunmap(dpy, sizeof(*dpy));
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();
}

View File

@@ -63,7 +63,7 @@ static unsigned long __initdata mem_reserve = EFI_INVALID_TABLE_ADDR;
static unsigned long __initdata rt_prop = EFI_INVALID_TABLE_ADDR;
static unsigned long __initdata initrd = EFI_INVALID_TABLE_ADDR;
extern unsigned long screen_info_table;
extern unsigned long primary_display_table;
struct mm_struct efi_mm = {
.mm_mt = MTREE_INIT_EXT(mm_mt, MM_MT_FLAGS, efi_mm.mmap_lock),
@@ -642,7 +642,7 @@ static const efi_config_table_type_t common_tables[] __initconst = {
{LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID, &efi.unaccepted, "Unaccepted" },
#endif
#ifdef CONFIG_EFI_GENERIC_STUB
{LINUX_EFI_SCREEN_INFO_TABLE_GUID, &screen_info_table },
{LINUX_EFI_PRIMARY_DISPLAY_TABLE_GUID, &primary_display_table },
#endif
{},
};

View File

@@ -80,7 +80,7 @@ $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
$(call if_changed_rule,cc_o_c)
lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o \
screen_info.o efi-stub-entry.o
primary_display.o efi-stub-entry.o
lib-$(CONFIG_ARM) += arm32-stub.o
lib-$(CONFIG_ARM64) += kaslr.o arm64.o arm64-stub.o smbios.o

View File

@@ -1,23 +1,28 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/efi.h>
#include <linux/screen_info.h>
#include <linux/sysfb.h>
#include <asm/efi.h>
#include "efistub.h"
static unsigned long screen_info_offset;
static unsigned long kernel_image_offset;
struct screen_info *alloc_screen_info(void)
static void *kernel_image_addr(void *addr)
{
return addr + kernel_image_offset;
}
struct sysfb_display_info *alloc_primary_display(void)
{
if (IS_ENABLED(CONFIG_ARM))
return __alloc_screen_info();
return __alloc_primary_display();
if (IS_ENABLED(CONFIG_X86) ||
IS_ENABLED(CONFIG_EFI_EARLYCON) ||
IS_ENABLED(CONFIG_SYSFB))
return (void *)&screen_info + screen_info_offset;
return kernel_image_addr(&sysfb_primary_display);
return NULL;
}
@@ -73,7 +78,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);

View File

@@ -10,7 +10,7 @@
*/
#include <linux/efi.h>
#include <linux/screen_info.h>
#include <linux/sysfb.h>
#include <asm/efi.h>
#include "efistub.h"
@@ -48,23 +48,33 @@
static u64 virtmap_base = EFI_RT_VIRTUAL_BASE;
static bool flat_va_mapping = (EFI_RT_VIRTUAL_OFFSET != 0);
void __weak free_screen_info(struct screen_info *si)
void __weak free_primary_display(struct sysfb_display_info *dpy)
{ }
static struct sysfb_display_info *setup_primary_display(void)
{
}
struct sysfb_display_info *dpy;
struct screen_info *screen = NULL;
struct edid_info *edid = NULL;
efi_status_t status;
static struct screen_info *setup_graphics(void)
{
struct screen_info *si, tmp = {};
if (efi_setup_graphics(&tmp, NULL) != EFI_SUCCESS)
dpy = alloc_primary_display();
if (!dpy)
return NULL;
screen = &dpy->screen;
#if defined(CONFIG_FIRMWARE_EDID)
edid = &dpy->edid;
#endif
si = alloc_screen_info();
if (!si)
return NULL;
status = efi_setup_graphics(screen, edid);
if (status != EFI_SUCCESS)
goto err_free_primary_display;
*si = tmp;
return si;
return dpy;
err_free_primary_display:
free_primary_display(dpy);
return NULL;
}
static void install_memreserve_table(void)
@@ -145,14 +155,14 @@ efi_status_t efi_stub_common(efi_handle_t handle,
unsigned long image_addr,
char *cmdline_ptr)
{
struct screen_info *si;
struct sysfb_display_info *dpy;
efi_status_t status;
status = check_platform_features();
if (status != EFI_SUCCESS)
return status;
si = setup_graphics();
dpy = setup_primary_display();
efi_retrieve_eventlog();
@@ -172,7 +182,8 @@ efi_status_t efi_stub_common(efi_handle_t handle,
status = efi_boot_kernel(handle, image, image_addr, cmdline_ptr);
free_screen_info(si);
free_primary_display(dpy);
return status;
}

View File

@@ -36,6 +36,7 @@
struct edid_info;
struct screen_info;
struct sysfb_display_info;
extern bool efi_no5lvl;
extern bool efi_nochunk;
@@ -1175,9 +1176,9 @@ efi_enable_reset_attack_mitigation(void) { }
void efi_retrieve_eventlog(void);
struct screen_info *alloc_screen_info(void);
struct screen_info *__alloc_screen_info(void);
void free_screen_info(struct screen_info *si);
struct sysfb_display_info *alloc_primary_display(void);
struct sysfb_display_info *__alloc_primary_display(void);
void free_primary_display(struct sysfb_display_info *dpy);
void efi_cache_sync_image(unsigned long image_base,
unsigned long alloc_size);

View File

@@ -0,0 +1,56 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/efi.h>
#include <linux/sysfb.h>
#include <asm/efi.h>
#include "efistub.h"
/*
* There are two ways of populating the core kernel's sysfb_primary_display
* via the stub:
*
* - using a configuration table, which relies on the EFI init code to
* locate the table and copy the contents; or
*
* - by linking directly to the core kernel's copy of the global symbol.
*
* The latter is preferred because it makes the EFIFB earlycon available very
* early, but it only works if the EFI stub is part of the core kernel image
* itself. The zboot decompressor can only use the configuration table
* approach.
*/
static efi_guid_t primary_display_guid = LINUX_EFI_PRIMARY_DISPLAY_TABLE_GUID;
struct sysfb_display_info *__alloc_primary_display(void)
{
struct sysfb_display_info *dpy;
efi_status_t status;
status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY,
sizeof(*dpy), (void **)&dpy);
if (status != EFI_SUCCESS)
return NULL;
memset(dpy, 0, sizeof(*dpy));
status = efi_bs_call(install_configuration_table,
&primary_display_guid, dpy);
if (status == EFI_SUCCESS)
return dpy;
efi_bs_call(free_pool, dpy);
return NULL;
}
void free_primary_display(struct sysfb_display_info *dpy)
{
if (!dpy)
return;
efi_bs_call(install_configuration_table, &primary_display_guid, NULL);
efi_bs_call(free_pool, dpy);
}

View File

@@ -1,53 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/efi.h>
#include <linux/screen_info.h>
#include <asm/efi.h>
#include "efistub.h"
/*
* There are two ways of populating the core kernel's struct screen_info via the stub:
* - using a configuration table, like below, which relies on the EFI init code
* to locate the table and copy the contents;
* - by linking directly to the core kernel's copy of the global symbol.
*
* The latter is preferred because it makes the EFIFB earlycon available very
* early, but it only works if the EFI stub is part of the core kernel image
* itself. The zboot decompressor can only use the configuration table
* approach.
*/
static efi_guid_t screen_info_guid = LINUX_EFI_SCREEN_INFO_TABLE_GUID;
struct screen_info *__alloc_screen_info(void)
{
struct screen_info *si;
efi_status_t status;
status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY,
sizeof(*si), (void **)&si);
if (status != EFI_SUCCESS)
return NULL;
memset(si, 0, sizeof(*si));
status = efi_bs_call(install_configuration_table,
&screen_info_guid, si);
if (status == EFI_SUCCESS)
return si;
efi_bs_call(free_pool, si);
return NULL;
}
void free_screen_info(struct screen_info *si)
{
if (!si)
return;
efi_bs_call(install_configuration_table, &screen_info_guid, NULL);
efi_bs_call(free_pool, si);
}

View File

@@ -26,9 +26,9 @@ void __weak efi_cache_sync_image(unsigned long image_base,
// executable code loaded into memory to be safe for execution.
}
struct screen_info *alloc_screen_info(void)
struct sysfb_display_info *alloc_primary_display(void)
{
return __alloc_screen_info();
return __alloc_primary_display();
}
asmlinkage efi_status_t __efiapi

View File

@@ -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(&sysfb_primary_display.screen, id);
}
#define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \
{ \
efifb_set_system, \
efifb_set_system_callback, \
name, \
{ \
DMI_MATCH(DMI_BIOS_VENDOR, vendor), \
@@ -231,6 +235,44 @@ 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 = &sysfb_primary_display.screen;
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;
}
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 = &sysfb_primary_display.screen;
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
@@ -248,6 +290,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 +299,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 +308,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 +317,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,16 +326,38 @@ 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,
},
{
/* 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,
},
{},
};
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);
@@ -311,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(&sysfb_primary_display.screen, &range))
return np;
}
return NULL;
@@ -349,25 +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 &&
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;
screen_info.lfb_linelength = 4 * screen_info.lfb_width;
}
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;
}

View File

@@ -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,8 @@ static struct device *sysfb_parent_dev(const struct screen_info *si)
static __init int sysfb_init(void)
{
struct screen_info *si = &screen_info;
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;
@@ -155,7 +156,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,9 +201,9 @@ 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));
ret = platform_device_add_data(pd, dpy, sizeof(*dpy));
if (ret)
goto err;

View File

@@ -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)

View File

@@ -4,7 +4,7 @@
#include <linux/efi.h>
#include <linux/limits.h>
#include <linux/platform_device.h>
#include <linux/screen_info.h>
#include <linux/sysfb.h>
#include <drm/clients/drm_client_setup.h>
#include <drm/drm_atomic.h>
@@ -24,7 +24,6 @@
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <video/edid.h>
#include <video/pixel_format.h>
#include "drm_sysfb_helper.h"
@@ -141,6 +140,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 +160,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);
@@ -204,8 +206,8 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv,
&format->format, width, height, stride);
#if defined(CONFIG_FIRMWARE_EDID)
if (drm_edid_header_is_valid(edid_info.dummy) == 8)
sysfb->edid = edid_info.dummy;
if (drm_edid_header_is_valid(dpy->edid.dummy) == 8)
sysfb->edid = dpy->edid.dummy;
#endif
sysfb->fb_mode = drm_sysfb_mode(width, height, 0, 0);
sysfb->fb_format = format;

View File

@@ -4,7 +4,7 @@
#include <linux/ioport.h>
#include <linux/limits.h>
#include <linux/platform_device.h>
#include <linux/screen_info.h>
#include <linux/sysfb.h>
#include <drm/clients/drm_client_setup.h>
#include <drm/drm_atomic.h>
@@ -25,7 +25,6 @@
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <video/edid.h>
#include <video/pixel_format.h>
#include <video/vga.h>
@@ -391,6 +390,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 +410,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);
@@ -471,8 +473,8 @@ static struct vesadrm_device *vesadrm_device_create(struct drm_driver *drv,
}
#if defined(CONFIG_FIRMWARE_EDID)
if (drm_edid_header_is_valid(edid_info.dummy) == 8)
sysfb->edid = edid_info.dummy;
if (drm_edid_header_is_valid(dpy->edid.dummy) == 8)
sysfb->edid = dpy->edid.dummy;
#endif
sysfb->fb_mode = drm_sysfb_mode(width, height, 0, 0);
sysfb->fb_format = format;

View File

@@ -29,7 +29,7 @@
#include <linux/delay.h>
#include <linux/panic_notifier.h>
#include <linux/ptrace.h>
#include <linux/screen_info.h>
#include <linux/sysfb.h>
#include <linux/efi.h>
#include <linux/random.h>
#include <linux/kernel.h>
@@ -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 */

View File

@@ -26,7 +26,7 @@
#include <linux/poll.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/screen_info.h>
#include <linux/sysfb.h>
#include <linux/vt.h>
#include <linux/console.h>
#include <linux/acpi.h>
@@ -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

View File

@@ -63,11 +63,13 @@ endif # HAS_IOMEM
config FIRMWARE_EDID
bool "Enable firmware EDID"
depends on X86
depends on EFI_GENERIC_STUB || X86
help
This enables access to the EDID transferred from the firmware.
On x86, this is from the VESA BIOS. DRM display drivers will
be able to export the information to userspace.
On EFI systems, the EDID comes from the same device as the
primary GOP. On x86 with BIOS, it comes from the VESA BIOS.
DRM display drivers will be able to export the information
to userspace.
Also enable this if DDC/I2C transfers do not work for your driver
and if you are using nvidiafb, i810fb or savagefb.

View File

@@ -32,11 +32,13 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <video/edid.h>
#include <linux/string_choices.h>
#include <linux/sysfb.h>
#include <video/of_videomode.h>
#include <video/videomode.h>
#include "../edid.h"
#include <linux/string_choices.h>
/*
* EDID parser
@@ -1504,7 +1506,7 @@ const unsigned char *fb_firmware_edid(struct device *device)
res = &dev->resource[PCI_ROM_RESOURCE];
if (res && res->flags & IORESOURCE_ROM_SHADOW)
edid = edid_info.dummy;
edid = sysfb_primary_display.edid.dummy;
return edid;
}

View File

@@ -15,7 +15,7 @@
#include <linux/fb.h>
#include <linux/platform_device.h>
#include <linux/printk.h>
#include <linux/screen_info.h>
#include <linux/sysfb.h>
#include <video/vga.h>
#include <asm/efi.h>
#include <drm/drm_utils.h> /* For drm_get_panel_orientation_quirk */
@@ -345,6 +345,7 @@ ATTRIBUTE_GROUPS(efifb);
static int efifb_probe(struct platform_device *dev)
{
struct sysfb_display_info *dpy;
struct screen_info *si;
struct fb_info *info;
struct efifb_par *par;
@@ -360,10 +361,11 @@ static int efifb_probe(struct platform_device *dev)
* driver. We get a copy of the attached screen_info, so that we can
* modify its values without affecting later drivers.
*/
si = dev_get_platdata(&dev->dev);
if (!si)
dpy = dev_get_platdata(&dev->dev);
if (!dpy)
return -ENODEV;
si = devm_kmemdup(&dev->dev, si, sizeof(*si), GFP_KERNEL);
si = devm_kmemdup(&dev->dev, &dpy->screen, sizeof(*si), GFP_KERNEL);
if (!si)
return -ENOMEM;

View File

@@ -20,7 +20,7 @@
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/screen_info.h>
#include <linux/sysfb.h>
#include <linux/io.h>
#include <video/vga.h>
@@ -243,6 +243,7 @@ static int vesafb_setup(char *options)
static int vesafb_probe(struct platform_device *dev)
{
struct sysfb_display_info *dpy;
struct screen_info *si;
struct fb_info *info;
struct vesafb_par *par;
@@ -257,10 +258,11 @@ static int vesafb_probe(struct platform_device *dev)
* driver. We get a copy of the attached screen_info, so that we can
* modify its values without affecting later drivers.
*/
si = dev_get_platdata(&dev->dev);
if (!si)
dpy = dev_get_platdata(&dev->dev);
if (!dpy)
return -ENODEV;
si = devm_kmemdup(&dev->dev, si, sizeof(*si), GFP_KERNEL);
si = devm_kmemdup(&dev->dev, &dpy->screen, sizeof(*si), GFP_KERNEL);
if (!si)
return -ENOMEM;

View File

@@ -21,7 +21,7 @@
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/screen_info.h>
#include <linux/sysfb.h>
#include <asm/io.h>
#include <video/vga.h>
@@ -1305,15 +1305,17 @@ static const struct fb_ops vga16fb_ops = {
static int vga16fb_probe(struct platform_device *dev)
{
struct sysfb_display_info *dpy;
struct screen_info *si;
struct fb_info *info;
struct vga16fb_par *par;
int i;
int ret = 0;
si = dev_get_platdata(&dev->dev);
if (!si)
dpy = dev_get_platdata(&dev->dev);
if (!dpy)
return -ENODEV;
si = &dpy->screen;
ret = check_mode_supported(si);
if (ret)

View File

@@ -4,6 +4,7 @@
#include <linux/printk.h>
#include <linux/screen_info.h>
#include <linux/string.h>
#include <linux/sysfb.h>
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

View File

@@ -406,11 +406,12 @@ void efi_native_runtime_setup(void);
#define EFI_CC_FINAL_EVENTS_TABLE_GUID EFI_GUID(0xdd4a4648, 0x2de7, 0x4665, 0x96, 0x4d, 0x21, 0xd9, 0xef, 0x5f, 0xb4, 0x46)
/*
* This GUID is used to pass to the kernel proper the struct screen_info
* structure that was populated by the stub based on the GOP protocol instance
* associated with ConOut
* This GUIDs are used to pass to the kernel proper the primary
* display that has been populated by the stub based on the GOP
* instance associated with ConOut.
*/
#define LINUX_EFI_SCREEN_INFO_TABLE_GUID EFI_GUID(0xe03fc20a, 0x85dc, 0x406e, 0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95)
#define LINUX_EFI_PRIMARY_DISPLAY_TABLE_GUID EFI_GUID(0xe03fc20a, 0x85dc, 0x406e, 0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95)
#define LINUX_EFI_ARM_CPU_STATE_TABLE_GUID EFI_GUID(0xef79e4aa, 0x3c3d, 0x4989, 0xb9, 0x02, 0x07, 0xa9, 0x43, 0xe5, 0x50, 0xd2)
#define LINUX_EFI_LOADER_ENTRY_GUID EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f)
#define LINUX_EFI_RANDOM_SEED_TABLE_GUID EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2, 0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b)

View File

@@ -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 */

View File

@@ -8,9 +8,11 @@
*/
#include <linux/err.h>
#include <linux/platform_data/simplefb.h>
#include <linux/screen_info.h>
#include <linux/types.h>
#include <linux/platform_data/simplefb.h>
#include <video/edid.h>
struct device;
struct platform_device;
@@ -60,6 +62,16 @@ struct efifb_dmi_info {
int flags;
};
struct sysfb_display_info {
struct screen_info screen;
#if defined(CONFIG_FIRMWARE_EDID)
struct edid_info edid;
#endif
};
extern struct sysfb_display_info sysfb_primary_display;
#ifdef CONFIG_SYSFB
void sysfb_disable(struct device *dev);
@@ -82,16 +94,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)
{
}

View File

@@ -4,8 +4,4 @@
#include <uapi/video/edid.h>
#if defined(CONFIG_FIRMWARE_EDID)
extern struct edid_info edid_info;
#endif
#endif /* __linux_video_edid_h__ */