From dfe86cba7676d58db8de7e623f5e72f1b0d3ca35 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 11 Aug 2010 14:17:46 -0700 Subject: mmc: add erase, secure erase, trim and secure trim operations SD/MMC cards tend to support an erase operation. In addition, eMMC v4.4 cards can support secure erase, trim and secure trim operations that are all variants of the basic erase command. SD/MMC device attributes "erase_size" and "preferred_erase_size" have been added. "erase_size" is the minimum size, in bytes, of an erase operation. For MMC, "erase_size" is the erase group size reported by the card. Note that "erase_size" does not apply to trim or secure trim operations where the minimum size is always one 512 byte sector. For SD, "erase_size" is 512 if the card is block-addressed, 0 otherwise. SD/MMC cards can erase an arbitrarily large area up to and including the whole card. When erasing a large area it may be desirable to do it in smaller chunks for three reasons: 1. A single erase command will make all other I/O on the card wait. This is not a problem if the whole card is being erased, but erasing one partition will make I/O for another partition on the same card wait for the duration of the erase - which could be a several minutes. 2. To be able to inform the user of erase progress. 3. The erase timeout becomes too large to be very useful. Because the erase timeout contains a margin which is multiplied by the size of the erase area, the value can end up being several minutes for large areas. "erase_size" is not the most efficient unit to erase (especially for SD where it is just one sector), hence "preferred_erase_size" provides a good chunk size for erasing large areas. For MMC, "preferred_erase_size" is the high-capacity erase size if a card specifies one, otherwise it is based on the capacity of the card. For SD, "preferred_erase_size" is the allocation unit size specified by the card. "preferred_erase_size" is in bytes. Signed-off-by: Adrian Hunter Acked-by: Jens Axboe Cc: Kyungmin Park Cc: Madhusudhan Chikkature Cc: Christoph Hellwig Cc: Ben Gardiner Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmc/core.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include/linux/mmc/core.h') diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index e4898e9eeb59..7429033acb66 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -92,6 +92,8 @@ struct mmc_command { * actively failing requests */ + unsigned int erase_timeout; /* in milliseconds */ + struct mmc_data *data; /* data segment associated with cmd */ struct mmc_request *mrq; /* associated request */ }; @@ -134,6 +136,23 @@ extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, struct mmc_command *, int); +#define MMC_ERASE_ARG 0x00000000 +#define MMC_SECURE_ERASE_ARG 0x80000000 +#define MMC_TRIM_ARG 0x00000001 +#define MMC_SECURE_TRIM1_ARG 0x80000001 +#define MMC_SECURE_TRIM2_ARG 0x80008000 + +#define MMC_SECURE_ARGS 0x80000000 +#define MMC_TRIM_ARGS 0x00008001 + +extern int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, + unsigned int arg); +extern int mmc_can_erase(struct mmc_card *card); +extern int mmc_can_trim(struct mmc_card *card); +extern int mmc_can_secure_erase_trim(struct mmc_card *card); +extern int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, + unsigned int nr); + extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int); -- cgit v1.2.3 From dfc13e8402c75e7c2e0a52e123c0500a3259866b Mon Sep 17 00:00:00 2001 From: Hanumath Prasad Date: Thu, 30 Sep 2010 17:37:23 -0400 Subject: mmc: MMC 4.4 DDR support Add support for Dual Data Rate MMC cards as defined in the 4.4 specification. Signed-off-by: Hanumath Prasad Cc: linux-mmc@vger.kernel.org Acked-by: Linus Walleij Tested-by Zhangfei Gao Signed-off-by: Chris Ball --- drivers/mmc/card/block.c | 10 +++++++--- drivers/mmc/core/mmc.c | 37 +++++++++++++++++++++++++++++++++++-- include/linux/mmc/card.h | 4 ++++ include/linux/mmc/core.h | 1 + include/linux/mmc/host.h | 4 ++++ include/linux/mmc/mmc.h | 10 +++++++++- 6 files changed, 60 insertions(+), 6 deletions(-) (limited to 'include/linux/mmc/core.h') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 759a105cb216..aab593480975 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -373,7 +373,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) readcmd = MMC_READ_SINGLE_BLOCK; writecmd = MMC_WRITE_BLOCK; } - + if (mmc_card_ddr_mode(card)) + brq.data.flags |= MMC_DDR_MODE; if (rq_data_dir(req) == READ) { brq.cmd.opcode = readcmd; brq.data.flags |= MMC_DATA_READ; @@ -655,8 +656,11 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) struct mmc_command cmd; int err; - /* Block-addressed cards ignore MMC_SET_BLOCKLEN. */ - if (mmc_card_blockaddr(card)) + /* + * Block-addressed and ddr mode supported cards + * ignore MMC_SET_BLOCKLEN. + */ + if (mmc_card_blockaddr(card) || mmc_card_ddr_mode(card)) return 0; mmc_claim_host(card->host); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 6570c03f9c76..66c4a59fee5f 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -258,6 +258,21 @@ static int mmc_read_ext_csd(struct mmc_card *card) } switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { + case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | + EXT_CSD_CARD_TYPE_26: + card->ext_csd.hs_max_dtr = 52000000; + card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_52; + break; + case EXT_CSD_CARD_TYPE_DDR_1_2V | EXT_CSD_CARD_TYPE_52 | + EXT_CSD_CARD_TYPE_26: + card->ext_csd.hs_max_dtr = 52000000; + card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_2V; + break; + case EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_52 | + EXT_CSD_CARD_TYPE_26: + card->ext_csd.hs_max_dtr = 52000000; + card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_8V; + break; case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: card->ext_csd.hs_max_dtr = 52000000; break; @@ -502,6 +517,18 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, mmc_set_clock(host, max_dtr); + /* + * Activate DDR50 mode (if supported). + */ + if (mmc_card_highspeed(card)) { + if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) + && (host->caps & (MMC_CAP_1_8V_DDR))) + mmc_card_set_ddr_mode(card); + else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) + && (host->caps & (MMC_CAP_1_2V_DDR))) + mmc_card_set_ddr_mode(card); + } + /* * Activate wide bus (if supported). */ @@ -510,10 +537,16 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, unsigned ext_csd_bit, bus_width; if (host->caps & MMC_CAP_8_BIT_DATA) { - ext_csd_bit = EXT_CSD_BUS_WIDTH_8; + if (mmc_card_ddr_mode(card)) + ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_8; + else + ext_csd_bit = EXT_CSD_BUS_WIDTH_8; bus_width = MMC_BUS_WIDTH_8; } else { - ext_csd_bit = EXT_CSD_BUS_WIDTH_4; + if (mmc_card_ddr_mode(card)) + ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_4; + else + ext_csd_bit = EXT_CSD_BUS_WIDTH_4; bus_width = MMC_BUS_WIDTH_4; } diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 7bd49234cd88..8ce082781ccb 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -48,6 +48,7 @@ struct mmc_ext_csd { unsigned int sa_timeout; /* Units: 100ns */ unsigned int hs_max_dtr; unsigned int sectors; + unsigned int card_type; unsigned int hc_erase_size; /* In sectors */ unsigned int hc_erase_timeout; /* In milliseconds */ unsigned int sec_trim_mult; /* Secure trim multiplier */ @@ -113,6 +114,7 @@ struct mmc_card { #define MMC_STATE_READONLY (1<<1) /* card is read-only */ #define MMC_STATE_HIGHSPEED (1<<2) /* card is in high speed mode */ #define MMC_STATE_BLOCKADDR (1<<3) /* card uses block-addressing */ +#define MMC_STATE_HIGHSPEED_DDR (1<<4) /* card is in high speed mode */ unsigned int quirks; /* card quirks */ #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ @@ -154,11 +156,13 @@ struct mmc_card { #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) #define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED) #define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR) +#define mmc_card_ddr_mode(c) ((c)->state & MMC_STATE_HIGHSPEED_DDR) #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) #define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED) #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) +#define mmc_card_set_ddr_mode(c) ((c)->state |= MMC_STATE_HIGHSPEED_DDR) static inline int mmc_card_lenient_fn0(const struct mmc_card *c) { diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 7429033acb66..d0fbcacab52c 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -109,6 +109,7 @@ struct mmc_data { #define MMC_DATA_WRITE (1 << 8) #define MMC_DATA_READ (1 << 9) #define MMC_DATA_STREAM (1 << 10) +#define MMC_DDR_MODE (1 << 11) unsigned int bytes_xfered; diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index ccac56ae1286..6711eb8715ba 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -158,6 +158,10 @@ struct mmc_host { #define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */ #define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */ #define MMC_CAP_ERASE (1 << 10) /* Allow erase/trim commands */ +#define MMC_CAP_1_8V_DDR (1 << 11) /* can support */ + /* DDR mode at 1.8V */ +#define MMC_CAP_1_2V_DDR (1 << 12) /* can support */ + /* DDR mode at 1.2V */ mmc_pm_flag_t pm_caps; /* supported pm features */ diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index dd11ae51fb68..956fbd877692 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -277,11 +277,19 @@ struct _mmc_csd { #define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */ #define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */ -#define EXT_CSD_CARD_TYPE_MASK 0x3 /* Mask out reserved and DDR bits */ +#define EXT_CSD_CARD_TYPE_MASK 0xF /* Mask out reserved bits */ +#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */ + /* DDR mode @1.8V or 3V I/O */ +#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */ + /* DDR mode @1.2V I/O */ +#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \ + | EXT_CSD_CARD_TYPE_DDR_1_2V) #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */ +#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */ +#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */ #define EXT_CSD_SEC_ER_EN BIT(0) #define EXT_CSD_SEC_BD_BLK_EN BIT(2) -- cgit v1.2.3 From 0f8d8ea64ec7c77ca5beb59534d386fe0235961a Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 24 Aug 2010 13:20:26 +0300 Subject: mmc: Fixes for Dual Data Rate (DDR) support The DDR support patch needs the following fixes: - The block driver does not need to know about DDR, any more than it needs to know about bus width. - Not only the card must be switched to DDR mode. The host controller must also be configured, which is done through the 'set_ios()' function. - Do not set the DDR mode state until after the switch command is successful. - Setting block length is not supported in DDR mode. Make that a core function and change the other place it is used (mmc_test) also. Signed-off-by: Adrian Hunter Signed-off-by: Chris Ball --- drivers/mmc/card/block.c | 19 +++---------------- drivers/mmc/card/mmc_test.c | 12 +----------- drivers/mmc/core/bus.c | 6 ++++-- drivers/mmc/core/core.c | 28 ++++++++++++++++++++++++++-- drivers/mmc/core/core.h | 1 + drivers/mmc/core/mmc.c | 21 +++++++++++---------- include/linux/mmc/core.h | 3 ++- include/linux/mmc/host.h | 5 +++++ 8 files changed, 53 insertions(+), 42 deletions(-) (limited to 'include/linux/mmc/core.h') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index aab593480975..a9970504cabb 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -373,8 +373,6 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) readcmd = MMC_READ_SINGLE_BLOCK; writecmd = MMC_WRITE_BLOCK; } - if (mmc_card_ddr_mode(card)) - brq.data.flags |= MMC_DDR_MODE; if (rq_data_dir(req) == READ) { brq.cmd.opcode = readcmd; brq.data.flags |= MMC_DATA_READ; @@ -653,26 +651,15 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) static int mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) { - struct mmc_command cmd; int err; - /* - * Block-addressed and ddr mode supported cards - * ignore MMC_SET_BLOCKLEN. - */ - if (mmc_card_blockaddr(card) || mmc_card_ddr_mode(card)) - return 0; - mmc_claim_host(card->host); - cmd.opcode = MMC_SET_BLOCKLEN; - cmd.arg = 512; - cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; - err = mmc_wait_for_cmd(card->host, &cmd, 5); + err = mmc_set_blocklen(card, 512); mmc_release_host(card->host); if (err) { - printk(KERN_ERR "%s: unable to set block size to %d: %d\n", - md->disk->disk_name, cmd.arg, err); + printk(KERN_ERR "%s: unable to set block size to 512: %d\n", + md->disk->disk_name, err); return -EINVAL; } diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index c38a3a84a455..21adc27f4132 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c @@ -155,17 +155,7 @@ struct mmc_test_card { */ static int mmc_test_set_blksize(struct mmc_test_card *test, unsigned size) { - struct mmc_command cmd; - int ret; - - cmd.opcode = MMC_SET_BLOCKLEN; - cmd.arg = size; - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; - ret = mmc_wait_for_cmd(test->card->host, &cmd, 0); - if (ret) - return ret; - - return 0; + return mmc_set_blocklen(test->card, size); } /* diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index e70bd6641cee..da3c01b214ec 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -253,14 +253,16 @@ int mmc_add_card(struct mmc_card *card) } if (mmc_host_is_spi(card->host)) { - printk(KERN_INFO "%s: new %s%s card on SPI\n", + printk(KERN_INFO "%s: new %s%s%s card on SPI\n", mmc_hostname(card->host), mmc_card_highspeed(card) ? "high speed " : "", + mmc_card_ddr_mode(card) ? "DDR " : "", type); } else { - printk(KERN_INFO "%s: new %s%s card at address %04x\n", + printk(KERN_INFO "%s: new %s%s%s card at address %04x\n", mmc_hostname(card->host), mmc_card_highspeed(card) ? "high speed " : "", + mmc_card_ddr_mode(card) ? "DDR " : "", type, card->rca); } diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 46029d5c0364..7cb352b3b247 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -651,14 +651,23 @@ void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) } /* - * Change data bus width of a host. + * Change data bus width and DDR mode of a host. */ -void mmc_set_bus_width(struct mmc_host *host, unsigned int width) +void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width, int ddr) { host->ios.bus_width = width; + host->ios.ddr = ddr ? MMC_DDR_MODE : MMC_SDR_MODE; mmc_set_ios(host); } +/* + * Change data bus width of a host. + */ +void mmc_set_bus_width(struct mmc_host *host, unsigned int width) +{ + mmc_set_bus_width_ddr(host, width, 0); +} + /** * mmc_vdd_to_ocrbitnum - Convert a voltage to the OCR bit number * @vdd: voltage (mV) @@ -1399,6 +1408,21 @@ int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, } EXPORT_SYMBOL(mmc_erase_group_aligned); +int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen) +{ + struct mmc_command cmd; + + if (mmc_card_blockaddr(card) || mmc_card_ddr_mode(card)) + return 0; + + memset(&cmd, 0, sizeof(struct mmc_command)); + cmd.opcode = MMC_SET_BLOCKLEN; + cmd.arg = blocklen; + cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; + return mmc_wait_for_cmd(card->host, &cmd, 5); +} +EXPORT_SYMBOL(mmc_set_blocklen); + void mmc_rescan(struct work_struct *work) { struct mmc_host *host = diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index a2ca770ca89b..13240d128a69 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -35,6 +35,7 @@ void mmc_set_chip_select(struct mmc_host *host, int mode); void mmc_set_clock(struct mmc_host *host, unsigned int hz); void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); void mmc_set_bus_width(struct mmc_host *host, unsigned int width); +void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width, int ddr); u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); void mmc_set_timing(struct mmc_host *host, unsigned int timing); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 66c4a59fee5f..3ea58ce773ff 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -375,7 +375,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, struct mmc_card *oldcard) { struct mmc_card *card; - int err; + int err, ddr = 0; u32 cid[4]; unsigned int max_dtr; @@ -518,32 +518,32 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, mmc_set_clock(host, max_dtr); /* - * Activate DDR50 mode (if supported). + * Indicate DDR mode (if supported). */ if (mmc_card_highspeed(card)) { if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) && (host->caps & (MMC_CAP_1_8V_DDR))) - mmc_card_set_ddr_mode(card); + ddr = 1; else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) && (host->caps & (MMC_CAP_1_2V_DDR))) - mmc_card_set_ddr_mode(card); + ddr = 1; } /* - * Activate wide bus (if supported). + * Activate wide bus and DDR (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { unsigned ext_csd_bit, bus_width; if (host->caps & MMC_CAP_8_BIT_DATA) { - if (mmc_card_ddr_mode(card)) + if (ddr) ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_8; else ext_csd_bit = EXT_CSD_BUS_WIDTH_8; bus_width = MMC_BUS_WIDTH_8; } else { - if (mmc_card_ddr_mode(card)) + if (ddr) ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_4; else ext_csd_bit = EXT_CSD_BUS_WIDTH_4; @@ -557,12 +557,13 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, goto free_card; if (err) { - printk(KERN_WARNING "%s: switch to bus width %d " + printk(KERN_WARNING "%s: switch to bus width %d ddr %d " "failed\n", mmc_hostname(card->host), - 1 << bus_width); + 1 << bus_width, ddr); err = 0; } else { - mmc_set_bus_width(card->host, bus_width); + mmc_card_set_ddr_mode(card); + mmc_set_bus_width_ddr(card->host, bus_width, ddr); } } diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index d0fbcacab52c..64e013f1cfb8 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -109,7 +109,6 @@ struct mmc_data { #define MMC_DATA_WRITE (1 << 8) #define MMC_DATA_READ (1 << 9) #define MMC_DATA_STREAM (1 << 10) -#define MMC_DDR_MODE (1 << 11) unsigned int bytes_xfered; @@ -154,6 +153,8 @@ extern int mmc_can_secure_erase_trim(struct mmc_card *card); extern int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, unsigned int nr); +extern int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen); + extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 6711eb8715ba..c4fb1c5efc44 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -50,6 +50,11 @@ struct mmc_ios { #define MMC_TIMING_LEGACY 0 #define MMC_TIMING_MMC_HS 1 #define MMC_TIMING_SD_HS 2 + + unsigned char ddr; /* dual data rate used */ + +#define MMC_SDR_MODE 0 +#define MMC_DDR_MODE 1 }; struct mmc_host_ops { -- cgit v1.2.3