4d7a83f02b2a4d486f4b4a7064da1fbbd591c8ea
[openwrt/openwrt.git] /
1 From bf41f32582df3ca5faab2cf2de15e5d4ff688822 Mon Sep 17 00:00:00 2001
2 From: Tim Gover <tim.gover@raspberrypi.com>
3 Date: Tue, 20 Oct 2020 11:55:37 +0100
4 Subject: [PATCH] firmware: raspberrypi: Add support for tryonce
5 reboot flag
6
7 Define a new mailbox (SET_REBOOT_FLAGS) which may be used to
8 pass optional flags to the Raspberry Pi firmware that changes
9 the behaviour of the bootloader and firmware during a reboot.
10
11 Currently this just defines the 'tryboot' flag which causes
12 the firmware to load tryboot.txt instead config.txt. This
13 alternate configuration file can be used to specify the
14 path of an alternate firmware and kernels allowing a fallback
15 mechanism to be implemented for OS upgrades.
16 ---
17 drivers/firmware/raspberrypi.c | 25 ++++++++++++++++++++--
18 include/soc/bcm2835/raspberrypi-firmware.h | 2 ++
19 2 files changed, 25 insertions(+), 2 deletions(-)
20
21 --- a/drivers/firmware/raspberrypi.c
22 +++ b/drivers/firmware/raspberrypi.c
23 @@ -190,6 +190,7 @@ static int rpi_firmware_notify_reboot(st
24 {
25 struct rpi_firmware *fw;
26 struct platform_device *pdev = g_pdev;
27 + u32 reboot_flags = 0;
28
29 if (!pdev)
30 return 0;
31 @@ -198,8 +199,28 @@ static int rpi_firmware_notify_reboot(st
32 if (!fw)
33 return 0;
34
35 - (void)rpi_firmware_property(fw, RPI_FIRMWARE_NOTIFY_REBOOT,
36 - 0, 0);
37 + // The partition id is the first parameter followed by zero or
38 + // more flags separated by spaces indicating the reason for the reboot.
39 + //
40 + // 'tryboot': Sets a one-shot flag which is cleared upon reboot and
41 + // causes the tryboot.txt to be loaded instead of config.txt
42 + // by the bootloader and the start.elf firmware.
43 + //
44 + // This is intended to allow automatic fallback to a known
45 + // good image if an OS/FW upgrade fails.
46 + //
47 + // N.B. The firmware mechanism for storing reboot flags may vary
48 + // on different Raspberry Pi models.
49 + if (data && strstr(data, " tryboot"))
50 + reboot_flags |= 0x1;
51 +
52 + // The mailbox might have been called earlier, directly via vcmailbox
53 + // so only overwrite if reboot flags are passed to the reboot command.
54 + if (reboot_flags)
55 + (void)rpi_firmware_property(fw, RPI_FIRMWARE_SET_REBOOT_FLAGS,
56 + &reboot_flags, sizeof(reboot_flags));
57 +
58 + (void)rpi_firmware_property(fw, RPI_FIRMWARE_NOTIFY_REBOOT, NULL, 0);
59
60 return 0;
61 }
62 --- a/include/soc/bcm2835/raspberrypi-firmware.h
63 +++ b/include/soc/bcm2835/raspberrypi-firmware.h
64 @@ -96,6 +96,8 @@ enum rpi_firmware_property_tag {
65 RPI_FIRMWARE_GET_POE_HAT_VAL = 0x00030049,
66 RPI_FIRMWARE_SET_POE_HAT_VAL = 0x00030050,
67 RPI_FIRMWARE_NOTIFY_XHCI_RESET = 0x00030058,
68 + RPI_FIRMWARE_GET_REBOOT_FLAGS = 0x00030064,
69 + RPI_FIRMWARE_SET_REBOOT_FLAGS = 0x00038064,
70
71 /* Dispmanx TAGS */
72 RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE = 0x00040001,