[PATCH v6 01/11] mtd: core: always create master device

Alexander Usyskin posted 11 patches 11 months, 2 weeks ago
There is a newer version of this series
[PATCH v6 01/11] mtd: core: always create master device
Posted by Alexander Usyskin 11 months, 2 weeks ago
Create master device without partition when
CONFIG_MTD_PARTITIONED_MASTER flag is unset.

This streamlines device tree and allows to anchor
runtime power management on master device in all cases.

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
 drivers/mtd/mtdcore.c | 141 +++++++++++++++++++++++++++++-------------
 drivers/mtd/mtdcore.h |   2 +-
 drivers/mtd/mtdpart.c |  17 ++---
 3 files changed, 110 insertions(+), 50 deletions(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 724f917f91ba..d0e7fb027eb6 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -68,7 +68,13 @@ static struct class mtd_class = {
 	.pm = MTD_CLS_PM_OPS,
 };
 
+static struct class mtd_master_class = {
+	.name = "mtd_master",
+	.pm = MTD_CLS_PM_OPS,
+};
+
 static DEFINE_IDR(mtd_idr);
+static DEFINE_IDR(mtd_master_idr);
 
 /* These are exported solely for the purpose of mtd_blkdevs.c. You
    should not use them for _anything_ else */
@@ -83,8 +89,9 @@ EXPORT_SYMBOL_GPL(__mtd_next_device);
 
 static LIST_HEAD(mtd_notifiers);
 
-
+#define MTD_MASTER_DEVS 255
 #define MTD_DEVT(index) MKDEV(MTD_CHAR_MAJOR, (index)*2)
+static dev_t mtd_master_devt;
 
 /* REVISIT once MTD uses the driver model better, whoever allocates
  * the mtd_info will probably want to use the release() hook...
@@ -104,6 +111,17 @@ static void mtd_release(struct device *dev)
 	device_destroy(&mtd_class, index + 1);
 }
 
+static void mtd_master_release(struct device *dev)
+{
+	struct mtd_info *mtd = dev_get_drvdata(dev);
+
+	idr_remove(&mtd_master_idr, mtd->index);
+	of_node_put(mtd_get_of_node(mtd));
+
+	if (mtd_is_partition(mtd))
+		release_mtd_partition(mtd);
+}
+
 static void mtd_device_release(struct kref *kref)
 {
 	struct mtd_info *mtd = container_of(kref, struct mtd_info, refcnt);
@@ -367,6 +385,11 @@ static const struct device_type mtd_devtype = {
 	.release	= mtd_release,
 };
 
+static const struct device_type mtd_master_devtype = {
+	.name		= "mtd_master",
+	.release	= mtd_master_release,
+};
+
 static bool mtd_expert_analysis_mode;
 
 #ifdef CONFIG_DEBUG_FS
@@ -634,13 +657,13 @@ static void mtd_check_of_node(struct mtd_info *mtd)
 /**
  *	add_mtd_device - register an MTD device
  *	@mtd: pointer to new MTD device info structure
+ *	@partitioned: create partitioned device
  *
  *	Add a device to the list of MTD devices present in the system, and
  *	notify each currently active MTD 'user' of its arrival. Returns
  *	zero on success or non-zero on failure.
  */
-
-int add_mtd_device(struct mtd_info *mtd)
+int add_mtd_device(struct mtd_info *mtd, bool partitioned)
 {
 	struct device_node *np = mtd_get_of_node(mtd);
 	struct mtd_info *master = mtd_get_master(mtd);
@@ -687,10 +710,17 @@ int add_mtd_device(struct mtd_info *mtd)
 	ofidx = -1;
 	if (np)
 		ofidx = of_alias_get_id(np, "mtd");
-	if (ofidx >= 0)
-		i = idr_alloc(&mtd_idr, mtd, ofidx, ofidx + 1, GFP_KERNEL);
-	else
-		i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL);
+	if (partitioned) {
+		if (ofidx >= 0)
+			i = idr_alloc(&mtd_idr, mtd, ofidx, ofidx + 1, GFP_KERNEL);
+		else
+			i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL);
+	} else {
+		if (ofidx >= 0)
+			i = idr_alloc(&mtd_master_idr, mtd, ofidx, ofidx + 1, GFP_KERNEL);
+		else
+			i = idr_alloc(&mtd_master_idr, mtd, 0, 0, GFP_KERNEL);
+	}
 	if (i < 0) {
 		error = i;
 		goto fail_locked;
@@ -738,15 +768,23 @@ int add_mtd_device(struct mtd_info *mtd)
 	/* Caller should have set dev.parent to match the
 	 * physical device, if appropriate.
 	 */
-	mtd->dev.type = &mtd_devtype;
-	mtd->dev.class = &mtd_class;
-	mtd->dev.devt = MTD_DEVT(i);
-	dev_set_name(&mtd->dev, "mtd%d", i);
+	if (partitioned) {
+		mtd->dev.type = &mtd_devtype;
+		mtd->dev.class = &mtd_class;
+		mtd->dev.devt = MTD_DEVT(i);
+		dev_set_name(&mtd->dev, "mtd%d", i);
+	} else {
+		mtd->dev.type = &mtd_master_devtype;
+		mtd->dev.class = &mtd_master_class;
+		mtd->dev.devt = MKDEV(MAJOR(mtd_master_devt), i);
+		dev_set_name(&mtd->dev, "mtd_master%d", i);
+	}
 	dev_set_drvdata(&mtd->dev, mtd);
 	mtd_check_of_node(mtd);
 	of_node_get(mtd_get_of_node(mtd));
 	error = device_register(&mtd->dev);
 	if (error) {
+		pr_err("mtd: %s device_register fail %d\n", mtd->name, error);
 		put_device(&mtd->dev);
 		goto fail_added;
 	}
@@ -758,10 +796,13 @@ int add_mtd_device(struct mtd_info *mtd)
 
 	mtd_debugfs_populate(mtd);
 
-	device_create(&mtd_class, mtd->dev.parent, MTD_DEVT(i) + 1, NULL,
-		      "mtd%dro", i);
+	if (partitioned) {
+		device_create(&mtd_class, mtd->dev.parent, MTD_DEVT(i) + 1, NULL,
+			      "mtd%dro", i);
+	}
 
-	pr_debug("mtd: Giving out device %d to %s\n", i, mtd->name);
+	pr_debug("mtd: Giving out %spartitioned device %d to %s\n",
+		 partitioned ? "" : "un-", i, mtd->name);
 	/* No need to get a refcount on the module containing
 	   the notifier, since we hold the mtd_table_mutex */
 	list_for_each_entry(not, &mtd_notifiers, list)
@@ -769,13 +810,16 @@ int add_mtd_device(struct mtd_info *mtd)
 
 	mutex_unlock(&mtd_table_mutex);
 
-	if (of_property_read_bool(mtd_get_of_node(mtd), "linux,rootfs")) {
-		if (IS_BUILTIN(CONFIG_MTD)) {
-			pr_info("mtd: setting mtd%d (%s) as root device\n", mtd->index, mtd->name);
-			ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
-		} else {
-			pr_warn("mtd: can't set mtd%d (%s) as root device - mtd must be builtin\n",
-				mtd->index, mtd->name);
+	if (partitioned) {
+		if (of_property_read_bool(mtd_get_of_node(mtd), "linux,rootfs")) {
+			if (IS_BUILTIN(CONFIG_MTD)) {
+				pr_info("mtd: setting mtd%d (%s) as root device\n",
+					mtd->index, mtd->name);
+				ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
+			} else {
+				pr_warn("mtd: can't set mtd%d (%s) as root device - mtd must be builtin\n",
+					mtd->index, mtd->name);
+			}
 		}
 	}
 
@@ -790,7 +834,10 @@ int add_mtd_device(struct mtd_info *mtd)
 	device_unregister(&mtd->dev);
 fail_added:
 	of_node_put(mtd_get_of_node(mtd));
-	idr_remove(&mtd_idr, i);
+	if (partitioned)
+		idr_remove(&mtd_idr, i);
+	else
+		idr_remove(&mtd_master_idr, i);
 fail_locked:
 	mutex_unlock(&mtd_table_mutex);
 	return error;
@@ -808,12 +855,14 @@ int add_mtd_device(struct mtd_info *mtd)
 
 int del_mtd_device(struct mtd_info *mtd)
 {
-	int ret;
 	struct mtd_notifier *not;
+	struct idr *idr;
+	int ret;
 
 	mutex_lock(&mtd_table_mutex);
 
-	if (idr_find(&mtd_idr, mtd->index) != mtd) {
+	idr = mtd->dev.class == &mtd_class ? &mtd_idr : &mtd_master_idr;
+	if (idr_find(idr, mtd->index) != mtd) {
 		ret = -ENODEV;
 		goto out_error;
 	}
@@ -1061,12 +1110,6 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 	if (ret)
 		goto out;
 
-	if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) {
-		ret = add_mtd_device(mtd);
-		if (ret)
-			goto out;
-	}
-
 	/* Prefer parsed partitions over driver-provided fallback */
 	ret = parse_mtd_partitions(mtd, types, parser_data);
 	if (ret == -EPROBE_DEFER)
@@ -1076,10 +1119,8 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 		ret = 0;
 	else if (nr_parts)
 		ret = add_mtd_partitions(mtd, parts, nr_parts);
-	else if (!device_is_registered(&mtd->dev))
-		ret = add_mtd_device(mtd);
 	else
-		ret = 0;
+		ret = add_mtd_device(mtd, true);
 
 	if (ret)
 		goto out;
@@ -1099,13 +1140,14 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
 		register_reboot_notifier(&mtd->reboot_notifier);
 	}
 
+	return 0;
 out:
-	if (ret) {
-		nvmem_unregister(mtd->otp_user_nvmem);
-		nvmem_unregister(mtd->otp_factory_nvmem);
-	}
+	nvmem_unregister(mtd->otp_user_nvmem);
+	nvmem_unregister(mtd->otp_factory_nvmem);
 
-	if (ret && device_is_registered(&mtd->dev))
+	del_mtd_partitions(mtd);
+
+	if (device_is_registered(&mtd->dev))
 		del_mtd_device(mtd);
 
 	return ret;
@@ -1261,8 +1303,7 @@ int __get_mtd_device(struct mtd_info *mtd)
 		mtd = mtd->parent;
 	}
 
-	if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
-		kref_get(&master->refcnt);
+	kref_get(&master->refcnt);
 
 	return 0;
 }
@@ -1356,8 +1397,7 @@ void __put_mtd_device(struct mtd_info *mtd)
 		mtd = parent;
 	}
 
