[U-Boot] [PATCH v2 20/24] dm: mmc: Add support for driver-model block devices

Simon Glass sjg at chromium.org
Sun May 1 21:52:41 CEST 2016


Add support for enabling CONFIG_BLK with MMC. This involves changing a
few functions to use struct udevice and adding a MMC block device driver.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v2: None

 drivers/mmc/mmc.c         | 48 +++++++++++++++++++++++++++++++++++++----------
 drivers/mmc/mmc_private.h |  9 +++++++--
 drivers/mmc/mmc_write.c   |  9 +++++++++
 include/mmc.h             |  4 ++++
 include/part.h            | 18 ------------------
 5 files changed, 58 insertions(+), 30 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 7183afc..74b3d68 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -216,9 +216,17 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
 	return blkcnt;
 }
 
+#ifdef CONFIG_BLK
+static ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
+		       void *dst)
+#else
 static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start,
 		       lbaint_t blkcnt, void *dst)
+#endif
 {
+#ifdef CONFIG_BLK
+	struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
 	int dev_num = block_dev->devnum;
 	int err;
 	lbaint_t cur, blocks_todo = blkcnt;
@@ -580,15 +588,15 @@ static int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
 	return ret;
 }
 
-static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart)
+#ifdef CONFIG_BLK
+static int mmc_select_hwpart(struct udevice *bdev, int hwpart)
 {
-	struct mmc *mmc = find_mmc_device(desc->devnum);
+	struct udevice *mmc_dev = dev_get_parent(bdev);
+	struct mmc *mmc = mmc_get_mmc_dev(mmc_dev);
+	struct blk_desc *desc = dev_get_uclass_platdata(bdev);
 	int ret;
 
-	if (!mmc)
-		return -ENODEV;
-
-	if (mmc->block_dev.hwpart == hwpart)
+	if (desc->hwpart == hwpart)
 		return 0;
 
 	if (mmc->part_config == MMCPART_NOAVAILABLE)
@@ -600,10 +608,10 @@ static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart)
 
 	return 0;
 }
-
-int mmc_select_hwpart(int dev_num, int hwpart)
+#else
+static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart)
 {
-	struct mmc *mmc = find_mmc_device(dev_num);
+	struct mmc *mmc = find_mmc_device(desc->devnum);
 	int ret;
 
 	if (!mmc)
@@ -621,6 +629,7 @@ int mmc_select_hwpart(int dev_num, int hwpart)
 
 	return 0;
 }
+#endif
 
 int mmc_hwpart_config(struct mmc *mmc,
 		      const struct mmc_hwpart_conf *conf,
@@ -1554,7 +1563,6 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
 	mmc->dsr_imp = 0;
 	mmc->dsr = 0xffffffff;
 	/* Setup the universal parts of the block interface just once */
-	bdesc->if_type = IF_TYPE_MMC;
 	bdesc->removable = 1;
 
 	/* setup initial part type */
@@ -1623,6 +1631,7 @@ void mmc_destroy(struct mmc *mmc)
 }
 #endif
 
+#ifndef CONFIG_BLK
 static int mmc_get_dev(int dev, struct blk_desc **descp)
 {
 	struct mmc *mmc = find_mmc_device(dev);
@@ -1638,6 +1647,7 @@ static int mmc_get_dev(int dev, struct blk_desc **descp)
 
 	return 0;
 }
+#endif
 
 /* board-specific MMC power initializations. */
 __weak void board_mmc_power_init(void)
@@ -1729,7 +1739,11 @@ int mmc_init(struct mmc *mmc)
 {
 	int err = 0;
 	unsigned start;
+#ifdef CONFIG_DM_MMC
+	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
 
+	upriv->mmc = mmc;
+#endif
 	if (mmc->has_init)
 		return 0;
 
@@ -1957,6 +1971,19 @@ int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
 }
 #endif
 
