diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 9077a82876f277f3dccfa3f7f8e41af2975a90cf..7dde95d4b1e858fd12c881afb1617033e12e33f0 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -12,6 +12,8 @@
 		eth3 = &eth_3;
 		eth5 = &eth_5;
 		i2c0 = "/i2c@0";
+		mmc0 = "/mmc0";
+		mmc1 = "/mmc1";
 		pci0 = &pci;
 		remoteproc1 = &rproc_1;
 		remoteproc2 = &rproc_2;
@@ -259,7 +261,15 @@
 		mbox-names = "other", "test";
 	};
 
-	mmc {
+	mmc2 {
+		compatible = "sandbox,mmc";
+	};
+
+	mmc1 {
+		compatible = "sandbox,mmc";
+	};
+
+	mmc0 {
 		compatible = "sandbox,mmc";
 	};
 
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index 881c39f77471d327e08ec06b7e0bad2c24ae4a12..614567527182956ba5ff9e260087dfcbc76d5679 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -486,6 +486,31 @@ static int blk_next_free_devnum(enum if_type if_type)
 	return ret + 1;
 }
 
+static int blk_claim_devnum(enum if_type if_type, int devnum)
+{
+	struct udevice *dev;
+	struct uclass *uc;
+	int ret;
+
+	ret = uclass_get(UCLASS_BLK, &uc);
+	if (ret)
+		return ret;
+	uclass_foreach_dev(dev, uc) {
+		struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+		if (desc->if_type == if_type && desc->devnum == devnum) {
+			int next = blk_next_free_devnum(if_type);
+
+			if (next < 0)
+				return next;
+			desc->devnum = next;
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
 int blk_create_device(struct udevice *parent, const char *drv_name,
 		      const char *name, int if_type, int devnum, int blksz,
 		      lbaint_t size, struct udevice **devp)
@@ -495,11 +520,14 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
 	int ret;
 
 	if (devnum == -1) {
-		ret = blk_next_free_devnum(if_type);
-		if (ret < 0)
+		devnum = blk_next_free_devnum(if_type);
+	} else {
+		ret = blk_claim_devnum(if_type, devnum);
+		if (ret < 0 && ret != -ENOENT)
 			return ret;
-		devnum = ret;
 	}
+	if (devnum < 0)
+		return devnum;
 	ret = device_bind_driver(parent, drv_name, name, &dev);
 	if (ret)
 		return ret;
diff --git a/test/dm/blk.c b/test/dm/blk.c
index 3e34336fae1d2db895fda0ccd4e5b96204b55c44..5c5eb829a023379f606ed4623973f2cafb93161c 100644
--- a/test/dm/blk.c
+++ b/test/dm/blk.c
@@ -83,12 +83,12 @@ static int dm_test_blk_usb(struct unit_test_state *uts)
 	ut_asserteq_ptr(usb_dev, dev_get_parent(dev));
 
 	/* Check we have one block device for each mass storage device */
-	ut_asserteq(4, count_blk_devices());
+	ut_asserteq(6, count_blk_devices());
 
 	/* Now go around again, making sure the old devices were unbound */
 	ut_assertok(usb_stop());
 	ut_assertok(usb_init());
-	ut_asserteq(4, count_blk_devices());
+	ut_asserteq(6, count_blk_devices());
 	ut_assertok(usb_stop());
 
 	return 0;
@@ -115,3 +115,38 @@ static int dm_test_blk_find(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_blk_find, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that block device numbering works as expected */
+static int dm_test_blk_devnum(struct unit_test_state *uts)
+{
+	struct udevice *dev, *mmc_dev, *parent;
+	int i;
+
+	/*
+	 * Probe the devices, with the first one being probed last. This is the
+	 * one with no alias / sequence numnber.
+	 */
+	ut_assertok(uclass_get_device(UCLASS_MMC, 1, &dev));
+	ut_assertok(uclass_get_device(UCLASS_MMC, 2, &dev));
+	ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
+	for (i = 0; i < 3; i++) {
+		struct blk_desc *desc;
+
+		/* Check that the bblock device is attached */
+		ut_assertok(uclass_get_device_by_seq(UCLASS_MMC, i, &mmc_dev));
+		ut_assertok(blk_find_device(IF_TYPE_MMC, i, &dev));
+		parent = dev_get_parent(dev);
+		ut_asserteq_ptr(parent, mmc_dev);
+		ut_asserteq(trailing_strtol(mmc_dev->name), i);
+
+		/*
+		 * Check that the block device devnum matches its parent's
+		 * sequence number
+		 */
+		desc = dev_get_uclass_platdata(dev);
+		ut_asserteq(desc->devnum, i);
+	}
+
+	return 0;
+}
+DM_TEST(dm_test_blk_devnum, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);