diff mbox

[U-Boot,5/7] sniper: Proper reboot mode and boot reason validation

Message ID 1459166834-26015-5-git-send-email-contact@paulk.fr
State Accepted
Commit c15ab5be8ff3d07b1afafac9f1e79b3e37ab8624
Delegated to: Tom Rini
Headers show

Commit Message

Paul Kocialkowski March 28, 2016, 12:07 p.m. UTC
With the previous implementation, rebooting without registering a recognized
reboot mode (despite registering the magic) would end up with U-Boot checking
for a valid power-on reason, which might result in the device turning off (e.g.
with no USB cable attached and no buttons pressed).

This was designed to catch reboots that are actually intended to be power-off,
something that old Android kernels do, instead of properly turning the device
off using the TWL4030.

However, since this approach is not viable (breaks reboot in most cases), the
validity of the reboot mode magic is checked to detect a reboot and the 'o' char
is recognized to indicate that power-off is required. Still, that might be
overridden by the detection of usual power-on reasons, on purpose.

Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
---
 board/lge/sniper/sniper.c | 33 +++++++++++++++++++++++----------
 1 file changed, 23 insertions(+), 10 deletions(-)

Comments

Tom Rini March 28, 2016, 2:06 p.m. UTC | #1
On Mon, Mar 28, 2016 at 02:07:12PM +0200, Paul Kocialkowski wrote:

> With the previous implementation, rebooting without registering a recognized
> reboot mode (despite registering the magic) would end up with U-Boot checking
> for a valid power-on reason, which might result in the device turning off (e.g.
> with no USB cable attached and no buttons pressed).
> 
> This was designed to catch reboots that are actually intended to be power-off,
> something that old Android kernels do, instead of properly turning the device
> off using the TWL4030.
> 
> However, since this approach is not viable (breaks reboot in most cases), the
> validity of the reboot mode magic is checked to detect a reboot and the 'o' char
> is recognized to indicate that power-off is required. Still, that might be
> overridden by the detection of usual power-on reasons, on purpose.
> 
> Signed-off-by: Paul Kocialkowski <contact@paulk.fr>

Reviewed-by: Tom Rini <trini@konsulko.com>
diff mbox

Patch

diff --git a/board/lge/sniper/sniper.c b/board/lge/sniper/sniper.c
index 29a7045..0662449 100644
--- a/board/lge/sniper/sniper.c
+++ b/board/lge/sniper/sniper.c
@@ -94,6 +94,7 @@  int misc_init_r(void)
 	char reboot_mode[2] = { 0 };
 	unsigned char keys[3];
 	unsigned char data = 0;
+	int rc;
 
 	/* Power button reset init */
 
@@ -109,22 +110,14 @@  int misc_init_r(void)
 
 	/* Reboot mode */
 
-	omap_reboot_mode(reboot_mode, sizeof(reboot_mode));
+	rc = omap_reboot_mode(reboot_mode, sizeof(reboot_mode));
 
 	if (keys[0])
 		reboot_mode[0] = 'r';
 	else if (keys[1])
 		reboot_mode[0] = 'b';
 
-	if (reboot_mode[0] > 0 && isascii(reboot_mode[0])) {
-		if (!getenv("reboot-mode"))
-			setenv("reboot-mode", (char *)reboot_mode);
-
-		omap_reboot_mode_clear();
-	} else {
-		/* Reboot mode garbage may still be valid, so clear it. */
-		omap_reboot_mode_clear();
-
+	if (rc < 0 || reboot_mode[0] == 'o') {
 		/*
 		 * When not rebooting, valid power on reasons are either the
 		 * power button, charger plug or USB plug.
@@ -138,6 +131,13 @@  int misc_init_r(void)
 			twl4030_power_off();
 	}
 
+	if (reboot_mode[0] > 0 && isascii(reboot_mode[0])) {
+		if (!getenv("reboot-mode"))
+			setenv("reboot-mode", (char *)reboot_mode);
+	}
+
+	omap_reboot_mode_clear();
+
 	/* Serial number */
 
 	omap_die_id_serial();
@@ -160,6 +160,19 @@  void get_board_serial(struct tag_serialnr *serialnr)
 	omap_die_id_get_board_serial(serialnr);
 }
 
+void reset_misc(void)
+{
+	char reboot_mode[2] = { 0 };
+
+	/*
+	 * Valid resets must contain the reboot mode magic, but we must not
+	 * override it when set previously (e.g. reboot to bootloader).
+	 */
+
+	omap_reboot_mode(reboot_mode, sizeof(reboot_mode));
+	omap_reboot_mode_store(reboot_mode);
+}
+
 int fb_set_reboot_flag(void)
 {
 	return omap_reboot_mode_store("b");