diff options
-rw-r--r-- | drivers/mmc/core/core.c | 8 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 10 | ||||
-rw-r--r-- | include/linux/mmc/sd.h | 1 |
3 files changed, 14 insertions, 5 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index b45aaa904107..681b089f669a 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -1847,7 +1847,7 @@ static unsigned int mmc_align_erase_size(struct mmc_card *card, | |||
1847 | * @card: card to erase | 1847 | * @card: card to erase |
1848 | * @from: first sector to erase | 1848 | * @from: first sector to erase |
1849 | * @nr: number of sectors to erase | 1849 | * @nr: number of sectors to erase |
1850 | * @arg: erase command argument (SD supports only %SD_ERASE_ARG) | 1850 | * @arg: erase command argument |
1851 | * | 1851 | * |
1852 | * Caller must claim host before calling this function. | 1852 | * Caller must claim host before calling this function. |
1853 | */ | 1853 | */ |
@@ -1864,14 +1864,14 @@ int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, | |||
1864 | if (!card->erase_size) | 1864 | if (!card->erase_size) |
1865 | return -EOPNOTSUPP; | 1865 | return -EOPNOTSUPP; |
1866 | 1866 | ||
1867 | if (mmc_card_sd(card) && arg != SD_ERASE_ARG) | 1867 | if (mmc_card_sd(card) && arg != SD_ERASE_ARG && arg != SD_DISCARD_ARG) |
1868 | return -EOPNOTSUPP; | 1868 | return -EOPNOTSUPP; |
1869 | 1869 | ||
1870 | if ((arg & MMC_SECURE_ARGS) && | 1870 | if (mmc_card_mmc(card) && (arg & MMC_SECURE_ARGS) && |
1871 | !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN)) | 1871 | !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN)) |
1872 | return -EOPNOTSUPP; | 1872 | return -EOPNOTSUPP; |
1873 | 1873 | ||
1874 | if ((arg & MMC_TRIM_ARGS) && | 1874 | if (mmc_card_mmc(card) && (arg & MMC_TRIM_ARGS) && |
1875 | !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)) | 1875 | !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)) |
1876 | return -EOPNOTSUPP; | 1876 | return -EOPNOTSUPP; |
1877 | 1877 | ||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index c2db94dab711..2b4fc2205b53 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -231,6 +231,8 @@ static int mmc_read_ssr(struct mmc_card *card) | |||
231 | { | 231 | { |
232 | unsigned int au, es, et, eo; | 232 | unsigned int au, es, et, eo; |
233 | __be32 *raw_ssr; | 233 | __be32 *raw_ssr; |
234 | u32 resp[4] = {}; | ||
235 | u8 discard_support; | ||
234 | int i; | 236 | int i; |
235 | 237 | ||
236 | if (!(card->csd.cmdclass & CCC_APP_SPEC)) { | 238 | if (!(card->csd.cmdclass & CCC_APP_SPEC)) { |
@@ -276,7 +278,13 @@ static int mmc_read_ssr(struct mmc_card *card) | |||
276 | } | 278 | } |
277 | } | 279 | } |
278 | 280 | ||
279 | card->erase_arg = SD_ERASE_ARG; | 281 | /* |
282 | * starting SD5.1 discard is supported if DISCARD_SUPPORT (b313) is set | ||
283 | */ | ||
284 | resp[3] = card->raw_ssr[6]; | ||
285 | discard_support = UNSTUFF_BITS(resp, 313 - 288, 1); | ||
286 | card->erase_arg = (card->scr.sda_specx && discard_support) ? | ||
287 | SD_DISCARD_ARG : SD_ERASE_ARG; | ||
280 | 288 | ||
281 | return 0; | 289 | return 0; |
282 | } | 290 | } |
diff --git a/include/linux/mmc/sd.h b/include/linux/mmc/sd.h index 1a6d10fdf682..ec94a5aa02bb 100644 --- a/include/linux/mmc/sd.h +++ b/include/linux/mmc/sd.h | |||
@@ -95,5 +95,6 @@ | |||
95 | * Erase/discard | 95 | * Erase/discard |
96 | */ | 96 | */ |
97 | #define SD_ERASE_ARG 0x00000000 | 97 | #define SD_ERASE_ARG 0x00000000 |
98 | #define SD_DISCARD_ARG 0x00000001 | ||
98 | 99 | ||
99 | #endif /* LINUX_MMC_SD_H */ | 100 | #endif /* LINUX_MMC_SD_H */ |