[PATCH 1/8] reboot-mode: parse up to 3 magic cells per mode

Balaji Selvanathan via U-Boot <[email protected]>
Newsgroups org.u-boot-project.lists.u-boot
Message-ID <20260811-b4-reset-edl-rebootmode-v1-1-2e15adc156a3@oss.qualcomm.com>
The reboot-mode framework currently stores a single u32 magic value per
mode and parses exactly one cell from each "mode-*" device tree property.
That is sufficient for the existing backing-store users (nvmem, gpio,
rtc), but a PSCI SYSTEM_RESET2 vendor reset is described by up to three
32-bit cells: <reset_type[, cookie_hi[, cookie_lo]]>, matching the
reboot-mode binding for the psci "reboot-mode" subnode.

Restructure struct reboot_mode_mode to hold an array of up to
REBOOT_MODE_MAX_MAGIC (3) cells plus a cell count, and make
dm_reboot_mode_pre_probe() length-aware so it reads 1 to 3 cells from
each property. dm_reboot_mode_update() now matches the backing-store
value against magic[0].

Existing single-cell modes (e.g. nvmem "mode-bootloader = <0x02>") parse
to magic[0] = 0x02, count = 1 and keep matching exactly as before, so
there is no functional change for current users.

Signed-off-by: Balaji Selvanathan <[email protected]>
---
 drivers/reboot-mode/reboot-mode-uclass.c | 28 ++++++++++++++++++++++------
 include/reboot-mode/reboot-mode.h        |  8 +++++++-
 2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/drivers/reboot-mode/reboot-mode-uclass.c b/drivers/reboot-mode/reboot-mode-uclass.c
index 7cbe02eb4ed..80aabf54750 100644
--- a/drivers/reboot-mode/reboot-mode-uclass.c
+++ b/drivers/reboot-mode/reboot-mode-uclass.c
@@ -30,7 +30,7 @@ int dm_reboot_mode_update(struct udevice *dev)
 		dev_get_uclass_plat(dev);
 
 	for (i = 0; i < plat_data->count; i++) {
-		if (plat_data->modes[i].mode_id == rebootmode) {
+		if (plat_data->modes[i].magic[0] == rebootmode) {
 			ret = env_set(plat_data->env_variable,
 				      plat_data->modes[i].mode_name);
 			if (ret) {
@@ -68,6 +68,7 @@ int dm_reboot_mode_pre_probe(struct udevice *dev)
 	struct ofprop property;
 	const u32 *propvalue;
 	const char *propname;
+	int len, cells, i;
 
 	plat_data->env_variable = dev_read_string(dev, "u-boot,env-variable");
 	if (!plat_data->env_variable)
@@ -93,19 +94,34 @@ int dm_reboot_mode_pre_probe(struct udevice *dev)
 	struct reboot_mode_mode *next = plat_data->modes;
 
 	dev_for_each_property(property, dev) {
-		propvalue = dev_read_prop_by_prop(&property, &propname, NULL);
+		propvalue = dev_read_prop_by_prop(&property, &propname, &len);
 		if (!propvalue) {
 			dev_err(dev, "Could not get the value for property %s\n",
 				propname);
 			return -EINVAL;
 		}
 
-		if (!strncmp(propname, mode_prefix, mode_prefix_len)) {
-			next->mode_name = &propname[mode_prefix_len];
-			next->mode_id = fdt32_to_cpu(*propvalue);
+		if (strncmp(propname, mode_prefix, mode_prefix_len))
+			continue;
 
-			next++;
+		/*
+		 * A mode may carry 1 to REBOOT_MODE_MAX_MAGIC 32-bit cells.
+		 * Cells beyond the maximum are ignored.
+		 */
+		cells = len / sizeof(u32);
+		if (cells < 1) {
+			dev_err(dev, "Mode %s has no magic value\n", propname);
+			return -EINVAL;
 		}
+		if (cells > REBOOT_MODE_MAX_MAGIC)
+			cells = REBOOT_MODE_MAX_MAGIC;
+
+		next->mode_name = &propname[mode_prefix_len];
+		next->count = cells;
+		for (i = 0; i < cells; i++)
+			next->magic[i] = fdt32_to_cpu(propvalue[i]);
+
+		next++;
 	}
 #else
 	if (!plat_data->env_variable)
diff --git a/include/reboot-mode/reboot-mode.h b/include/reboot-mode/reboot-mode.h
index 5fbd7c801af..54a8c09650e 100644
--- a/include/reboot-mode/reboot-mode.h
+++ b/include/reboot-mode/reboot-mode.h
@@ -9,9 +9,15 @@
 #include <asm/types.h>
 #include <dm/device.h>
 
+/*
+ * Maximum number of 32-bit magic cells a reboot mode may carry.
+ */
+#define REBOOT_MODE_MAX_MAGIC	3
+
 struct reboot_mode_mode {
 	const char *mode_name;
-	u32 mode_id;
+	u32 magic[REBOOT_MODE_MAX_MAGIC];
+	u8 count;
 };
 
 struct reboot_mode_uclass_platdata {

-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.