Add a trigger-only reboot-mode backend and two device tree modes to the
sandbox test tree, then cover the new trigger path:

  - reboot_mode_request() fires the owning device's trigger op with the
    correct magic cells for both a 2-cell and a 1-cell mode;
  - an unknown mode, and a backing-store-only mode (gpio/rtc), both return
    -ENOENT because they are not triggerable;
  - reboot_mode_list() enumerates only the triggerable modes and hides the
    backing-store modes.

Signed-off-by: Balaji Selvanathan <[email protected]>
---
 arch/sandbox/dts/test.dts |  6 ++++
 test/dm/reboot-mode.c     | 87 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index d24feec5422..a060c3a8a94 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -209,6 +209,12 @@
                mode-download = <0x51939147>;
        };
 
+       reboot-mode-trigger {
+               compatible = "reboot-mode-test-trigger";
+               mode-obelisk = <0x80000000 0x00000001>;
+               mode-sarcophagus = <0x80000000>;
+       };
+
        audio: audio-codec {
                compatible = "sandbox,audio-codec";
                #sound-dai-cells = <1>;
diff --git a/test/dm/reboot-mode.c b/test/dm/reboot-mode.c
index 9a3b2bf0a43..7dbaea8c9cc 100644
--- a/test/dm/reboot-mode.c
+++ b/test/dm/reboot-mode.c
@@ -5,6 +5,7 @@
 
 #include <dm.h>
 #include <reboot-mode/reboot-mode.h>
+#include <console.h>
 #include <env.h>
 #include <log.h>
 #include <asm/gpio.h>
@@ -16,6 +17,42 @@
 #include <rtc.h>
 #include <linux/byteorder/generic.h>
 
+/*
+ * A trigger-only reboot-mode backend used to prove framework-driven dispatch
+ * and enumeration without touching hardware. Instead of resetting, its
+ * trigger() records the decoded magic cells so the test can inspect them.
+ */
+static u32 test_trigger_magic[REBOOT_MODE_MAX_MAGIC];
+static int test_trigger_count;
+
+static int test_trigger(struct udevice *dev, const u32 *magic, int count)
+{
+       int i;
+
+       test_trigger_count = count;
+       for (i = 0; i < count && i < REBOOT_MODE_MAX_MAGIC; i++)
+               test_trigger_magic[i] = magic[i];
+
+       /* A real backend does not return here; the test one does. */
+       return -EINPROGRESS;
+}
+
+static const struct reboot_mode_ops test_trigger_ops = {
+       .trigger = test_trigger,
+};
+
+static const struct udevice_id test_trigger_ids[] = {
+       { .compatible = "reboot-mode-test-trigger" },
+       { }
+};
+
+U_BOOT_DRIVER(reboot_mode_test_trigger) = {
+       .name = "reboot_mode_test_trigger",
+       .id = UCLASS_REBOOT_MODE,
+       .of_match = test_trigger_ids,
+       .ops = &test_trigger_ops,
+};
+
 static int dm_test_reboot_mode_gpio(struct unit_test_state *uts)
 {
        struct udevice *gpio_dev;
@@ -66,3 +103,53 @@ static int dm_test_reboot_mode_rtc(struct unit_test_state 
*uts)
 }
 DM_TEST(dm_test_reboot_mode_rtc,
        UTF_PROBE_TEST | UTF_SCAN_FDT | UTF_FLAT_TREE);
+
+/* reboot_mode_request() triggers a named mode with the right magic cells */
+static int dm_test_reboot_mode_request(struct unit_test_state *uts)
+{
+       test_trigger_count = 0;
+       test_trigger_magic[0] = 0;
+       test_trigger_magic[1] = 0;
+
+       /*
+        * "obelisk" is a 2-cell mode <0x80000000 0x00000001>. The trigger
+        * backend records the cells instead of resetting and returns
+        * -EINPROGRESS.
+        */
+       ut_asserteq(-EINPROGRESS, reboot_mode_request("obelisk"));
+       ut_asserteq(2, test_trigger_count);
+       ut_asserteq(0x80000000, test_trigger_magic[0]);
+       ut_asserteq(0x00000001, test_trigger_magic[1]);
+
+       /* "sarcophagus" is a 1-cell mode <0x80000000> */
+       test_trigger_count = 0;
+       ut_asserteq(-EINPROGRESS, reboot_mode_request("sarcophagus"));
+       ut_asserteq(1, test_trigger_count);
+       ut_asserteq(0x80000000, test_trigger_magic[0]);
+
+       /* An unknown mode, and a backing-store-only mode, are not triggerable 
*/
+       ut_asserteq(-ENOENT, reboot_mode_request("nonesuch"));
+       ut_asserteq(-ENOENT, reboot_mode_request("download"));
+
+       return 0;
+}
+DM_TEST(dm_test_reboot_mode_request,
+       UTF_PROBE_TEST | UTF_SCAN_FDT | UTF_FLAT_TREE);
+
+/* reboot_mode_list() enumerates only triggerable modes */
+static int dm_test_reboot_mode_list(struct unit_test_state *uts)
+{
+       ut_assertok(console_record_reset_enable());
+
+       ut_assertok(reboot_mode_list());
+
+       ut_assert_nextline("Available reset modes:");
+       ut_assert_nextline("  obelisk");
+       ut_assert_nextline("  sarcophagus");
+       /* Backing-store modes (test/download) have no trigger and are hidden */
+       ut_assert_console_end();
+
+       return 0;
+}
+DM_TEST(dm_test_reboot_mode_list,
+       UTF_PROBE_TEST | UTF_SCAN_FDT | UTF_FLAT_TREE);

-- 
2.34.1

Reply via email to