-	if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
-		kref_put(&master->refcnt, mtd_device_release);
+	kref_put(&master->refcnt, mtd_device_release);
 
 	module_put(master->owner);
 
@@ -2524,6 +2564,16 @@ static int __init init_mtd(void)
 	if (ret)
 		goto err_reg;
 
+	ret = class_register(&mtd_master_class);
+	if (ret)
+		goto err_reg2;
+
+	ret = alloc_chrdev_region(&mtd_master_devt, 0, MTD_MASTER_DEVS, "mtd_master");
+	if (ret < 0) {
+		pr_err("unable to allocate char dev region\n");
+		goto err_chrdev;
+	}
+
 	mtd_bdi = mtd_bdi_init("mtd");
 	if (IS_ERR(mtd_bdi)) {
 		ret = PTR_ERR(mtd_bdi);
@@ -2548,6 +2598,10 @@ static int __init init_mtd(void)
 	bdi_unregister(mtd_bdi);
 	bdi_put(mtd_bdi);
 err_bdi:
+	unregister_chrdev_region(mtd_master_devt, MTD_MASTER_DEVS);
+err_chrdev:
+	class_unregister(&mtd_master_class);
+err_reg2:
 	class_unregister(&mtd_class);
 err_reg:
 	pr_err("Error registering mtd class or bdi: %d\n", ret);
@@ -2561,9 +2615,12 @@ static void __exit cleanup_mtd(void)
 	if (proc_mtd)
 		remove_proc_entry("mtd", NULL);
 	class_unregister(&mtd_class);
+	class_unregister(&mtd_master_class);
+	unregister_chrdev_region(mtd_master_devt, MTD_MASTER_DEVS);
 	bdi_unregister(mtd_bdi);
 	bdi_put(mtd_bdi);
 	idr_destroy(&mtd_idr);
+	idr_destroy(&mtd_master_idr);
 }
 
 module_init(init_mtd);
diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h
index b014861a06a6..2258d31c5aa6 100644
--- a/drivers/mtd/mtdcore.h
+++ b/drivers/mtd/mtdcore.h
@@ -8,7 +8,7 @@ extern struct mutex mtd_table_mutex;
 extern struct backing_dev_info *mtd_bdi;
 
 struct mtd_info *__mtd_next_device(int i);
-int __must_check add_mtd_device(struct mtd_info *mtd);
+int __must_check add_mtd_device(struct mtd_info *mtd, bool partitioned);
 int del_mtd_device(struct mtd_info *mtd);
 int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
 int del_mtd_partitions(struct mtd_info *);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 6811a714349d..97505b132313 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -86,8 +86,7 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent,
 	 * parent conditional on that option. Note, this is a way to
 	 * distinguish between the parent and its partitions in sysfs.
 	 */
-	child->dev.parent = IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) || mtd_is_partition(parent) ?
-			    &parent->dev : parent->dev.parent;
+	child->dev.parent = &parent->dev;
 	child->dev.of_node = part->of_node;
 	child->parent = parent;
 	child->part.offset = part->offset;