+#ifdef CONFIG_BLK
+static const struct blk_ops mmc_blk_ops = {
+	.read	= mmc_bread,
+	.write	= mmc_bwrite,
+	.select_hwpart	= mmc_select_hwpart,
+};
+
+U_BOOT_DRIVER(mmc_blk) = {
+	.name		= "mmc_blk",
+	.id		= UCLASS_BLK,
+	.ops		= &mmc_blk_ops,
+};
+#else
 U_BOOT_LEGACY_BLK(mmc) = {
 	.if_typename	= "mmc",
 	.if_type	= IF_TYPE_MMC,
@@ -1964,3 +1991,4 @@ U_BOOT_LEGACY_BLK(mmc) = {
 	.get_dev	= mmc_get_dev,
 	.select_hwpart	= mmc_select_hwpartp,
 };
+#endif
diff --git a/drivers/mmc/mmc_private.h b/drivers/mmc/mmc_private.h
index 6ec52fd..27b9e5f 100644
--- a/drivers/mmc/mmc_private.h
+++ b/drivers/mmc/mmc_private.h
@@ -25,8 +25,13 @@ void mmc_adapter_card_type_ident(void);
 unsigned long mmc_berase(struct blk_desc *block_dev, lbaint_t start,
 			 lbaint_t blkcnt);
 
-unsigned long mmc_bwrite(struct blk_desc *block_dev, lbaint_t start,
-			 lbaint_t blkcnt, const void *src);
+#ifdef CONFIG_BLK
+ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
+		 const void *src);
+#else
+ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
+		 const void *src);
+#endif
 
 #else /* CONFIG_SPL_BUILD */
 
diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
index bd07b20..0f8b5c7 100644
--- a/drivers/mmc/mmc_write.c
+++ b/drivers/mmc/mmc_write.c
@@ -9,6 +9,7 @@
 
 #include <config.h>
 #include <common.h>
+#include <dm.h>
 #include <part.h>
 #include <div64.h>
 #include <linux/math64.h>
@@ -172,9 +173,17 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
 	return blkcnt;
 }
 
+#ifdef CONFIG_BLK
+ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
+		 const void *src)
+#else
 ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
 		 const void *src)
+#endif
 {
+#ifdef CONFIG_BLK
+	struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
+#endif
 	int dev_num = block_dev->devnum;
 	lbaint_t cur, blocks_todo = blkcnt;
 	int err;
diff --git a/include/mmc.h b/include/mmc.h
index fb8d9b2..a5c6573 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -344,7 +344,9 @@ struct mmc_config {
 
 /* TODO struct mmc should be in mmc_private but it's hard to fix right now */
 struct mmc {
+#ifndef CONFIG_BLK
 	struct list_head link;
+#endif
 	const struct mmc_config *cfg;	/* provided configuration */
 	uint version;
 	void *priv;
@@ -376,7 +378,9 @@ struct mmc {
 	u64 capacity_gp[4];
 	u64 enh_user_start;
 	u64 enh_user_size;
+#ifndef CONFIG_BLK
 	struct blk_desc block_dev;
+#endif
 	char op_cond_pending;	/* 1 if we are waiting on an op_cond command */
 	char init_in_progress;	/* 1 if we have done mmc_start_init() */
 	char preinit;		/* start init as early as possible */
diff --git a/include/part.h b/include/part.h
index bc9dc64..226b5be 100644
--- a/include/part.h
+++ b/include/part.h
@@ -73,23 +73,6 @@ typedef struct disk_partition {
  */
 struct blk_desc *blk_get_dev(const char *ifname, int dev);
 
-/**
- * mmc_select_hwpart() - Select the MMC hardware partiion on an MMC device
- *
- * MMC devices can support partitioning at the hardware level. This is quite
- * separate from the normal idea of software-based partitions. MMC hardware
- * partitions must be explicitly selected. Once selected only the region of
- * the device covered by that partition is accessible.
- *
- * The MMC standard provides for two boot partitions (numbered 1 and 2),
- * rpmb (3), and up to 4 addition general-purpose partitions (4-7).
- *
- * @dev_num:	Block device number (struct blk_desc->dev value)
- * @hwpart:	Hardware partition number to select. 0 means the raw device,
- *		1 is the first partition, 2 is the second, etc.
- * @return 0 if OK, other value for an error
- */
-int mmc_select_hwpart(int dev_num, int hwpart);
 struct blk_desc *mg_disk_get_dev(int dev);
 int host_get_dev_err(int dev, struct blk_desc **blk_devp);
 
@@ -167,7 +150,6 @@ extern const struct block_drvr block_drvr[];
 #else
 static inline struct blk_desc *blk_get_dev(const char *ifname, int dev)
 { return NULL; }
-static inline int mmc_select_hwpart(int dev_num, int hwpart) { return -1; }
 static inline struct blk_desc *mg_disk_get_dev(int dev) { return NULL; }
 
 static inline int part_get_info(struct blk_desc *dev_desc, int part,
-- 
2.8.0.rc3.226.g39d4020



More information about the U-Boot mailing list