Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH v2 00/10] arch,sysfb,efi: Support EDID on non-x86 EFI systems
From: Thomas Zimmermann @ 2025-11-24 16:40 UTC (permalink / raw)
  To: ardb, javierm, arnd, richard.lyu
  Cc: x86, linux-arm-kernel, linux-kernel, linux-efi, loongarch,
	linux-riscv, dri-devel, linux-hyperv, linux-pci, linux-fbdev,
	Thomas Zimmermann

Replace screen_info and edid_info with sysfb_primary_device of type
struct sysfb_display_info. Update all users. Then implement EDID support
in EFI's libstub.

Sysfb DRM drivers currently fetch the global edid_info directly, when
they should get that information together with the screen_info from their
device. Wrapping screen_info and edid_info in sysfb_primary_display and
passing this to drivers enables this.

Replacing both with sysfb_primary_display has been motivate by the EFI
stub. EFI wants to transfer EDID via config table in a single entry.
Using struct sysfb_display_info this will become easily possible. Hence
accept some churn in architecture code for the long-term improvements.

Add a new UUID to transfer sysfb_primary_display via EFI's config table.
Then implement support in the kernel and EFI's libstub.

Patches 1 and 2 reduce the exposure of screen_info in EFI-related code.

Patch 3 adds struct sysfb_display_info.

Patch 4 replaces scren_info with sysfb_primary_display. This results in
several changes throught the kernel, but is really just a refactoring.

Patch 5 updates sysfb to transfer sysfb_primary_display to the related
drivers.

Patch 6 moves edid_info into sysfb_primary_display. This resolves some
drivers' reference to the global edid_info, but also makes the EDID data
available on non-x86 architectures.

Patches 7 and 8 add kernel-side support for EDID transfers on non-x86
EFI systems.

Patches 9 implements EDID support in libstub. Patch 10 cleans up the
config-table allocation to be easier to understand.

This is v2 of the series. It combines v1 of the series at [1] plus
changes from [2] and [3].

[1] https://lore.kernel.org/dri-devel/20251121135624.494768-1-tzimmermann@suse.de/
[2] https://lore.kernel.org/dri-devel/20251015160816.525825-1-tzimmermann@suse.de/
[3] https://lore.kernel.org/linux-efi/20251119123011.1187249-5-ardb+git@google.com/

Thomas Zimmermann (10):
  efi: earlycon: Reduce number of references to global screen_info
  efi: sysfb_efi: Reduce number of references to global screen_info
  sysfb: Add struct sysfb_display_info
  sysfb: Replace screen_info with sysfb_primary_display
  sysfb: Pass sysfb_primary_display to devices
  sysfb: Move edid_info into sysfb_primary_display
  efi: Refactor init_primary_display() helpers
  efi: Support EDID information
  efi: libstub: Transfer EDID to kernel
  efi: libstub: Simplify interfaces for primary_display

 arch/arm64/kernel/image-vars.h                |  2 +-
 arch/loongarch/kernel/efi.c                   | 47 +++++++----
 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                       | 16 ++--
 arch/x86/video/video-common.c                 |  4 +-
 drivers/firmware/efi/earlycon.c               | 42 +++++-----
 drivers/firmware/efi/efi-init.c               | 47 +++++++----
 drivers/firmware/efi/efi.c                    |  2 +
 drivers/firmware/efi/libstub/Makefile         |  2 +-
 drivers/firmware/efi/libstub/efi-stub-entry.c | 36 +++++++--
 drivers/firmware/efi/libstub/efi-stub.c       | 49 +++++++----
 drivers/firmware/efi/libstub/efistub.h        |  7 +-
 .../firmware/efi/libstub/primary_display.c    | 41 ++++++++++
 drivers/firmware/efi/libstub/screen_info.c    | 53 ------------
 drivers/firmware/efi/libstub/zboot.c          |  6 +-
 drivers/firmware/efi/sysfb_efi.c              | 81 ++++++++++---------
 drivers/firmware/sysfb.c                      | 13 +--
 drivers/firmware/sysfb_simplefb.c             |  2 +-
 drivers/gpu/drm/sysfb/efidrm.c                | 14 ++--
 drivers/gpu/drm/sysfb/vesadrm.c               | 14 ++--
 drivers/hv/vmbus_drv.c                        |  6 +-
 drivers/pci/vgaarb.c                          |  4 +-
 drivers/video/Kconfig                         |  8 +-
 drivers/video/fbdev/core/fbmon.c              |  8 +-
 drivers/video/fbdev/efifb.c                   | 10 ++-
 drivers/video/fbdev/vesafb.c                  | 10 ++-
 drivers/video/fbdev/vga16fb.c                 |  8 +-
 drivers/video/screen_info_pci.c               |  5 +-
 include/linux/efi.h                           |  8 +-
 include/linux/screen_info.h                   |  2 -
 include/linux/sysfb.h                         | 23 ++++--
 include/video/edid.h                          |  4 -
 34 files changed, 337 insertions(+), 245 deletions(-)
 create mode 100644 drivers/firmware/efi/libstub/primary_display.c
 delete mode 100644 drivers/firmware/efi/libstub/screen_info.c


base-commit: d724c6f85e80a23ed46b7ebc6e38b527c09d64f5
-- 
2.51.1


^ permalink raw reply

* Re: [PATCH v2 1/2] backlight: Add Congatec Board Controller (CGBC) backlight support
From: Petri Karhula @ 2025-11-24 14:10 UTC (permalink / raw)
  To: danielt@kernel.org, lee@kernel.org, thomas.richard@bootlin.com,
	deller@gmx.de, jingoohan1@gmail.com
  Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	linux-fbdev@vger.kernel.org
In-Reply-To: <f40abf01-46f2-41e6-a21f-c58c21d653c4@bootlin.com>


Hello Thomas and Krzysztof, 

Thanks for the comments. I have fixed most of them, but I disagree
about removing the error messages. I think that those would be needed.
Without those the kernel does not seem to print any errors to the logs
if the operation fails. It would be then the responsible of the calling
user space program to print the error to the log. But that also could
be missing due to the bug or bad design. This is targeted to be running
in the embedded device that is possibly used in places without internet
coverage. If the user is in such case calling to the support and
complains that backlight control is not working, the only way to get
further information are the logs that the device will send to the cloud
when it happens to be in the coverage of the network. When the log is
the only source of information, it would be really nice to be able to
read clear error messages if the oration has been failed in the driver.
> 

> +	bl_data->current_brightness = reply_buf[0] &
BLT_PWM_DUTY_MASK;
> +
> +	/* Verify the setting was applied correctly */
> +	if (bl_data->current_brightness != brightness) {
> +		dev_err(bl_data->dev,
> +			"Brightness setting verification failed\n");
> +		return -EIO;
> +	}
> 
> Do we really need to check the brightness returned by the board
> controller? Have you ever run into a situation where cbgc_command
> completed without errors, but the brightness level didn’t match what
> you
> expected? Maybe we could assume that if the cbgc_command returned
> successfully the brightness value is correct?
> 
> I'm not against checking the backlight value. I looked at Congatec's
> implementation and they also check it.
> 

You are absolutely right. It is extremely unlikely that the brightness
level wouldn't match to what is expected. A bug in the Congatec's
firmware could be one possibility. But then that extremely unlikely
situation will happen, I definitely would like to see it in the log.


Best Regards, 
Petri

^ permalink raw reply

* Re: [PATCH] backlight: aw99706: Fix unused function warnings from suspend/resume ops
From: Daniel Thompson @ 2025-11-24 10:34 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: Lee Jones, Daniel Thompson, Jingoo Han, Helge Deller, Pengyu Luo,
	Junjie Cao, dri-devel, linux-fbdev, patches
In-Reply-To: <20251120-backlight-aw99706-fix-unused-pm-functions-v1-1-8b9c17c4e783@kernel.org>

On Thu, Nov 20, 2025 at 01:22:46PM -0700, Nathan Chancellor wrote:
> When building for a platform without CONFIG_PM_SLEEP, such as s390,
> there are two unused function warnings:
>
>   drivers/video/backlight/aw99706.c:436:12: error: 'aw99706_resume' defined but not used [-Werror=unused-function]
>     436 | static int aw99706_resume(struct device *dev)
>         |            ^~~~~~~~~~~~~~
>   drivers/video/backlight/aw99706.c:429:12: error: 'aw99706_suspend' defined but not used [-Werror=unused-function]
>     429 | static int aw99706_suspend(struct device *dev)
>         |            ^~~~~~~~~~~~~~~
>
> SET_SYSTEM_SLEEP_PM_OPS, used within SIMPLE_DEV_PM_OPS, expands to
> nothing when CONFIG_PM_SLEEP is not set, so these functions are
> completely unused in this configuration.
>
> SIMPLE_DEV_PM_OPS is deprecated in favor of DEFINE_SIMPLE_DEV_PM_OPS,
> which avoids this issue by using pm_sleep_ptr to make these callbacks
> NULL when CONFIG_PM_SLEEP is unset while making the callback functions
> always appear used to the compiler regardless of configuration. Switch
> to DEFINE_SIMPLE_DEV_PM_OPS for aw99706_pm_ops to clear up the warning.
>
> Additionally, wrap the pointer to aw99706_pm_ops in pm_ptr() in
> aw99706_i2c_driver to ensure that the structure is completely eliminated
> in configurations without CONFIG_PM.
>
> Fixes: 88a8e9b49ee8 ("backlight: aw99706: Add support for Awinic AW99706 backlight")
> Signed-off-by: Nathan Chancellor <nathan@kernel.org>