@@ -276,7 +275,7 @@ int mtd_add_partition(struct mtd_info *parent, const char *name,
 	list_add_tail(&child->part.node, &parent->partitions);
 	mutex_unlock(&master->master.partitions_lock);
 
-	ret = add_mtd_device(child);
+	ret = add_mtd_device(child, true);
 	if (ret)
 		goto err_remove_part;
 
@@ -402,6 +401,12 @@ int add_mtd_partitions(struct mtd_info *parent,
 	printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n",
 	       nbparts, parent->name);
 
+	if (!mtd_is_partition(parent)) {
+		ret = add_mtd_device(parent, IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER));
+		if (ret)
+			return ret;
+	}
+
 	for (i = 0; i < nbparts; i++) {
 		child = allocate_partition(parent, parts + i, i, cur_offset);
 		if (IS_ERR(child)) {
@@ -413,7 +418,7 @@ int add_mtd_partitions(struct mtd_info *parent,
 		list_add_tail(&child->part.node, &parent->partitions);
 		mutex_unlock(&master->master.partitions_lock);
 
-		ret = add_mtd_device(child);
+		ret = add_mtd_device(child, true);
 		if (ret) {
 			mutex_lock(&master->master.partitions_lock);
 			list_del(&child->part.node);
@@ -590,9 +595,6 @@ static int mtd_part_of_parse(struct mtd_info *master,
 	int ret, err = 0;
 
 	dev = &master->dev;
-	/* Use parent device (controller) if the top level MTD is not registered */
-	if (!IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) && !mtd_is_partition(master))
-		dev = master->dev.parent;
 
 	np = mtd_get_of_node(master);
 	if (mtd_is_partition(master))
@@ -712,6 +714,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
 		if (ret < 0 && !err)
 			err = ret;
 	}
+
 	return err;
 }
 
-- 
2.43.0
Re: [PATCH v6 01/11] mtd: core: always create master device
Posted by Guenter Roeck 8 months, 1 week ago
Hi,

On Sun, Mar 02, 2025 at 04:09:11PM +0200, Alexander Usyskin wrote:
> Create master device without partition when
> CONFIG_MTD_PARTITIONED_MASTER flag is unset.
> 
> This streamlines device tree and allows to anchor
> runtime power management on master device in all cases.
> 
> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>

Several of my qemu boot tests fail to boot from mtd devices with this patch
in the mainline kernel. Reverting it fixes the problem. As far as I can
see this affects configurations with CONFIG_MTD_PARTITIONED_MASTER=y when
trying to boot from an mtd partition other than mtdblock0, with the
mtd partition data in devicetree (.../aspeed/openbmc-flash-layout.dtsi).
Is there a guidance describing the changed behavior, by any chance,
and how the boot command line now needs to look like when using one of
the flash partitions as root file system ?

Thanks,
Guenter
RE: [PATCH v6 01/11] mtd: core: always create master device
Posted by Usyskin, Alexander 8 months, 1 week ago
> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
> 
> Hi,
> 
> On Sun, Mar 02, 2025 at 04:09:11PM +0200, Alexander Usyskin wrote:
> > Create master device without partition when
> > CONFIG_MTD_PARTITIONED_MASTER flag is unset.
> >
> > This streamlines device tree and allows to anchor
> > runtime power management on master device in all cases.
> >
> > Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> 
> Several of my qemu boot tests fail to boot from mtd devices with this patch
> in the mainline kernel. Reverting it fixes the problem. As far as I can
> see this affects configurations with CONFIG_MTD_PARTITIONED_MASTER=y
> when
> trying to boot from an mtd partition other than mtdblock0, with the
> mtd partition data in devicetree (.../aspeed/openbmc-flash-layout.dtsi).
> Is there a guidance describing the changed behavior, by any chance,
> and how the boot command line now needs to look like when using one of
> the flash partitions as root file system ?
> 
> Thanks,
> Guenter

I've tried to make is as transparent as possible for the existing users.
Only change is that now every partition has master that is not partitioned.
Is the CONFIG_MTD_PARTITIONED_MASTER=n fixed the problem for you?

- - 
Thanks,
Sasha



Re: [PATCH v6 01/11] mtd: core: always create master device
Posted by Miquel Raynal 8 months, 1 week ago
Hi Guenter,

On 08/06/2025 at 07:00:10 GMT, "Usyskin, Alexander" <alexander.usyskin@intel.com> wrote:

>> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
>> 
>> Hi,
>> 
>> On Sun, Mar 02, 2025 at 04:09:11PM +0200, Alexander Usyskin wrote:
>> > Create master device without partition when
>> > CONFIG_MTD_PARTITIONED_MASTER flag is unset.
>> >
>> > This streamlines device tree and allows to anchor
>> > runtime power management on master device in all cases.
>> >
>> > Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
>> 
>> Several of my qemu boot tests fail to boot from mtd devices with this patch
>> in the mainline kernel. Reverting it fixes the problem. As far as I can
>> see this affects configurations with CONFIG_MTD_PARTITIONED_MASTER=y
>> when
>> trying to boot from an mtd partition other than mtdblock0, with the
>> mtd partition data in devicetree (.../aspeed/openbmc-flash-layout.dtsi).
>> Is there a guidance describing the changed behavior, by any chance,
>> and how the boot command line now needs to look like when using one of
>> the flash partitions as root file system ?
>> 
>> Thanks,
>> Guenter
>
> I've tried to make is as transparent as possible for the existing users.
> Only change is that now every partition has master that is not partitioned.
> Is the CONFIG_MTD_PARTITIONED_MASTER=n fixed the problem for you?

No change is expected, can you please describe the devices that you
observe with and without the patch? Maybe there is something wrong in
the core logic.

Thanks,
Miquèl
Re: [PATCH v6 01/11] mtd: core: always create master device
Posted by Guenter Roeck 8 months, 1 week ago
On 6/8/25 12:37, Miquel Raynal wrote:
> Hi Guenter,
> 
> On 08/06/2025 at 07:00:10 GMT, "Usyskin, Alexander" <alexander.usyskin@intel.com> wrote:
> 
>>> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
>>>
>>> Hi,
>>>
>>> On Sun, Mar 02, 2025 at 04:09:11PM +0200, Alexander Usyskin wrote:
>>>> Create master device without partition when
>>>> CONFIG_MTD_PARTITIONED_MASTER flag is unset.
>>>>
>>>> This streamlines device tree and allows to anchor
>>>> runtime power management on master device in all cases.
>>>>
>>>> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
>>>
>>> Several of my qemu boot tests fail to boot from mtd devices with this patch
>>> in the mainline kernel. Reverting it fixes the problem. As far as I can
>>> see this affects configurations with CONFIG_MTD_PARTITIONED_MASTER=y
>>> when
>>> trying to boot from an mtd partition other than mtdblock0, with the
>>> mtd partition data in devicetree (.../aspeed/openbmc-flash-layout.dtsi).
>>> Is there a guidance describing the changed behavior, by any chance,
>>> and how the boot command line now needs to look like when using one of
>>> the flash partitions as root file system ?
>>>
>>> Thanks,
>>> Guenter
>>
>> I've tried to make is as transparent as possible for the existing users.
>> Only change is that now every partition has master that is not partitioned.
>> Is the CONFIG_MTD_PARTITIONED_MASTER=n fixed the problem for you?
> 
> No change is expected, can you please describe the devices that you
> observe with and without the patch? Maybe there is something wrong in
> the core logic.
> 

I am trying to boot supermicro-x11spi-bmc in qemu from flash partition 6.
The qemu command line is something like

     qemu-system-arm -M supermicro-x11spi-bmc,fmc-model=n25q256a13,spi-model=n25q256a13 \
	-kernel arch/arm/boot/zImage -no-reboot -snapshot \
	-audio none \
	-drive file=/tmp/flash,format=raw,if=mtd,index=1 \
	-nic user \
	--append "root=/dev/mtdblock6 rootwait console=ttyS4,115200 earlycon=uart8250,mmio32,0x1e784000,115200n8" \
	-dtb arch/arm/boot/dts/aspeed/aspeed-bmc-supermicro-x11spi.dtb \
	-nographic -monitor null -serial stdio

This is with aspeed_g5_defconfig. Note that the flash models need to be specified.
The default flashes are no longer recognized when booting from qemu since commit
947c86e481a0 ("mtd: spi-nor: macronix: Drop the redundant flash info fields").

The above only works with this patch reverted (or with v6.15 and older, of course).

Guenter
Re: [PATCH v6 01/11] mtd: core: always create master device
Posted by Miquel Raynal 8 months ago
>>>> Several of my qemu boot tests fail to boot from mtd devices with this patch
>>>> in the mainline kernel. Reverting it fixes the problem. As far as I can
>>>> see this affects configurations with CONFIG_MTD_PARTITIONED_MASTER=y
>>>> when
>>>> trying to boot from an mtd partition other than mtdblock0, with the
>>>> mtd partition data in devicetree (.../aspeed/openbmc-flash-layout.dtsi).
>>>> Is there a guidance describing the changed behavior, by any chance,
>>>> and how the boot command line now needs to look like when using one of
>>>> the flash partitions as root file system ?
>>>>
>>>> Thanks,
>>>> Guenter
>>>
>>> I've tried to make is as transparent as possible for the existing users.
>>> Only change is that now every partition has master that is not partitioned.
>>> Is the CONFIG_MTD_PARTITIONED_MASTER=n fixed the problem for you?
>> No change is expected, can you please describe the devices that you
>> observe with and without the patch? Maybe there is something wrong in
>> the core logic.
>> 
>
> I am trying to boot supermicro-x11spi-bmc in qemu from flash partition 6.
> The qemu command line is something like
>
>     qemu-system-arm -M supermicro-x11spi-bmc,fmc-model=n25q256a13,spi-model=n25q256a13 \
> 	-kernel arch/arm/boot/zImage -no-reboot -snapshot \
> 	-audio none \
> 	-drive file=/tmp/flash,format=raw,if=mtd,index=1 \
> 	-nic user \
> 	--append "root=/dev/mtdblock6 rootwait console=ttyS4,115200 earlycon=uart8250,mmio32,0x1e784000,115200n8" \
> 	-dtb arch/arm/boot/dts/aspeed/aspeed-bmc-supermicro-x11spi.dtb \
> 	-nographic -monitor null -serial stdio
>
> This is with aspeed_g5_defconfig. Note that the flash models need to be specified.
> The default flashes are no longer recognized when booting from qemu since commit
> 947c86e481a0 ("mtd: spi-nor: macronix: Drop the redundant flash info fields").
>
> The above only works with this patch reverted (or with v6.15 and older, of course).
>
> Guenter

Alexander, can you please investigate? We need a fix because Guenter
might not be the only affecter user. Otherwise this patch can't stand,
unfortunately.

Thanks,
Miquèl
RE: [PATCH v6 01/11] mtd: core: always create master device
Posted by Usyskin, Alexander 8 months ago
> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
> 
> 
> >>>> Several of my qemu boot tests fail to boot from mtd devices with this
> patch
> >>>> in the mainline kernel. Reverting it fixes the problem. As far as I can
> >>>> see this affects configurations with
> CONFIG_MTD_PARTITIONED_MASTER=y
> >>>> when
> >>>> trying to boot from an mtd partition other than mtdblock0, with the
> >>>> mtd partition data in devicetree (.../aspeed/openbmc-flash-layout.dtsi).
> >>>> Is there a guidance describing the changed behavior, by any chance,
> >>>> and how the boot command line now needs to look like when using one
> of
> >>>> the flash partitions as root file system ?
> >>>>
> >>>> Thanks,
> >>>> Guenter
> >>>
> >>> I've tried to make is as transparent as possible for the existing users.
> >>> Only change is that now every partition has master that is not partitioned.
> >>> Is the CONFIG_MTD_PARTITIONED_MASTER=n fixed the problem for you?
> >> No change is expected, can you please describe the devices that you
> >> observe with and without the patch? Maybe there is something wrong in
> >> the core logic.
> >>
> >
> > I am trying to boot supermicro-x11spi-bmc in qemu from flash partition 6.
> > The qemu command line is something like
> >
> >     qemu-system-arm -M supermicro-x11spi-bmc,fmc-
> model=n25q256a13,spi-model=n25q256a13 \
> > 	-kernel arch/arm/boot/zImage -no-reboot -snapshot \
> > 	-audio none \
> > 	-drive file=/tmp/flash,format=raw,if=mtd,index=1 \
> > 	-nic user \
> > 	--append "root=/dev/mtdblock6 rootwait console=ttyS4,115200
> earlycon=uart8250,mmio32,0x1e784000,115200n8" \
> > 	-dtb arch/arm/boot/dts/aspeed/aspeed-bmc-supermicro-x11spi.dtb
> \
> > 	-nographic -monitor null -serial stdio
> >
> > This is with aspeed_g5_defconfig. Note that the flash models need to be
> specified.
> > The default flashes are no longer recognized when booting from qemu since
> commit
> > 947c86e481a0 ("mtd: spi-nor: macronix: Drop the redundant flash info
> fields").
> >
> > The above only works with this patch reverted (or with v6.15 and older, of
> course).
> >
> > Guenter
> 
> Alexander, can you please investigate? We need a fix because Guenter
> might not be the only affecter user. Otherwise this patch can't stand,
> unfortunately.
> 
> Thanks,
> Miquèl

Maybe something is moved, and it is not /dev/mtdblock6 now.

Guenter, if it works with CONFIG_MTD_PARTITIONED_MASTER=n, can
you dump the list of devices that you can see?

- - 
Thanks,
Sasha


Re: [PATCH v6 01/11] mtd: core: always create master device
Posted by Guenter Roeck 8 months ago
On 6/9/25 05:23, Usyskin, Alexander wrote:
>> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
>>
>>
>>>>>> Several of my qemu boot tests fail to boot from mtd devices with this
>> patch
>>>>>> in the mainline kernel. Reverting it fixes the problem. As far as I can
>>>>>> see this affects configurations with
>> CONFIG_MTD_PARTITIONED_MASTER=y
>>>>>> when
>>>>>> trying to boot from an mtd partition other than mtdblock0, with the
>>>>>> mtd partition data in devicetree (.../aspeed/openbmc-flash-layout.dtsi).
>>>>>> Is there a guidance describing the changed behavior, by any chance,
>>>>>> and how the boot command line now needs to look like when using one
>> of
>>>>>> the flash partitions as root file system ?
>>>>>>
>>>>>> Thanks,
>>>>>> Guenter
>>>>>
>>>>> I've tried to make is as transparent as possible for the existing users.
>>>>> Only change is that now every partition has master that is not partitioned.
>>>>> Is the CONFIG_MTD_PARTITIONED_MASTER=n fixed the problem for you?
>>>> No change is expected, can you please describe the devices that you
>>>> observe with and without the patch? Maybe there is something wrong in
>>>> the core logic.
>>>>
>>>
>>> I am trying to boot supermicro-x11spi-bmc in qemu from flash partition 6.
>>> The qemu command line is something like
>>>
>>>      qemu-system-arm -M supermicro-x11spi-bmc,fmc-
>> model=n25q256a13,spi-model=n25q256a13 \
>>> 	-kernel arch/arm/boot/zImage -no-reboot -snapshot \
>>> 	-audio none \
>>> 	-drive file=/tmp/flash,format=raw,if=mtd,index=1 \
>>> 	-nic user \
>>> 	--append "root=/dev/mtdblock6 rootwait console=ttyS4,115200
>> earlycon=uart8250,mmio32,0x1e784000,115200n8" \
>>> 	-dtb arch/arm/boot/dts/aspeed/aspeed-bmc-supermicro-x11spi.dtb
>> \
>>> 	-nographic -monitor null -serial stdio
>>>
>>> This is with aspeed_g5_defconfig. Note that the flash models need to be
>> specified.
>>> The default flashes are no longer recognized when booting from qemu since
>> commit
>>> 947c86e481a0 ("mtd: spi-nor: macronix: Drop the redundant flash info
>> fields").
>>>
>>> The above only works with this patch reverted (or with v6.15 and older, of
>> course).
>>>
>>> Guenter
>>
>> Alexander, can you please investigate? We need a fix because Guenter
>> might not be the only affecter user. Otherwise this patch can't stand,
>> unfortunately.
>>
>> Thanks,
>> Miquèl
> 
> Maybe something is moved, and it is not /dev/mtdblock6 now.
> 

With this patch:

# ls -l /dev/*mtd*
crw-------    1 root     root       90,   0 Jan  1 00:00 /dev/mtd0
crw-------    1 root     root       90,   1 Jan  1 00:00 /dev/mtd0ro
crw-------    1 root     root       90,   2 Jan  1 00:00 /dev/mtd1
crw-------    1 root     root       90,   3 Jan  1 00:00 /dev/mtd1ro
crw-------    1 root     root      244,   0 Jan  1 00:00 /dev/mtd_master0
crw-------    1 root     root      244,   1 Jan  1 00:00 /dev/mtd_master1
brw-------    1 root     root       31,   0 Jan  1 00:00 /dev/mtdblock0
brw-------    1 root     root       31,   1 Jan  1 00:00 /dev/mtdblock1
~ # ls /proc/mtd
/proc/mtd
~ # cat /proc/mtd
dev:    size   erasesize  name
mtd0: 02000000 00010000 "bmc"
mtd1: 02000000 00010000 "pnor"

After reverting it:

# ls -l /dev/mtd*
crw-------    1 root     root       90,   0 Jan  1 00:00 /dev/mtd0
crw-------    1 root     root       90,   1 Jan  1 00:00 /dev/mtd0ro
crw-------    1 root     root       90,   2 Jan  1 00:00 /dev/mtd1
crw-------    1 root     root       90,   3 Jan  1 00:00 /dev/mtd1ro
crw-------    1 root     root       90,   4 Jan  1 00:00 /dev/mtd2
crw-------    1 root     root       90,   5 Jan  1 00:00 /dev/mtd2ro
crw-------    1 root     root       90,   6 Jan  1 00:00 /dev/mtd3
crw-------    1 root     root       90,   7 Jan  1 00:00 /dev/mtd3ro
crw-------    1 root     root       90,   8 Jan  1 00:00 /dev/mtd4
crw-------    1 root     root       90,   9 Jan  1 00:00 /dev/mtd4ro
crw-------    1 root     root       90,  10 Jan  1 00:00 /dev/mtd5
crw-------    1 root     root       90,  11 Jan  1 00:00 /dev/mtd5ro
crw-------    1 root     root       90,  12 Jan  1 00:00 /dev/mtd6
crw-------    1 root     root       90,  13 Jan  1 00:00 /dev/mtd6ro
brw-------    1 root     root       31,   0 Jan  1 00:00 /dev/mtdblock0
brw-------    1 root     root       31,   1 Jan  1 00:00 /dev/mtdblock1
brw-------    1 root     root       31,   2 Jan  1 00:00 /dev/mtdblock2
brw-------    1 root     root       31,   3 Jan  1 00:00 /dev/mtdblock3
brw-------    1 root     root       31,   4 Jan  1 00:00 /dev/mtdblock4
brw-------    1 root     root       31,   5 Jan  1 00:00 /dev/mtdblock5
brw-------    1 root     root       31,   6 Jan  1 00:00 /dev/mtdblock6
~ # cat /proc/mtd
dev:    size   erasesize  name
mtd0: 02000000 00010000 "bmc"
mtd1: 00060000 00010000 "u-boot"
mtd2: 00020000 00010000 "u-boot-env"
mtd3: 00440000 00010000 "kernel"
mtd4: 01740000 00010000 "rofs"
mtd5: 00400000 00010000 "rwfs"
mtd6: 02000000 00010000 "pnor"

I am trying to boot from "pnor". It looks like the partition data (from devicetree)
is now ignored. mtdblock6 used to be the second flash.

Guenter

RE: [PATCH v6 01/11] mtd: core: always create master device
Posted by Usyskin, Alexander 8 months ago
> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
> 
> On 6/9/25 05:23, Usyskin, Alexander wrote:
> >> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
> >>
> >>
> >>>>>> Several of my qemu boot tests fail to boot from mtd devices with this
> >> patch
> >>>>>> in the mainline kernel. Reverting it fixes the problem. As far as I can
> >>>>>> see this affects configurations with
> >> CONFIG_MTD_PARTITIONED_MASTER=y
> >>>>>> when
> >>>>>> trying to boot from an mtd partition other than mtdblock0, with the
> >>>>>> mtd partition data in devicetree (.../aspeed/openbmc-flash-
> layout.dtsi).
> >>>>>> Is there a guidance describing the changed behavior, by any chance,
> >>>>>> and how the boot command line now needs to look like when using
> one
> >> of
> >>>>>> the flash partitions as root file system ?
> >>>>>>
> >>>>>> Thanks,
> >>>>>> Guenter
> >>>>>
> >>>>> I've tried to make is as transparent as possible for the existing users.
> >>>>> Only change is that now every partition has master that is not
> partitioned.
> >>>>> Is the CONFIG_MTD_PARTITIONED_MASTER=n fixed the problem for
> you?
> >>>> No change is expected, can you please describe the devices that you
> >>>> observe with and without the patch? Maybe there is something wrong in
> >>>> the core logic.
> >>>>
> >>>
> >>> I am trying to boot supermicro-x11spi-bmc in qemu from flash partition 6.
> >>> The qemu command line is something like
> >>>
> >>>      qemu-system-arm -M supermicro-x11spi-bmc,fmc-
> >> model=n25q256a13,spi-model=n25q256a13 \
> >>> 	-kernel arch/arm/boot/zImage -no-reboot -snapshot \
> >>> 	-audio none \
> >>> 	-drive file=/tmp/flash,format=raw,if=mtd,index=1 \
> >>> 	-nic user \
> >>> 	--append "root=/dev/mtdblock6 rootwait console=ttyS4,115200
> >> earlycon=uart8250,mmio32,0x1e784000,115200n8" \
> >>> 	-dtb arch/arm/boot/dts/aspeed/aspeed-bmc-supermicro-x11spi.dtb
> >> \
> >>> 	-nographic -monitor null -serial stdio
> >>>
> >>> This is with aspeed_g5_defconfig. Note that the flash models need to be
> >> specified.
> >>> The default flashes are no longer recognized when booting from qemu
> since
> >> commit
> >>> 947c86e481a0 ("mtd: spi-nor: macronix: Drop the redundant flash info
> >> fields").
> >>>
> >>> The above only works with this patch reverted (or with v6.15 and older, of
> >> course).
> >>>
> >>> Guenter
> >>
> >> Alexander, can you please investigate? We need a fix because Guenter
> >> might not be the only affecter user. Otherwise this patch can't stand,
> >> unfortunately.
> >>
> >> Thanks,
> >> Miquèl
> >
> > Maybe something is moved, and it is not /dev/mtdblock6 now.
> >
> 
> With this patch:
> 
> # ls -l /dev/*mtd*
> crw-------    1 root     root       90,   0 Jan  1 00:00 /dev/mtd0
> crw-------    1 root     root       90,   1 Jan  1 00:00 /dev/mtd0ro
> crw-------    1 root     root       90,   2 Jan  1 00:00 /dev/mtd1
> crw-------    1 root     root       90,   3 Jan  1 00:00 /dev/mtd1ro
> crw-------    1 root     root      244,   0 Jan  1 00:00 /dev/mtd_master0
> crw-------    1 root     root      244,   1 Jan  1 00:00 /dev/mtd_master1
> brw-------    1 root     root       31,   0 Jan  1 00:00 /dev/mtdblock0
> brw-------    1 root     root       31,   1 Jan  1 00:00 /dev/mtdblock1
> ~ # ls /proc/mtd
> /proc/mtd
> ~ # cat /proc/mtd
> dev:    size   erasesize  name
> mtd0: 02000000 00010000 "bmc"
> mtd1: 02000000 00010000 "pnor"
> 
> After reverting it:
> 
> # ls -l /dev/mtd*
> crw-------    1 root     root       90,   0 Jan  1 00:00 /dev/mtd0
> crw-------    1 root     root       90,   1 Jan  1 00:00 /dev/mtd0ro
> crw-------    1 root     root       90,   2 Jan  1 00:00 /dev/mtd1
> crw-------    1 root     root       90,   3 Jan  1 00:00 /dev/mtd1ro
> crw-------    1 root     root       90,   4 Jan  1 00:00 /dev/mtd2
> crw-------    1 root     root       90,   5 Jan  1 00:00 /dev/mtd2ro
> crw-------    1 root     root       90,   6 Jan  1 00:00 /dev/mtd3
> crw-------    1 root     root       90,   7 Jan  1 00:00 /dev/mtd3ro
> crw-------    1 root     root       90,   8 Jan  1 00:00 /dev/mtd4
> crw-------    1 root     root       90,   9 Jan  1 00:00 /dev/mtd4ro
> crw-------    1 root     root       90,  10 Jan  1 00:00 /dev/mtd5
> crw-------    1 root     root       90,  11 Jan  1 00:00 /dev/mtd5ro
> crw-------    1 root     root       90,  12 Jan  1 00:00 /dev/mtd6
> crw-------    1 root     root       90,  13 Jan  1 00:00 /dev/mtd6ro
> brw-------    1 root     root       31,   0 Jan  1 00:00 /dev/mtdblock0
> brw-------    1 root     root       31,   1 Jan  1 00:00 /dev/mtdblock1
> brw-------    1 root     root       31,   2 Jan  1 00:00 /dev/mtdblock2
> brw-------    1 root     root       31,   3 Jan  1 00:00 /dev/mtdblock3
> brw-------    1 root     root       31,   4 Jan  1 00:00 /dev/mtdblock4
> brw-------    1 root     root       31,   5 Jan  1 00:00 /dev/mtdblock5
> brw-------    1 root     root       31,   6 Jan  1 00:00 /dev/mtdblock6
> ~ # cat /proc/mtd
> dev:    size   erasesize  name
> mtd0: 02000000 00010000 "bmc"
> mtd1: 00060000 00010000 "u-boot"
> mtd2: 00020000 00010000 "u-boot-env"
> mtd3: 00440000 00010000 "kernel"
> mtd4: 01740000 00010000 "rofs"
> mtd5: 00400000 00010000 "rwfs"
> mtd6: 02000000 00010000 "pnor"
> 
> I am trying to boot from "pnor". It looks like the partition data (from
> devicetree)
> is now ignored. mtdblock6 used to be the second flash.
> 
> Guenter

Is this with CONFIG_MTD_PARTITIONED_MASTER?

I think that mtd_is_partition is ambiguous now.
We always have master partition when CONFIG_MTD_PARTITIONED_MASTER
is enabled and parent check is useless.
We must check grandparent in this case.
Miquel, am I right?

We can return to older patch version that have created partition
instead of the master device.
Or try to fix mtd_is_partition, like below.
Guenter, is below patch helps?

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 429d8c16baf0..b977dce6d58c 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -104,7 +104,7 @@ static void mtd_release(struct device *dev)
        idr_remove(&mtd_idr, mtd->index);
        of_node_put(mtd_get_of_node(mtd));

-       if (mtd_is_partition(mtd))
+       if (mtd_is_partition_or_master_partiton(mtd))
                release_mtd_partition(mtd);

        /* remove /dev/mtdXro node */
@@ -118,7 +118,7 @@ static void mtd_master_release(struct device *dev)
        idr_remove(&mtd_master_idr, mtd->index);
        of_node_put(mtd_get_of_node(mtd));

-       if (mtd_is_partition(mtd))
+       if (mtd_is_partition_or_master_partiton(mtd))
                release_mtd_partition(mtd);
 }

diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 8d10d9d2e830..05271458c4db 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -419,6 +419,15 @@ static inline u64 mtd_get_master_ofs(struct mtd_info *mtd, u64 ofs)
 }

 static inline bool mtd_is_partition(const struct mtd_info *mtd)
+{
+       if (!mtd->parent)
+               return false;
+       if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) && !mtd->parent->parent)
+               return false;
+       return true;
+}
+
+static inline bool mtd_is_partition_or_master_partiton(const struct mtd_info *mtd)
 {
        return mtd->parent;
 }






Re: [PATCH v6 01/11] mtd: core: always create master device
Posted by Guenter Roeck 8 months ago
On 6/9/25 08:16, Usyskin, Alexander wrote:
>> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
>>
>> On 6/9/25 05:23, Usyskin, Alexander wrote:
>>>> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
>>>>
>>>>
>>>>>>>> Several of my qemu boot tests fail to boot from mtd devices with this
>>>> patch
>>>>>>>> in the mainline kernel. Reverting it fixes the problem. As far as I can
>>>>>>>> see this affects configurations with
>>>> CONFIG_MTD_PARTITIONED_MASTER=y
>>>>>>>> when
>>>>>>>> trying to boot from an mtd partition other than mtdblock0, with the
>>>>>>>> mtd partition data in devicetree (.../aspeed/openbmc-flash-
>> layout.dtsi).
>>>>>>>> Is there a guidance describing the changed behavior, by any chance,
>>>>>>>> and how the boot command line now needs to look like when using
>> one
>>>> of
>>>>>>>> the flash partitions as root file system ?
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Guenter
>>>>>>>
>>>>>>> I've tried to make is as transparent as possible for the existing users.
>>>>>>> Only change is that now every partition has master that is not
>> partitioned.
>>>>>>> Is the CONFIG_MTD_PARTITIONED_MASTER=n fixed the problem for
>> you?
>>>>>> No change is expected, can you please describe the devices that you
>>>>>> observe with and without the patch? Maybe there is something wrong in
>>>>>> the core logic.
>>>>>>
>>>>>
>>>>> I am trying to boot supermicro-x11spi-bmc in qemu from flash partition 6.
>>>>> The qemu command line is something like
>>>>>
>>>>>       qemu-system-arm -M supermicro-x11spi-bmc,fmc-
>>>> model=n25q256a13,spi-model=n25q256a13 \
>>>>> 	-kernel arch/arm/boot/zImage -no-reboot -snapshot \
>>>>> 	-audio none \
>>>>> 	-drive file=/tmp/flash,format=raw,if=mtd,index=1 \
>>>>> 	-nic user \
>>>>> 	--append "root=/dev/mtdblock6 rootwait console=ttyS4,115200
>>>> earlycon=uart8250,mmio32,0x1e784000,115200n8" \
>>>>> 	-dtb arch/arm/boot/dts/aspeed/aspeed-bmc-supermicro-x11spi.dtb
>>>> \
>>>>> 	-nographic -monitor null -serial stdio
>>>>>
>>>>> This is with aspeed_g5_defconfig. Note that the flash models need to be
>>>> specified.
>>>>> The default flashes are no longer recognized when booting from qemu
>> since
>>>> commit
>>>>> 947c86e481a0 ("mtd: spi-nor: macronix: Drop the redundant flash info
>>>> fields").
>>>>>
>>>>> The above only works with this patch reverted (or with v6.15 and older, of
>>>> course).
>>>>>
>>>>> Guenter
>>>>
>>>> Alexander, can you please investigate? We need a fix because Guenter
>>>> might not be the only affecter user. Otherwise this patch can't stand,
>>>> unfortunately.
>>>>
>>>> Thanks,
>>>> Miquèl
>>>
>>> Maybe something is moved, and it is not /dev/mtdblock6 now.
>>>
>>
>> With this patch:
>>
>> # ls -l /dev/*mtd*
>> crw-------    1 root     root       90,   0 Jan  1 00:00 /dev/mtd0
>> crw-------    1 root     root       90,   1 Jan  1 00:00 /dev/mtd0ro
>> crw-------    1 root     root       90,   2 Jan  1 00:00 /dev/mtd1
>> crw-------    1 root     root       90,   3 Jan  1 00:00 /dev/mtd1ro
>> crw-------    1 root     root      244,   0 Jan  1 00:00 /dev/mtd_master0
>> crw-------    1 root     root      244,   1 Jan  1 00:00 /dev/mtd_master1
>> brw-------    1 root     root       31,   0 Jan  1 00:00 /dev/mtdblock0
>> brw-------    1 root     root       31,   1 Jan  1 00:00 /dev/mtdblock1
>> ~ # ls /proc/mtd
>> /proc/mtd
>> ~ # cat /proc/mtd
>> dev:    size   erasesize  name
>> mtd0: 02000000 00010000 "bmc"
>> mtd1: 02000000 00010000 "pnor"
>>
>> After reverting it:
>>
>> # ls -l /dev/mtd*
>> crw-------    1 root     root       90,   0 Jan  1 00:00 /dev/mtd0
>> crw-------    1 root     root       90,   1 Jan  1 00:00 /dev/mtd0ro
>> crw-------    1 root     root       90,   2 Jan  1 00:00 /dev/mtd1
>> crw-------    1 root     root       90,   3 Jan  1 00:00 /dev/mtd1ro
>> crw-------    1 root     root       90,   4 Jan  1 00:00 /dev/mtd2
>> crw-------    1 root     root       90,   5 Jan  1 00:00 /dev/mtd2ro
>> crw-------    1 root     root       90,   6 Jan  1 00:00 /dev/mtd3
>> crw-------    1 root     root       90,   7 Jan  1 00:00 /dev/mtd3ro
>> crw-------    1 root     root       90,   8 Jan  1 00:00 /dev/mtd4
>> crw-------    1 root     root       90,   9 Jan  1 00:00 /dev/mtd4ro
>> crw-------    1 root     root       90,  10 Jan  1 00:00 /dev/mtd5
>> crw-------    1 root     root       90,  11 Jan  1 00:00 /dev/mtd5ro
>> crw-------    1 root     root       90,  12 Jan  1 00:00 /dev/mtd6
>> crw-------    1 root     root       90,  13 Jan  1 00:00 /dev/mtd6ro
>> brw-------    1 root     root       31,   0 Jan  1 00:00 /dev/mtdblock0
>> brw-------    1 root     root       31,   1 Jan  1 00:00 /dev/mtdblock1
>> brw-------    1 root     root       31,   2 Jan  1 00:00 /dev/mtdblock2
>> brw-------    1 root     root       31,   3 Jan  1 00:00 /dev/mtdblock3
>> brw-------    1 root     root       31,   4 Jan  1 00:00 /dev/mtdblock4
>> brw-------    1 root     root       31,   5 Jan  1 00:00 /dev/mtdblock5
>> brw-------    1 root     root       31,   6 Jan  1 00:00 /dev/mtdblock6
>> ~ # cat /proc/mtd
>> dev:    size   erasesize  name
>> mtd0: 02000000 00010000 "bmc"
>> mtd1: 00060000 00010000 "u-boot"
>> mtd2: 00020000 00010000 "u-boot-env"
>> mtd3: 00440000 00010000 "kernel"
>> mtd4: 01740000 00010000 "rofs"
>> mtd5: 00400000 00010000 "rwfs"
>> mtd6: 02000000 00010000 "pnor"
>>
>> I am trying to boot from "pnor". It looks like the partition data (from
>> devicetree)
>> is now ignored. mtdblock6 used to be the second flash.
>>
>> Guenter
> 
> Is this with CONFIG_MTD_PARTITIONED_MASTER?
> 

Yes

> I think that mtd_is_partition is ambiguous now.
> We always have master partition when CONFIG_MTD_PARTITIONED_MASTER
> is enabled and parent check is useless.
> We must check grandparent in this case.
> Miquel, am I right?
> 
> We can return to older patch version that have created partition
> instead of the master device.
> Or try to fix mtd_is_partition, like below.
> Guenter, is below patch helps?
> 
No, it does not make a difference. Partitions are still not created.

Guenter

Re: [PATCH v6 01/11] mtd: core: always create master device
Posted by Richard Weinberger 8 months ago
----- Ursprüngliche Mail -----
> Von: "Guenter Roeck" <linux@roeck-us.net>
>>> I am trying to boot from "pnor". It looks like the partition data (from
>>> devicetree)
>>> is now ignored. mtdblock6 used to be the second flash.
>>>
>>> Guenter
>> 
>> Is this with CONFIG_MTD_PARTITIONED_MASTER?
>> 
> 
> Yes
> 
>> I think that mtd_is_partition is ambiguous now.
>> We always have master partition when CONFIG_MTD_PARTITIONED_MASTER
>> is enabled and parent check is useless.
>> We must check grandparent in this case.
>> Miquel, am I right?
>> 
>> We can return to older patch version that have created partition
>> instead of the master device.
>> Or try to fix mtd_is_partition, like below.
>> Guenter, is below patch helps?
>> 
> No, it does not make a difference. Partitions are still not created.

Looks like all partition parsing is broken when CONFIG_MTD_PARTITIONED_MASTER=y is set.
Alexander, I was able to reproduce with MTDRAM and the mtdparts= kernel parameter.
Build with CONFIG_MTD_MTDRAM=y and CONFIG_MTD_PARTITIONED_MASTER=y,
pass mtdparts=\"mtdram test device:256k(foo)ro,-(bar)\" to the kernel command line.

Before your change:
$ cat /proc/mtd 
dev:    size   erasesize  name
mtd0: 00400000 00020000 "mtdram test device"
mtd1: 00040000 00020000 "foo"
mtd2: 003c0000 00020000 "bar"

After:
$ cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00400000 00020000 "mtdram test device"

Hope this helps!

Thanks,
//richard
RE: [PATCH v6 01/11] mtd: core: always create master device
Posted by Usyskin, Alexander 8 months ago
> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
> 
> ----- Ursprüngliche Mail -----
> > Von: "Guenter Roeck" <linux@roeck-us.net>
> >>> I am trying to boot from "pnor". It looks like the partition data (from
> >>> devicetree)
> >>> is now ignored. mtdblock6 used to be the second flash.
> >>>
> >>> Guenter
> >>
> >> Is this with CONFIG_MTD_PARTITIONED_MASTER?
> >>
> >
> > Yes
> >
> >> I think that mtd_is_partition is ambiguous now.
> >> We always have master partition when
> CONFIG_MTD_PARTITIONED_MASTER
> >> is enabled and parent check is useless.
> >> We must check grandparent in this case.
> >> Miquel, am I right?
> >>
> >> We can return to older patch version that have created partition
> >> instead of the master device.
> >> Or try to fix mtd_is_partition, like below.
> >> Guenter, is below patch helps?
> >>
> > No, it does not make a difference. Partitions are still not created.
> 
> Looks like all partition parsing is broken when
> CONFIG_MTD_PARTITIONED_MASTER=y is set.
> Alexander, I was able to reproduce with MTDRAM and the mtdparts= kernel
> parameter.
> Build with CONFIG_MTD_MTDRAM=y and
> CONFIG_MTD_PARTITIONED_MASTER=y,
> pass mtdparts=\"mtdram test device:256k(foo)ro,-(bar)\" to the kernel
> command line.
> 
> Before your change:
> $ cat /proc/mtd
> dev:    size   erasesize  name
> mtd0: 00400000 00020000 "mtdram test device"
> mtd1: 00040000 00020000 "foo"
> mtd2: 003c0000 00020000 "bar"
> 
> After:
> $ cat /proc/mtd
> dev:    size   erasesize  name
> mtd0: 00400000 00020000 "mtdram test device"
> 
> Hope this helps!
> 
> Thanks,
> //Richard

Richard, I've reproduced your setup (modulo that I must load mtdram manually)
and patch provided in this thread helps to fix the issue.
Can you apply and confirm?

Guenter, as patch not helping and I'm not sure how to reproduce it locally,
can you add drivers/mtd to dynamic debug and collect dmesg for good
and bad cases?
If you have some explanation how to run qemu-system-arm I'll
be glad to try to reproduce it locally.

- - 
Thanks,
Sasha


Re: [PATCH v6 01/11] mtd: core: always create master device
Posted by Richard Weinberger 8 months ago
----- Ursprüngliche Mail -----
> Von: "Alexander Usyskin" <alexander.usyskin@intel.com>
> Richard, I've reproduced your setup (modulo that I must load mtdram manually)
> and patch provided in this thread helps to fix the issue.
> Can you apply and confirm?

Yes, it fixes the issue here! :-)

Thanks,
//richard
Re: [PATCH v6 01/11] mtd: core: always create master device
Posted by Guenter Roeck 8 months ago
On 6/10/25 05:54, Richard Weinberger wrote:
> ----- Ursprüngliche Mail -----
>> Von: "Alexander Usyskin" <alexander.usyskin@intel.com>
>> Richard, I've reproduced your setup (modulo that I must load mtdram manually)
>> and patch provided in this thread helps to fix the issue.
>> Can you apply and confirm?
> 
> Yes, it fixes the issue here! :-)
> 

