diff mbox

[U-Boot,19/23] dm: mmc: Add a way to bind MMC devices with driver model

Message ID 1460337163-5584-20-git-send-email-sjg@chromium.org
State Accepted
Commit ad27dd5e13436b554f0f3cb9cd3e79634494072d
Delegated to: Simon Glass
Headers show

Commit Message

Simon Glass April 11, 2016, 1:12 a.m. UTC
Binding an MMC device when CONFIG_BLK is enabled requires that a block
device be bound as a child of the MMC device. Add a function to do this.
The mmc_create() method will be used only when DM_BLK is disabled.

Add an unbind method also.

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

 drivers/mmc/mmc.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/mmc.h     | 22 ++++++++++++++++++++++
 2 files changed, 70 insertions(+)
diff mbox

Patch

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 4ba13a1..7183afc 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1531,6 +1531,53 @@  int __deprecated mmc_register(struct mmc *mmc)
 	return -1;
 }
 
+#ifdef CONFIG_BLK
+int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
+{
+	struct blk_desc *bdesc;
+	struct udevice *bdev;
+	int ret;
+
+	ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC, -1, 512,
+				 0, &bdev);
+	if (ret) {
+		debug("Cannot create block device\n");
+		return ret;
+	}
+	bdesc = dev_get_uclass_platdata(bdev);
+	mmc->cfg = cfg;
+	mmc->priv = dev;
+
+	/* the following chunk was from mmc_register() */
+
+	/* Setup dsr related values */
+	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 */
+	bdesc->part_type = mmc->cfg->part_type;
+	mmc->dev = dev;
+
+	return 0;
+}
+
+int mmc_unbind(struct udevice *dev)
+{
+	struct udevice *bdev;
+
+	device_find_first_child(dev, &bdev);
+	if (bdev) {
+		device_remove(bdev);
+		device_unbind(bdev);
+	}
+
+	return 0;
+}
+
+#else
 struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
 {
 	struct blk_desc *bdesc;
@@ -1574,6 +1621,7 @@  void mmc_destroy(struct mmc *mmc)
 	/* only freeing memory for now */
 	free(mmc);
 }
+#endif
 
 static int mmc_get_dev(int dev, struct blk_desc **descp)
 {
diff --git a/include/mmc.h b/include/mmc.h
index 6d1f05c..fb8d9b2 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -409,7 +409,29 @@  enum mmc_hwpart_conf_mode {
 
 int mmc_register(struct mmc *mmc);
 struct mmc *mmc_create(const struct mmc_config *cfg, void *priv);
+
+/**
+ * mmc_bind() - Set up a new MMC device ready for probing
+ *
+ * A child block device is bound with the IF_TYPE_MMC interface type. This
+ * allows the device to be used with CONFIG_BLK
+ *
+ * @dev:	MMC device to set up
+ * @mmc:	MMC struct
+ * @cfg:	MMC configuration
+ * @return 0 if OK, -ve on error
+ */
+int mmc_bind(struct udevice *dev, struct mmc *mmc,
+	     const struct mmc_config *cfg);
 void mmc_destroy(struct mmc *mmc);
+
+/**
+ * mmc_unbind() - Unbind a MMC device's child block device
+ *
+ * @dev:	MMC device
+ * @return 0 if OK, -ve on error
+ */
+int mmc_unbind(struct udevice *dev);
 int mmc_initialize(bd_t *bis);
 int mmc_init(struct mmc *mmc);
 int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);