Reviewed-by: Daniel Thompson (RISCstar) <danielt@kernel.org>


Daniel.

^ permalink raw reply

* Re: [PATCH 2/6] efi: sysfb_efi: Reduce number of references to global screen_info
From: Richard Lyu @ 2025-11-24  9:30 UTC (permalink / raw)
  To: Thomas Zimmermann, ardb, javierm, arnd
  Cc: x86, linux-arm-kernel, linux-kernel, linux-efi, loongarch,
	linux-riscv, dri-devel, linux-hyperv, linux-pci, linux-fbdev
In-Reply-To: <20251121135624.494768-3-tzimmermann@suse.de>

Reviewed-by: Richard Lyu <richard.lyu@suse.com>

On 2025/11/21 14:36, Thomas Zimmermann wrote:
> 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 <tzimmermann@suse.de>
> ---
>  drivers/firmware/efi/sysfb_efi.c  | 81 ++++++++++++++++---------------
>  drivers/firmware/sysfb.c          |  4 +-
>  drivers/firmware/sysfb_simplefb.c |  2 +-
>  include/linux/sysfb.h             |  9 ++--
>  4 files changed, 51 insertions(+), 45 deletions(-)
> 
> diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c
> index 1e509595ac03..8e0f9d08397f 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),	\
> @@ -284,12 +288,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);
> @@ -311,7 +316,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;
> @@ -349,25 +354,25 @@ 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)) {
> -		u16 temp = screen_info.lfb_width;
> +		u16 temp = si->lfb_width;
>  
> -		screen_info.lfb_width = screen_info.lfb_height;
> -		screen_info.lfb_height = temp;
> -		screen_info.lfb_linelength = 4 * screen_info.lfb_width;
> +		si->lfb_width = si->lfb_height;
> +		si->lfb_height = temp;
> +		si->lfb_linelength = 4 * si->lfb_width;
>  	}
>  }
>  
> -__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)
>  {
>  }
>  
> -- 
> 2.51.1
> 
> 

^ permalink raw reply

* Re: [PATCH 1/6] efi: earlycon: Reduce number of references to global screen_info
From: Richard Lyu @ 2025-11-24  9:28 UTC (permalink / raw)
  To: Thomas Zimmermann, ardb, javierm, arnd
  Cc: x86, linux-arm-kernel, linux-kernel, linux-efi, loongarch,
	linux-riscv, dri-devel, linux-hyperv, linux-pci, linux-fbdev
In-Reply-To: <20251121135624.494768-2-tzimmermann@suse.de>

Reviewed-by: Richard Lyu <richard.lyu@suse.com>

On 2025/11/21 14:36, Thomas Zimmermann wrote:
> 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 <tzimmermann@suse.de>
> ---
>  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..fac3a295c57f 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;
> -- 
> 2.51.1
> 
> 

^ permalink raw reply

* Re: [PATCH 0/6] arch, sysfb: Move screen and edid info into single place
From: Ard Biesheuvel @ 2025-11-22 11:42 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: Arnd Bergmann, Javier Martinez Canillas, x86, linux-arm-kernel,
	linux-kernel, linux-efi, loongarch, linux-riscv, dri-devel,
	linux-hyperv, linux-pci, linux-fbdev
In-Reply-To: <4c716fd1-c989-4e48-9878-e7312fefc302@suse.de>

On Sat, 22 Nov 2025 at 11:52, Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Hi
>
> Am 21.11.25 um 17:31 schrieb Ard Biesheuvel:
> > On Fri, 21 Nov 2025 at 17:26, Thomas Zimmermann <tzimmermann@suse.de> wrote:
> >> Hi
> >>
> >> Am 21.11.25 um 17:19 schrieb Ard Biesheuvel:
> >>> On Fri, 21 Nov 2025 at 17:09, Thomas Zimmermann <tzimmermann@suse.de> wrote:
> >>>>
> >>>> Am 21.11.25 um 17:08 schrieb Thomas Zimmermann:
> >>>>> Hi
> >>>>>
> >>>>> Am 21.11.25 um 16:56 schrieb Ard Biesheuvel:
> >>>>>> On Fri, 21 Nov 2025 at 16:53, Thomas Zimmermann <tzimmermann@suse.de>
> >>>>>> wrote:
> >>>>>>> Hi
> >>>>>>>
> >>>>>>> Am 21.11.25 um 16:16 schrieb Ard Biesheuvel:
> >>>>>>>> On Fri, 21 Nov 2025 at 16:10, Arnd Bergmann <arnd@arndb.de> wrote:
> >>>>>>>>> On Fri, Nov 21, 2025, at 14:36, Thomas Zimmermann wrote:
> >>>>>>>>>> Replace screen_info and edid_info with sysfb_primary_device of type
> >>>>>>>>>> struct sysfb_display_info. Update all users.
> >>>>>>>>>>
> >>>>>>>>>> Sysfb DRM drivers currently fetch the global edid_info directly,
> >>>>>>>>>> when
> >>>>>>>>>> they should get that information together with the screen_info
> >>>>>>>>>> from their
> >>>>>>>>>> device. Wrapping screen_info and edid_info in
> >>>>>>>>>> sysfb_primary_display and
> >>>>>>>>>> passing this to drivers enables this.
> >>>>>>>>>>
> >>>>>>>>>> Replacing both with sysfb_primary_display has been motivate by
> >>>>>>>>>> the EFI
> >>>>>>>>>> stub. EFI wants to transfer EDID via config table in a single entry.
> >>>>>>>>>> Using struct sysfb_display_info this will become easily possible.
> >>>>>>>>>> Hence
> >>>>>>>>>> accept some churn in architecture code for the long-term
> >>>>>>>>>> improvements.
> >>>>>>>>> This all looks good to me,
> >>>>>>>>>
> >>>>>>>>> Acked-by: Arnd Bergmann <arnd@arndb.de>
> >>>>>>> Thanks
> >>>>>>>
> >>>>>>>>> It should also bring us one step closer to eventually
> >>>>>>>>> disconnecting the x86 boot ABI from the kernel-internal
> >>>>>>>>> sysfb_primary_display.
> >>>>>>>>>
> >>>>>>>> Agreed
> >>>>>>>>
> >>>>>>>> Acked-by: Ard Biesheuvel <ardb@kernel.org>
> >>>>>>> Thanks
> >>>>>>>
> >>>>>>>> I can take patches 1-2 right away, if that helps during the next
> >>>>>>>> cycle.
> >>>>>>>     From my sysfb-focused POV, these patches would ideally all go through
> >>>>>>> the same tree, say efi or generic arch, or whatever fits best. Most of
> >>>>>>> the other code is only renames anyway.
> >>>>>>>
> >>>>>> I don't mind queueing all of it, but I did get a conflict on
> >>>>>> drivers/pci/vgaarb.c
> >>>>> Probably from a78835b86a44 ("PCI/VGA: Select SCREEN_INFO on X86")
> >>>> https://lore.kernel.org/all/20251013220829.1536292-1-superm1@kernel.org/
> >>>>
> >>> Yes, if I merge back -rc2 first, I can apply patches 1-5 onto my
> >>> efi/next tree. But then I hit
> >>>
> >>> Applying: sysfb: Move edid_info into sysfb_primary_display
> >>> error: sha1 information is lacking or useless (drivers/gpu/drm/sysfb/efidrm.c).
> >>> error: could not build fake ancestor
> >>> Patch failed at 0006 sysfb: Move edid_info into sysfb_primary_display
> >>>
> >>> If you prefer, you can take the whole lot via the sysfb tree instead,
> >>> assuming it does not depend on the EDID changes I already queued up?
> >> Sure, I can also add it to the drm-misc tree. ETA in upstream would be
> >> v6.20-rc1.
> >>
> > But does that mean the EDID firmware on non-x86 will have to wait for
> > 6.21? I was trying to avoid making this a 6 month effort.
>
> No problem. Then let me rebase onto linux-next and put the existing EDID
> patches for EFI on top. It's mostly acked or reviewed already. Once we
> have it in good shape we can merged it all at once via the linux-efi
> tree. Does that work for you?
>

Sounds good.

^ permalink raw reply

* Re: [PATCH 0/6] arch, sysfb: Move screen and edid info into single place
From: Thomas Zimmermann @ 2025-11-22 10:52 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Arnd Bergmann, Javier Martinez Canillas, x86, linux-arm-kernel,
	linux-kernel, linux-efi, loongarch, linux-riscv, dri-devel,
	linux-hyperv, linux-pci, linux-fbdev
In-Reply-To: <CAMj1kXFdethf2sb1tm1V4wRW1SyPt-OnCmaAXc5cHNKuLJMXWA@mail.gmail.com>

Hi

