[PATCH v1 3/3] arm: snapdragon: Integrate OF_LIVE fixup handlers in ft_board_setup()

Aswin Murugan aswin.murugan at oss.qualcomm.com
Tue Jan 13 12:54:04 CET 2026


Integrate the device tree fixup handlers into ft_board_setup() to
enable runtime device tree modifications for Qualcomm Snapdragon
platforms.

This patch adds:

1. ft_board_setup() implementation
   - Calls all registered fixup handlers
   - Provides central point for device tree modifications
   - Executes before passing DT to kernel

2. soc_specific_fixups() function
   - Handles SoC-specific device tree modifications
   - Currently implements QCS615 MMC node disable
   - Extensible for future SoC-specific fixups

3. fixup_dt_node() utility function
   - Generic device tree node manipulation helper
   - Supports multiple operation types:
     * APPEND_PROP_U32/U64: Append 32/64-bit properties
     * SET_PROP_U32/U64/STRING: Set property values
     * ADD_SUBNODE: Add new device tree nodes
   - Automatically adjusts FDT size as needed

Signed-off-by: Aswin Murugan <aswin.murugan at oss.qualcomm.com>
---
 arch/arm/mach-snapdragon/of_fixup.c | 114 ++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c
index eec2c0c757e..1a74db51cae 100644
--- a/arch/arm/mach-snapdragon/of_fixup.c
+++ b/arch/arm/mach-snapdragon/of_fixup.c
@@ -26,6 +26,7 @@
 #include <linux/errno.h>
 #include <stdlib.h>
 #include <time.h>
+#include "qcom_fixup_handlers.h"
 
 /* U-Boot only supports USB high-speed mode on Qualcomm platforms with DWC3
  * USB controllers. Rather than requiring source level DT changes, we fix up
@@ -165,7 +166,120 @@ static int qcom_of_fixup_nodes(void * __maybe_unused ctx, struct event *event)
 
 EVENT_SPY_FULL(EVT_OF_LIVE_BUILT, qcom_of_fixup_nodes);
 
+/**
+ * soc_specific_fixups() - Apply SoC-specific device tree fixups
+ * @fdt: Pointer to the device tree
+ *
+ * This function applies SoC-specific fixups based on the device tree
+ * compatible string. Each SoC can have its own fixup logic.
+ */
+static void soc_specific_fixups(struct fdt_header *fdt)
+{
+	int ret;
+
+	/* QCS615-specific fixup: Disable MMC node */
+	if (fdt_node_check_compatible(fdt, 0, "qcom,qcs615") == 0) {
+		int path_offset;
+		char prop_val[] = "disabled";
+
+		path_offset = fdt_path_offset(fdt, "/soc at 0/mmc at 7c4000");
+		if (path_offset >= 0) {
+			ret = fixup_dt_node(fdt, path_offset, "status",
+					    (void *)prop_val, SET_PROP_STRING);
+			if (ret)
+				log_err("Failed to disable MMC node for QCS615: %d\n", ret);
+		}
+	}
+}
+
 int ft_board_setup(void __maybe_unused *blob, struct bd_info __maybe_unused *bd)
 {
+	struct fdt_header *fdt = blob;
+
+	/* Apply SoC-specific fixups */
+	soc_specific_fixups(fdt);
+
+	/* Call all common fixup handlers */
+	boardinfo_fixup_handler(fdt);
+	ddrinfo_fixup_handler(fdt);
+	subsetparts_fixup_handler(fdt);
+
 	return 0;
 }
+
+int fixup_dt_node(void *fdt_ptr, int node_offset,
+		  const char *property_name,
+		  void *property_value,
+		  enum fdt_fixup_type type)
+{
+	int ret;
+
+	if ((!fdt_ptr || node_offset < 0) ||
+	    (!property_value && type != ADD_SUBNODE))
+		return -1;
+
+	switch (type) {
+	case APPEND_PROP_U32:
+		fdt_set_totalsize(fdt_ptr,
+				  (fdt_totalsize(fdt_ptr)
+				  + sizeof(struct fdt_property)
+				  + strlen(property_name) + 3
+				  + sizeof(u32)));
+		ret = fdt_appendprop_u32(fdt_ptr, node_offset,
+					 property_name,
+					 *(u32 *)property_value);
+		break;
+	case APPEND_PROP_U64:
+		fdt_set_totalsize(fdt_ptr,
+				  (fdt_totalsize(fdt_ptr)
+				  + sizeof(struct fdt_property)
+				  + strlen(property_name) + 3
+				  + sizeof(u64)));
+		ret = fdt_appendprop_u64(fdt_ptr, node_offset,
+					 property_name,
+					 *(u64 *)property_value);
+		break;
+	case SET_PROP_U32:
+		fdt_set_totalsize(fdt_ptr,
+				  (fdt_totalsize(fdt_ptr)
+				  + sizeof(struct fdt_property)
+				  + strlen(property_name) + 3
+				  + sizeof(u32)));
+		ret = fdt_setprop_u32(fdt_ptr, node_offset,
+				      property_name,
+				      *(u32 *)property_value);
+		break;
+	case SET_PROP_U64:
+		fdt_set_totalsize(fdt_ptr,
+				  (fdt_totalsize(fdt_ptr)
+				  + sizeof(struct fdt_property)
+				  + strlen(property_name) + 3
+				  + sizeof(u64)));
+		ret = fdt_setprop_u64(fdt_ptr, node_offset,
+				      property_name,
+				      *(u64 *)property_value);
+		break;
+	case SET_PROP_STRING:
+		fdt_set_totalsize(fdt_ptr,
+				  (fdt_totalsize(fdt_ptr)
+				  + sizeof(struct fdt_property)
+				  + strlen(property_name) + 3
+				  + strlen((char *)property_value)));
+		ret = fdt_setprop_string(fdt_ptr, node_offset,
+					 property_name,
+					 (char *)property_value);
+		break;
+	case ADD_SUBNODE:
+		fdt_set_totalsize(fdt_ptr,
+				  (fdt_totalsize(fdt_ptr)
+				  + sizeof(struct fdt_property)
+				  + strlen(property_name) + 3));
+		ret = fdt_add_subnode(fdt_ptr, node_offset,
+				      property_name);
+		break;
+	default:
+		ret = -1;
+	}
+
+	return ret;
+}
-- 
2.34.1



More information about the U-Boot mailing list