summaryrefslogtreecommitdiffstats
path: root/drivers/firmware/sysfb.c
diff options
context:
space:
mode:
authorJavier Martinez Canillas <javierm@redhat.com>2021-06-25 15:09:46 +0200
committerThomas Zimmermann <tzimmermann@suse.de>2021-07-21 12:04:56 +0200
commitd391c58271072d0b0fad93c82018d495b2633448 (patch)
tree3988519a245873dcc3311434ad89f438a952e26a /drivers/firmware/sysfb.c
parentvgaarb: don't pass a cookie to vga_client_register (diff)
downloadlinux-d391c58271072d0b0fad93c82018d495b2633448.tar.xz
linux-d391c58271072d0b0fad93c82018d495b2633448.zip
drivers/firmware: move x86 Generic System Framebuffers support
The x86 architecture has generic support to register a system framebuffer platform device. It either registers a "simple-framebuffer" if the config option CONFIG_X86_SYSFB is enabled, or a legacy VGA/VBE/EFI FB device. But the code is generic enough to be reused by other architectures and can be moved out of the arch/x86 directory. This will allow to also support the simple{fb,drm} drivers on non-x86 EFI platforms, such as aarch64 where these drivers are only supported with DT. Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Borislav Petkov <bp@suse.de> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20210625130947.1803678-2-javierm@redhat.com
Diffstat (limited to 'drivers/firmware/sysfb.c')
-rw-r--r--drivers/firmware/sysfb.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c
new file mode 100644
index 000000000000..1337515963d5
--- /dev/null
+++ b/drivers/firmware/sysfb.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Generic System Framebuffers on x86
+ * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com>
+ */
+
+/*
+ * Simple-Framebuffer support for x86 systems
+ * Create a platform-device for any available boot framebuffer. The
+ * simple-framebuffer platform device is already available on DT systems, so
+ * this module parses the global "screen_info" object and creates a suitable
+ * platform device compatible with the "simple-framebuffer" DT object. If
+ * the framebuffer is incompatible, we instead create a legacy
+ * "vesa-framebuffer", "efi-framebuffer" or "platform-framebuffer" device and
+ * pass the screen_info as platform_data. This allows legacy drivers
+ * to pick these devices up without messing with simple-framebuffer drivers.
+ * The global "screen_info" is still valid at all times.
+ *
+ * If CONFIG_X86_SYSFB is not selected, we never register "simple-framebuffer"
+ * platform devices, but only use legacy framebuffer devices for
+ * backwards compatibility.
+ *
+ * TODO: We set the dev_id field of all platform-devices to 0. This allows
+ * other x86 OF/DT parsers to create such devices, too. However, they must
+ * start at offset 1 for this to work.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/platform_data/simplefb.h>
+#include <linux/platform_device.h>
+#include <linux/screen_info.h>
+#include <linux/sysfb.h>
+
+static __init int sysfb_init(void)
+{
+ struct screen_info *si = &screen_info;
+ struct simplefb_platform_data mode;
+ struct platform_device *pd;
+ const char *name;
+ bool compatible;
+ int ret;
+
+ sysfb_apply_efi_quirks();
+
+ /* try to create a simple-framebuffer device */
+ compatible = parse_mode(si, &mode);
+ if (compatible) {
+ ret = create_simplefb(si, &mode);
+ if (!ret)
+ return 0;
+ }
+
+ /* if the FB is incompatible, create a legacy framebuffer device */
+ if (si->orig_video_isVGA == VIDEO_TYPE_EFI)
+ name = "efi-framebuffer";
+ else if (si->orig_video_isVGA == VIDEO_TYPE_VLFB)
+ name = "vesa-framebuffer";
+ else
+ name = "platform-framebuffer";
+
+ pd = platform_device_register_resndata(NULL, name, 0,
+ NULL, 0, si, sizeof(*si));
+ return PTR_ERR_OR_ZERO(pd);
+}
+
+/* must execute after PCI subsystem for EFI quirks */
+device_initcall(sysfb_init);