Am 21.11.25 um 17:31 schrieb Ard Biesheuvel:
> On Fri, 21 Nov 2025 at 17:26, Thomas Zimmermann <tzimmermann@suse.de> wrote:
>> Hi
>>
>> Am 21.11.25 um 17:19 schrieb Ard Biesheuvel:
>>> On Fri, 21 Nov 2025 at 17:09, Thomas Zimmermann <tzimmermann@suse.de> wrote:
>>>>
>>>> Am 21.11.25 um 17:08 schrieb Thomas Zimmermann:
>>>>> Hi
>>>>>
>>>>> Am 21.11.25 um 16:56 schrieb Ard Biesheuvel:
>>>>>> On Fri, 21 Nov 2025 at 16:53, Thomas Zimmermann <tzimmermann@suse.de>
>>>>>> wrote:
>>>>>>> Hi
>>>>>>>
>>>>>>> Am 21.11.25 um 16:16 schrieb Ard Biesheuvel:
>>>>>>>> On Fri, 21 Nov 2025 at 16:10, Arnd Bergmann <arnd@arndb.de> wrote:
>>>>>>>>> On Fri, Nov 21, 2025, at 14:36, Thomas Zimmermann wrote:
>>>>>>>>>> Replace screen_info and edid_info with sysfb_primary_device of type
>>>>>>>>>> struct sysfb_display_info. Update all users.
>>>>>>>>>>
>>>>>>>>>> Sysfb DRM drivers currently fetch the global edid_info directly,
>>>>>>>>>> when
>>>>>>>>>> they should get that information together with the screen_info
>>>>>>>>>> from their
>>>>>>>>>> device. Wrapping screen_info and edid_info in
>>>>>>>>>> sysfb_primary_display and
>>>>>>>>>> passing this to drivers enables this.
>>>>>>>>>>
>>>>>>>>>> Replacing both with sysfb_primary_display has been motivate by
>>>>>>>>>> the EFI
>>>>>>>>>> stub. EFI wants to transfer EDID via config table in a single entry.
>>>>>>>>>> Using struct sysfb_display_info this will become easily possible.
>>>>>>>>>> Hence
>>>>>>>>>> accept some churn in architecture code for the long-term
>>>>>>>>>> improvements.
>>>>>>>>> This all looks good to me,
>>>>>>>>>
>>>>>>>>> Acked-by: Arnd Bergmann <arnd@arndb.de>
>>>>>>> Thanks
>>>>>>>
>>>>>>>>> It should also bring us one step closer to eventually
>>>>>>>>> disconnecting the x86 boot ABI from the kernel-internal
>>>>>>>>> sysfb_primary_display.
>>>>>>>>>
>>>>>>>> Agreed
>>>>>>>>
>>>>>>>> Acked-by: Ard Biesheuvel <ardb@kernel.org>
>>>>>>> Thanks
>>>>>>>
>>>>>>>> I can take patches 1-2 right away, if that helps during the next
>>>>>>>> cycle.
>>>>>>>     From my sysfb-focused POV, these patches would ideally all go through
>>>>>>> the same tree, say efi or generic arch, or whatever fits best. Most of
>>>>>>> the other code is only renames anyway.
>>>>>>>
>>>>>> I don't mind queueing all of it, but I did get a conflict on
>>>>>> drivers/pci/vgaarb.c
>>>>> Probably from a78835b86a44 ("PCI/VGA: Select SCREEN_INFO on X86")
>>>> https://lore.kernel.org/all/20251013220829.1536292-1-superm1@kernel.org/
>>>>
>>> Yes, if I merge back -rc2 first, I can apply patches 1-5 onto my
>>> efi/next tree. But then I hit
>>>
>>> Applying: sysfb: Move edid_info into sysfb_primary_display
>>> error: sha1 information is lacking or useless (drivers/gpu/drm/sysfb/efidrm.c).
>>> error: could not build fake ancestor
>>> Patch failed at 0006 sysfb: Move edid_info into sysfb_primary_display
>>>
>>> If you prefer, you can take the whole lot via the sysfb tree instead,
>>> assuming it does not depend on the EDID changes I already queued up?
>> Sure, I can also add it to the drm-misc tree. ETA in upstream would be
>> v6.20-rc1.
>>
> But does that mean the EDID firmware on non-x86 will have to wait for
> 6.21? I was trying to avoid making this a 6 month effort.

No problem. Then let me rebase onto linux-next and put the existing EDID 
patches for EFI on top. It's mostly acked or reviewed already. Once we 
have it in good shape we can merged it all at once via the linux-efi 
tree. Does that work for you?

Best regards
Thomas


-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)



^ permalink raw reply

* Re: [PATCH 0/6] arch, sysfb: Move screen and edid info into single place
From: Ard Biesheuvel @ 2025-11-21 16:31 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: Arnd Bergmann, Javier Martinez Canillas, x86, linux-arm-kernel,
	linux-kernel, linux-efi, loongarch, linux-riscv, dri-devel,
	linux-hyperv, linux-pci, linux-fbdev
In-Reply-To: <8d0bc096-e346-462b-a274-f0cc1456eea3@suse.de>

On Fri, 21 Nov 2025 at 17:26, Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Hi
>
> Am 21.11.25 um 17:19 schrieb Ard Biesheuvel:
> > On Fri, 21 Nov 2025 at 17:09, Thomas Zimmermann <tzimmermann@suse.de> wrote:
> >>
> >>
> >> Am 21.11.25 um 17:08 schrieb Thomas Zimmermann:
> >>> Hi
> >>>
> >>> Am 21.11.25 um 16:56 schrieb Ard Biesheuvel:
> >>>> On Fri, 21 Nov 2025 at 16:53, Thomas Zimmermann <tzimmermann@suse.de>
> >>>> wrote:
> >>>>> Hi
> >>>>>
> >>>>> Am 21.11.25 um 16:16 schrieb Ard Biesheuvel:
> >>>>>> On Fri, 21 Nov 2025 at 16:10, Arnd Bergmann <arnd@arndb.de> wrote:
> >>>>>>> On Fri, Nov 21, 2025, at 14:36, Thomas Zimmermann wrote:
> >>>>>>>> Replace screen_info and edid_info with sysfb_primary_device of type
> >>>>>>>> struct sysfb_display_info. Update all users.
> >>>>>>>>
> >>>>>>>> Sysfb DRM drivers currently fetch the global edid_info directly,
> >>>>>>>> when
> >>>>>>>> they should get that information together with the screen_info
> >>>>>>>> from their
> >>>>>>>> device. Wrapping screen_info and edid_info in
> >>>>>>>> sysfb_primary_display and
> >>>>>>>> passing this to drivers enables this.
> >>>>>>>>
> >>>>>>>> Replacing both with sysfb_primary_display has been motivate by
> >>>>>>>> the EFI
> >>>>>>>> stub. EFI wants to transfer EDID via config table in a single entry.
> >>>>>>>> Using struct sysfb_display_info this will become easily possible.
> >>>>>>>> Hence
> >>>>>>>> accept some churn in architecture code for the long-term
> >>>>>>>> improvements.
> >>>>>>> This all looks good to me,
> >>>>>>>
> >>>>>>> Acked-by: Arnd Bergmann <arnd@arndb.de>
> >>>>> Thanks
> >>>>>
> >>>>>>> It should also bring us one step closer to eventually
> >>>>>>> disconnecting the x86 boot ABI from the kernel-internal
> >>>>>>> sysfb_primary_display.
> >>>>>>>
> >>>>>> Agreed
> >>>>>>
> >>>>>> Acked-by: Ard Biesheuvel <ardb@kernel.org>
> >>>>> Thanks
> >>>>>
> >>>>>> I can take patches 1-2 right away, if that helps during the next
> >>>>>> cycle.
> >>>>>    From my sysfb-focused POV, these patches would ideally all go through
> >>>>> the same tree, say efi or generic arch, or whatever fits best. Most of
> >>>>> the other code is only renames anyway.
> >>>>>
> >>>> I don't mind queueing all of it, but I did get a conflict on
> >>>> drivers/pci/vgaarb.c
> >>> Probably from a78835b86a44 ("PCI/VGA: Select SCREEN_INFO on X86")
> >> https://lore.kernel.org/all/20251013220829.1536292-1-superm1@kernel.org/
> >>
> > Yes, if I merge back -rc2 first, I can apply patches 1-5 onto my
> > efi/next tree. But then I hit
> >
> > Applying: sysfb: Move edid_info into sysfb_primary_display
> > error: sha1 information is lacking or useless (drivers/gpu/drm/sysfb/efidrm.c).
> > error: could not build fake ancestor
> > Patch failed at 0006 sysfb: Move edid_info into sysfb_primary_display
> >
> > If you prefer, you can take the whole lot via the sysfb tree instead,
> > assuming it does not depend on the EDID changes I already queued up?
>
> Sure, I can also add it to the drm-misc tree. ETA in upstream would be
> v6.20-rc1.
>

But does that mean the EDID firmware on non-x86 will have to wait for
6.21? I was trying to avoid making this a 6 month effort.

^ permalink raw reply

