diff options
Diffstat (limited to '0005-bootsplash.patch')
-rw-r--r-- | 0005-bootsplash.patch | 746 |
1 files changed, 0 insertions, 746 deletions
diff --git a/0005-bootsplash.patch b/0005-bootsplash.patch deleted file mode 100644 index 924f23f33ce9..000000000000 --- a/0005-bootsplash.patch +++ /dev/null @@ -1,746 +0,0 @@ -diff --git a/MAINTAINERS b/MAINTAINERS -index a74227ad082e..b5633b56391e 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -2705,6 +2705,14 @@ S: Supported - F: drivers/net/bonding/ - F: include/uapi/linux/if_bonding.h - -+BOOTSPLASH -+M: Max Staudt <mstaudt@suse.de> -+L: linux-fbdev@vger.kernel.org -+S: Maintained -+F: drivers/video/fbdev/core/bootsplash*.* -+F: drivers/video/fbdev/core/dummycon.c -+F: include/linux/bootsplash.h -+ - BPF (Safe dynamic programs and tools) - M: Alexei Starovoitov <ast@kernel.org> - M: Daniel Borkmann <daniel@iogearbox.net> -diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig -index 7f1f1fbcef9e..f3ff976266fe 100644 ---- a/drivers/video/console/Kconfig -+++ b/drivers/video/console/Kconfig -@@ -151,6 +151,30 @@ config FRAMEBUFFER_CONSOLE_ROTATION - such that other users of the framebuffer will remain normally - oriented. - -+config BOOTSPLASH -+ bool "Bootup splash screen" -+ depends on FRAMEBUFFER_CONSOLE -+ ---help--- -+ This option enables the Linux bootsplash screen. -+ -+ The bootsplash is a full-screen logo or animation indicating a -+ booting system. It replaces the classic scrolling text with a -+ graphical alternative, similar to other systems. -+ -+ Since this is technically implemented as a hook on top of fbcon, -+ it can only work if the FRAMEBUFFER_CONSOLE is enabled and a -+ framebuffer driver is active. Thus, to get a text-free boot, -+ the system needs to boot with vesafb, efifb, or similar. -+ -+ Once built into the kernel, the bootsplash needs to be enabled -+ with bootsplash.enabled=1 and a splash file needs to be supplied. -+ -+ Further documentation can be found in: -+ Documentation/fb/bootsplash.txt -+ -+ If unsure, say N. -+ This is typically used by distributors and system integrators. -+ - config STI_CONSOLE - bool "STI text console" - depends on PARISC -diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile -index 73493bbd7a15..66895321928e 100644 ---- a/drivers/video/fbdev/core/Makefile -+++ b/drivers/video/fbdev/core/Makefile -@@ -29,3 +29,6 @@ obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o - obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o - obj-$(CONFIG_FB_SVGALIB) += svgalib.o - obj-$(CONFIG_FB_DDC) += fb_ddc.o -+ -+obj-$(CONFIG_BOOTSPLASH) += bootsplash.o bootsplash_render.o \ -+ dummyblit.o -diff --git a/drivers/video/fbdev/core/bootsplash.c b/drivers/video/fbdev/core/bootsplash.c -new file mode 100644 -index 000000000000..e449755af268 ---- /dev/null -+++ b/drivers/video/fbdev/core/bootsplash.c -@@ -0,0 +1,294 @@ -+/* -+ * Kernel based bootsplash. -+ * -+ * (Main file: Glue code, workers, timer, PM, kernel and userland API) -+ * -+ * Authors: -+ * Max Staudt <mstaudt@suse.de> -+ * -+ * SPDX-License-Identifier: GPL-2.0 -+ */ -+ -+#define pr_fmt(fmt) "bootsplash: " fmt -+ -+ -+#include <linux/atomic.h> -+#include <linux/bootsplash.h> -+#include <linux/console.h> -+#include <linux/device.h> /* dev_warn() */ -+#include <linux/fb.h> -+#include <linux/fs.h> -+#include <linux/kernel.h> -+#include <linux/jiffies.h> -+#include <linux/module.h> -+#include <linux/mutex.h> -+#include <linux/platform_device.h> -+#include <linux/printk.h> -+#include <linux/selection.h> /* console_blanked */ -+#include <linux/stringify.h> -+#include <linux/types.h> -+#include <linux/vmalloc.h> -+#include <linux/vt_kern.h> -+#include <linux/workqueue.h> -+ -+#include "bootsplash_internal.h" -+ -+ -+/* -+ * We only have one splash screen, so let's keep a single -+ * instance of the internal state. -+ */ -+static struct splash_priv splash_state; -+ -+ -+static void splash_callback_redraw_vc(struct work_struct *ignored) -+{ -+ if (console_blanked) -+ return; -+ -+ console_lock(); -+ if (vc_cons[fg_console].d) -+ update_screen(vc_cons[fg_console].d); -+ console_unlock(); -+} -+ -+ -+static bool is_fb_compatible(const struct fb_info *info) -+{ -+ if (!(info->flags & FBINFO_BE_MATH) -+ != !fb_be_math((struct fb_info *)info)) { -+ dev_warn(info->device, -+ "Can't draw on foreign endianness framebuffer.\n"); -+ -+ return false; -+ } -+ -+ if (info->flags & FBINFO_MISC_TILEBLITTING) { -+ dev_warn(info->device, -+ "Can't draw splash on tiling framebuffer.\n"); -+ -+ return false; -+ } -+ -+ if (info->fix.type != FB_TYPE_PACKED_PIXELS -+ || (info->fix.visual != FB_VISUAL_TRUECOLOR -+ && info->fix.visual != FB_VISUAL_DIRECTCOLOR)) { -+ dev_warn(info->device, -+ "Can't draw splash on non-packed or non-truecolor framebuffer.\n"); -+ -+ dev_warn(info->device, -+ " type: %u visual: %u\n", -+ info->fix.type, info->fix.visual); -+ -+ return false; -+ } -+ -+ if (info->var.bits_per_pixel != 16 -+ && info->var.bits_per_pixel != 24 -+ && info->var.bits_per_pixel != 32) { -+ dev_warn(info->device, -+ "We only support drawing on framebuffers with 16, 24, or 32 bpp, not %d.\n", -+ info->var.bits_per_pixel); -+ -+ return false; -+ } -+ -+ return true; -+} -+ -+ -+/* -+ * Called by fbcon_switch() when an instance is activated or refreshed. -+ */ -+void bootsplash_render_full(struct fb_info *info) -+{ -+ if (!is_fb_compatible(info)) -+ return; -+ -+ bootsplash_do_render_background(info); -+} -+ -+ -+/* -+ * External status enquiry and on/off switch -+ */ -+bool bootsplash_would_render_now(void) -+{ -+ return !oops_in_progress -+ && !console_blanked -+ && bootsplash_is_enabled(); -+} -+ -+bool bootsplash_is_enabled(void) -+{ -+ bool was_enabled; -+ -+ /* Make sure we have the newest state */ -+ smp_rmb(); -+ -+ was_enabled = test_bit(0, &splash_state.enabled); -+ -+ return was_enabled; -+} -+ -+void bootsplash_disable(void) -+{ -+ int was_enabled; -+ -+ was_enabled = test_and_clear_bit(0, &splash_state.enabled); -+ -+ if (was_enabled) { -+ if (oops_in_progress) { -+ /* Redraw screen now so we can see a panic */ -+ if (vc_cons[fg_console].d) -+ update_screen(vc_cons[fg_console].d); -+ } else { -+ /* No urgency, redraw at next opportunity */ -+ schedule_work(&splash_state.work_redraw_vc); -+ } -+ } -+} -+ -+void bootsplash_enable(void) -+{ -+ bool was_enabled; -+ -+ if (oops_in_progress) -+ return; -+ -+ was_enabled = test_and_set_bit(0, &splash_state.enabled); -+ -+ if (!was_enabled) -+ schedule_work(&splash_state.work_redraw_vc); -+} -+ -+ -+/* -+ * Userland API via platform device in sysfs -+ */ -+static ssize_t splash_show_enabled(struct device *dev, -+ struct device_attribute *attr, char *buf) -+{ -+ return sprintf(buf, "%d\n", bootsplash_is_enabled()); -+} -+ -+static ssize_t splash_store_enabled(struct device *device, -+ struct device_attribute *attr, -+ const char *buf, size_t count) -+{ -+ bool enable; -+ int err; -+ -+ if (!buf || !count) -+ return -EFAULT; -+ -+ err = kstrtobool(buf, &enable); -+ if (err) -+ return err; -+ -+ if (enable) -+ bootsplash_enable(); -+ else -+ bootsplash_disable(); -+ -+ return count; -+} -+ -+static DEVICE_ATTR(enabled, 0644, splash_show_enabled, splash_store_enabled); -+ -+ -+static struct attribute *splash_dev_attrs[] = { -+ &dev_attr_enabled.attr, -+ NULL -+}; -+ -+ATTRIBUTE_GROUPS(splash_dev); -+ -+ -+ -+ -+/* -+ * Power management fixup via platform device -+ * -+ * When the system is woken from sleep or restored after hibernating, we -+ * cannot expect the screen contents to still be present in video RAM. -+ * Thus, we have to redraw the splash if we're currently active. -+ */ -+static int splash_resume(struct device *device) -+{ -+ if (bootsplash_would_render_now()) -+ schedule_work(&splash_state.work_redraw_vc); -+ -+ return 0; -+} -+ -+static int splash_suspend(struct device *device) -+{ -+ cancel_work_sync(&splash_state.work_redraw_vc); -+ -+ return 0; -+} -+ -+ -+static const struct dev_pm_ops splash_pm_ops = { -+ .thaw = splash_resume, -+ .restore = splash_resume, -+ .resume = splash_resume, -+ .suspend = splash_suspend, -+ .freeze = splash_suspend, -+}; -+ -+static struct platform_driver splash_driver = { -+ .driver = { -+ .name = "bootsplash", -+ .pm = &splash_pm_ops, -+ }, -+}; -+ -+ -+/* -+ * Main init -+ */ -+void bootsplash_init(void) -+{ -+ int ret; -+ -+ /* Initialized already? */ -+ if (splash_state.splash_device) -+ return; -+ -+ -+ /* Register platform device to export user API */ -+ ret = platform_driver_register(&splash_driver); -+ if (ret) { -+ pr_err("platform_driver_register() failed: %d\n", ret); -+ goto err; -+ } -+ -+ splash_state.splash_device -+ = platform_device_alloc("bootsplash", 0); -+ -+ if (!splash_state.splash_device) -+ goto err_driver; -+ -+ splash_state.splash_device->dev.groups = splash_dev_groups; -+ -+ ret = platform_device_add(splash_state.splash_device); -+ if (ret) { -+ pr_err("platform_device_add() failed: %d\n", ret); -+ goto err_device; -+ } -+ -+ -+ INIT_WORK(&splash_state.work_redraw_vc, splash_callback_redraw_vc); -+ -+ return; -+ -+err_device: -+ platform_device_put(splash_state.splash_device); -+ splash_state.splash_device = NULL; -+err_driver: -+ platform_driver_unregister(&splash_driver); -+err: -+ pr_err("Failed to initialize.\n"); -+} -diff --git a/drivers/video/fbdev/core/bootsplash_internal.h b/drivers/video/fbdev/core/bootsplash_internal.h -new file mode 100644 -index 000000000000..b11da5cb90bf ---- /dev/null -+++ b/drivers/video/fbdev/core/bootsplash_internal.h -@@ -0,0 +1,55 @@ -+/* -+ * Kernel based bootsplash. -+ * -+ * (Internal data structures used at runtime) -+ * -+ * Authors: -+ * Max Staudt <mstaudt@suse.de> -+ * -+ * SPDX-License-Identifier: GPL-2.0 -+ */ -+ -+#ifndef __BOOTSPLASH_INTERNAL_H -+#define __BOOTSPLASH_INTERNAL_H -+ -+ -+#include <linux/types.h> -+#include <linux/fb.h> -+#include <linux/kernel.h> -+#include <linux/mutex.h> -+#include <linux/spinlock.h> -+ -+ -+/* -+ * Runtime types -+ */ -+struct splash_priv { -+ /* -+ * Enabled/disabled state, to be used with atomic bit operations. -+ * Bit 0: 0 = Splash hidden -+ * 1 = Splash shown -+ * -+ * Note: fbcon.c uses this twice, by calling -+ * bootsplash_would_render_now() in set_blitting_type() and -+ * in fbcon_switch(). -+ * This is racy, but eventually consistent: Turning the -+ * splash on/off will cause a redraw, which calls -+ * fbcon_switch(), which calls set_blitting_type(). -+ * So the last on/off toggle will make things consistent. -+ */ -+ unsigned long enabled; -+ -+ /* Our gateway to userland via sysfs */ -+ struct platform_device *splash_device; -+ -+ struct work_struct work_redraw_vc; -+}; -+ -+ -+ -+/* -+ * Rendering functions -+ */ -+void bootsplash_do_render_background(struct fb_info *info); -+ -+#endif -diff --git a/drivers/video/fbdev/core/bootsplash_render.c b/drivers/video/fbdev/core/bootsplash_render.c -new file mode 100644 -index 000000000000..4d7e0117f653 ---- /dev/null -+++ b/drivers/video/fbdev/core/bootsplash_render.c -@@ -0,0 +1,93 @@ -+/* -+ * Kernel based bootsplash. -+ * -+ * (Rendering functions) -+ * -+ * Authors: -+ * Max Staudt <mstaudt@suse.de> -+ * -+ * SPDX-License-Identifier: GPL-2.0 -+ */ -+ -+#define pr_fmt(fmt) "bootsplash: " fmt -+ -+ -+#include <linux/bootsplash.h> -+#include <linux/fb.h> -+#include <linux/kernel.h> -+#include <linux/printk.h> -+#include <linux/types.h> -+ -+#include "bootsplash_internal.h" -+ -+ -+ -+ -+/* -+ * Rendering: Internal drawing routines -+ */ -+ -+ -+/* -+ * Pack pixel into target format and do Big/Little Endian handling. -+ * This would be a good place to handle endianness conversion if necessary. -+ */ -+static inline u32 pack_pixel(const struct fb_var_screeninfo *dst_var, -+ u8 red, u8 green, u8 blue) -+{ -+ u32 dstpix; -+ -+ /* Quantize pixel */ -+ red = red >> (8 - dst_var->red.length); -+ green = green >> (8 - dst_var->green.length); -+ blue = blue >> (8 - dst_var->blue.length); -+ -+ /* Pack pixel */ -+ dstpix = red << (dst_var->red.offset) -+ | green << (dst_var->green.offset) -+ | blue << (dst_var->blue.offset); -+ -+ /* -+ * Move packed pixel to the beginning of the memory cell, -+ * so we can memcpy() it out easily -+ */ -+#ifdef __BIG_ENDIAN -+ switch (dst_var->bits_per_pixel) { -+ case 16: -+ dstpix <<= 16; -+ break; -+ case 24: -+ dstpix <<= 8; -+ break; -+ case 32: -+ break; -+ } -+#else -+ /* This is intrinsically unnecessary on Little Endian */ -+#endif -+ -+ return dstpix; -+} -+ -+ -+void bootsplash_do_render_background(struct fb_info *info) -+{ -+ unsigned int x, y; -+ u32 dstpix; -+ u32 dst_octpp = info->var.bits_per_pixel / 8; -+ -+ dstpix = pack_pixel(&info->var, -+ 0, -+ 0, -+ 0); -+ -+ for (y = 0; y < info->var.yres_virtual; y++) { -+ u8 *dstline = info->screen_buffer + (y * info->fix.line_length); -+ -+ for (x = 0; x < info->var.xres_virtual; x++) { -+ memcpy(dstline, &dstpix, dst_octpp); -+ -+ dstline += dst_octpp; -+ } -+ } -+} -diff --git a/drivers/video/fbdev/core/dummyblit.c b/drivers/video/fbdev/core/dummyblit.c -new file mode 100644 -index 000000000000..8c22ff92ce24 ---- /dev/null -+++ b/drivers/video/fbdev/core/dummyblit.c -@@ -0,0 +1,89 @@ -+/* -+ * linux/drivers/video/fbdev/core/dummyblit.c -- Dummy Blitting Operation -+ * -+ * Authors: -+ * Max Staudt <mstaudt@suse.de> -+ * -+ * These functions are used in place of blitblit/tileblit to suppress -+ * fbcon's text output while a splash is shown. -+ * -+ * Only suppressing actual rendering keeps the text buffer in the VC layer -+ * intact and makes it easy to switch back from the bootsplash to a full -+ * text console with a simple redraw (with the original functions in place). -+ * -+ * Based on linux/drivers/video/fbdev/core/bitblit.c -+ * and linux/drivers/video/fbdev/core/tileblit.c -+ * -+ * SPDX-License-Identifier: GPL-2.0 -+ */ -+ -+#include <linux/module.h> -+#include <linux/fb.h> -+#include <linux/vt_kern.h> -+#include <linux/console.h> -+#include <asm/types.h> -+#include "fbcon.h" -+ -+static void dummy_bmove(struct vc_data *vc, struct fb_info *info, int sy, -+ int sx, int dy, int dx, int height, int width) -+{ -+ ; -+} -+ -+static void dummy_clear(struct vc_data *vc, struct fb_info *info, int sy, -+ int sx, int height, int width) -+{ -+ ; -+} -+ -+static void dummy_putcs(struct vc_data *vc, struct fb_info *info, -+ const unsigned short *s, int count, int yy, int xx, -+ int fg, int bg) -+{ -+ ; -+} -+ -+static void dummy_clear_margins(struct vc_data *vc, struct fb_info *info, -+ int color, int bottom_only) -+{ -+ ; -+} -+ -+static void dummy_cursor(struct vc_data *vc, struct fb_info *info, int mode, -+ int softback_lines, int fg, int bg) -+{ -+ ; -+} -+ -+static int dummy_update_start(struct fb_info *info) -+{ -+ /* -+ * Copied from bitblit.c and tileblit.c -+ * -+ * As of Linux 4.12, nobody seems to care about our return value. -+ */ -+ struct fbcon_ops *ops = info->fbcon_par; -+ int err; -+ -+ err = fb_pan_display(info, &ops->var); -+ ops->var.xoffset = info->var.xoffset; -+ ops->var.yoffset = info->var.yoffset; -+ ops->var.vmode = info->var.vmode; -+ return err; -+} -+ -+void fbcon_set_dummyops(struct fbcon_ops *ops) -+{ -+ ops->bmove = dummy_bmove; -+ ops->clear = dummy_clear; -+ ops->putcs = dummy_putcs; -+ ops->clear_margins = dummy_clear_margins; -+ ops->cursor = dummy_cursor; -+ ops->update_start = dummy_update_start; -+ ops->rotate_font = NULL; -+} -+EXPORT_SYMBOL_GPL(fbcon_set_dummyops); -+ -+MODULE_AUTHOR("Max Staudt <mstaudt@suse.de>"); -+MODULE_DESCRIPTION("Dummy Blitting Operation"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c -index 04612f938bab..9a39a6fcfe98 100644 ---- a/drivers/video/fbdev/core/fbcon.c -+++ b/drivers/video/fbdev/core/fbcon.c -@@ -80,6 +80,7 @@ - #include <asm/irq.h> - - #include "fbcon.h" -+#include <linux/bootsplash.h> - - #ifdef FBCONDEBUG - # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args) -@@ -542,6 +543,8 @@ static int do_fbcon_takeover(int show_logo) - for (i = first_fb_vc; i <= last_fb_vc; i++) - con2fb_map[i] = info_idx; - -+ bootsplash_init(); -+ - err = do_take_over_console(&fb_con, first_fb_vc, last_fb_vc, - fbcon_is_default); - -@@ -661,6 +664,9 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info) - else { - fbcon_set_rotation(info); - fbcon_set_bitops(ops); -+ -+ if (bootsplash_would_render_now()) -+ fbcon_set_dummyops(ops); - } - } - -@@ -683,6 +689,19 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info) - ops->p = &fb_display[vc->vc_num]; - fbcon_set_rotation(info); - fbcon_set_bitops(ops); -+ -+ /* -+ * Note: -+ * This is *eventually correct*. -+ * Setting the fbcon operations and drawing the splash happen at -+ * different points in time. If the splash is enabled/disabled -+ * in between, then bootsplash_{en,dis}able will schedule a -+ * redraw, which will again render the splash (or not) and set -+ * the correct fbcon ops. -+ * The last run will then be the right one. -+ */ -+ if (bootsplash_would_render_now()) -+ fbcon_set_dummyops(ops); - } - - static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount) -@@ -2184,6 +2203,9 @@ static int fbcon_switch(struct vc_data *vc) - info = registered_fb[con2fb_map[vc->vc_num]]; - ops = info->fbcon_par; - -+ if (bootsplash_would_render_now()) -+ bootsplash_render_full(info); -+ - if (softback_top) { - if (softback_lines) - fbcon_set_origin(vc); -diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h -index 18f3ac144237..45f94347fe5e 100644 ---- a/drivers/video/fbdev/core/fbcon.h -+++ b/drivers/video/fbdev/core/fbcon.h -@@ -214,6 +214,11 @@ static inline int attr_col_ec(int shift, struct vc_data *vc, - #define SCROLL_REDRAW 0x004 - #define SCROLL_PAN_REDRAW 0x005 - -+#ifdef CONFIG_BOOTSPLASH -+extern void fbcon_set_dummyops(struct fbcon_ops *ops); -+#else /* CONFIG_BOOTSPLASH */ -+#define fbcon_set_dummyops(x) -+#endif /* CONFIG_BOOTSPLASH */ - #ifdef CONFIG_FB_TILEBLITTING - extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info); - #endif -diff --git a/include/linux/bootsplash.h b/include/linux/bootsplash.h -new file mode 100644 -index 000000000000..c6dd0b43180d ---- /dev/null -+++ b/include/linux/bootsplash.h -@@ -0,0 +1,43 @@ -+/* -+ * Kernel based bootsplash. -+ * -+ * Authors: -+ * Max Staudt <mstaudt@suse.de> -+ * -+ * SPDX-License-Identifier: GPL-2.0 -+ */ -+ -+#ifndef __LINUX_BOOTSPLASH_H -+#define __LINUX_BOOTSPLASH_H -+ -+#include <linux/fb.h> -+ -+ -+#ifdef CONFIG_BOOTSPLASH -+ -+extern void bootsplash_render_full(struct fb_info *info); -+ -+extern bool bootsplash_would_render_now(void); -+ -+extern bool bootsplash_is_enabled(void); -+extern void bootsplash_disable(void); -+extern void bootsplash_enable(void); -+ -+extern void bootsplash_init(void); -+ -+#else /* CONFIG_BOOTSPLASH */ -+ -+#define bootsplash_render_full(x) -+ -+#define bootsplash_would_render_now() (false) -+ -+#define bootsplash_is_enabled() (false) -+#define bootsplash_disable() -+#define bootsplash_enable() -+ -+#define bootsplash_init() -+ -+#endif /* CONFIG_BOOTSPLASH */ -+ -+ -+#endif |