It doesn't seem to fix the issue if the partition data is in devicetree.

Here is my sample qemu command line:

qemu-system-arm -M supermicro-x11spi-bmc,fmc-model=n25q256a13,spi-model=n25q256a13 \
	-kernel arch/arm/boot/zImage -no-reboot \
	-snapshot -audio none \
	-drive file=/tmp/flash,format=raw,if=mtd \
	-drive file=/tmp/flash,format=raw,if=mtd,index=1 \
	-nic user \
	--append "kunit.enable=0 root=/dev/mtdblock0 rootwait console=ttyS4,115200 earlycon=uart8250,mmio32,0x1e784000,115200n8" \
	-dtb arch/arm/boot/dts/aspeed/aspeed-bmc-supermicro-x11spi.dtb \
	-nographic -monitor null -serial stdio

This does not create any mtd partitions, even after applying the
patch suggested earlier.

Guenter

Re: [PATCH v6 01/11] mtd: core: always create master device
Posted by Miquel Raynal 8 months ago
On 10/06/2025 at 09:15:25 -07, Guenter Roeck <linux@roeck-us.net> wrote:

> On 6/10/25 05:54, Richard Weinberger wrote:
>> ----- Ursprüngliche Mail -----
>>> Von: "Alexander Usyskin" <alexander.usyskin@intel.com>
>>> Richard, I've reproduced your setup (modulo that I must load mtdram manually)
>>> and patch provided in this thread helps to fix the issue.
>>> Can you apply and confirm?
>> Yes, it fixes the issue here! :-)
>> 
>
> It doesn't seem to fix the issue if the partition data is in
> devicetree.