* Re: [PATCH 0/6] arch, sysfb: Move screen and edid info into single place
From: Thomas Zimmermann @ 2025-11-21 16:26 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Arnd Bergmann, Javier Martinez Canillas, x86, linux-arm-kernel,
	linux-kernel, linux-efi, loongarch, linux-riscv, dri-devel,
	linux-hyperv, linux-pci, linux-fbdev
In-Reply-To: <CAMj1kXGpC_162bFL65kQw=7qVP7ezYw77Q76y217dDs8pqHogw@mail.gmail.com>

Hi

Am 21.11.25 um 17:19 schrieb Ard Biesheuvel:
> On Fri, 21 Nov 2025 at 17:09, Thomas Zimmermann <tzimmermann@suse.de> wrote:
>>
>>
>> Am 21.11.25 um 17:08 schrieb Thomas Zimmermann:
>>> Hi
>>>
>>> Am 21.11.25 um 16:56 schrieb Ard Biesheuvel:
>>>> On Fri, 21 Nov 2025 at 16:53, Thomas Zimmermann <tzimmermann@suse.de>
>>>> wrote:
>>>>> Hi
>>>>>
>>>>> Am 21.11.25 um 16:16 schrieb Ard Biesheuvel:
>>>>>> On Fri, 21 Nov 2025 at 16:10, Arnd Bergmann <arnd@arndb.de> wrote:
>>>>>>> On Fri, Nov 21, 2025, at 14:36, Thomas Zimmermann wrote:
>>>>>>>> Replace screen_info and edid_info with sysfb_primary_device of type
>>>>>>>> struct sysfb_display_info. Update all users.
>>>>>>>>
>>>>>>>> Sysfb DRM drivers currently fetch the global edid_info directly,
>>>>>>>> when
>>>>>>>> they should get that information together with the screen_info
>>>>>>>> from their
>>>>>>>> device. Wrapping screen_info and edid_info in
>>>>>>>> sysfb_primary_display and
>>>>>>>> passing this to drivers enables this.
>>>>>>>>
>>>>>>>> Replacing both with sysfb_primary_display has been motivate by
>>>>>>>> the EFI
>>>>>>>> stub. EFI wants to transfer EDID via config table in a single entry.
>>>>>>>> Using struct sysfb_display_info this will become easily possible.
>>>>>>>> Hence
>>>>>>>> accept some churn in architecture code for the long-term
>>>>>>>> improvements.
>>>>>>> This all looks good to me,
>>>>>>>
>>>>>>> Acked-by: Arnd Bergmann <arnd@arndb.de>
>>>>> Thanks
>>>>>
>>>>>>> It should also bring us one step closer to eventually
>>>>>>> disconnecting the x86 boot ABI from the kernel-internal
>>>>>>> sysfb_primary_display.
>>>>>>>
>>>>>> Agreed
>>>>>>
>>>>>> Acked-by: Ard Biesheuvel <ardb@kernel.org>
>>>>> Thanks
>>>>>
>>>>>> I can take patches 1-2 right away, if that helps during the next
>>>>>> cycle.
>>>>>    From my sysfb-focused POV, these patches would ideally all go through
>>>>> the same tree, say efi or generic arch, or whatever fits best. Most of
>>>>> the other code is only renames anyway.
>>>>>
>>>> I don't mind queueing all of it, but I did get a conflict on
>>>> drivers/pci/vgaarb.c
>>> Probably from a78835b86a44 ("PCI/VGA: Select SCREEN_INFO on X86")
>> https://lore.kernel.org/all/20251013220829.1536292-1-superm1@kernel.org/
>>
> Yes, if I merge back -rc2 first, I can apply patches 1-5 onto my
> efi/next tree. But then I hit
>
> Applying: sysfb: Move edid_info into sysfb_primary_display
> error: sha1 information is lacking or useless (drivers/gpu/drm/sysfb/efidrm.c).
> error: could not build fake ancestor
> Patch failed at 0006 sysfb: Move edid_info into sysfb_primary_display
>
> If you prefer, you can take the whole lot via the sysfb tree instead,
> assuming it does not depend on the EDID changes I already queued up?

Sure, I can also add it to the drm-misc tree. ETA in upstream would be 
v6.20-rc1.

Best regards
Thomas


-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)



^ permalink raw reply

* Re: [PATCH 0/6] arch, sysfb: Move screen and edid info into single place
From: Ard Biesheuvel @ 2025-11-21 16:19 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: Arnd Bergmann, Javier Martinez Canillas, x86, linux-arm-kernel,
	linux-kernel, linux-efi, loongarch, linux-riscv, dri-devel,
	linux-hyperv, linux-pci, linux-fbdev
In-Reply-To: <6dff8e7e-c99b-443d-a1d8-22650ca0b595@suse.de>

On Fri, 21 Nov 2025 at 17:09, Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
>
>
> Am 21.11.25 um 17:08 schrieb Thomas Zimmermann:
> > Hi
> >
> > Am 21.11.25 um 16:56 schrieb Ard Biesheuvel:
> >> On Fri, 21 Nov 2025 at 16:53, Thomas Zimmermann <tzimmermann@suse.de>
> >> wrote:
> >>> Hi
> >>>
> >>> Am 21.11.25 um 16:16 schrieb Ard Biesheuvel:
> >>>> On Fri, 21 Nov 2025 at 16:10, Arnd Bergmann <arnd@arndb.de> wrote:
> >>>>> On Fri, Nov 21, 2025, at 14:36, Thomas Zimmermann wrote:
> >>>>>> Replace screen_info and edid_info with sysfb_primary_device of type
> >>>>>> struct sysfb_display_info. Update all users.
> >>>>>>
> >>>>>> Sysfb DRM drivers currently fetch the global edid_info directly,
> >>>>>> when
> >>>>>> they should get that information together with the screen_info
> >>>>>> from their
> >>>>>> device. Wrapping screen_info and edid_info in
> >>>>>> sysfb_primary_display and
> >>>>>> passing this to drivers enables this.
> >>>>>>
> >>>>>> Replacing both with sysfb_primary_display has been motivate by
> >>>>>> the EFI
> >>>>>> stub. EFI wants to transfer EDID via config table in a single entry.
> >>>>>> Using struct sysfb_display_info this will become easily possible.
> >>>>>> Hence
> >>>>>> accept some churn in architecture code for the long-term
> >>>>>> improvements.
> >>>>> This all looks good to me,
> >>>>>
> >>>>> Acked-by: Arnd Bergmann <arnd@arndb.de>
> >>> Thanks
> >>>
> >>>>> It should also bring us one step closer to eventually
> >>>>> disconnecting the x86 boot ABI from the kernel-internal
> >>>>> sysfb_primary_display.
> >>>>>
> >>>> Agreed
> >>>>
> >>>> Acked-by: Ard Biesheuvel <ardb@kernel.org>
> >>> Thanks
> >>>
> >>>> I can take patches 1-2 right away, if that helps during the next
> >>>> cycle.
> >>>   From my sysfb-focused POV, these patches would ideally all go through
> >>> the same tree, say efi or generic arch, or whatever fits best. Most of
> >>> the other code is only renames anyway.
> >>>
> >> I don't mind queueing all of it, but I did get a conflict on
> >> drivers/pci/vgaarb.c
> >
> > Probably from a78835b86a44 ("PCI/VGA: Select SCREEN_INFO on X86")
>
> https://lore.kernel.org/all/20251013220829.1536292-1-superm1@kernel.org/
>

Yes, if I merge back -rc2 first, I can apply patches 1-5 onto my
efi/next tree. But then I hit

Applying: sysfb: Move edid_info into sysfb_primary_display
error: sha1 information is lacking or useless (drivers/gpu/drm/sysfb/efidrm.c).
error: could not build fake ancestor
Patch failed at 0006 sysfb: Move edid_info into sysfb_primary_display

If you prefer, you can take the whole lot via the sysfb tree instead,
assuming it does not depend on the EDID changes I already queued up?

^ permalink raw reply

* Re: [PATCH 0/6] arch, sysfb: Move screen and edid info into single place
From: Thomas Zimmermann @ 2025-11-21 16:09 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Arnd Bergmann, Javier Martinez Canillas, x86, linux-arm-kernel,
	linux-kernel, linux-efi, loongarch, linux-riscv, dri-devel,
	linux-hyperv, linux-pci, linux-fbdev
In-Reply-To: <d080729c-6586-4b9c-b234-470977849d3d@suse.de>



