[RFC PATCH] firmware: coreboot: Disable sysfb if Coreboot already provides a FB

From: Javier Martinez Canillas
Date: Thu Sep 12 2024 - 06:55:29 EST


On Coreboot platforms, a system framebuffer may be provided to the Linux
kernel by filling a LB_TAG_FRAMEBUFFER entry in the Coreboot table. But
it seems SeaBIOS payload can also provide a VGA mode in the boot params.

If that the case, early arch x86 boot code will fill the global struct
screen_info data.

The data is used by the Generic System Framebuffers (sysfb) framework to
add a platform device with platform data about the system framebuffer.

But if there is information about the system framebuffer in the Coreboot
table as well, the framebuffer_coreboot driver will also try to do the
same and add another device for the system framebuffer. This will fail
though because there's already a simple-framebuffer.0 device registered:

sysfs: cannot create duplicate filename '/bus/platform/devices/simple-framebuffer.0'
...
coreboot: could not register framebuffer
framebuffer coreboot8: probe with driver framebuffer failed with error -17

To prevent the issue, make the framebuffer_core driver to disable sysfb
if there is system framebuffer data in the Coreboot table. That way only
this driver will register a device and sysfb would not attempt to do it
(or remove its registered device if was already executed before).

Reported-by: Brian Norris <briannorris@xxxxxxxxxxxx>
Link: https://lore.kernel.org/all/ZuCG-DggNThuF4pj@b20ea791c01f/T/#ma7fb65acbc1a56042258adac910992bb225a20d2
Suggested-by: Thomas Zimmermann <tzimmermann@xxxxxxx>
Signed-off-by: Javier Martinez Canillas <javierm@xxxxxxxxxx>
---
drivers/firmware/google/framebuffer-coreboot.c | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/drivers/firmware/google/framebuffer-coreboot.c b/drivers/firmware/google/framebuffer-coreboot.c
index daadd71d8ddd..0a28aa5b17dc 100644
--- a/drivers/firmware/google/framebuffer-coreboot.c
+++ b/drivers/firmware/google/framebuffer-coreboot.c
@@ -61,6 +61,19 @@ static int framebuffer_probe(struct coreboot_device *dev)
if (res.end <= res.start)
return -EINVAL;

+ /*
+ * Since a "simple-framebuffer" device is already added
+ * here, disable the Generic System Framebuffers (sysfb)
+ * to prevent it from registering another device for the
+ * system framebuffer later (e.g: using the screen_info
+ * data that may had been filled as well).
+ *
+ * This can happen for example on Coreboot systems, that
+ * advertise a LB_TAG_FRAMEBUFFER entry in their Coreboot
+ * table and also a VESA mode by the BIOS used as payload.
+ */
+ sysfb_disable();
+
pdev = platform_device_register_resndata(&dev->dev,
"simple-framebuffer", 0,
&res, 1, &pdata,
--

Best regards,

Javier Martinez Canillas
Core Platforms
Red Hat