dm: mmc: Add a way to bind MMC devices with driver model
authorSimon Glass <sjg@chromium.org>
Sun, 1 May 2016 19:52:40 +0000 (13:52 -0600)
committerSimon Glass <sjg@chromium.org>
Tue, 17 May 2016 15:54:43 +0000 (09:54 -0600)
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
include/mmc.h

index 4ba13a14e85e03783df790e7b62842489988b15b..7183afcff2af52eafcd6b3f9d9c2b4d9c03509f9 100644 (file)
@@ -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)
 {
index 6d1f05c328c99bb1cd215b420f3435affe94304b..fb8d9b2f55d7c77385556b6c34cbe49104625359 100644 (file)
@@ -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);