Am 21.11.25 um 17:08 schrieb Thomas Zimmermann:
> Hi
>
> Am 21.11.25 um 16:56 schrieb Ard Biesheuvel:
>> On Fri, 21 Nov 2025 at 16:53, Thomas Zimmermann <tzimmermann@suse.de> 
>> wrote:
>>> Hi
>>>
>>> Am 21.11.25 um 16:16 schrieb Ard Biesheuvel:
>>>> On Fri, 21 Nov 2025 at 16:10, Arnd Bergmann <arnd@arndb.de> wrote:
>>>>> On Fri, Nov 21, 2025, at 14:36, Thomas Zimmermann wrote:
>>>>>> Replace screen_info and edid_info with sysfb_primary_device of type
>>>>>> struct sysfb_display_info. Update all users.
>>>>>>
>>>>>> Sysfb DRM drivers currently fetch the global edid_info directly, 
>>>>>> when
>>>>>> they should get that information together with the screen_info 
>>>>>> from their
>>>>>> device. Wrapping screen_info and edid_info in 
>>>>>> sysfb_primary_display and
>>>>>> passing this to drivers enables this.
>>>>>>
>>>>>> Replacing both with sysfb_primary_display has been motivate by 
>>>>>> the EFI
>>>>>> stub. EFI wants to transfer EDID via config table in a single entry.
>>>>>> Using struct sysfb_display_info this will become easily possible. 
>>>>>> Hence
>>>>>> accept some churn in architecture code for the long-term 
>>>>>> improvements.
>>>>> This all looks good to me,
>>>>>
>>>>> Acked-by: Arnd Bergmann <arnd@arndb.de>
>>> Thanks
>>>
>>>>> It should also bring us one step closer to eventually
>>>>> disconnecting the x86 boot ABI from the kernel-internal
>>>>> sysfb_primary_display.
>>>>>
>>>> Agreed
>>>>
>>>> Acked-by: Ard Biesheuvel <ardb@kernel.org>
>>> Thanks
>>>
>>>> I can take patches 1-2 right away, if that helps during the next 
>>>> cycle.
>>>   From my sysfb-focused POV, these patches would ideally all go through
>>> the same tree, say efi or generic arch, or whatever fits best. Most of
>>> the other code is only renames anyway.
>>>
>> I don't mind queueing all of it, but I did get a conflict on
>> drivers/pci/vgaarb.c
>
> Probably from a78835b86a44 ("PCI/VGA: Select SCREEN_INFO on X86")

https://lore.kernel.org/all/20251013220829.1536292-1-superm1@kernel.org/


>  that I have in my tree. You can fix it by replacing screen_info with 
> sysfb_primary_display.screen. The later merge conflict seems manageable.
>
> Best regards
> Thomas
>
>

-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)



^ permalink raw reply

* Re: [PATCH 0/6] arch, sysfb: Move screen and edid info into single place
From: Thomas Zimmermann @ 2025-11-21 16:08 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Arnd Bergmann, Javier Martinez Canillas, x86, linux-arm-kernel,
	linux-kernel, linux-efi, loongarch, linux-riscv, dri-devel,
	linux-hyperv, linux-pci, linux-fbdev
In-Reply-To: <CAMj1kXE+mS1Sm5GaROU0P97J2w1pew0P_To4sKiw8h1iOMuLcg@mail.gmail.com>

Hi

Am 21.11.25 um 16:56 schrieb Ard Biesheuvel:
> On Fri, 21 Nov 2025 at 16:53, Thomas Zimmermann <tzimmermann@suse.de> wrote:
>> Hi
>>
>> Am 21.11.25 um 16:16 schrieb Ard Biesheuvel:
>>> On Fri, 21 Nov 2025 at 16:10, Arnd Bergmann <arnd@arndb.de> wrote:
>>>> On Fri, Nov 21, 2025, at 14:36, Thomas Zimmermann wrote:
>>>>> Replace screen_info and edid_info with sysfb_primary_device of type
>>>>> struct sysfb_display_info. Update all users.
>>>>>
>>>>> Sysfb DRM drivers currently fetch the global edid_info directly, when
>>>>> they should get that information together with the screen_info from their
>>>>> device. Wrapping screen_info and edid_info in sysfb_primary_display and
>>>>> passing this to drivers enables this.
>>>>>
>>>>> Replacing both with sysfb_primary_display has been motivate by the EFI
>>>>> stub. EFI wants to transfer EDID via config table in a single entry.
>>>>> Using struct sysfb_display_info this will become easily possible. Hence
>>>>> accept some churn in architecture code for the long-term improvements.
>>>> This all looks good to me,
>>>>
>>>> Acked-by: Arnd Bergmann <arnd@arndb.de>
>> Thanks
>>
>>>> It should also bring us one step closer to eventually
>>>> disconnecting the x86 boot ABI from the kernel-internal
>>>> sysfb_primary_display.
>>>>
>>> Agreed
>>>
>>> Acked-by: Ard Biesheuvel <ardb@kernel.org>
>> Thanks
>>
>>> I can take patches 1-2 right away, if that helps during the next cycle.
>>   From my sysfb-focused POV, these patches would ideally all go through
>> the same tree, say efi or generic arch, or whatever fits best. Most of
>> the other code is only renames anyway.
>>
> I don't mind queueing all of it, but I did get a conflict on
> drivers/pci/vgaarb.c

Probably from a78835b86a44 ("PCI/VGA: Select SCREEN_INFO on X86") that I 
have in my tree. You can fix it by replacing screen_info with 
sysfb_primary_display.screen. The later merge conflict seems manageable.

Best regards
Thomas


-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)



^ permalink raw reply

* Re: [PATCH 0/6] arch, sysfb: Move screen and edid info into single place
From: Ard Biesheuvel @ 2025-11-21 15:56 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: Arnd Bergmann, Javier Martinez Canillas, x86, linux-arm-kernel,
	linux-kernel, linux-efi, loongarch, linux-riscv, dri-devel,
	linux-hyperv, linux-pci, linux-fbdev
In-Reply-To: <199e7538-5b4a-483b-8976-84e4a8a0f2fd@suse.de>

On Fri, 21 Nov 2025 at 16:53, Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Hi
>
> Am 21.11.25 um 16:16 schrieb Ard Biesheuvel:
> > On Fri, 21 Nov 2025 at 16:10, Arnd Bergmann <arnd@arndb.de> wrote:
> >> On Fri, Nov 21, 2025, at 14:36, Thomas Zimmermann wrote:
> >>> Replace screen_info and edid_info with sysfb_primary_device of type
> >>> struct sysfb_display_info. Update all users.
> >>>
> >>> Sysfb DRM drivers currently fetch the global edid_info directly, when
> >>> they should get that information together with the screen_info from their
> >>> device. Wrapping screen_info and edid_info in sysfb_primary_display and
> >>> passing this to drivers enables this.
> >>>
> >>> Replacing both with sysfb_primary_display has been motivate by the EFI
> >>> stub. EFI wants to transfer EDID via config table in a single entry.
> >>> Using struct sysfb_display_info this will become easily possible. Hence
> >>> accept some churn in architecture code for the long-term improvements.
> >> This all looks good to me,
> >>
> >> Acked-by: Arnd Bergmann <arnd@arndb.de>
>
> Thanks
>
> >>
> >> It should also bring us one step closer to eventually
> >> disconnecting the x86 boot ABI from the kernel-internal
> >> sysfb_primary_display.
> >>
> > Agreed
> >
> > Acked-by: Ard Biesheuvel <ardb@kernel.org>
>
> Thanks
>
> >
> > I can take patches 1-2 right away, if that helps during the next cycle.
>
>  From my sysfb-focused POV, these patches would ideally all go through
> the same tree, say efi or generic arch, or whatever fits best. Most of
> the other code is only renames anyway.
>

I don't mind queueing all of it, but I did get a conflict on
drivers/pci/vgaarb.c

^ permalink raw reply

* Re: [PATCH 6/6] sysfb: Move edid_info into sysfb_primary_display
From: Thomas Zimmermann @ 2025-11-21 15:56 UTC (permalink / raw)
  To: ardb, javierm, arnd
  Cc: x86, linux-arm-kernel, linux-kernel, linux-efi, loongarch,
	linux-riscv, dri-devel, linux-hyperv, linux-pci, linux-fbdev
In-Reply-To: <20251121135624.494768-7-tzimmermann@suse.de>



Am 21.11.25 um 14:36 schrieb Thomas Zimmermann:
> Move x86's edid_info into sysfb_primary_display as a new field named
> edid. Adapt all users.
>
> An instance of edid_info has only been defined on x86. With the move
> into sysfb_primary_display, it becomes available on all architectures.
> Therefore remove this contraint from CONFIG_FIRMWARE_EDID.

s/contraint/constraint/

