[RFC PATCH v2 1/4] mtd: ubi: register UBI attachments as DM devices

Sam Edwards cfsworks at gmail.com
Fri Oct 6 01:08:28 CEST 2023


This is in preparation for exposing static UBI volumes as block devices.

A UBI uclass and driver are introduced, and a "ubi0" virtual device
with the proper driver is created below whichever MTD device is
attached as the active UBI partition. This virtual device will soon
be the parent for the BLK devices that represent the static volumes.

Signed-off-by: Sam Edwards <CFSworks at gmail.com>
---
 cmd/ubi.c                    | 11 ++++++
 drivers/mtd/ubi/Makefile     |  1 +
 drivers/mtd/ubi/ubi-uclass.c | 74 ++++++++++++++++++++++++++++++++++++
 include/dm/uclass-id.h       |  1 +
 include/ubi_uboot.h          |  5 +++
 5 files changed, 92 insertions(+)
 create mode 100644 drivers/mtd/ubi/ubi-uclass.c

diff --git a/cmd/ubi.c b/cmd/ubi.c
index 0a6a80bdd1..314c7f60f4 100644
--- a/cmd/ubi.c
+++ b/cmd/ubi.c
@@ -560,6 +560,13 @@ static int ubi_detach(void)
 		cmd_ubifs_umount();
 #endif
 
+#ifdef CONFIG_DM_MTD
+	/*
+	 * Clean up any UBI devices in DM
+	 */
+	ubi_dm_unbind_all();
+#endif
+
 	/*
 	 * Call ubi_exit() before re-initializing the UBI subsystem
 	 */
@@ -598,6 +605,10 @@ int ubi_part(char *part_name, const char *vid_header_offset)
 		return err;
 	}
 
+#ifdef CONFIG_DM_MTD
+	ubi_dm_bind(0);
+#endif
+
 	ubi = ubi_devices[0];
 
 	return 0;
diff --git a/drivers/mtd/ubi/Makefile b/drivers/mtd/ubi/Makefile
index 30d00fbdfe..375075f75e 100644
--- a/drivers/mtd/ubi/Makefile
+++ b/drivers/mtd/ubi/Makefile
@@ -7,3 +7,4 @@ obj-y += attach.o build.o vtbl.o vmt.o upd.o kapi.o eba.o io.o wl.o crc32.o
 obj-$(CONFIG_MTD_UBI_FASTMAP) += fastmap.o
 obj-y += misc.o
 obj-y += debug.o
+obj-$(CONFIG_DM_MTD) += ubi-uclass.o
diff --git a/drivers/mtd/ubi/ubi-uclass.c b/drivers/mtd/ubi/ubi-uclass.c
new file mode 100644
index 0000000000..f8971e793e
--- /dev/null
+++ b/drivers/mtd/ubi/ubi-uclass.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * ubi-uclass.c - UBI partition and volume block device uclass driver
+ *
+ * Copyright (C) 2023 Sam Edwards <CFSworks at gmail.com>
+ */
+
+#define LOG_CATEGORY UCLASS_UBI
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <ubi_uboot.h>
+
+int ubi_dm_bind(unsigned int index)
+{
+	struct udevice *dev;
+	int ret;
+	char name[16];
+	const char *name_dup;
+	struct ubi_device *ubi = ubi_devices[index];
+	const struct mtd_info *mtd = ubi->mtd;
+
+	/* MTD partitions are not in DM; navigate to the real MTD device */
+	if (mtd->parent)
+		mtd = mtd->parent;
+
+	snprintf(name, sizeof(name), "ubi%u", index);
+	name_dup = strdup(name);
+	ret = device_bind(mtd->dev, DM_DRIVER_GET(ubi), name_dup, ubi,
+			  ofnode_null(), &dev);
+	if (ret) {
+		free((void *)name_dup);
+		return ret;
+	}
+
+	device_set_name_alloced(dev);
+
+	return 0;
+}
+
+int ubi_dm_unbind_all(void)
+{
+	int ret;
+	struct uclass *uc;
+	struct udevice *dev;
+	struct udevice *next;
+
+	ret = uclass_get(UCLASS_UBI, &uc);
+	if (ret)
+		return ret;
+
+	uclass_foreach_dev_safe(dev, next, uc) {
+		ret = device_remove(dev, DM_REMOVE_NORMAL);
+		if (ret)
+			return ret;
+
+		ret = device_unbind(dev);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+U_BOOT_DRIVER(ubi) = {
+	.id		= UCLASS_UBI,
+	.name		= "ubi_dev",
+};
+
+UCLASS_DRIVER(ubi) = {
+	.id		= UCLASS_UBI,
+	.name		= "ubi",
+};
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 0432c95c9e..ee11fbb38d 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -140,6 +140,7 @@ enum uclass_id {
 	UCLASS_THERMAL,		/* Thermal sensor */
 	UCLASS_TIMER,		/* Timer device */
 	UCLASS_TPM,		/* Trusted Platform Module TIS interface */
+	UCLASS_UBI,		/* Unsorted Block Images MTD partition */
 	UCLASS_UFS,		/* Universal Flash Storage */
 	UCLASS_USB,		/* USB bus */
 	UCLASS_USB_DEV_GENERIC,	/* USB generic device */
diff --git a/include/ubi_uboot.h b/include/ubi_uboot.h
index 6da348eb62..9d37848f03 100644
--- a/include/ubi_uboot.h
+++ b/include/ubi_uboot.h
@@ -52,6 +52,11 @@ extern int ubi_part(char *part_name, const char *vid_header_offset);
 extern int ubi_volume_write(char *volume, void *buf, size_t size);
 extern int ubi_volume_read(char *volume, char *buf, size_t size);
 
+#ifdef CONFIG_DM_MTD
+extern int ubi_dm_bind(unsigned int);
+extern int ubi_dm_unbind_all(void);
+#endif
+
 extern struct ubi_device *ubi_devices[];
 int cmd_ubifs_mount(char *vol_name);
 int cmd_ubifs_umount(void);
-- 
2.41.0



More information about the U-Boot mailing list