From: Sam Day <[email protected]>

The weak symbol currently implements `fastboot reboot` support using the
BCB. Nowadays, there's robust reboot-mode driver support which is ideal
for this use-case.

Signed-off-by: Sam Day <[email protected]>
---
 drivers/fastboot/Kconfig          |  7 ++++++
 drivers/fastboot/Makefile         |  1 +
 drivers/fastboot/fb_reboot_mode.c | 51 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+)

diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig
index 90212fcf9ef..a1586e79c7e 100644
--- a/drivers/fastboot/Kconfig
+++ b/drivers/fastboot/Kconfig
@@ -108,6 +108,13 @@ config FASTBOOT_UUU_SUPPORT
          feature if you are using verified boot, as it will allow an attacker
          to bypass any restrictions you have in place.
 
+config FASTBOOT_REBOOT_MODE
+       bool "Use reboot-mode for fastboot reboot commands"
+       depends on DM_REBOOT_MODE
+       help
+         Use a reboot-mode driver to implement fastboot reboot target flags
+         such as reboot-bootloader, reboot-fastboot and reboot-recovery.
+
 choice
        prompt "Flash provider for FASTBOOT"
        depends on FASTBOOT_FLASH
diff --git a/drivers/fastboot/Makefile b/drivers/fastboot/Makefile
index a341af076d1..531e694f393 100644
--- a/drivers/fastboot/Makefile
+++ b/drivers/fastboot/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_FASTBOOT_FLASH_BLOCK) += fb_block.o
 obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fb_block.o fb_mmc.o
 obj-$(CONFIG_FASTBOOT_FLASH_NAND) += fb_nand.o
 obj-$(CONFIG_FASTBOOT_FLASH_SPI) += fb_spi_flash.o
+obj-$(CONFIG_FASTBOOT_REBOOT_MODE) += fb_reboot_mode.o
diff --git a/drivers/fastboot/fb_reboot_mode.c 
b/drivers/fastboot/fb_reboot_mode.c
new file mode 100644
index 00000000000..abf4066f1f5
--- /dev/null
+++ b/drivers/fastboot/fb_reboot_mode.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <dm.h>
+#include <dm/uclass.h>
+#include <errno.h>
+#include <fastboot.h>
+#include <reboot-mode/reboot-mode.h>
+#include <linux/kernel.h>
+
+static int fastboot_set_reboot_mode(const char *mode)
+{
+       struct udevice *dev;
+       int ret = -ENOENT;
+
+       uclass_foreach_dev_probe(UCLASS_REBOOT_MODE, dev)
+       {
+               ret = dm_reboot_mode_activate(dev, mode);
+               if (!ret || (ret != -ENOENT && ret != -ENOSYS))
+                       return ret;
+       }
+
+       return ret;
+}
+
+int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
+{
+       static const char *const
+               reboot_modes[FASTBOOT_REBOOT_REASONS_COUNT][2] = {
+                       [FASTBOOT_REBOOT_REASON_BOOTLOADER] = { "bootloader",
+                                                               NULL },
+                       [FASTBOOT_REBOOT_REASON_FASTBOOTD] = { "fastboot",
+                                                              "bootloader" },
+                       [FASTBOOT_REBOOT_REASON_RECOVERY] = { "recovery",
+                                                             NULL },
+               };
+       int i, ret;
+
+       if (reason >= FASTBOOT_REBOOT_REASONS_COUNT)
+               return -EINVAL;
+
+       for (i = 0; i < ARRAY_SIZE(reboot_modes[reason]); i++) {
+               if (!reboot_modes[reason][i])
+                       continue;
+
+               ret = fastboot_set_reboot_mode(reboot_modes[reason][i]);
+               if (!ret || (ret != -ENOENT && ret != -ENOSYS))
+                       return ret;
+       }
+
+       return -ENOENT;
+}

-- 
2.54.0


Reply via email to