>
> x86 fills the EDID data from boot_params.edid_info. DRM drivers pick
> up the raw data and make it available to DRM clients. Replace the
> drivers' references to edid_info and instead use the sysfb_display_info
> as passed from sysfb.
>
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
>   arch/x86/kernel/setup.c          | 6 +-----
>   drivers/gpu/drm/sysfb/efidrm.c   | 5 ++---
>   drivers/gpu/drm/sysfb/vesadrm.c  | 5 ++---
>   drivers/video/Kconfig            | 1 -
>   drivers/video/fbdev/core/fbmon.c | 8 +++++---
>   include/linux/sysfb.h            | 6 ++++++
>   include/video/edid.h             | 4 ----
>   7 files changed, 16 insertions(+), 19 deletions(-)
>
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index 675e4b9deb1f..d9bfe2032cd9 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -215,10 +215,6 @@ arch_initcall(init_x86_sysctl);
>   
>   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);
> -#endif
>   
>   extern int root_mountflags;
>   
> @@ -530,7 +526,7 @@ static void __init parse_boot_params(void)
>   	ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev);
>   	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;
> diff --git a/drivers/gpu/drm/sysfb/efidrm.c b/drivers/gpu/drm/sysfb/efidrm.c
> index 29533ae8fbbf..50e0aeef709c 100644
> --- a/drivers/gpu/drm/sysfb/efidrm.c
> +++ b/drivers/gpu/drm/sysfb/efidrm.c
> @@ -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"
> @@ -207,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;
> diff --git a/drivers/gpu/drm/sysfb/vesadrm.c b/drivers/gpu/drm/sysfb/vesadrm.c
> index 16fc223f8c5b..0680638b8131 100644
> --- a/drivers/gpu/drm/sysfb/vesadrm.c
> +++ b/drivers/gpu/drm/sysfb/vesadrm.c
> @@ -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>
>   
> @@ -474,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;
> diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
> index d51777df12d1..ad55e7d62159 100644
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -63,7 +63,6 @@ endif # HAS_IOMEM
>   
>   config FIRMWARE_EDID
>   	bool "Enable firmware EDID"
> -	depends on X86
>   	help
>   	  This enables access to the EDID transferred from the firmware.
>   	  On x86, this is from the VESA BIOS. DRM display drivers will
> diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c
> index 0a65bef01e3c..07df7e98f8a3 100644
> --- a/drivers/video/fbdev/core/fbmon.c
> +++ b/drivers/video/fbdev/core/fbmon.c
> @@ -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;
>   }
> diff --git a/include/linux/sysfb.h b/include/linux/sysfb.h
> index e8bde392c690..5226efde9ad4 100644
> --- a/include/linux/sysfb.h
> +++ b/include/linux/sysfb.h
> @@ -12,6 +12,8 @@
>   #include <linux/screen_info.h>
>   #include <linux/types.h>
>   
> +#include <video/edid.h>
> +
>   struct device;
>   struct platform_device;
>   struct screen_info;
> @@ -62,6 +64,10 @@ struct efifb_dmi_info {
>   
>   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;
> diff --git a/include/video/edid.h b/include/video/edid.h
> index c2b186b1933a..52aabb706032 100644
> --- a/include/video/edid.h
> +++ b/include/video/edid.h
> @@ -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__ */

-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)



^ permalink raw reply

* Re: [PATCH 0/6] arch, sysfb: Move screen and edid info into single place
From: Thomas Zimmermann @ 2025-11-21 15:53 UTC (permalink / raw)
  To: Ard Biesheuvel, Arnd Bergmann
  Cc: Javier Martinez Canillas, x86, linux-arm-kernel, linux-kernel,
	linux-efi, loongarch, linux-riscv, dri-devel, linux-hyperv,
	linux-pci, linux-fbdev
In-Reply-To: <CAMj1kXF1Dh0RbuqYc0fhAPf-CM0mdYh8BhenM8-ugKVHfwnhBg@mail.gmail.com>

Hi

Am 21.11.25 um 16:16 schrieb Ard Biesheuvel:
> On Fri, 21 Nov 2025 at 16:10, Arnd Bergmann <arnd@arndb.de> wrote:
>> On Fri, Nov 21, 2025, at 14:36, Thomas Zimmermann wrote:
>>> Replace screen_info and edid_info with sysfb_primary_device of type
>>> struct sysfb_display_info. Update all users.
>>>
>>> Sysfb DRM drivers currently fetch the global edid_info directly, when
>>> they should get that information together with the screen_info from their
>>> device. Wrapping screen_info and edid_info in sysfb_primary_display and
>>> passing this to drivers enables this.
>>>
>>> Replacing both with sysfb_primary_display has been motivate by the EFI
>>> stub. EFI wants to transfer EDID via config table in a single entry.
>>> Using struct sysfb_display_info this will become easily possible. Hence
>>> accept some churn in architecture code for the long-term improvements.
>> This all looks good to me,
>>
>> Acked-by: Arnd Bergmann <arnd@arndb.de>

Thanks

>>
>> It should also bring us one step closer to eventually
>> disconnecting the x86 boot ABI from the kernel-internal
>> sysfb_primary_display.
>>
> Agreed
>
> Acked-by: Ard Biesheuvel <ardb@kernel.org>

Thanks

>
> I can take patches 1-2 right away, if that helps during the next cycle.

 From my sysfb-focused POV, these patches would ideally all go through 
the same tree, say efi or generic arch, or whatever fits best. Most of 
the other code is only renames anyway.

Best regards
Thomas


-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)



^ permalink raw reply

* Re: [PATCH 0/6] arch,sysfb: Move screen and edid info into single place
From: Ard Biesheuvel @ 2025-11-21 15:16 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Thomas Zimmermann, Javier Martinez Canillas, x86,
	linux-arm-kernel, linux-kernel, linux-efi, loongarch, linux-riscv,
	dri-devel, linux-hyperv, linux-pci, linux-fbdev
In-Reply-To: <96a8d591-29d5-4764-94f9-6042252e53ff@app.fastmail.com>

On Fri, 21 Nov 2025 at 16:10, Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Fri, Nov 21, 2025, at 14:36, Thomas Zimmermann wrote:
> > Replace screen_info and edid_info with sysfb_primary_device of type
> > struct sysfb_display_info. Update all users.
> >
> > Sysfb DRM drivers currently fetch the global edid_info directly, when
> > they should get that information together with the screen_info from their
> > device. Wrapping screen_info and edid_info in sysfb_primary_display and
> > passing this to drivers enables this.
> >
> > Replacing both with sysfb_primary_display has been motivate by the EFI
> > stub. EFI wants to transfer EDID via config table in a single entry.
> > Using struct sysfb_display_info this will become easily possible. Hence
> > accept some churn in architecture code for the long-term improvements.
>
> This all looks good to me,
>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
>
> It should also bring us one step closer to eventually
> disconnecting the x86 boot ABI from the kernel-internal
> sysfb_primary_display.
>

Agreed

Acked-by: Ard Biesheuvel <ardb@kernel.org>

I can take patches 1-2 right away, if that helps during the next cycle.

^ permalink raw reply

* Re: [PATCH 0/6] arch,sysfb: Move screen and edid info into single place
From: Arnd Bergmann @ 2025-11-21 15:09 UTC (permalink / raw)
  To: Thomas Zimmermann, Ard Biesheuvel, Javier Martinez Canillas
  Cc: x86, linux-arm-kernel, linux-kernel, linux-efi, loongarch,
	linux-riscv, dri-devel, linux-hyperv, linux-pci, linux-fbdev
In-Reply-To: <20251121135624.494768-1-tzimmermann@suse.de>

On Fri, Nov 21, 2025, at 14:36, Thomas Zimmermann wrote:
> Replace screen_info and edid_info with sysfb_primary_device of type
> struct sysfb_display_info. Update all users.
>
> Sysfb DRM drivers currently fetch the global edid_info directly, when
> they should get that information together with the screen_info from their
> device. Wrapping screen_info and edid_info in sysfb_primary_display and
> passing this to drivers enables this.
>
> Replacing both with sysfb_primary_display has been motivate by the EFI
> stub. EFI wants to transfer EDID via config table in a single entry.
> Using struct sysfb_display_info this will become easily possible. Hence
> accept some churn in architecture code for the long-term improvements.

This all looks good to me,

Acked-by: Arnd Bergmann <arnd@arndb.de>

It should also bring us one step closer to eventually
disconnecting the x86 boot ABI from the kernel-internal
sysfb_primary_display.

    Arnd

^ permalink raw reply

* Re: [PATCH] drm, fbcon, vga_switcheroo: Avoid race condition in fbcon setup
From: Alex Deucher @ 2025-11-21 14:15 UTC (permalink / raw)
  To: Thomas Zimmermann
  Cc: maarten.lankhorst, mripard, airlied, simona, deller, lukas,
	ville.syrjala, sam, javierm, dri-devel, linux-fbdev
In-Reply-To: <20251105161549.98836-1-tzimmermann@suse.de>

On Wed, Nov 5, 2025 at 12:11 PM Thomas Zimmermann <tzimmermann@suse.de> wrote:
>
> Protect vga_switcheroo_client_fb_set() with console lock. Avoids OOB
> access in fbcon_remap_all(). Without holding the console lock the call
> races with switching outputs.
>
> VGA switcheroo calls fbcon_remap_all() when switching clients. The fbcon
> function uses struct fb_info.node, which is set by register_framebuffer().
> As the fb-helper code currently sets up VGA switcheroo before registering
> the framebuffer, the value of node is -1 and therefore not a legal value.
> For example, fbcon uses the value within set_con2fb_map() [1] as an index
> into an array.
>
> Moving vga_switcheroo_client_fb_set() after register_framebuffer() can
> result in VGA switching that does not switch fbcon correctly.
>
> Therefore move vga_switcheroo_client_fb_set() under fbcon_fb_registered(),
> which already holds the console lock. Fbdev calls fbcon_fb_registered()
> from within register_framebuffer(). Serializes the helper with VGA
> switcheroo's call to fbcon_remap_all().
>
> Although vga_switcheroo_client_fb_set() takes an instance of struct fb_info
> as parameter, it really only needs the contained fbcon state. Moving the
> call to fbcon initialization is therefore cleaner than before. Only amdgpu,
> i915, nouveau and radeon support vga_switcheroo. For all other drivers,
> this change does nothing.
>
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> Link: https://elixir.bootlin.com/linux/v6.17/source/drivers/video/fbdev/core/fbcon.c#L2942 # [1]