I had a look at the patch again. The whole mtd core makes assumptions on
parenting, which is totally changed with this patch. There are so many
creative ways this can break, I don't believe we are going to continue
this route. I propose to revert the patch entirely for now. We need to
find another approach, I'm sorry.

Alexander, can you please remind me what was your initial problem? I
believe you needed to anchor runtime PM on the master device. Can you
please elaborate again? Why taking the controller as source (the
default, before your change) did not work? Also why was selecting
MTD_PARTITIONED_MASTER not an option for you? I'm trying to get to the
root of this change again, so we can find a solution fixing "the world"
(fast) and in a second time a way to address your problem.

Thanks,
Miquèl
Re: [PATCH v6 01/11] mtd: core: always create master device
Posted by Richard Weinberger 8 months ago
----- Ursprüngliche Mail -----
> Von: "Miquel Raynal" <miquel.raynal@bootlin.com>
>> On 6/10/25 05:54, Richard Weinberger wrote:
>>> ----- Ursprüngliche Mail -----
>>>> Von: "Alexander Usyskin" <alexander.usyskin@intel.com>
>>>> Richard, I've reproduced your setup (modulo that I must load mtdram manually)
>>>> and patch provided in this thread helps to fix the issue.
>>>> Can you apply and confirm?
>>> Yes, it fixes the issue here! :-)
>>> 
>>
>> It doesn't seem to fix the issue if the partition data is in
>> devicetree.
> 
> I had a look at the patch again. The whole mtd core makes assumptions on
> parenting, which is totally changed with this patch. There are so many
> creative ways this can break, I don't believe we are going to continue
> this route. I propose to revert the patch entirely for now. We need to
> find another approach, I'm sorry.

