diff options
Diffstat (limited to '0011-bootsplash.patch')
-rw-r--r--[-rwxr-xr-x] | 0011-bootsplash.patch | 351 |
1 files changed, 33 insertions, 318 deletions
diff --git a/0011-bootsplash.patch b/0011-bootsplash.patch index 2785c5e65277..e8cd479312be 100755..100644 --- a/0011-bootsplash.patch +++ b/0011-bootsplash.patch @@ -1,327 +1,42 @@ -diff --git a/drivers/video/fbdev/core/bootsplash.c b/drivers/video/fbdev/core/bootsplash.c -index 815b007f81ca..c8642142cfea 100644 ---- a/drivers/video/fbdev/core/bootsplash.c -+++ b/drivers/video/fbdev/core/bootsplash.c -@@ -53,6 +53,14 @@ static void splash_callback_redraw_vc(struct work_struct *ignored) - console_unlock(); - } - -+static void splash_callback_animation(struct work_struct *ignored) -+{ -+ if (bootsplash_would_render_now()) { -+ /* This will also re-schedule this delayed worker */ -+ splash_callback_redraw_vc(ignored); -+ } -+} -+ - - static bool is_fb_compatible(const struct fb_info *info) - { -@@ -103,17 +111,44 @@ static bool is_fb_compatible(const struct fb_info *info) - */ - void bootsplash_render_full(struct fb_info *info) - { -+ bool is_update = false; -+ - mutex_lock(&splash_state.data_lock); - -- if (!is_fb_compatible(info)) -- goto out; -+ /* -+ * If we've painted on this FB recently, we don't have to do -+ * the sanity checks and background drawing again. -+ */ -+ if (splash_state.splash_fb == info) -+ is_update = true; -+ -+ -+ if (!is_update) { -+ /* Check whether we actually support this FB. */ -+ splash_state.splash_fb = NULL; -+ -+ if (!is_fb_compatible(info)) -+ goto out; -+ -+ /* Draw the background only once */ -+ bootsplash_do_render_background(info, splash_state.file); - -- bootsplash_do_render_background(info, splash_state.file); -+ /* Mark this FB as last seen */ -+ splash_state.splash_fb = info; -+ } - -- bootsplash_do_render_pictures(info, splash_state.file); -+ bootsplash_do_render_pictures(info, splash_state.file, is_update); - - bootsplash_do_render_flush(info); - -+ bootsplash_do_step_animations(splash_state.file); -+ -+ /* Schedule update for animated splash screens */ -+ if (splash_state.file->frame_ms > 0) -+ schedule_delayed_work(&splash_state.dwork_animation, -+ msecs_to_jiffies( -+ splash_state.file->frame_ms)); -+ - out: - mutex_unlock(&splash_state.data_lock); - } -@@ -169,8 +204,14 @@ void bootsplash_enable(void) - - was_enabled = test_and_set_bit(0, &splash_state.enabled); - -- if (!was_enabled) -+ if (!was_enabled) { -+ /* Force a full redraw when the splash is re-activated */ -+ mutex_lock(&splash_state.data_lock); -+ splash_state.splash_fb = NULL; -+ mutex_unlock(&splash_state.data_lock); -+ - schedule_work(&splash_state.work_redraw_vc); -+ } - } - - -@@ -227,6 +268,14 @@ ATTRIBUTE_GROUPS(splash_dev); - */ - static int splash_resume(struct device *device) - { -+ /* -+ * Force full redraw on resume since we've probably lost the -+ * framebuffer's contents meanwhile -+ */ -+ mutex_lock(&splash_state.data_lock); -+ splash_state.splash_fb = NULL; -+ mutex_unlock(&splash_state.data_lock); -+ - if (bootsplash_would_render_now()) - schedule_work(&splash_state.work_redraw_vc); - -@@ -235,6 +284,7 @@ static int splash_resume(struct device *device) - - static int splash_suspend(struct device *device) - { -+ cancel_delayed_work_sync(&splash_state.dwork_animation); - cancel_work_sync(&splash_state.work_redraw_vc); - - return 0; -@@ -296,6 +346,8 @@ void bootsplash_init(void) - set_bit(0, &splash_state.enabled); - - INIT_WORK(&splash_state.work_redraw_vc, splash_callback_redraw_vc); -+ INIT_DELAYED_WORK(&splash_state.dwork_animation, -+ splash_callback_animation); - - - if (!splash_state.bootfile || !strlen(splash_state.bootfile)) -diff --git a/drivers/video/fbdev/core/bootsplash_internal.h b/drivers/video/fbdev/core/bootsplash_internal.h -index 0acb383aa4e3..b3a74835d90f 100644 ---- a/drivers/video/fbdev/core/bootsplash_internal.h -+++ b/drivers/video/fbdev/core/bootsplash_internal.h -@@ -37,6 +37,8 @@ struct splash_pic_priv { - - struct splash_blob_priv *blobs; - u16 blobs_loaded; -+ -+ u16 anim_nextframe; - }; - - -@@ -45,6 +47,12 @@ struct splash_file_priv { - const struct splash_file_header *header; - - struct splash_pic_priv *pics; -+ -+ /* -+ * A local copy of the frame delay in the header. -+ * We modify it to keep the code simple. -+ */ -+ u16 frame_ms; - }; +diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c +index f4166263bb3a..a248429194bb 100644 +--- a/drivers/tty/vt/keyboard.c ++++ b/drivers/tty/vt/keyboard.c +@@ -47,6 +47,8 @@ + #include <asm/irq_regs.h> -@@ -71,6 +79,7 @@ struct splash_priv { - struct platform_device *splash_device; - - struct work_struct work_redraw_vc; -+ struct delayed_work dwork_animation; - - /* Splash data structures including lock for everything below */ - struct mutex data_lock; -@@ -88,8 +97,10 @@ struct splash_priv { - void bootsplash_do_render_background(struct fb_info *info, - const struct splash_file_priv *fp); - void bootsplash_do_render_pictures(struct fb_info *info, -- const struct splash_file_priv *fp); -+ const struct splash_file_priv *fp, -+ bool is_update); - void bootsplash_do_render_flush(struct fb_info *info); -+void bootsplash_do_step_animations(struct splash_file_priv *fp); - - - void bootsplash_free_file(struct splash_file_priv *fp); -diff --git a/drivers/video/fbdev/core/bootsplash_load.c b/drivers/video/fbdev/core/bootsplash_load.c -index fd807571ab7d..1f661b2d4cc9 100644 ---- a/drivers/video/fbdev/core/bootsplash_load.c -+++ b/drivers/video/fbdev/core/bootsplash_load.c -@@ -71,6 +71,7 @@ struct splash_file_priv *bootsplash_load_firmware(struct device *device, - { - const struct firmware *fw; - struct splash_file_priv *fp; -+ bool have_anim = false; - unsigned int i; - const u8 *walker; - -@@ -135,6 +136,13 @@ struct splash_file_priv *bootsplash_load_firmware(struct device *device, - goto err; - } - -+ if (ph->anim_type > SPLASH_ANIM_LOOP_FORWARD) { -+ pr_warn("Picture %u: Unsupported animation type %u.\n", -+ i, ph->anim_type); -+ -+ ph->anim_type = SPLASH_ANIM_NONE; -+ } ++#include <linux/bootsplash.h> + - pp->pic_header = ph; - pp->blobs = vzalloc(ph->num_blobs - * sizeof(struct splash_blob_priv)); -@@ -202,6 +210,7 @@ struct splash_file_priv *bootsplash_load_firmware(struct device *device, - /* Walk over pictures and ensure all blob slots are filled */ - for (i = 0; i < fp->header->num_pics; i++) { - struct splash_pic_priv *pp = &fp->pics[i]; -+ const struct splash_pic_header *ph = pp->pic_header; + extern void ctrl_alt_del(void); - if (pp->blobs_loaded != pp->pic_header->num_blobs) { - pr_err("Picture %u doesn't have all blob slots filled.\n", -@@ -209,8 +218,20 @@ struct splash_file_priv *bootsplash_load_firmware(struct device *device, - - goto err; - } -+ -+ if (ph->anim_type -+ && ph->num_blobs > 1 -+ && ph->anim_loop < pp->blobs_loaded) -+ have_anim = true; + /* +@@ -1353,6 +1355,28 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) } + #endif -+ if (!have_anim) -+ /* Disable animation timer if there is nothing to animate */ -+ fp->frame_ms = 0; -+ else -+ /* Enforce minimum delay between frames */ -+ fp->frame_ms = max((u16)20, fp->header->frame_ms); -+ - pr_info("Loaded (%ld bytes, %u pics, %u blobs).\n", - fw->size, - fp->header->num_pics, -diff --git a/drivers/video/fbdev/core/bootsplash_render.c b/drivers/video/fbdev/core/bootsplash_render.c -index 07e3a4eab811..76033606ca8a 100644 ---- a/drivers/video/fbdev/core/bootsplash_render.c -+++ b/drivers/video/fbdev/core/bootsplash_render.c -@@ -148,7 +148,8 @@ void bootsplash_do_render_background(struct fb_info *info, - - - void bootsplash_do_render_pictures(struct fb_info *info, -- const struct splash_file_priv *fp) -+ const struct splash_file_priv *fp, -+ bool is_update) - { - unsigned int i; - -@@ -161,7 +162,11 @@ void bootsplash_do_render_pictures(struct fb_info *info, - if (pp->blobs_loaded < 1) - continue; - -- bp = &pp->blobs[0]; -+ /* Skip static pictures when refreshing animations */ -+ if (ph->anim_type == SPLASH_ANIM_NONE && is_update) -+ continue; -+ -+ bp = &pp->blobs[pp->anim_nextframe]; - - if (!bp || bp->blob_header->type != 0) - continue; -@@ -351,3 +356,24 @@ void bootsplash_do_render_flush(struct fb_info *info) - info->fbops->fb_copyarea(info, &area); - } - } -+ -+ -+void bootsplash_do_step_animations(struct splash_file_priv *fp) -+{ -+ unsigned int i; -+ -+ /* Step every animation once */ -+ for (i = 0; i < fp->header->num_pics; i++) { -+ struct splash_pic_priv *pp = &fp->pics[i]; -+ -+ if (pp->blobs_loaded < 2 -+ || pp->pic_header->anim_loop > pp->blobs_loaded) -+ continue; -+ -+ if (pp->pic_header->anim_type == SPLASH_ANIM_LOOP_FORWARD) { -+ pp->anim_nextframe++; -+ if (pp->anim_nextframe >= pp->pic_header->num_blobs) -+ pp->anim_nextframe = pp->pic_header->anim_loop; ++ /* Trap keys when bootsplash is shown */ ++ if (bootsplash_would_render_now()) { ++ /* Deactivate bootsplash on ESC or Alt+Fxx VT switch */ ++ if (keycode >= KEY_F1 && keycode <= KEY_F12) { ++ bootsplash_disable(); ++ ++ /* ++ * No return here since we want to actually ++ * perform the VT switch. ++ */ ++ } else { ++ if (keycode == KEY_ESC) ++ bootsplash_disable(); ++ ++ /* ++ * Just drop any other keys. ++ * Their effect would be hidden by the splash. ++ */ ++ return; + } + } -+} -diff --git a/include/uapi/linux/bootsplash_file.h b/include/uapi/linux/bootsplash_file.h -index 71cedcc68933..b3af0a3c6487 100644 ---- a/include/uapi/linux/bootsplash_file.h -+++ b/include/uapi/linux/bootsplash_file.h -@@ -77,7 +77,17 @@ struct splash_file_header { - uint16_t num_blobs; - uint8_t num_pics; - -- uint8_t padding[103]; -+ uint8_t unused_1; -+ -+ /* -+ * Milliseconds to wait before painting the next frame in -+ * an animation. -+ * This is actually a minimum, as the system is allowed to -+ * stall for longer between frames. -+ */ -+ uint16_t frame_ms; -+ -+ uint8_t padding[100]; - } __attribute__((__packed__)); - - -@@ -116,7 +126,23 @@ struct splash_pic_header { - */ - uint16_t position_offset; - -- uint8_t padding[24]; -+ /* -+ * Animation type. -+ * 0 - off -+ * 1 - forward loop -+ */ -+ uint8_t anim_type; + -+ /* -+ * Animation loop point. -+ * Actual meaning depends on animation type: -+ * Type 0 - Unused -+ * 1 - Frame at which to restart the forward loop -+ * (allowing for "intro" frames) -+ */ -+ uint8_t anim_loop; -+ -+ uint8_t padding[22]; - } __attribute__((__packed__)); - - -@@ -158,4 +184,9 @@ enum splash_position { - SPLASH_POS_FLAG_CORNER = 0x10, - }; - -+enum splash_anim_type { -+ SPLASH_ANIM_NONE = 0, -+ SPLASH_ANIM_LOOP_FORWARD = 1, -+}; -+ - #endif + if (kbd->kbdmode == VC_MEDIUMRAW) { + /* + * This is extended medium raw mode, with keys above 127 |