diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-02-22 09:05:28 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-02-22 09:05:28 -0800 |
commit | 19472481bf58f7c6c939668be885bd300afcb6c6 (patch) | |
tree | 2ea5dff1cbdc6f6552ed803f635a5f632b4f8943 /drivers/mmc/core | |
parent | 32c080c4b5cfadeb1d1d5952840d696d5cda8bb8 (diff) | |
parent | a56f44138a2c57047f1ea94ea121af31c595132b (diff) |
Merge tag 'mmc-v5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson:
"MMC core:
- Add support for eMMC inline encryption
- Add a helper function to parse DT properties for clock phases
- Some improvements and cleanups for the mmc_test module
MMC host:
- android-goldfish: Remove driver
- cqhci: Add support for eMMC inline encryption
- dw_mmc-zx: Remove driver
- meson-gx: Extend support for scatter-gather to allow SD_IO_RW_EXTENDED
- mmci: Add support for probing bus voltage level translator
- mtk-sd: Address race condition for request timeouts
- sdhci_am654: Add Support for the variant on TI's AM64 SoC
- sdhci-esdhc-imx: Prevent kernel panic at ->remove()
- sdhci-iproc: Add ACPI bindings for the RPi to enable SD and WiFi on RPi4
- sdhci-msm: Add Inline Crypto Engine support
- sdhci-msm: Use actual_clock to improve timeout calculations
- sdhci-of-aspeed: Add Andrew Jeffery as maintainer
- sdhci-of-aspeed: Extend clock support for the AST2600 variant
- sdhci-pci-gli: Increase idle period for low power state for GL9763E
- sdhci-pci-o2micro: Make tuning for SDR104 HW more robust
- sdhci-sirf: Remove driver
- sdhci-xenon: Add support for the AP807 variant
- sunxi-mmc: Add support for the A100 variant
- sunxi-mmc: Ensure host is suspended during system sleep
- tmio: Add detection of data timeout errors
- tmio/renesas_sdhi: Extend support for retuning
- renesas_sdhi_internal_dmac: Add support for the ->pre|post_req() ops"
* tag 'mmc-v5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (86 commits)
mmc: sdhci-esdhc-imx: fix kernel panic when remove module
mmc: host: Retire MMC_GOLDFISH
mmc: cb710: Use new tasklet API
mmc: sdhci-pci-o2micro: Bug fix for SDR104 HW tuning failure
mmc: mmc_test: use erase_arg for mmc_erase command
mmc: wbsd: Use new tasklet API
mmc: via-sdmmc: Use new tasklet API
mmc: uniphier-sd: Use new tasklet API
mmc: tifm_sd: Use new tasklet API
mmc: s3cmci: Use new tasklet API
mmc: omap: Use new tasklet API
mmc: dw_mmc: Use new tasklet API
mmc: au1xmmc: Use new tasklet API
mmc: atmel-mci: Use new tasklet API
mmc: cavium: Replace spin_lock_irqsave with spin_lock in hard IRQ
mmc: queue: Remove unused define
mmc: core: Drop redundant bouncesz from struct mmc_card
mmc: core: Drop redundant member in struct mmc host
mmc: core: Use host instead of card argument to mmc_spi_send_csd()
mmc: core: Exclude unnecessary header file
...
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r-- | drivers/mmc/core/Kconfig | 8 | ||||
-rw-r--r-- | drivers/mmc/core/Makefile | 1 | ||||
-rw-r--r-- | drivers/mmc/core/block.c | 3 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 11 | ||||
-rw-r--r-- | drivers/mmc/core/crypto.c | 48 | ||||
-rw-r--r-- | drivers/mmc/core/crypto.h | 40 | ||||
-rw-r--r-- | drivers/mmc/core/host.c | 45 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 6 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.c | 6 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_test.c | 31 | ||||
-rw-r--r-- | drivers/mmc/core/queue.c | 6 | ||||
-rw-r--r-- | drivers/mmc/core/queue.h | 1 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 4 | ||||
-rw-r--r-- | drivers/mmc/core/sd.h | 2 | ||||
-rw-r--r-- | drivers/mmc/core/sdio.c | 2 |
15 files changed, 169 insertions, 45 deletions
diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig index c12fe13e4b14..ae8b69aee619 100644 --- a/drivers/mmc/core/Kconfig +++ b/drivers/mmc/core/Kconfig @@ -81,3 +81,11 @@ config MMC_TEST This driver is only of interest to those developing or testing a host driver. Most people should say N here. +config MMC_CRYPTO + bool "MMC Crypto Engine Support" + depends on BLK_INLINE_ENCRYPTION + help + Enable Crypto Engine Support in MMC. + Enabling this makes it possible for the kernel to use the crypto + capabilities of the MMC device (if present) to perform crypto + operations on data being transferred to/from the device. diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index 95ffe008ebdf..6a907736cd7a 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile @@ -18,3 +18,4 @@ obj-$(CONFIG_MMC_BLOCK) += mmc_block.o mmc_block-objs := block.o queue.o obj-$(CONFIG_MMC_TEST) += mmc_test.o obj-$(CONFIG_SDIO_UART) += sdio_uart.o +mmc_core-$(CONFIG_MMC_CRYPTO) += crypto.o diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index a1d6b68320ae..d666e24fbe0e 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -51,6 +51,7 @@ #include "block.h" #include "core.h" #include "card.h" +#include "crypto.h" #include "host.h" #include "bus.h" #include "mmc_ops.h" @@ -1247,6 +1248,8 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq, memset(brq, 0, sizeof(struct mmc_blk_request)); + mmc_crypto_prepare_req(mqrq); + brq->mrq.data = &brq->data; brq->mrq.tag = req->tag; diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 19f1ee57fb34..1136b859ddd8 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -37,6 +37,7 @@ #include "core.h" #include "card.h" +#include "crypto.h" #include "bus.h" #include "host.h" #include "sdio_bus.h" @@ -547,10 +548,10 @@ int mmc_cqe_recovery(struct mmc_host *host) host->cqe_ops->cqe_recovery_start(host); memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = MMC_STOP_TRANSMISSION, - cmd.flags = MMC_RSP_R1B | MMC_CMD_AC, + cmd.opcode = MMC_STOP_TRANSMISSION; + cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; cmd.flags &= ~MMC_RSP_CRC; /* Ignore CRC */ - cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT, + cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT; mmc_wait_for_cmd(host, &cmd, 0); memset(&cmd, 0, sizeof(cmd)); @@ -558,7 +559,7 @@ int mmc_cqe_recovery(struct mmc_host *host) cmd.arg = 1; /* Discard entire queue */ cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; cmd.flags &= ~MMC_RSP_CRC; /* Ignore CRC */ - cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT, + cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT; err = mmc_wait_for_cmd(host, &cmd, 0); host->cqe_ops->cqe_recovery_finish(host); @@ -992,6 +993,8 @@ void mmc_set_initial_state(struct mmc_host *host) host->ops->hs400_enhanced_strobe(host, &host->ios); mmc_set_ios(host); + + mmc_crypto_set_initial_state(host); } /** diff --git a/drivers/mmc/core/crypto.c b/drivers/mmc/core/crypto.c new file mode 100644 index 000000000000..419a368f8402 --- /dev/null +++ b/drivers/mmc/core/crypto.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * MMC crypto engine (inline encryption) support + * + * Copyright 2020 Google LLC + */ + +#include <linux/blk-crypto.h> +#include <linux/mmc/host.h> + +#include "core.h" +#include "crypto.h" +#include "queue.h" + +void mmc_crypto_set_initial_state(struct mmc_host *host) +{ + /* Reset might clear all keys, so reprogram all the keys. */ + if (host->caps2 & MMC_CAP2_CRYPTO) + blk_ksm_reprogram_all_keys(&host->ksm); +} + +void mmc_crypto_setup_queue(struct request_queue *q, struct mmc_host *host) +{ + if (host->caps2 & MMC_CAP2_CRYPTO) + blk_ksm_register(&host->ksm, q); +} +EXPORT_SYMBOL_GPL(mmc_crypto_setup_queue); + +void mmc_crypto_prepare_req(struct mmc_queue_req *mqrq) +{ + struct request *req = mmc_queue_req_to_req(mqrq); + struct mmc_request *mrq = &mqrq->brq.mrq; + + if (!req->crypt_keyslot) + return; + + mrq->crypto_enabled = true; + mrq->crypto_key_slot = blk_ksm_get_slot_idx(req->crypt_keyslot); + + /* + * For now we assume that all MMC drivers set max_dun_bytes_supported=4, + * which is the limit for CQHCI crypto. So all DUNs should be 32-bit. + */ + WARN_ON_ONCE(req->crypt_ctx->bc_dun[0] > U32_MAX); + + mrq->data_unit_num = req->crypt_ctx->bc_dun[0]; +} +EXPORT_SYMBOL_GPL(mmc_crypto_prepare_req); diff --git a/drivers/mmc/core/crypto.h b/drivers/mmc/core/crypto.h new file mode 100644 index 000000000000..fbe9a520bf90 --- /dev/null +++ b/drivers/mmc/core/crypto.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * MMC crypto engine (inline encryption) support + * + * Copyright 2020 Google LLC + */ + +#ifndef _MMC_CORE_CRYPTO_H +#define _MMC_CORE_CRYPTO_H + +struct mmc_host; +struct mmc_queue_req; +struct request_queue; + +#ifdef CONFIG_MMC_CRYPTO + +void mmc_crypto_set_initial_state(struct mmc_host *host); + +void mmc_crypto_setup_queue(struct request_queue *q, struct mmc_host *host); + +void mmc_crypto_prepare_req(struct mmc_queue_req *mqrq); + +#else /* CONFIG_MMC_CRYPTO */ + +static inline void mmc_crypto_set_initial_state(struct mmc_host *host) +{ +} + +static inline void mmc_crypto_setup_queue(struct request_queue *q, + struct mmc_host *host) +{ +} + +static inline void mmc_crypto_prepare_req(struct mmc_queue_req *mqrq) +{ +} + +#endif /* !CONFIG_MMC_CRYPTO */ + +#endif /* _MMC_CORE_CRYPTO_H */ diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 96b2ca1f1b06..9b89a91b6b47 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -25,6 +25,7 @@ #include <linux/mmc/slot-gpio.h> #include "core.h" +#include "crypto.h" #include "host.h" #include "slot-gpio.h" #include "pwrseq.h" @@ -163,6 +164,50 @@ static void mmc_retune_timer(struct timer_list *t) mmc_retune_needed(host); } +static void mmc_of_parse_timing_phase(struct device *dev, const char *prop, + struct mmc_clk_phase *phase) +{ + int degrees[2] = {0}; + int rc; + + rc = device_property_read_u32_array(dev, prop, degrees, 2); + phase->valid = !rc; + if (phase->valid) { + phase->in_deg = degrees[0]; + phase->out_deg = degrees[1]; + } +} + +void +mmc_of_parse_clk_phase(struct mmc_host *host, struct mmc_clk_phase_map *map) +{ + struct device *dev = host->parent; + + mmc_of_parse_timing_phase(dev, "clk-phase-legacy", + &map->phase[MMC_TIMING_LEGACY]); + mmc_of_parse_timing_phase(dev, "clk-phase-mmc-hs", + &map->phase[MMC_TIMING_MMC_HS]); + mmc_of_parse_timing_phase(dev, "clk-phase-sd-hs", + &map->phase[MMC_TIMING_SD_HS]); + mmc_of_parse_timing_phase(dev, "clk-phase-uhs-sdr12", + &map->phase[MMC_TIMING_UHS_SDR12]); + mmc_of_parse_timing_phase(dev, "clk-phase-uhs-sdr25", + &map->phase[MMC_TIMING_UHS_SDR25]); + mmc_of_parse_timing_phase(dev, "clk-phase-uhs-sdr50", + &map->phase[MMC_TIMING_UHS_SDR50]); + mmc_of_parse_timing_phase(dev, "clk-phase-uhs-sdr104", + &map->phase[MMC_TIMING_UHS_SDR104]); + mmc_of_parse_timing_phase(dev, "clk-phase-uhs-ddr50", + &map->phase[MMC_TIMING_UHS_DDR50]); + mmc_of_parse_timing_phase(dev, "clk-phase-mmc-ddr52", + &map->phase[MMC_TIMING_MMC_DDR52]); + mmc_of_parse_timing_phase(dev, "clk-phase-mmc-hs200", + &map->phase[MMC_TIMING_MMC_HS200]); + mmc_of_parse_timing_phase(dev, "clk-phase-mmc-hs400", + &map->phase[MMC_TIMING_MMC_HS400]); +} +EXPORT_SYMBOL(mmc_of_parse_clk_phase); + /** * mmc_of_parse() - parse host's device-tree node * @host: host whose node should be parsed. diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index ff3063ce2acd..0d80b72ddde8 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1697,7 +1697,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, goto free_card; if (err) { - err = 0; /* * Just disable enhanced area off & sz * will try to enable ERASE_GROUP_DEF @@ -1802,7 +1801,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, pr_warn("%s: Enabling HPI failed\n", mmc_hostname(card->host)); card->ext_csd.hpi_en = 0; - err = 0; } else { card->ext_csd.hpi_en = 1; } @@ -1831,7 +1829,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, pr_warn("%s: Cache is supported, but failed to turn on (%d)\n", mmc_hostname(card->host), err); card->ext_csd.cache_ctrl = 0; - err = 0; } else { card->ext_csd.cache_ctrl = 1; } @@ -1851,7 +1848,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, mmc_hostname(card->host)); card->ext_csd.cmdq_support = false; card->ext_csd.cmdq_depth = 0; - err = 0; } } /* @@ -1899,7 +1895,7 @@ err: static int mmc_can_sleep(struct mmc_card *card) { - return (card && card->ext_csd.rev >= 3); + return card->ext_csd.rev >= 3; } static int mmc_sleep(struct mmc_host *host) diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index baa6314f69b4..265d95ec82ce 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -296,7 +296,7 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host, return 0; } -static int mmc_spi_send_csd(struct mmc_card *card, u32 *csd) +static int mmc_spi_send_csd(struct mmc_host *host, u32 *csd) { int ret, i; __be32 *csd_tmp; @@ -305,7 +305,7 @@ static int mmc_spi_send_csd(struct mmc_card *card, u32 *csd) if (!csd_tmp) return -ENOMEM; - ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd_tmp, 16); + ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CSD, csd_tmp, 16); if (ret) goto err; @@ -320,7 +320,7 @@ err: int mmc_send_csd(struct mmc_card *card, u32 *csd) { if (mmc_host_is_spi(card->host)) - return mmc_spi_send_csd(card, csd); + return mmc_spi_send_csd(card->host, csd); return mmc_send_cxd_native(card->host, card->rca << 16, csd, MMC_SEND_CSD); diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c index 152e7525ed33..63524551a13a 100644 --- a/drivers/mmc/core/mmc_test.c +++ b/drivers/mmc/core/mmc_test.c @@ -624,7 +624,7 @@ static unsigned int mmc_test_capacity(struct mmc_card *card) * Fill the first couple of sectors of the card with known data * so that bad reads/writes can be detected */ -static int __mmc_test_prepare(struct mmc_test_card *test, int write) +static int __mmc_test_prepare(struct mmc_test_card *test, int write, int val) { int ret, i; @@ -633,7 +633,7 @@ static int __mmc_test_prepare(struct mmc_test_card *test, int write) return ret; if (write) - memset(test->buffer, 0xDF, 512); + memset(test->buffer, val, 512); else { for (i = 0; i < 512; i++) test->buffer[i] = i; @@ -650,31 +650,17 @@ static int __mmc_test_prepare(struct mmc_test_card *test, int write) static int mmc_test_prepare_write(struct mmc_test_card *test) { - return __mmc_test_prepare(test, 1); + return __mmc_test_prepare(test, 1, 0xDF); } static int mmc_test_prepare_read(struct mmc_test_card *test) { - return __mmc_test_prepare(test, 0); + return __mmc_test_prepare(test, 0, 0); } static int mmc_test_cleanup(struct mmc_test_card *test) { - int ret, i; - - ret = mmc_test_set_blksize(test, 512); - if (ret) - return ret; - - memset(test->buffer, 0, 512); - - for (i = 0; i < BUFFER_SIZE / 512; i++) { - ret = mmc_test_buffer_transfer(test, test->buffer, i, 512, 1); - if (ret) - return ret; - } - - return 0; + return __mmc_test_prepare(test, 1, 0); } /*******************************************************************/ @@ -2124,7 +2110,7 @@ static int mmc_test_rw_multiple(struct mmc_test_card *test, if (mmc_can_erase(test->card) && tdata->prepare & MMC_TEST_PREP_ERASE) { ret = mmc_erase(test->card, dev_addr, - size / 512, MMC_SECURE_ERASE_ARG); + size / 512, test->card->erase_arg); if (ret) ret = mmc_erase(test->card, dev_addr, size / 512, MMC_ERASE_ARG); @@ -3267,17 +3253,12 @@ static void mmc_test_remove(struct mmc_card *card) mmc_test_free_dbgfs_file(card); } -static void mmc_test_shutdown(struct mmc_card *card) -{ -} - static struct mmc_driver mmc_driver = { .drv = { .name = "mmc_test", }, .probe = mmc_test_probe, .remove = mmc_test_remove, - .shutdown = mmc_test_shutdown, }; static int __init mmc_test_init(void) diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index 002426e3cf76..27d2b8ed9484 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -7,7 +7,6 @@ #include <linux/module.h> #include <linux/blkdev.h> #include <linux/freezer.h> -#include <linux/kthread.h> #include <linux/scatterlist.h> #include <linux/dma-mapping.h> #include <linux/backing-dev.h> @@ -19,6 +18,7 @@ #include "block.h" #include "core.h" #include "card.h" +#include "crypto.h" #include "host.h" #define MMC_DMA_MAP_MERGE_SEGMENTS 512 @@ -33,8 +33,6 @@ void mmc_cqe_check_busy(struct mmc_queue *mq) { if ((mq->cqe_busy & MMC_CQE_DCMD_BUSY) && !mmc_cqe_dcmd_busy(mq)) mq->cqe_busy &= ~MMC_CQE_DCMD_BUSY; - - mq->cqe_busy &= ~MMC_CQE_QUEUE_FULL; } static inline bool mmc_cqe_can_dcmd(struct mmc_host *host) @@ -407,6 +405,8 @@ static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card) mutex_init(&mq->complete_lock); init_waitqueue_head(&mq->wait); + + mmc_crypto_setup_queue(mq->queue, host); } static inline bool mmc_merge_capable(struct mmc_host *host) diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h index fd11491ced9f..57c59b6cb1b9 100644 --- a/drivers/mmc/core/queue.h +++ b/drivers/mmc/core/queue.h @@ -81,7 +81,6 @@ struct mmc_queue { int in_flight[MMC_ISSUE_MAX]; unsigned int cqe_busy; #define MMC_CQE_DCMD_BUSY BIT(0) -#define MMC_CQE_QUEUE_FULL BIT(1) bool busy; bool use_cqe; bool recovery_needed; diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 6f054c449d46..6fa51a6ed058 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -860,7 +860,7 @@ try_again: return err; } -int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card) +int mmc_sd_get_csd(struct mmc_card *card) { int err; @@ -1046,7 +1046,7 @@ retry: } if (!oldcard) { - err = mmc_sd_get_csd(host, card); + err = mmc_sd_get_csd(card); if (err) goto free_card; diff --git a/drivers/mmc/core/sd.h b/drivers/mmc/core/sd.h index 497c026a5c5a..1af5a038bae9 100644 --- a/drivers/mmc/core/sd.h +++ b/drivers/mmc/core/sd.h @@ -10,7 +10,7 @@ struct mmc_host; struct mmc_card; int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr); -int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card); +int mmc_sd_get_csd(struct mmc_card *card); void mmc_decode_cid(struct mmc_card *card); int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, bool reinit); diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 694a212cbe25..0fda7784cab2 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -751,7 +751,7 @@ try_again: * Read CSD, before selecting the card */ if (!oldcard && card->type == MMC_TYPE_SD_COMBO) { - err = mmc_sd_get_csd(host, card); + err = mmc_sd_get_csd(card); if (err) goto remove; |