summarylogtreecommitdiffstats
path: root/0010-bootsplash.patch
diff options
context:
space:
mode:
Diffstat (limited to '0010-bootsplash.patch')
-rw-r--r--0010-bootsplash.patch342
1 files changed, 18 insertions, 324 deletions
diff --git a/0010-bootsplash.patch b/0010-bootsplash.patch
index 2785c5e6527..8a3b715ce46 100644
--- a/0010-bootsplash.patch
+++ b/0010-bootsplash.patch
@@ -1,327 +1,21 @@
-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;
- };
-
-
-@@ -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,
+diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
+index 3ffc1ce29023..bc6a24c9dfa8 100644
+--- a/drivers/tty/sysrq.c
++++ b/drivers/tty/sysrq.c
+@@ -49,6 +49,7 @@
+ #include <linux/syscalls.h>
+ #include <linux/of.h>
+ #include <linux/rcupdate.h>
++#include <linux/bootsplash.h>
+
+ #include <asm/ptrace.h>
+ #include <asm/irq_regs.h>
+@@ -104,6 +105,8 @@ static void sysrq_handle_SAK(int key)
{
- 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;
-+ }
+ struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
+ schedule_work(SAK_work);
+
- 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;
-
- 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;
- }
-
-+ 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);
- }
++ bootsplash_disable();
}
-+
-+
-+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;
-+ }
-+ }
-+}
-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
+ static struct sysrq_key_op sysrq_SAK_op = {
+ .handler = sysrq_handle_SAK,