I haven't paged switcheroo into my head in a while, but this seems to
make sense so:
Acked-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/drm_fb_helper.c  | 14 --------------
>  drivers/video/fbdev/core/fbcon.c |  9 +++++++++
>  2 files changed, 9 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index 53e9dc0543de..c0343ec16a57 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -31,9 +31,7 @@
>
>  #include <linux/console.h>
>  #include <linux/export.h>
> -#include <linux/pci.h>
>  #include <linux/sysrq.h>
> -#include <linux/vga_switcheroo.h>
>
>  #include <drm/drm_atomic.h>
>  #include <drm/drm_drv.h>
> @@ -570,11 +568,6 @@ EXPORT_SYMBOL(drm_fb_helper_release_info);
>   */
>  void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper)
>  {
> -       struct fb_info *info = fb_helper->info;
> -       struct device *dev = info->device;
> -
> -       if (dev_is_pci(dev))
> -               vga_switcheroo_client_fb_set(to_pci_dev(dev), NULL);
>         unregister_framebuffer(fb_helper->info);
>  }
>  EXPORT_SYMBOL(drm_fb_helper_unregister_info);
> @@ -1614,7 +1607,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper)
>         struct drm_client_dev *client = &fb_helper->client;
>         struct drm_device *dev = fb_helper->dev;
>         struct drm_fb_helper_surface_size sizes;
> -       struct fb_info *info;
>         int ret;
>
>         if (drm_WARN_ON(dev, !dev->driver->fbdev_probe))
> @@ -1635,12 +1627,6 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper)
>
>         strcpy(fb_helper->fb->comm, "[fbcon]");
>
> -       info = fb_helper->info;
> -
> -       /* Set the fb info for vgaswitcheroo clients. Does nothing otherwise. */
> -       if (dev_is_pci(info->device))
> -               vga_switcheroo_client_fb_set(to_pci_dev(info->device), info);
> -
>         return 0;
>  }
>
> diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
> index 7f35ad66b462..863944530c8e 100644
> --- a/drivers/video/fbdev/core/fbcon.c
> +++ b/drivers/video/fbdev/core/fbcon.c
> @@ -66,6 +66,7 @@
>  #include <linux/string.h>
>  #include <linux/kd.h>
>  #include <linux/panic.h>
> +#include <linux/pci.h>
>  #include <linux/printk.h>
>  #include <linux/slab.h>
>  #include <linux/fb.h>
> @@ -78,6 +79,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/crc32.h> /* For counting font checksums */
>  #include <linux/uaccess.h>
> +#include <linux/vga_switcheroo.h>
>  #include <asm/irq.h>
>
>  #include "fbcon.h"
> @@ -2894,6 +2896,9 @@ void fbcon_fb_unregistered(struct fb_info *info)
>
>         console_lock();
>
> +       if (info->device && dev_is_pci(info->device))
> +               vga_switcheroo_client_fb_set(to_pci_dev(info->device), NULL);
> +
>         fbcon_registered_fb[info->node] = NULL;
>         fbcon_num_registered_fb--;
>
> @@ -3027,6 +3032,10 @@ static int do_fb_registered(struct fb_info *info)
>                 }
>         }
>
> +       /* Set the fb info for vga_switcheroo clients. Does nothing otherwise. */
> +       if (info->device && dev_is_pci(info->device))
> +               vga_switcheroo_client_fb_set(to_pci_dev(info->device), info);
> +
>         return ret;
>  }
>
> --
> 2.51.1
>

^ permalink raw reply

* [PATCH 6/6] sysfb: Move edid_info into sysfb_primary_display
From: Thomas Zimmermann @ 2025-11-21 13:36 UTC (permalink / raw)
  To: ardb, javierm, arnd
  Cc: x86, linux-arm-kernel, linux-kernel, linux-efi, loongarch,
	linux-riscv, dri-devel, linux-hyperv, linux-pci, linux-fbdev,
	Thomas Zimmermann
In-Reply-To: <20251121135624.494768-1-tzimmermann@suse.de>

Move x86's edid_info into sysfb_primary_display as a new field named
edid. Adapt all users.

An instance of edid_info has only been defined on x86. With the move
into sysfb_primary_display, it becomes available on all architectures.
Therefore remove this contraint from CONFIG_FIRMWARE_EDID.

x86 fills the EDID data from boot_params.edid_info. DRM drivers pick
up the raw data and make it available to DRM clients. Replace the
drivers' references to edid_info and instead use the sysfb_display_info
as passed from sysfb.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 arch/x86/kernel/setup.c          | 6 +-----
 drivers/gpu/drm/sysfb/efidrm.c   | 5 ++---
 drivers/gpu/drm/sysfb/vesadrm.c  | 5 ++---
 drivers/video/Kconfig            | 1 -
 drivers/video/fbdev/core/fbmon.c | 8 +++++---
 include/linux/sysfb.h            | 6 ++++++
 include/video/edid.h             | 4 ----
 7 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 675e4b9deb1f..d9bfe2032cd9 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -215,10 +215,6 @@ arch_initcall(init_x86_sysctl);
 
 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);
-#endif
 
 extern int root_mountflags;
 
@@ -530,7 +526,7 @@ static void __init parse_boot_params(void)
 	ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev);
 	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;
diff --git a/drivers/gpu/drm/sysfb/efidrm.c b/drivers/gpu/drm/sysfb/efidrm.c
index 29533ae8fbbf..50e0aeef709c 100644
--- a/drivers/gpu/drm/sysfb/efidrm.c
+++ b/drivers/gpu/drm/sysfb/efidrm.c
@@ -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"
@@ -207,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;
diff --git a/drivers/gpu/drm/sysfb/vesadrm.c b/drivers/gpu/drm/sysfb/vesadrm.c
index 16fc223f8c5b..0680638b8131 100644
--- a/drivers/gpu/drm/sysfb/vesadrm.c
+++ b/drivers/gpu/drm/sysfb/vesadrm.c
@@ -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>
 
@@ -474,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;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d51777df12d1..ad55e7d62159 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -63,7 +63,6 @@ endif # HAS_IOMEM
 
 config FIRMWARE_EDID
 	bool "Enable firmware EDID"
-	depends on X86
 	help
 	  This enables access to the EDID transferred from the firmware.
 	  On x86, this is from the VESA BIOS. DRM display drivers will
diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c
index 0a65bef01e3c..07df7e98f8a3 100644
--- a/drivers/video/fbdev/core/fbmon.c
+++ b/drivers/video/fbdev/core/fbmon.c
@@ -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;
 }
diff --git a/include/linux/sysfb.h b/include/linux/sysfb.h
index e8bde392c690..5226efde9ad4 100644
--- a/include/linux/sysfb.h
+++ b/include/linux/sysfb.h
@@ -12,6 +12,8 @@
 #include <linux/screen_info.h>
 #include <linux/types.h>
 
+#include <video/edid.h>
+
 struct device;
 struct platform_device;
 struct screen_info;
@@ -62,6 +64,10 @@ struct efifb_dmi_info {
 
 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;
diff --git a/include/video/edid.h b/include/video/edid.h
index c2b186b1933a..52aabb706032 100644
--- a/include/video/edid.h
+++ b/include/video/edid.h
@@ -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__ */
-- 
2.51.1


^ permalink raw reply related

* [PATCH 3/6] sysfb: Add struct sysfb_display_info
From: Thomas Zimmermann @ 2025-11-21 13:36 UTC (permalink / raw)
  To: ardb, javierm, arnd
  Cc: x86, linux-arm-kernel, linux-kernel, linux-efi, loongarch,
	linux-riscv, dri-devel, linux-hyperv, linux-pci, linux-fbdev,
	Thomas Zimmermann
In-Reply-To: <20251121135624.494768-1-tzimmermann@suse.de>

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 <tzimmermann@suse.de>
---
 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 <linux/err.h>
+#include <linux/screen_info.h>
 #include <linux/types.h>
 
 #include <linux/platform_data/simplefb.h>
@@ -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);
-- 
2.51.1


^ permalink raw reply related

* [PATCH 5/6] sysfb: Pass sysfb_primary_display to devices
From: Thomas Zimmermann @ 2025-11-21 13:36 UTC (permalink / raw)
  To: ardb, javierm, arnd
  Cc: x86, linux-arm-kernel, linux-kernel, linux-efi, loongarch,
	linux-riscv, dri-devel, linux-hyperv, linux-pci, linux-fbdev,
	Thomas Zimmermann
In-Reply-To: <20251121135624.494768-1-tzimmermann@suse.de>

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 <tzimmermann@suse.de>
---
 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 <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>
@@ -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 <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>
@@ -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 <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;
 
diff --git a/drivers/video/fbdev/vesafb.c b/drivers/video/fbdev/vesafb.c
index a81df8865143..10d3d9ae73aa 100644
--- a/drivers/video/fbdev/vesafb.c
+++ b/drivers/video/fbdev/vesafb.c
@@ -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;
 