I think reverting is a valid option to consider if the issue turns out to be
a "back to the drawing board" problem.
 
> Alexander, can you please remind me what was your initial problem? I
> believe you needed to anchor runtime PM on the master device. Can you
> please elaborate again? Why taking the controller as source (the
> default, before your change) did not work? Also why was selecting
> MTD_PARTITIONED_MASTER not an option for you? I'm trying to get to the
> root of this change again, so we can find a solution fixing "the world"
> (fast) and in a second time a way to address your problem.

IIRC the problem is that depending on CONFIG_MTD_PARTITIONED_MASTER
won't fly as PM needs to work with any configuration.
And enforcing CONFIG_MTD_PARTITIONED_MASTER will break existing
setups because mtd id's will change.

On the other hand, how about placing the master device at the end
of the available mtd id space if CONFIG_MTD_PARTITIONED_MASTER=n?
A bit hacky but IMHO worth a thought.

Thanks,
//richard
RE: [PATCH v6 01/11] mtd: core: always create master device
Posted by Usyskin, Alexander 8 months ago
> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
> 
> ----- Ursprüngliche Mail -----
> > Von: "Miquel Raynal" <miquel.raynal@bootlin.com>
> >> On 6/10/25 05:54, Richard Weinberger wrote:
> >>> ----- Ursprüngliche Mail -----
> >>>> Von: "Alexander Usyskin" <alexander.usyskin@intel.com>
> >>>> Richard, I've reproduced your setup (modulo that I must load mtdram
> manually)
> >>>> and patch provided in this thread helps to fix the issue.
> >>>> Can you apply and confirm?
> >>> Yes, it fixes the issue here! :-)
> >>>
> >>
> >> It doesn't seem to fix the issue if the partition data is in
> >> devicetree.
> >
> > I had a look at the patch again. The whole mtd core makes assumptions on
> > parenting, which is totally changed with this patch. There are so many
> > creative ways this can break, I don't believe we are going to continue
> > this route. I propose to revert the patch entirely for now. We need to
> > find another approach, I'm sorry.
> 
> I think reverting is a valid option to consider if the issue turns out to be
> a "back to the drawing board" problem.
> 
> > Alexander, can you please remind me what was your initial problem? I
> > believe you needed to anchor runtime PM on the master device. Can you
> > please elaborate again? Why taking the controller as source (the
> > default, before your change) did not work? Also why was selecting
> > MTD_PARTITIONED_MASTER not an option for you? I'm trying to get to the
> > root of this change again, so we can find a solution fixing "the world"
> > (fast) and in a second time a way to address your problem.
> 
> IIRC the problem is that depending on CONFIG_MTD_PARTITIONED_MASTER
> won't fly as PM needs to work with any configuration.
> And enforcing CONFIG_MTD_PARTITIONED_MASTER will break existing
> setups because mtd id's will change.
> 
> On the other hand, how about placing the master device at the end
> of the available mtd id space if CONFIG_MTD_PARTITIONED_MASTER=n?
> A bit hacky but IMHO worth a thought.
> 
> Thanks,
> //Richard

