summaryrefslogtreecommitdiff
path: root/drivers/mmc/core
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-02-22 09:05:28 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2021-02-22 09:05:28 -0800
commit19472481bf58f7c6c939668be885bd300afcb6c6 (patch)
tree2ea5dff1cbdc6f6552ed803f635a5f632b4f8943 /drivers/mmc/core
parent32c080c4b5cfadeb1d1d5952840d696d5cda8bb8 (diff)
parenta56f44138a2c57047f1ea94ea121af31c595132b (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/Kconfig8
-rw-r--r--drivers/mmc/core/Makefile1
-rw-r--r--drivers/mmc/core/block.c3
-rw-r--r--drivers/mmc/core/core.c11
-rw-r--r--drivers/mmc/core/crypto.c48
-rw-r--r--drivers/mmc/core/crypto.h40
-rw-r--r--drivers/mmc/core/host.c45
-rw-r--r--drivers/mmc/core/mmc.c6
-rw-r--r--drivers/mmc/core/mmc_ops.c6
-rw-r--r--drivers/mmc/core/mmc_test.c31
-rw-r--r--drivers/mmc/core/queue.c6
-rw-r--r--drivers/mmc/core/queue.h1
-rw-r--r--drivers/mmc/core/sd.c4
-rw-r--r--drivers/mmc/core/sd.h2
-rw-r--r--drivers/mmc/core/sdio.c2
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;