From 663acabdc548216d61a9d2b1f789d4e6606f7a52 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 May 2016 11:36:07 -0600 Subject: dm: mmc: Add a legacy block interface for MMC Add a legacy block interface for MMC. Signed-off-by: Simon Glass --- drivers/mmc/mmc.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'drivers/mmc/mmc.c') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index d3c22abfd5..024368c727 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1582,14 +1582,31 @@ void mmc_destroy(struct mmc *mmc) free(mmc); } +static int mmc_get_devp(int dev, struct blk_desc **descp) +{ + struct mmc *mmc = find_mmc_device(dev); + int ret; + + if (!mmc) + return -ENODEV; + ret = mmc_init(mmc); + if (ret) + return ret; + + *descp = &mmc->block_dev; + + return 0; +} + #ifdef CONFIG_PARTITIONS struct blk_desc *mmc_get_dev(int dev) { - struct mmc *mmc = find_mmc_device(dev); - if (!mmc || mmc_init(mmc)) + struct blk_desc *desc; + + if (mmc_get_devp(dev, &desc)) return NULL; - return &mmc->block_dev; + return desc; } #endif @@ -1965,3 +1982,10 @@ int mmc_set_rst_n_function(struct mmc *mmc, u8 enable) enable); } #endif + +U_BOOT_LEGACY_BLK(mmc) = { + .if_typename = "mmc", + .if_type = IF_TYPE_MMC, + .max_devs = -1, + .get_dev = mmc_get_devp, +}; -- cgit v1.2.1 From 3c457f4d2e47cc91385abe15d3c825d0ce1a2b6f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 May 2016 11:36:15 -0600 Subject: dm: mmc: Drop the get_dev() function This function is implemented by the legacy block functions now. Drop it. Signed-off-by: Simon Glass --- drivers/mmc/mmc.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'drivers/mmc/mmc.c') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 024368c727..185d7b2a8e 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1582,7 +1582,7 @@ void mmc_destroy(struct mmc *mmc) free(mmc); } -static int mmc_get_devp(int dev, struct blk_desc **descp) +static int mmc_get_dev(int dev, struct blk_desc **descp) { struct mmc *mmc = find_mmc_device(dev); int ret; @@ -1598,18 +1598,6 @@ static int mmc_get_devp(int dev, struct blk_desc **descp) return 0; } -#ifdef CONFIG_PARTITIONS -struct blk_desc *mmc_get_dev(int dev) -{ - struct blk_desc *desc; - - if (mmc_get_devp(dev, &desc)) - return NULL; - - return desc; -} -#endif - /* board-specific MMC power initializations. */ __weak void board_mmc_power_init(void) { @@ -1987,5 +1975,5 @@ U_BOOT_LEGACY_BLK(mmc) = { .if_typename = "mmc", .if_type = IF_TYPE_MMC, .max_devs = -1, - .get_dev = mmc_get_devp, + .get_dev = mmc_get_dev, }; -- cgit v1.2.1 From ff3882ac23fcfda81284f372924063036bea507b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 May 2016 13:52:25 -0600 Subject: dm: mmc: Move mmc_switch_part() above its callers This function is defined after it is used. In preparation for making it static, move it up a little. Also drop the printf() which should not appear in a driver. Signed-off-by: Simon Glass --- drivers/mmc/mmc.c | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) (limited to 'drivers/mmc/mmc.c') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 185d7b2a8e..2211ac6d99 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -582,30 +582,6 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num) return 0; } -int mmc_select_hwpart(int dev_num, int hwpart) -{ - struct mmc *mmc = find_mmc_device(dev_num); - int ret; - - if (!mmc) - return -ENODEV; - - if (mmc->block_dev.hwpart == hwpart) - return 0; - - if (mmc->part_config == MMCPART_NOAVAILABLE) { - printf("Card doesn't support part_switch\n"); - return -EMEDIUMTYPE; - } - - ret = mmc_switch_part(dev_num, hwpart); - if (ret) - return ret; - - return 0; -} - - int mmc_switch_part(int dev_num, unsigned int part_num) { struct mmc *mmc = find_mmc_device(dev_num); @@ -630,6 +606,27 @@ int mmc_switch_part(int dev_num, unsigned int part_num) return ret; } +int mmc_select_hwpart(int dev_num, int hwpart) +{ + struct mmc *mmc = find_mmc_device(dev_num); + int ret; + + if (!mmc) + return -ENODEV; + + if (mmc->block_dev.hwpart == hwpart) + return 0; + + if (mmc->part_config == MMCPART_NOAVAILABLE) + return -EMEDIUMTYPE; + + ret = mmc_switch_part(dev_num, hwpart); + if (ret) + return ret; + + return 0; +} + int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf, enum mmc_hwpart_conf_mode mode) -- cgit v1.2.1 From e17d1143c1a3f6f9bb1b21acb50e5e6a79855023 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 May 2016 13:52:26 -0600 Subject: dm: mmc: Implement the select_hwpart() method Implement this method so that hardware partitions will work correctly with MMC. Signed-off-by: Simon Glass --- drivers/mmc/mmc.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers/mmc/mmc.c') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 2211ac6d99..e270f5f644 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -606,6 +606,27 @@ int mmc_switch_part(int dev_num, unsigned int part_num) return ret; } +static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart) +{ + struct mmc *mmc = find_mmc_device(desc->devnum); + int ret; + + if (!mmc) + return -ENODEV; + + if (mmc->block_dev.hwpart == hwpart) + return 0; + + if (mmc->part_config == MMCPART_NOAVAILABLE) + return -EMEDIUMTYPE; + + ret = mmc_switch_part(desc->devnum, hwpart); + if (ret) + return ret; + + return 0; +} + int mmc_select_hwpart(int dev_num, int hwpart) { struct mmc *mmc = find_mmc_device(dev_num); @@ -1973,4 +1994,5 @@ U_BOOT_LEGACY_BLK(mmc) = { .if_type = IF_TYPE_MMC, .max_devs = -1, .get_dev = mmc_get_dev, + .select_hwpart = mmc_select_hwpartp, }; -- cgit v1.2.1 From cb5ec33d9096f1f57c5ccc97d44ca0fb771729f5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 May 2016 13:52:27 -0600 Subject: dm: mmc: Add a function to obtain the block device The MMC block device is contained within struct mmc. But with driver model this will not be the case. Add a function to obtain the block device. We can later implement this for CONFIG_BLK. Signed-off-by: Simon Glass --- drivers/mmc/mmc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/mmc/mmc.c') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index e270f5f644..49996a891c 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -24,6 +24,11 @@ static struct list_head mmc_devices; static int cur_dev_num = -1; +struct blk_desc *mmc_get_blk_desc(struct mmc *mmc) +{ + return &mmc->block_dev; +} + __weak int board_mmc_getwp(struct mmc *mmc) { return -1; -- cgit v1.2.1 From 69f45cd53b8ad8bc3afef2cf2410baf58fe75a6f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 May 2016 13:52:29 -0600 Subject: dm: mmc: Use the new select_hwpart() API Avoid calling directly into the MMC code - use the new API call instead. Signed-off-by: Simon Glass --- drivers/mmc/mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mmc/mmc.c') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 49996a891c..7322f33404 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -257,7 +257,7 @@ static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, if (!mmc) return 0; - err = mmc_select_hwpart(dev_num, block_dev->hwpart); + err = blk_dselect_hwpart(block_dev, block_dev->hwpart); if (err < 0) return 0; -- cgit v1.2.1 From c40fdca6b7db469d3982cc44fd68a269adb41b25 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 May 2016 13:52:35 -0600 Subject: dm: mmc: Move the device list into a separate file At present the MMC subsystem maintains its own list of MMC devices. This cannot work with driver model, which needs to maintain this itself. Move the list code into a separate 'legacy' file. The core MMC code remains, and will be shared with the driver-model implementation. Signed-off-by: Simon Glass --- drivers/mmc/mmc.c | 149 +++++++++++++----------------------------------------- 1 file changed, 34 insertions(+), 115 deletions(-) (limited to 'drivers/mmc/mmc.c') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 7322f33404..48aedc212c 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -21,14 +21,6 @@ #include #include "mmc_private.h" -static struct list_head mmc_devices; -static int cur_dev_num = -1; - -struct blk_desc *mmc_get_blk_desc(struct mmc *mmc) -{ - return &mmc->block_dev; -} - __weak int board_mmc_getwp(struct mmc *mmc) { return -1; @@ -183,25 +175,6 @@ int mmc_set_blocklen(struct mmc *mmc, int len) return mmc_send_cmd(mmc, &cmd, NULL); } -struct mmc *find_mmc_device(int dev_num) -{ - struct mmc *m; - struct list_head *entry; - - list_for_each(entry, &mmc_devices) { - m = list_entry(entry, struct mmc, link); - - if (m->block_dev.devnum == dev_num) - return m; - } - -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - printf("MMC Device %d not found\n", dev_num); -#endif - - return NULL; -} - static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start, lbaint_t blkcnt) { @@ -261,10 +234,10 @@ static ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, if (err < 0) return 0; - if ((start + blkcnt) > mmc->block_dev.lba) { + if ((start + blkcnt) > block_dev->lba) { #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n", - start + blkcnt, mmc->block_dev.lba); + start + blkcnt, block_dev->lba); #endif return 0; } @@ -582,7 +555,7 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num) return -1; } - mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len); + mmc_get_blk_desc(mmc)->lba = lldiv(mmc->capacity, mmc->read_bl_len); return 0; } @@ -1062,6 +1035,7 @@ static int mmc_startup(struct mmc *mmc) int timeout = 1000; bool has_parts = false; bool part_completed; + struct blk_desc *bdesc; #ifdef CONFIG_MMC_SPI_CRC_ON if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */ @@ -1358,7 +1332,7 @@ static int mmc_startup(struct mmc *mmc) mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET]; } - err = mmc_set_capacity(mmc, mmc->block_dev.hwpart); + err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart); if (err) return err; @@ -1498,31 +1472,32 @@ static int mmc_startup(struct mmc *mmc) } /* fill in device description */ - mmc->block_dev.lun = 0; - mmc->block_dev.hwpart = 0; - mmc->block_dev.type = 0; - mmc->block_dev.blksz = mmc->read_bl_len; - mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz); - mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len); + bdesc = mmc_get_blk_desc(mmc); + bdesc->lun = 0; + bdesc->hwpart = 0; + bdesc->type = 0; + bdesc->blksz = mmc->read_bl_len; + bdesc->log2blksz = LOG2(bdesc->blksz); + bdesc->lba = lldiv(mmc->capacity, mmc->read_bl_len); #if !defined(CONFIG_SPL_BUILD) || \ (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \ !defined(CONFIG_USE_TINY_PRINTF)) - sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x", + sprintf(bdesc->vendor, "Man %06x Snr %04x%04x", mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff), (mmc->cid[3] >> 16) & 0xffff); - sprintf(mmc->block_dev.product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff, + sprintf(bdesc->product, "%c%c%c%c%c%c", mmc->cid[0] & 0xff, (mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff, (mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff, (mmc->cid[2] >> 24) & 0xff); - sprintf(mmc->block_dev.revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf, + sprintf(bdesc->revision, "%d.%d", (mmc->cid[2] >> 20) & 0xf, (mmc->cid[2] >> 16) & 0xf); #else - mmc->block_dev.vendor[0] = 0; - mmc->block_dev.product[0] = 0; - mmc->block_dev.revision[0] = 0; + bdesc->vendor[0] = 0; + bdesc->product[0] = 0; + bdesc->revision[0] = 0; #endif #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT) - part_init(&mmc->block_dev); + part_init(bdesc); #endif return 0; @@ -1562,6 +1537,7 @@ int __deprecated mmc_register(struct mmc *mmc) struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) { + struct blk_desc *bdesc; struct mmc *mmc; /* quick validation */ @@ -1582,19 +1558,17 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) mmc->dsr_imp = 0; mmc->dsr = 0xffffffff; /* Setup the universal parts of the block interface just once */ - mmc->block_dev.if_type = IF_TYPE_MMC; - mmc->block_dev.devnum = cur_dev_num++; - mmc->block_dev.removable = 1; - mmc->block_dev.block_read = mmc_bread; - mmc->block_dev.block_write = mmc_bwrite; - mmc->block_dev.block_erase = mmc_berase; + bdesc = mmc_get_blk_desc(mmc); + bdesc->if_type = IF_TYPE_MMC; + bdesc->removable = 1; + bdesc->devnum = mmc_get_next_devnum(); + bdesc->block_read = mmc_bread; + bdesc->block_write = mmc_bwrite; + bdesc->block_erase = mmc_berase; /* setup initial part type */ - mmc->block_dev.part_type = mmc->cfg->part_type; - - INIT_LIST_HEAD(&mmc->link); - - list_add_tail(&mmc->link, &mmc_devices); + bdesc->part_type = mmc->cfg->part_type; + mmc_list_add(mmc); return mmc; } @@ -1664,7 +1638,7 @@ int mmc_start_init(struct mmc *mmc) return err; /* The internal partition reset to user partition(0) at every CMD0*/ - mmc->block_dev.hwpart = 0; + mmc_get_blk_desc(mmc)->hwpart = 0; /* Test for SD version 2 */ err = mmc_send_if_cond(mmc); @@ -1744,66 +1718,11 @@ __weak int board_mmc_init(bd_t *bis) return -1; } -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) - -void print_mmc_devices(char separator) -{ - struct mmc *m; - struct list_head *entry; - char *mmc_type; - - list_for_each(entry, &mmc_devices) { - m = list_entry(entry, struct mmc, link); - - if (m->has_init) - mmc_type = IS_SD(m) ? "SD" : "eMMC"; - else - mmc_type = NULL; - - printf("%s: %d", m->cfg->name, m->block_dev.devnum); - if (mmc_type) - printf(" (%s)", mmc_type); - - if (entry->next != &mmc_devices) { - printf("%c", separator); - if (separator != '\n') - puts (" "); - } - } - - printf("\n"); -} - -#else -void print_mmc_devices(char separator) { } -#endif - -int get_mmc_num(void) -{ - return cur_dev_num; -} - void mmc_set_preinit(struct mmc *mmc, int preinit) { mmc->preinit = preinit; } -static void do_preinit(void) -{ - struct mmc *m; - struct list_head *entry; - - list_for_each(entry, &mmc_devices) { - m = list_entry(entry, struct mmc, link); - -#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT - mmc_set_preinit(m, 1); -#endif - if (m->preinit) - mmc_start_init(m); - } -} - #if defined(CONFIG_DM_MMC) && defined(CONFIG_SPL_BUILD) static int mmc_probe(bd_t *bis) { @@ -1856,9 +1775,9 @@ int mmc_initialize(bd_t *bis) return 0; initialized = 1; - INIT_LIST_HEAD (&mmc_devices); - cur_dev_num = 0; - +#ifndef CONFIG_BLK + mmc_list_init(); +#endif ret = mmc_probe(bis); if (ret) return ret; @@ -1867,7 +1786,7 @@ int mmc_initialize(bd_t *bis) print_mmc_devices(','); #endif - do_preinit(); + mmc_do_preinit(); return 0; } -- cgit v1.2.1 From fdbb139f0ce10325b44dd3ec76993f8c8e798395 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 May 2016 13:52:37 -0600 Subject: dm: mmc: Adjust mmc_switch_part() to use a struct mmc Instead of looking up the MMC device by number, just pass it in. This makes it possible to use this function with driver model. Signed-off-by: Simon Glass --- drivers/mmc/mmc.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers/mmc/mmc.c') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 48aedc212c..4ba13a14e8 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -560,14 +560,10 @@ static int mmc_set_capacity(struct mmc *mmc, int part_num) return 0; } -int mmc_switch_part(int dev_num, unsigned int part_num) +static int mmc_switch_part(struct mmc *mmc, unsigned int part_num) { - struct mmc *mmc = find_mmc_device(dev_num); int ret; - if (!mmc) - return -1; - ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF, (mmc->part_config & ~PART_ACCESS_MASK) | (part_num & PART_ACCESS_MASK)); @@ -578,7 +574,7 @@ int mmc_switch_part(int dev_num, unsigned int part_num) */ if ((ret == 0) || ((ret == -ENODEV) && (part_num == 0))) { ret = mmc_set_capacity(mmc, part_num); - mmc->block_dev.hwpart = part_num; + mmc_get_blk_desc(mmc)->hwpart = part_num; } return ret; @@ -598,7 +594,7 @@ static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart) if (mmc->part_config == MMCPART_NOAVAILABLE) return -EMEDIUMTYPE; - ret = mmc_switch_part(desc->devnum, hwpart); + ret = mmc_switch_part(mmc, hwpart); if (ret) return ret; @@ -619,7 +615,7 @@ int mmc_select_hwpart(int dev_num, int hwpart) if (mmc->part_config == MMCPART_NOAVAILABLE) return -EMEDIUMTYPE; - ret = mmc_switch_part(dev_num, hwpart); + ret = mmc_switch_part(mmc, hwpart); if (ret) return ret; -- cgit v1.2.1 From ad27dd5e13436b554f0f3cb9cd3e79634494072d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 May 2016 13:52:40 -0600 Subject: dm: mmc: Add a way to bind MMC devices with driver model 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 --- drivers/mmc/mmc.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'drivers/mmc/mmc.c') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 4ba13a14e8..7183afcff2 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) { -- cgit v1.2.1 From 33fb211dd2706e666db4008801dc0d5903fd82f6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 1 May 2016 13:52:41 -0600 Subject: dm: mmc: Add support for driver-model block devices 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 --- drivers/mmc/mmc.c | 48 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-) (limited to 'drivers/mmc/mmc.c') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 7183afcff2..74b3d68f87 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 -- cgit v1.2.1