The original problem was that general purpose OS never set
CONFIG_MTD_PARTITIONED_MASTER and we need valid device tree
to power management to work.

We can return to V7 of this patch that only creates dummy master if
CONFIG_MTD_PARTITIONED_MASTER is off.
In this case the hierarchy remains the same.

Miquel, can you re-review v7 and say if it worth to revert current version and
put v7 instead?

- - 
Thanks,
Sasha


Re: [PATCH v6 01/11] mtd: core: always create master device
Posted by Miquel Raynal 8 months ago
Hello,

On 11/06/2025 at 10:52:36 GMT, "Usyskin, Alexander" <alexander.usyskin@intel.com> wrote:

>> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
>> 
>> ----- Ursprüngliche Mail -----
>> > Von: "Miquel Raynal" <miquel.raynal@bootlin.com>
>> >> On 6/10/25 05:54, Richard Weinberger wrote:
>> >>> ----- Ursprüngliche Mail -----
>> >>>> Von: "Alexander Usyskin" <alexander.usyskin@intel.com>
>> >>>> Richard, I've reproduced your setup (modulo that I must load mtdram
>> manually)
>> >>>> and patch provided in this thread helps to fix the issue.
>> >>>> Can you apply and confirm?
>> >>> Yes, it fixes the issue here! :-)
>> >>>
>> >>
>> >> It doesn't seem to fix the issue if the partition data is in
>> >> devicetree.
>> >
>> > I had a look at the patch again. The whole mtd core makes assumptions on
>> > parenting, which is totally changed with this patch. There are so many
>> > creative ways this can break, I don't believe we are going to continue
>> > this route. I propose to revert the patch entirely for now. We need to
>> > find another approach, I'm sorry.
>> 
>> I think reverting is a valid option to consider if the issue turns out to be
>> a "back to the drawing board" problem.
>> 
>> > Alexander, can you please remind me what was your initial problem? I
>> > believe you needed to anchor runtime PM on the master device. Can you
>> > please elaborate again? Why taking the controller as source (the
>> > default, before your change) did not work? Also why was selecting
>> > MTD_PARTITIONED_MASTER not an option for you? I'm trying to get to the
>> > root of this change again, so we can find a solution fixing "the world"
>> > (fast) and in a second time a way to address your problem.
>> 
>> IIRC the problem is that depending on CONFIG_MTD_PARTITIONED_MASTER
>> won't fly as PM needs to work with any configuration.
>> And enforcing CONFIG_MTD_PARTITIONED_MASTER will break existing
>> setups because mtd id's will change.
>> 
>> On the other hand, how about placing the master device at the end
>> of the available mtd id space if CONFIG_MTD_PARTITIONED_MASTER=n?
>> A bit hacky but IMHO worth a thought.
>> 
>> Thanks,
>> //Richard
>
> The original problem was that general purpose OS never set
> CONFIG_MTD_PARTITIONED_MASTER and we need valid device tree
> to power management to work.
>
> We can return to V7 of this patch that only creates dummy master if
> CONFIG_MTD_PARTITIONED_MASTER is off.
> In this case the hierarchy remains the same.
>
> Miquel, can you re-review v7 and say if it worth to revert current version and
> put v7 instead?