diff --git a/drivers/video/fbdev/vga16fb.c b/drivers/video/fbdev/vga16fb.c
index eedab14c7d51..7853d84f10df 100644
--- a/drivers/video/fbdev/vga16fb.c
+++ b/drivers/video/fbdev/vga16fb.c
@@ -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)
-- 
2.51.1


^ permalink raw reply related

* [PATCH 2/6] efi: sysfb_efi: Reduce number of references to global screen_info
From: Thomas Zimmermann @ 2025-11-21 13:36 UTC (permalink / raw)
  To: ardb, javierm, arnd
  Cc: x86, linux-arm-kernel, linux-kernel, linux-efi, loongarch,
	linux-riscv, dri-devel, linux-hyperv, linux-pci, linux-fbdev,
	Thomas Zimmermann
In-Reply-To: <20251121135624.494768-1-tzimmermann@suse.de>

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 <tzimmermann@suse.de>
---
 drivers/firmware/efi/sysfb_efi.c  | 81 ++++++++++++++++---------------
 drivers/firmware/sysfb.c          |  4 +-
 drivers/firmware/sysfb_simplefb.c |  2 +-
 include/linux/sysfb.h             |  9 ++--
 4 files changed, 51 insertions(+), 45 deletions(-)

diff --git a/drivers/firmware/efi/sysfb_efi.c b/drivers/firmware/efi/sysfb_efi.c
index 1e509595ac03..8e0f9d08397f 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),	\
@@ -284,12 +288,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);
@@ -311,7 +316,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;
@@ -349,25 +354,25 @@ 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)) {
-		u16 temp = screen_info.lfb_width;
+		u16 temp = si->lfb_width;
 
-		screen_info.lfb_width = screen_info.lfb_height;
-		screen_info.lfb_height = temp;
-		screen_info.lfb_linelength = 4 * screen_info.lfb_width;
+		si->lfb_width = si->lfb_height;
+		si->lfb_height = temp;
+		si->lfb_linelength = 4 * si->lfb_width;
 	}
 }
 
-__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)
 {
 }
 
-- 
2.51.1


^ permalink raw reply related

* [PATCH 4/6] sysfb: Replace screen_info with sysfb_primary_display
From: Thomas Zimmermann @ 2025-11-21 13:36 UTC (permalink / raw)
  To: ardb, javierm, arnd
  Cc: x86, linux-arm-kernel, linux-kernel, linux-efi, loongarch,
	linux-riscv, dri-devel, linux-hyperv, linux-pci, linux-fbdev,
	Thomas Zimmermann
In-Reply-To: <20251121135624.494768-1-tzimmermann@suse.de>

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 <tzimmermann@suse.de>
---
 arch/arm64/kernel/image-vars.h                |  2 +-
 arch/loongarch/kernel/efi.c                   | 11 ++++++-----
 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               | 14 +++++++-------
 drivers/firmware/efi/libstub/efi-stub-entry.c | 18 +++++++++++++-----
 drivers/firmware/efi/sysfb_efi.c              |  4 ++--
 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, 60 insertions(+), 47 deletions(-)

diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index 5369763606e7..a7867bd8cfb6 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 860a3bc030e0..b11188413f4d 100644
--- a/arch/loongarch/kernel/efi.c
+++ b/arch/loongarch/kernel/efi.c
@@ -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>
@@ -75,8 +75,8 @@ 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)
@@ -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)
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 <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;
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 <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,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 <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
diff --git a/drivers/firmware/efi/earlycon.c b/drivers/firmware/efi/earlycon.c
index fac3a295c57f..d63849457164 100644
--- a/drivers/firmware/efi/earlycon.c
+++ b/drivers/firmware/efi/earlycon.c
@@ -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,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..ced12c82d2a9 100644
--- a/drivers/firmware/efi/efi-init.c
+++ b/drivers/firmware/efi/efi-init.c
@@ -19,7 +19,7 @@
 #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>
 
@@ -61,8 +61,8 @@ extern __weak const efi_config_table_type_t efi_arch_tables[];
  * everything else can get it 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)
@@ -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();
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 <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;
+
+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 8e0f9d08397f..46ad95084b50 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)		\
@@ -316,7 +316,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 69591dc7bad2..e7ebfa4cee45 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -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>
@@ -2282,8 +2282,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 <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
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 <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
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 <linux/err.h>
+#include <linux/platform_data/simplefb.h>
 #include <linux/screen_info.h>
 #include <linux/types.h>
 
-#include <linux/platform_data/simplefb.h>
-
 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);
-- 
2.51.1


^ permalink raw reply related

* [PATCH 1/6] efi: earlycon: Reduce number of references to global screen_info
From: Thomas Zimmermann @ 2025-11-21 13:36 UTC (permalink / raw)
  To: ardb, javierm, arnd
  Cc: x86, linux-arm-kernel, linux-kernel, linux-efi, loongarch,
	linux-riscv, dri-devel, linux-hyperv, linux-pci, linux-fbdev,
	Thomas Zimmermann
In-Reply-To: <20251121135624.494768-1-tzimmermann@suse.de>

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 <tzimmermann@suse.de>
---
 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..fac3a295c57f 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;
-- 
2.51.1


^ permalink raw reply related

* [PATCH 0/6] arch,sysfb: Move screen and edid info into single place
From: Thomas Zimmermann @ 2025-11-21 13:36 UTC (permalink / raw)
  To: ardb, javierm, arnd
  Cc: x86, linux-arm-kernel, linux-kernel, linux-efi, loongarch,
	linux-riscv, dri-devel, linux-hyperv, linux-pci, linux-fbdev,
	Thomas Zimmermann

Replace screen_info and edid_info with sysfb_primary_device of type
struct sysfb_display_info. Update all users.

Sysfb DRM drivers currently fetch the global edid_info directly, when
they should get that information together with the screen_info from their
device. Wrapping screen_info and edid_info in sysfb_primary_display and
passing this to drivers enables this.

Replacing both with sysfb_primary_display has been motivate by the EFI
stub. EFI wants to transfer EDID via config table in a single entry.
Using struct sysfb_display_info this will become easily possible. Hence
accept some churn in architecture code for the long-term improvements.

Patches 1 and 2 reduce the exposure of screen_info in EFI-related code.

Patch 3 adds struct sysfb_display_info.

Patch 4 replaces scren_info with sysfb_primary_display. This results in
several changes throught the kernel, but is really just a refactoring.

Patch 5 updates sysfb to transfer sysfb_primary_display to the related
drivers.

Patch 6 moves edid_info into sysfb_primary_display. This resolves some
drivers' reference to the global edid_info, but also makes the EDID data
available on non-x86 architectures.

The short-term benefit of this series is in patches 5 and 6. With
sysfb_primary_display in place a follow-up series will improve EFI support
for EDID as outlined in the series at [1] and [2].

[1] https://lore.kernel.org/dri-devel/20251015160816.525825-1-tzimmermann@suse.de/
[2] https://lore.kernel.org/linux-efi/20251119123011.1187249-5-ardb+git@google.com/

Thomas Zimmermann (6):
  efi: earlycon: Reduce number of references to global screen_info
  efi: sysfb_efi: Reduce number of references to global screen_info
  sysfb: Add struct sysfb_display_info
  sysfb: Replace screen_info with sysfb_primary_display
  sysfb: Pass sysfb_primary_display to devices
  sysfb: Move edid_info into sysfb_primary_display

 arch/arm64/kernel/image-vars.h                |  2 +-
 arch/loongarch/kernel/efi.c                   | 11 +--
 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                       | 16 ++--
 arch/x86/video/video-common.c                 |  4 +-
 drivers/firmware/efi/earlycon.c               | 42 +++++-----
 drivers/firmware/efi/efi-init.c               | 14 ++--
 drivers/firmware/efi/libstub/efi-stub-entry.c | 18 +++--
 drivers/firmware/efi/sysfb_efi.c              | 81 ++++++++++---------
 drivers/firmware/sysfb.c                      | 13 +--
 drivers/firmware/sysfb_simplefb.c             |  2 +-
 drivers/gpu/drm/sysfb/efidrm.c                | 14 ++--
 drivers/gpu/drm/sysfb/vesadrm.c               | 14 ++--
 drivers/hv/vmbus_drv.c                        |  6 +-
 drivers/pci/vgaarb.c                          |  4 +-
 drivers/video/Kconfig                         |  1 -
 drivers/video/fbdev/core/fbmon.c              |  8 +-
 drivers/video/fbdev/efifb.c                   | 10 ++-
 drivers/video/fbdev/vesafb.c                  | 10 ++-
 drivers/video/fbdev/vga16fb.c                 |  8 +-
 drivers/video/screen_info_pci.c               |  5 +-
 include/linux/screen_info.h                   |  2 -
 include/linux/sysfb.h                         | 23 ++++--
 include/video/edid.h                          |  4 -
 26 files changed, 177 insertions(+), 143 deletions(-)


base-commit: 57e807d4454add8b60e8807ad1cf812141f34cdb
-- 
2.51.1


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox