aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyungmin Park <kyungmin.park@samsung.com>2011-10-17 20:34:04 -0400
committerChris Ball <cjb@laptop.org>2011-10-26 16:32:27 -0400
commitb3bf915308ca2b50f3beec6cc824083870f0f4b5 (patch)
tree955978242b333e1388358b4b50b5f8f4a5abca04
parentd9ddd62943ee07a75d0428ffcf52f1a747a28c39 (diff)
mmc: core: new discard feature support at eMMC v4.5
MMC v4.5 supports the DISCARD feature (CMD38). It's different from trim and there's no check bit. Currently it's only supported at v4.5. Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r--drivers/mmc/card/block.c4
-rw-r--r--drivers/mmc/core/core.c14
-rw-r--r--drivers/mmc/core/mmc.c4
-rw-r--r--include/linux/mmc/card.h3
-rw-r--r--include/linux/mmc/core.h2
5 files changed, 26 insertions, 1 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index e85816e1634a..370472797fff 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -756,7 +756,9 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
756 from = blk_rq_pos(req); 756 from = blk_rq_pos(req);
757 nr = blk_rq_sectors(req); 757 nr = blk_rq_sectors(req);
758 758
759 if (mmc_can_trim(card)) 759 if (mmc_can_discard(card))
760 arg = MMC_DISCARD_ARG;
761 else if (mmc_can_trim(card))
760 arg = MMC_TRIM_ARG; 762 arg = MMC_TRIM_ARG;
761 else 763 else
762 arg = MMC_ERASE_ARG; 764 arg = MMC_ERASE_ARG;
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index d9836e5a4e59..772de2cdfd1d 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1709,10 +1709,24 @@ int mmc_can_trim(struct mmc_card *card)
1709{ 1709{
1710 if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) 1710 if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)
1711 return 1; 1711 return 1;
1712 if (mmc_can_discard(card))
1713 return 1;
1712 return 0; 1714 return 0;
1713} 1715}
1714EXPORT_SYMBOL(mmc_can_trim); 1716EXPORT_SYMBOL(mmc_can_trim);
1715 1717
1718int mmc_can_discard(struct mmc_card *card)
1719{
1720 /*
1721 * As there's no way to detect the discard support bit at v4.5
1722 * use the s/w feature support filed.
1723 */
1724 if (card->ext_csd.feature_support & MMC_DISCARD_FEATURE)
1725 return 1;
1726 return 0;
1727}
1728EXPORT_SYMBOL(mmc_can_discard);
1729
1716int mmc_can_sanitize(struct mmc_card *card) 1730int mmc_can_sanitize(struct mmc_card *card)
1717{ 1731{
1718 if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE) 1732 if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE)
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index f8ea9387d75c..54088768776c 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -452,6 +452,10 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
452 card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION]; 452 card->ext_csd.rst_n_function = ext_csd[EXT_CSD_RST_N_FUNCTION];
453 } 453 }
454 454
455 /* eMMC v4.5 or later */
456 if (card->ext_csd.rev >= 6)
457 card->ext_csd.feature_support |= MMC_DISCARD_FEATURE;
458
455 card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT]; 459 card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT];
456 if (ext_csd[EXT_CSD_ERASED_MEM_CONT]) 460 if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
457 card->erased_byte = 0xFF; 461 card->erased_byte = 0xFF;
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 711c3f8bfabd..551378508784 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -80,6 +80,9 @@ struct mmc_ext_csd {
80 u8 raw_sec_feature_support;/* 231 */ 80 u8 raw_sec_feature_support;/* 231 */
81 u8 raw_trim_mult; /* 232 */ 81 u8 raw_trim_mult; /* 232 */
82 u8 raw_sectors[4]; /* 212 - 4 bytes */ 82 u8 raw_sectors[4]; /* 212 - 4 bytes */
83
84 unsigned int feature_support;
85#define MMC_DISCARD_FEATURE BIT(0) /* CMD38 feature */
83}; 86};
84 87
85struct sd_scr { 88struct sd_scr {
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 9585835cbc42..e918120235bd 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -146,6 +146,7 @@ extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
146#define MMC_ERASE_ARG 0x00000000 146#define MMC_ERASE_ARG 0x00000000
147#define MMC_SECURE_ERASE_ARG 0x80000000 147#define MMC_SECURE_ERASE_ARG 0x80000000
148#define MMC_TRIM_ARG 0x00000001 148#define MMC_TRIM_ARG 0x00000001
149#define MMC_DISCARD_ARG 0x00000003
149#define MMC_SECURE_TRIM1_ARG 0x80000001 150#define MMC_SECURE_TRIM1_ARG 0x80000001
150#define MMC_SECURE_TRIM2_ARG 0x80008000 151#define MMC_SECURE_TRIM2_ARG 0x80008000
151 152
@@ -156,6 +157,7 @@ extern int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr,
156 unsigned int arg); 157 unsigned int arg);
157extern int mmc_can_erase(struct mmc_card *card); 158extern int mmc_can_erase(struct mmc_card *card);
158extern int mmc_can_trim(struct mmc_card *card); 159extern int mmc_can_trim(struct mmc_card *card);
160extern int mmc_can_discard(struct mmc_card *card);
159extern int mmc_can_sanitize(struct mmc_card *card); 161extern int mmc_can_sanitize(struct mmc_card *card);
160extern int mmc_can_secure_erase_trim(struct mmc_card *card); 162extern int mmc_can_secure_erase_trim(struct mmc_card *card);
161extern int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from, 163extern int mmc_erase_group_aligned(struct mmc_card *card, unsigned int from,