After taking inspiration from Richard's wisdom on IRC, we have another
proposal. Let's drop the mtd_master class. We need an mtd device to be
the master device, we already have one but we cannot keep *at the
beginning* of the ID space under the CONFIG_MTD_PARTITIONED_MASTER=n
configuration to avoid breaking userspace. So let's keep the master
anyway, with the following specificities in the problematic case:
- id is allocated from the max value downwards (avoids messing with
  numbering)
- mtd device is simply hidden (same user experience as before)

Apparently this second point, while not natively supported, is something
the block world already does:
https://elixir.bootlin.com/linux/v6.15.1/source/include/linux/blkdev.h#L88

What do you think?

Thanks,
Miquèl
RE: [PATCH v6 01/11] mtd: core: always create master device
Posted by Usyskin, Alexander 8 months ago
> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
> 
> Hello,
> 
> On 11/06/2025 at 10:52:36 GMT, "Usyskin, Alexander"
> <alexander.usyskin@intel.com> wrote:
> 
> >> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
> >>
> >> ----- Ursprüngliche Mail -----
> >> > Von: "Miquel Raynal" <miquel.raynal@bootlin.com>
> >> >> On 6/10/25 05:54, Richard Weinberger wrote:
> >> >>> ----- Ursprüngliche Mail -----
> >> >>>> Von: "Alexander Usyskin" <alexander.usyskin@intel.com>
> >> >>>> Richard, I've reproduced your setup (modulo that I must load mtdram
> >> manually)
> >> >>>> and patch provided in this thread helps to fix the issue.
> >> >>>> Can you apply and confirm?
> >> >>> Yes, it fixes the issue here! :-)
> >> >>>
> >> >>
> >> >> It doesn't seem to fix the issue if the partition data is in
> >> >> devicetree.
> >> >
> >> > I had a look at the patch again. The whole mtd core makes assumptions
> on
> >> > parenting, which is totally changed with this patch. There are so many
> >> > creative ways this can break, I don't believe we are going to continue
> >> > this route. I propose to revert the patch entirely for now. We need to
> >> > find another approach, I'm sorry.
> >>
> >> I think reverting is a valid option to consider if the issue turns out to be
> >> a "back to the drawing board" problem.
> >>
> >> > Alexander, can you please remind me what was your initial problem? I
> >> > believe you needed to anchor runtime PM on the master device. Can you
> >> > please elaborate again? Why taking the controller as source (the
> >> > default, before your change) did not work? Also why was selecting
> >> > MTD_PARTITIONED_MASTER not an option for you? I'm trying to get to
> the
> >> > root of this change again, so we can find a solution fixing "the world"
> >> > (fast) and in a second time a way to address your problem.
> >>
> >> IIRC the problem is that depending on
> CONFIG_MTD_PARTITIONED_MASTER
> >> won't fly as PM needs to work with any configuration.
> >> And enforcing CONFIG_MTD_PARTITIONED_MASTER will break existing
> >> setups because mtd id's will change.
> >>
> >> On the other hand, how about placing the master device at the end
> >> of the available mtd id space if CONFIG_MTD_PARTITIONED_MASTER=n?
> >> A bit hacky but IMHO worth a thought.
> >>
> >> Thanks,
> >> //Richard
> >
> > The original problem was that general purpose OS never set
> > CONFIG_MTD_PARTITIONED_MASTER and we need valid device tree
> > to power management to work.
> >
> > We can return to V7 of this patch that only creates dummy master if
> > CONFIG_MTD_PARTITIONED_MASTER is off.
> > In this case the hierarchy remains the same.
> >
> > Miquel, can you re-review v7 and say if it worth to revert current version and
> > put v7 instead?
> 
> After taking inspiration from Richard's wisdom on IRC, we have another
> proposal. Let's drop the mtd_master class. We need an mtd device to be
> the master device, we already have one but we cannot keep *at the
> beginning* of the ID space under the CONFIG_MTD_PARTITIONED_MASTER=n
> configuration to avoid breaking userspace. So let's keep the master
> anyway, with the following specificities in the problematic case:
> - id is allocated from the max value downwards (avoids messing with
>   numbering)
> - mtd device is simply hidden (same user experience as before)
> 
> Apparently this second point, while not natively supported, is something
> the block world already does:
> https://elixir.bootlin.com/linux/v6.15.1/source/include/linux/blkdev.h#L88
> 
> What do you think?
> 
> Thanks,
> Miquèl

In general, it is fine for me - we have parent mtd initialized and participating
in power management.

I can't see how to bend idr_alloc to allocate from the end and corner case
of full idr range is also will be problematic.

- - 
Thanks,
Sasha


Re: [PATCH v6 01/11] mtd: core: always create master device
Posted by Richard Weinberger 8 months ago
----- Ursprüngliche Mail -----
> Von: "Alexander Usyskin" <alexander.usyskin@intel.com>
> In general, it is fine for me - we have parent mtd initialized and participating
> in power management.
> 
> I can't see how to bend idr_alloc to allocate from the end and corner case
> of full idr range is also will be problematic.

I expected it to work because we can track the highest mtd ID and pass limits
to idr_alloc(), no?

Thanks,
//richard
RE: [PATCH v6 01/11] mtd: core: always create master device
Posted by Usyskin, Alexander 8 months ago
> Subject: Re: [PATCH v6 01/11] mtd: core: always create master device
> 
> ----- Ursprüngliche Mail -----
> > Von: "Alexander Usyskin" <alexander.usyskin@intel.com>
> > In general, it is fine for me - we have parent mtd initialized and participating
> > in power management.
> >
> > I can't see how to bend idr_alloc to allocate from the end and corner case
> > of full idr range is also will be problematic.
> 
> I expected it to work because we can track the highest mtd ID and pass limits
> to idr_alloc(), no?
> 
> Thanks,
> //richard

This will produce different ids if there are two mtd chips.
E.g.:
Before patches:
0 - first chip partition 1 - second chip partition
After patches:
0 - first chip partition 1 - first chip master
2 - second chip partition 3 - second chip master

Or we should manually give region for master's ids at the end
of idr range near UINT_MAX.
And that requires careful manual handling of overflows.

Personally, I think it is bad idea to rely on partition number,
but it is the status-quo now.

- - 
Thanks,
Sasha