summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-08-21 14:07:16 +0100
committerMark Brown <broonie@kernel.org>2026-08-21 14:07:16 +0100
commit04e480772ce27c05ffbdcb09b25ef96709b6220d (patch)
treee339eb55758c07a1cebe42e4741bfc8ea957c6f8 /drivers
parent7904005d0a38ca6389dbf8c82aedd5a6adac1a6a (diff)
parent35e689fb79dcbaa8d69cc4a58a7ad4d0d7346e4a (diff)
downloadlinux-next-04e480772ce27c05ffbdcb09b25ef96709b6220d.tar.gz
linux-next-04e480772ce27c05ffbdcb09b25ef96709b6220d.zip
Merge branch 'next' of https://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc.git
Diffstat (limited to 'drivers')
-rw-r--r--drivers/misc/cardreader/rtsx_usb.c26
-rw-r--r--drivers/mmc/core/block.c5
-rw-r--r--drivers/mmc/core/sd.c9
-rw-r--r--drivers/mmc/host/alcor.c3
-rw-r--r--drivers/mmc/host/bcm2835.c37
-rw-r--r--drivers/mmc/host/cavium-octeon.c10
-rw-r--r--drivers/mmc/host/cqhci-core.c17
-rw-r--r--drivers/mmc/host/cqhci.h3
-rw-r--r--drivers/mmc/host/dw_mmc-pltfm.h1
-rw-r--r--drivers/mmc/host/dw_mmc.c1
-rw-r--r--drivers/mmc/host/dw_mmc.h2
-rw-r--r--drivers/mmc/host/litex_mmc.c131
-rw-r--r--drivers/mmc/host/meson-mx-sdio.c5
-rw-r--r--drivers/mmc/host/moxart-mmc.c40
-rw-r--r--drivers/mmc/host/mtk-sd.c2
-rw-r--r--drivers/mmc/host/mvsdio.c4
-rw-r--r--drivers/mmc/host/omap_hsmmc.c15
-rw-r--r--drivers/mmc/host/owl-mmc.c5
-rw-r--r--drivers/mmc/host/pxamci.c3
-rw-r--r--drivers/mmc/host/rtsx_usb_sdmmc.c13
-rw-r--r--drivers/mmc/host/sdhci-brcmstb.c2
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c2
-rw-r--r--drivers/mmc/host/sdhci-esdhc-mcf.c24
-rw-r--r--drivers/mmc/host/sdhci-msm.c6
-rw-r--r--drivers/mmc/host/sdhci-of-arasan.c2
-rw-r--r--drivers/mmc/host/sdhci-of-dwcmshc.c3
-rw-r--r--drivers/mmc/host/sdhci-of-ma35d1.c1
-rw-r--r--drivers/mmc/host/sdhci-pci-core.c2
-rw-r--r--drivers/mmc/host/sdhci-pci-gli.c2
-rw-r--r--drivers/mmc/host/sdhci-tegra.c32
-rw-r--r--drivers/mmc/host/sdhci_am654.c2
-rw-r--r--drivers/mmc/host/sh_mmcif.c8
-rw-r--r--drivers/mmc/host/via-sdmmc.c12
-rw-r--r--drivers/mmc/host/wbsd.c6
34 files changed, 206 insertions, 230 deletions
diff --git a/drivers/misc/cardreader/rtsx_usb.c b/drivers/misc/cardreader/rtsx_usb.c
index 1830e9ed2521..a127744918f4 100644
--- a/drivers/misc/cardreader/rtsx_usb.c
+++ b/drivers/misc/cardreader/rtsx_usb.c
@@ -312,6 +312,9 @@ int rtsx_usb_get_card_status(struct rtsx_ucr *ucr, u16 *status)
if (ret < 0)
return ret;
+ ucr->card_status_cache = *status;
+ ucr->card_status_valid = true;
+
return 0;
}
EXPORT_SYMBOL_GPL(rtsx_usb_get_card_status);
@@ -623,6 +626,7 @@ static int rtsx_usb_probe(struct usb_interface *intf,
{
struct usb_device *usb_dev = interface_to_usbdev(intf);
struct rtsx_ucr *ucr;
+ u16 status;
int ret;
dev_dbg(&intf->dev,
@@ -659,6 +663,9 @@ static int rtsx_usb_probe(struct usb_interface *intf,
if (ret)
goto out_init_fail;
+ /* Prime cached status for runtime autosuspend decisions. */
+ rtsx_usb_get_card_status(ucr, &status);
+
/* initialize USB SG transfer timer */
timer_setup(&ucr->sg_timer, rtsx_usb_sg_timed_out, 0);
@@ -713,22 +720,29 @@ static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message)
struct rtsx_ucr *ucr =
(struct rtsx_ucr *)usb_get_intfdata(intf);
u16 val = 0;
+ bool valid = false;
dev_dbg(&intf->dev, "%s called with pm message 0x%04x\n",
__func__, message.event);
if (PMSG_IS_AUTO(message)) {
if (mutex_trylock(&ucr->dev_mutex)) {
- rtsx_usb_get_card_status(ucr, &val);
+ valid = ucr->card_status_valid;
+ if (valid)
+ val = ucr->card_status_cache;
mutex_unlock(&ucr->dev_mutex);
- /* Defer the autosuspend if card exists */
- if (val & (SD_CD | MS_CD)) {
+ /*
+ * Do not issue USB commands from runtime autosuspend.
+ * Raw SD_CD is not authoritative on tray-based readers,
+ * while a real SD card is protected by the SD/MMC child
+ * runtime-PM reference once the card is powered. Keep
+ * the historical Memory Stick autosuspend deferral when
+ * the cached status says MS media is present.
+ */
+ if (valid && (val & MS_CD)) {
device_for_each_child(&intf->dev, NULL, rtsx_usb_resume_child);
return -EAGAIN;
- } else {
- /* if the card does not exists, clear OCP status */
- rtsx_usb_write_register(ucr, OCPCTL, MS_OCP_CLEAR, MS_OCP_CLEAR);
}
} else {
/* There is an ongoing operation*/
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 54a923ba4f1e..e760d13ee325 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -3337,6 +3337,11 @@ static int __init mmc_blk_init(void)
{
int res;
+ if (perdev_minors <= 0) {
+ pr_err("mmcblk: invalid minors per device: %d\n", perdev_minors);
+ return -EINVAL;
+ }
+
res = bus_register(&mmc_rpmb_bus_type);
if (res < 0) {
pr_err("mmcblk: could not register RPMB bus type\n");
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 948948ca9b4a..c763efb10f64 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -1379,15 +1379,10 @@ out:
static int sd_enable_cache(struct mmc_card *card)
{
- u8 *reg_buf;
int err;
card->ext_perf.feature_enabled &= ~SD_EXT_PERF_CACHE;
- reg_buf = kzalloc(512, GFP_KERNEL);
- if (!reg_buf)
- return -ENOMEM;
-
/*
* Set Cache Enable at bit 0 in the performance enhancement register at
* 260 bytes offset.
@@ -1397,7 +1392,7 @@ static int sd_enable_cache(struct mmc_card *card)
if (err) {
pr_warn("%s: error %d writing Cache Enable bit\n",
mmc_hostname(card->host), err);
- goto out;
+ return err;
}
err = mmc_poll_for_busy(card, SD_WRITE_EXTR_SINGLE_TIMEOUT_MS, false,
@@ -1405,8 +1400,6 @@ static int sd_enable_cache(struct mmc_card *card)
if (!err)
card->ext_perf.feature_enabled |= SD_EXT_PERF_CACHE;
-out:
- kfree(reg_buf);
return err;
}
diff --git a/drivers/mmc/host/alcor.c b/drivers/mmc/host/alcor.c
index 721db54739c1..45528909a758 100644
--- a/drivers/mmc/host/alcor.c
+++ b/drivers/mmc/host/alcor.c
@@ -1103,8 +1103,7 @@ static int alcor_pci_sdmmc_drv_probe(struct platform_device *pdev)
alcor_irq, alcor_irq_thread, IRQF_SHARED,
DRV_NAME_ALCOR_PCI_SDMMC, host);
if (ret)
- return dev_err_probe(&pdev->dev, ret,
- "Failed to get irq for data line\n");
+ return ret;
mutex_init(&host->cmd_mutex);
INIT_DELAYED_WORK(&host->timeout_work, alcor_timeout_timer);
diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c
index ee63835b3ca0..c949a3eaae79 100644
--- a/drivers/mmc/host/bcm2835.c
+++ b/drivers/mmc/host/bcm2835.c
@@ -188,7 +188,7 @@ struct bcm2835_host {
u32 drain_words;
struct page *drain_page;
u32 drain_offset;
- bool use_dma;
+ struct device *dma_dev;
};
static void bcm2835_dumpcmd(struct bcm2835_host *host, struct mmc_command *cmd,
@@ -494,8 +494,7 @@ void bcm2835_prepare_dma(struct bcm2835_host *host, struct mmc_data *data)
&host->dma_cfg_rx :
&host->dma_cfg_tx);
- sg_len = dma_map_sg(dma_chan->device->dev, data->sg, data->sg_len,
- dir_data);
+ sg_len = dma_map_sg(host->dma_dev, data->sg, data->sg_len, dir_data);
if (!sg_len)
return;
@@ -503,8 +502,7 @@ void bcm2835_prepare_dma(struct bcm2835_host *host, struct mmc_data *data)
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
- dma_unmap_sg(dma_chan->device->dev, data->sg, data->sg_len,
- dir_data);
+ dma_unmap_sg(host->dma_dev, data->sg, data->sg_len, dir_data);
return;
}
@@ -1057,7 +1055,7 @@ static void bcm2835_dma_complete_work(struct work_struct *work)
data = host->data;
if (host->dma_chan) {
- dma_unmap_sg(host->dma_chan->device->dev,
+ dma_unmap_sg(host->dma_dev,
data->sg, data->sg_len,
host->dma_dir);
@@ -1201,7 +1199,7 @@ static void bcm2835_request(struct mmc_host *mmc, struct mmc_request *mrq)
return;
}
- if (host->use_dma && mrq->data && (mrq->data->blocks > PIO_THRESHOLD))
+ if (host->dma_dev && mrq->data && (mrq->data->blocks > PIO_THRESHOLD))
bcm2835_prepare_dma(host, mrq->data);
host->use_sbc = !!mrq->sbc && host->mrq->data &&
@@ -1281,10 +1279,7 @@ static int bcm2835_add_host(struct bcm2835_host *host)
if (!host->dma_chan_rxtx) {
dev_warn(dev, "unable to initialise DMA channel. Falling back to PIO\n");
- host->use_dma = false;
} else {
- host->use_dma = true;
-
host->dma_cfg_tx.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
host->dma_cfg_tx.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
host->dma_cfg_tx.direction = DMA_MEM_TO_DEV;
@@ -1297,15 +1292,21 @@ static int bcm2835_add_host(struct bcm2835_host *host)
host->dma_cfg_rx.src_addr = host->phys_addr + SDDATA;
host->dma_cfg_rx.dst_addr = 0;
- if (dmaengine_slave_config(host->dma_chan_rxtx,
- &host->dma_cfg_tx) != 0 ||
- dmaengine_slave_config(host->dma_chan_rxtx,
- &host->dma_cfg_rx) != 0)
- host->use_dma = false;
+ if (!dmaengine_slave_config(host->dma_chan_rxtx,
+ &host->dma_cfg_tx) &&
+ !dmaengine_slave_config(host->dma_chan_rxtx,
+ &host->dma_cfg_rx)) {
+ host->dma_dev =
+ dmaengine_get_dma_device(host->dma_chan_rxtx);
+ }
}
mmc->max_segs = 128;
- mmc->max_req_size = min_t(size_t, 524288, dma_max_mapping_size(dev));
+ mmc->max_req_size = 524288;
+ if (host->dma_dev) {
+ mmc->max_req_size = min_t(size_t, mmc->max_req_size,
+ dma_max_mapping_size(host->dma_dev));
+ }
mmc->max_seg_size = mmc->max_req_size;
mmc->max_blk_size = 1024;
mmc->max_blk_count = 65535;
@@ -1336,10 +1337,10 @@ static int bcm2835_add_host(struct bcm2835_host *host)
}
pio_limit_string[0] = '\0';
- if (host->use_dma && (PIO_THRESHOLD > 0))
+ if (host->dma_dev && (PIO_THRESHOLD > 0))
sprintf(pio_limit_string, " (>%d)", PIO_THRESHOLD);
dev_info(dev, "loaded - DMA %s%s\n",
- host->use_dma ? "enabled" : "disabled", pio_limit_string);
+ host->dma_dev ? "enabled" : "disabled", pio_limit_string);
return 0;
}
diff --git a/drivers/mmc/host/cavium-octeon.c b/drivers/mmc/host/cavium-octeon.c
index 8a0daddd9200..1bfc1a4f9fe9 100644
--- a/drivers/mmc/host/cavium-octeon.c
+++ b/drivers/mmc/host/cavium-octeon.c
@@ -240,21 +240,15 @@ static int octeon_mmc_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev, mmc_irq[i],
cvm_mmc_interrupt,
0, cvm_mmc_irq_names[i], host);
- if (ret < 0) {
- dev_err(&pdev->dev, "Error: devm_request_irq %d\n",
- mmc_irq[i]);
+ if (ret < 0)
return ret;
- }
}
} else {
ret = devm_request_irq(&pdev->dev, mmc_irq[0],
cvm_mmc_interrupt, 0, KBUILD_MODNAME,
host);
- if (ret < 0) {
- dev_err(&pdev->dev, "Error: devm_request_irq %d\n",
- mmc_irq[0]);
+ if (ret < 0)
return ret;
- }
}
host->global_pwr_gpiod = devm_gpiod_get_optional(&pdev->dev,
diff --git a/drivers/mmc/host/cqhci-core.c b/drivers/mmc/host/cqhci-core.c
index 178277d90c31..a466cd88b043 100644
--- a/drivers/mmc/host/cqhci-core.c
+++ b/drivers/mmc/host/cqhci-core.c
@@ -484,11 +484,11 @@ void cqhci_set_tran_desc(u8 *desc, dma_addr_t addr, int len, bool end,
{
__le32 *attr = (__le32 __force *)desc;
- *attr = (CQHCI_VALID(1) |
- CQHCI_END(end ? 1 : 0) |
- CQHCI_INT(0) |
- CQHCI_ACT(0x4) |
- CQHCI_DAT_LENGTH(len));
+ *attr = cpu_to_le32((CQHCI_VALID(1) |
+ CQHCI_END(end ? 1 : 0) |
+ CQHCI_INT(0) |
+ CQHCI_ACT(0x4) |
+ CQHCI_DAT_LENGTH(len)));
if (dma64) {
__le64 *dataddr = (__le64 __force *)(desc + 4);
@@ -542,7 +542,7 @@ static int cqhci_prep_tran_desc(struct mmc_request *mrq,
static void cqhci_prep_dcmd_desc(struct mmc_host *mmc,
struct mmc_request *mrq)
{
- u64 *task_desc = NULL;
+ __le64 *task_desc = NULL;
u64 data = 0;
u8 resp_type;
u8 *desc;
@@ -574,7 +574,7 @@ static void cqhci_prep_dcmd_desc(struct mmc_host *mmc,
CQHCI_CMD_TIMING(timing) | CQHCI_RESP_TYPE(resp_type));
if (cq_host->ops->update_dcmd_desc)
cq_host->ops->update_dcmd_desc(mmc, mrq, &data);
- *task_desc |= data;
+ *task_desc |= cpu_to_le64(data);
desc = (u8 *)task_desc;
pr_debug("%s: cqhci: dcmd: cmd: %d timing: %d resp: %d\n",
mmc_hostname(mmc), mrq->cmd->opcode, timing, resp_type);
@@ -819,8 +819,7 @@ static void cqhci_finish_mrq(struct mmc_host *mmc, unsigned int tag)
mmc_cqe_request_done(mmc, mrq);
}
-irqreturn_t cqhci_irq(struct mmc_host *mmc, u32 intmask, int cmd_error,
- int data_error)
+irqreturn_t cqhci_irq(struct mmc_host *mmc, int cmd_error, int data_error)
{
u32 status;
unsigned long tag = 0, comp_status;
diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h
index 3668856531c1..8fbbc48c3f85 100644
--- a/drivers/mmc/host/cqhci.h
+++ b/drivers/mmc/host/cqhci.h
@@ -315,8 +315,7 @@ static inline u32 cqhci_readl(struct cqhci_host *host, int reg)
struct platform_device;
-irqreturn_t cqhci_irq(struct mmc_host *mmc, u32 intmask, int cmd_error,
- int data_error);
+irqreturn_t cqhci_irq(struct mmc_host *mmc, int cmd_error, int data_error);
int cqhci_init(struct cqhci_host *cq_host, struct mmc_host *mmc, bool dma64);
struct cqhci_host *cqhci_pltfm_init(struct platform_device *pdev);
int cqhci_deactivate(struct mmc_host *mmc);
diff --git a/drivers/mmc/host/dw_mmc-pltfm.h b/drivers/mmc/host/dw_mmc-pltfm.h
index ef1b05d484c3..f3193662abf1 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.h
+++ b/drivers/mmc/host/dw_mmc-pltfm.h
@@ -11,6 +11,5 @@
extern int dw_mci_pltfm_register(struct platform_device *pdev,
const struct dw_mci_drv_data *drv_data);
extern void dw_mci_pltfm_remove(struct platform_device *pdev);
-extern const struct dev_pm_ops dw_mci_pmops;
#endif /* _DW_MMC_PLTFM_H_ */
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index d734d010444d..cf5cecc5491d 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -2057,6 +2057,7 @@ static void dw_mci_work_func(struct work_struct *t)
}
dw_mci_stop_fault_timer(host);
+ dw_mci_stop_dma(host);
host->data = NULL;
set_bit(EVENT_DATA_COMPLETE, &host->completed_events);
err = dw_mci_data_complete(host, data);
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 9ffcd3946cff..38610c89d54a 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -19,6 +19,8 @@
#include <linux/interrupt.h>
#include <linux/workqueue.h>
+extern const struct dev_pm_ops dw_mci_pmops;
+
enum dw_mci_state {
STATE_IDLE = 0,
STATE_SENDING_CMD,
diff --git a/drivers/mmc/host/litex_mmc.c b/drivers/mmc/host/litex_mmc.c
index 06a6f24702e0..332fef8b6646 100644
--- a/drivers/mmc/host/litex_mmc.c
+++ b/drivers/mmc/host/litex_mmc.c
@@ -28,6 +28,7 @@
#define LITEX_PHY_CLOCKERDIV 0x04
#define LITEX_PHY_INITIALIZE 0x08
#define LITEX_PHY_WRITESTATUS 0x0C
+#define LITEX_PHY_SETTINGS 0x18
#define LITEX_CORE_CMDARG 0x00
#define LITEX_CORE_CMDCMD 0x04
#define LITEX_CORE_CMDSND 0x08
@@ -71,6 +72,10 @@
#define SD_INIT_DELAY_US 1000
#define SD_INIT_CLK_HZ 400000
+#define SD_PHY_SPEED_1X 0
+#define SD_PHY_SPEED_4X 1
+#define SD_PHY_SPEED_8X 2
+
#define SDIRQ_CARD_DETECT 1
#define SDIRQ_SD_TO_MEM_DONE 2
#define SDIRQ_MEM_TO_SD_DONE 4
@@ -95,11 +100,9 @@ struct litex_mmc_host {
unsigned int ref_clk;
unsigned int sd_clk;
- u32 resp[4];
- u16 rca;
+ u8 width;
- bool is_bus_width_set;
- bool app_cmd;
+ u32 resp[4];
};
static int litex_mmc_sdcard_wait_done(void __iomem *reg, struct device *dev)
@@ -164,11 +167,6 @@ static int litex_mmc_send_cmd(struct litex_mmc_host *host,
host->sdcore + LITEX_CORE_CMDRSP, 0x10);
}
- if (!host->app_cmd && cmd == SD_SEND_RELATIVE_ADDR)
- host->rca = (host->resp[3] >> 16);
-
- host->app_cmd = (cmd == MMC_APP_CMD);
-
if (transfer == SD_CTL_DATA_XFER_NONE)
return ret; /* OK from prior litex_mmc_sdcard_wait_done() */
@@ -190,51 +188,6 @@ static int litex_mmc_send_cmd(struct litex_mmc_host *host,
return ret;
}
-static int litex_mmc_send_app_cmd(struct litex_mmc_host *host)
-{
- return litex_mmc_send_cmd(host, MMC_APP_CMD, host->rca << 16,
- SD_CTL_RESP_SHORT, SD_CTL_DATA_XFER_NONE);
-}
-
-static int litex_mmc_send_set_bus_w_cmd(struct litex_mmc_host *host, u32 width)
-{
- return litex_mmc_send_cmd(host, SD_APP_SET_BUS_WIDTH, width,
- SD_CTL_RESP_SHORT, SD_CTL_DATA_XFER_NONE);
-}
-
-static int litex_mmc_set_bus_width(struct litex_mmc_host *host)
-{
- bool app_cmd_sent;
- int ret;
-
- if (host->is_bus_width_set)
- return 0;
-
- /* Ensure 'app_cmd' precedes 'app_set_bus_width_cmd' */
- app_cmd_sent = host->app_cmd; /* was preceding command app_cmd? */
- if (!app_cmd_sent) {
- ret = litex_mmc_send_app_cmd(host);
- if (ret)
- return ret;
- }
-
- /* LiteSDCard only supports 4-bit bus width */
- ret = litex_mmc_send_set_bus_w_cmd(host, MMC_BUS_WIDTH_4);
- if (ret)
- return ret;
-
- /* Re-send 'app_cmd' if necessary */
- if (app_cmd_sent) {
- ret = litex_mmc_send_app_cmd(host);
- if (ret)
- return ret;
- }
-
- host->is_bus_width_set = true;
-
- return 0;
-}
-
static int litex_mmc_get_cd(struct mmc_host *mmc)
{
struct litex_mmc_host *host = mmc_priv(mmc);
@@ -247,9 +200,6 @@ static int litex_mmc_get_cd(struct mmc_host *mmc)
if (ret)
return ret;
- /* Ensure bus width will be set (again) upon card (re)insertion */
- host->is_bus_width_set = false;
-
return 0;
}
@@ -365,39 +315,19 @@ static void litex_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
litex_mmc_response_len(sbc),
SD_CTL_DATA_XFER_NONE);
if (sbc->error) {
- host->is_bus_width_set = false;
mmc_request_done(mmc, mrq);
return;
}
}
- if (data) {
- /*
- * LiteSDCard only supports 4-bit bus width; therefore, we MUST
- * inject a SET_BUS_WIDTH (acmd6) before the very first data
- * transfer, earlier than when the mmc subsystem would normally
- * get around to it!
- */
- cmd->error = litex_mmc_set_bus_width(host);
- if (cmd->error) {
- dev_err(dev, "Can't set bus width!\n");
- mmc_request_done(mmc, mrq);
- return;
- }
-
+ if (data)
litex_mmc_do_dma(host, data, &len, &direct, &transfer);
- }
do {
cmd->error = litex_mmc_send_cmd(host, cmd->opcode, cmd->arg,
response_len, transfer);
} while (cmd->error && retries-- > 0);
- if (cmd->error) {
- /* Card may be gone; don't assume bus width is still set */
- host->is_bus_width_set = false;
- }
-
if (response_len == SD_CTL_RESP_SHORT) {
/* Pull short response fields from appropriate host registers */
cmd->resp[0] = host->resp[3];
@@ -410,13 +340,10 @@ static void litex_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
}
/* Send stop-transmission command if required */
- if (stop && (cmd->error || !sbc)) {
+ if (stop && (cmd->error || !sbc))
stop->error = litex_mmc_send_cmd(host, stop->opcode, stop->arg,
litex_mmc_response_len(stop),
SD_CTL_DATA_XFER_NONE);
- if (stop->error)
- host->is_bus_width_set = false;
- }
if (data) {
dma_unmap_sg(dev, data->sg, data->sg_len,
@@ -450,6 +377,24 @@ static void litex_mmc_setclk(struct litex_mmc_host *host, unsigned int freq)
static void litex_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct litex_mmc_host *host = mmc_priv(mmc);
+ unsigned int bus_width = SD_PHY_SPEED_1X;
+
+ switch (ios->bus_width) {
+ case MMC_BUS_WIDTH_1:
+ bus_width = SD_PHY_SPEED_1X;
+ break;
+ case MMC_BUS_WIDTH_4:
+ bus_width = SD_PHY_SPEED_4X;
+ break;
+ case MMC_BUS_WIDTH_8:
+ bus_width = SD_PHY_SPEED_8X;
+ break;
+ }
+
+ if (host->width != ios->bus_width) {
+ litex_write8(host->sdphy + LITEX_PHY_SETTINGS, bus_width);
+ host->width = ios->bus_width;
+ }
/*
* The SD specification requires at least 74 idle clocks before CMD0.
@@ -462,13 +407,6 @@ static void litex_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
return;
}
- /*
- * NOTE: Ignore any ios->bus_width updates; they occur right after
- * the mmc core sends its own acmd6 bus-width change notification,
- * which is redundant since we snoop on the command flow and inject
- * an early acmd6 before the first data transfer command is sent!
- */
-
/* Update sd_clk */
if (ios->clock != host->sd_clk)
litex_mmc_setclk(host, ios->clock);
@@ -546,14 +484,7 @@ static int litex_mmc_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(clk), "can't get clock\n");
host->ref_clk = clk_get_rate(clk);
host->sd_clk = 0;
-
- /*
- * LiteSDCard only supports 4-bit bus width; therefore, we MUST inject
- * a SET_BUS_WIDTH (acmd6) before the very first data transfer, earlier
- * than when the mmc subsystem would normally get around to it!
- */
- host->is_bus_width_set = false;
- host->app_cmd = false;
+ host->width = MMC_BUS_WIDTH_1;
/* LiteSDCard can support 64-bit DMA addressing */
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
@@ -586,6 +517,9 @@ static int litex_mmc_probe(struct platform_device *pdev)
litex_write8(host->sdreader + LITEX_BLK2MEM_ENA, 0);
litex_write8(host->sdwriter + LITEX_MEM2BLK_ENA, 0);
+ /* Ensure the litex is at bus width x1 */
+ litex_write8(host->sdphy + LITEX_PHY_SETTINGS, SD_PHY_SPEED_1X);
+
init_completion(&host->cmd_done);
ret = litex_mmc_irq_init(pdev, host);
if (ret)
@@ -610,9 +544,8 @@ static int litex_mmc_probe(struct platform_device *pdev)
if (ret)
return ret;
- /* Force 4-bit bus_width (only width supported by hardware) */
+ /* Only drop 8-bit bus_width support */
mmc->caps &= ~MMC_CAP_8_BIT_DATA;
- mmc->caps |= MMC_CAP_4_BIT_DATA;
/* Set default capabilities */
mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY |
diff --git a/drivers/mmc/host/meson-mx-sdio.c b/drivers/mmc/host/meson-mx-sdio.c
index 5921e2cb2180..bef5e843f449 100644
--- a/drivers/mmc/host/meson-mx-sdio.c
+++ b/drivers/mmc/host/meson-mx-sdio.c
@@ -683,11 +683,8 @@ static int meson_mx_mmc_probe(struct platform_device *pdev)
meson_mx_mmc_irq,
meson_mx_mmc_irq_thread, IRQF_ONESHOT,
NULL, host);
- if (ret) {
- dev_err_probe(host->controller_dev, ret,
- "Failed to request IRQ\n");
+ if (ret)
goto error_unregister_slot_pdev;
- }
core_clk = devm_clk_get_enabled(host->controller_dev, "core");
if (IS_ERR(core_clk)) {
diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c
index 3dd8f232052f..28aed13549a6 100644
--- a/drivers/mmc/host/moxart-mmc.c
+++ b/drivers/mmc/host/moxart-mmc.c
@@ -26,8 +26,6 @@
#include <linux/mmc/sd.h>
#include <linux/sched.h>
#include <linux/io.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
#include <linux/clk.h>
#include <linux/bitops.h>
#include <linux/of_dma.h>
@@ -264,6 +262,7 @@ static void moxart_transfer_dma(struct mmc_data *data, struct moxart_host *host)
u32 len, dir_slave;
struct dma_async_tx_descriptor *desc = NULL;
struct dma_chan *dma_chan;
+ long timeout;
if (host->data_len == data->bytes_xfered)
return;
@@ -296,11 +295,17 @@ static void moxart_transfer_dma(struct mmc_data *data, struct moxart_host *host)
dma_async_issue_pending(dma_chan);
}
- wait_for_completion_interruptible_timeout(&host->dma_complete,
- host->timeout);
+ timeout = wait_for_completion_interruptible_timeout(&host->dma_complete,
+ host->timeout);
+ if (timeout <= 0) {
+ dmaengine_terminate_sync(dma_chan);
+ data->error = timeout ?: -ETIMEDOUT;
+ goto unmap;
+ }
data->bytes_xfered = host->data_len;
+unmap:
dma_unmap_sg(dma_chan->device->dev,
data->sg, data->sg_len,
mmc_get_dma_dir(data));
@@ -548,8 +553,7 @@ static const struct mmc_host_ops moxart_ops = {
static int moxart_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct device_node *node = dev->of_node;
- struct resource res_mmc;
+ struct resource *res_mmc;
struct mmc_host *mmc;
struct moxart_host *host = NULL;
struct dma_slave_config cfg;
@@ -558,30 +562,24 @@ static int moxart_probe(struct platform_device *pdev)
int irq, ret;
u32 i;
+ reg_mmc = devm_platform_get_and_ioremap_resource(pdev, 0, &res_mmc);
+ if (IS_ERR(reg_mmc))
+ return PTR_ERR(reg_mmc);
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
mmc = devm_mmc_alloc_host(dev, sizeof(*host));
if (!mmc) {
dev_err(dev, "devm_mmc_alloc_host failed\n");
return -ENOMEM;
}
- ret = of_address_to_resource(node, 0, &res_mmc);
- if (ret)
- return dev_err_probe(dev, ret,
- "of_address_to_resource failed\n");
-
- irq = irq_of_parse_and_map(node, 0);
- if (irq <= 0)
- return dev_err_probe(dev, -EINVAL,
- "irq_of_parse_and_map failed\n");
-
clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk))
return PTR_ERR(clk);
- reg_mmc = devm_ioremap_resource(dev, &res_mmc);
- if (IS_ERR(reg_mmc))
- return PTR_ERR(reg_mmc);
-
ret = mmc_of_parse(mmc);
if (ret)
return ret;
@@ -589,7 +587,7 @@ static int moxart_probe(struct platform_device *pdev)
host = mmc_priv(mmc);
host->mmc = mmc;
host->base = reg_mmc;
- host->reg_phys = res_mmc.start;
+ host->reg_phys = res_mmc->start;
host->timeout = msecs_to_jiffies(1000);
host->sysclk = clk_get_rate(clk);
host->fifo_width = readl(host->base + REG_FEATURE) << 2;
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index b2680cc054bd..01ea3adbdf3b 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1805,7 +1805,7 @@ static irqreturn_t msdc_cmdq_irq(struct msdc_host *host, u32 intsts)
cmd_err, dat_err, intsts);
}
- return cqhci_irq(mmc, 0, cmd_err, dat_err);
+ return cqhci_irq(mmc, cmd_err, dat_err);
}
static irqreturn_t msdc_irq(int irq, void *dev_id)
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
index 79df2fa89a3f..cf705b265e21 100644
--- a/drivers/mmc/host/mvsdio.c
+++ b/drivers/mmc/host/mvsdio.c
@@ -764,10 +764,8 @@ static int mvsd_probe(struct platform_device *pdev)
mvsd_power_down(host);
ret = devm_request_irq(&pdev->dev, irq, mvsd_irq, 0, DRIVER_NAME, host);
- if (ret) {
- dev_err(&pdev->dev, "cannot assign irq %d\n", irq);
+ if (ret)
goto out;
- }
timer_setup(&host->timer, mvsd_timeout_timer, 0);
platform_set_drvdata(pdev, mmc);
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 3356ac5a1fa0..de5a3b70107d 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -1764,7 +1764,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
struct mmc_host *mmc;
struct omap_hsmmc_host *host = NULL;
struct resource *res;
- int ret, irq;
+ int ret, irq, wake_irq;
const struct of_device_id *match;
const struct omap_mmc_of_data *data;
void __iomem *base;
@@ -1792,6 +1792,11 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
+ wake_irq = platform_get_irq_optional(pdev, 1);
+ if (wake_irq == -EPROBE_DEFER)
+ return wake_irq;
+ wake_irq = max(wake_irq, 0);
+
base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(base))
return PTR_ERR(base);
@@ -1811,6 +1816,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
host->use_dma = 1;
host->dma_ch = -1;
host->irq = irq;
+ host->wake_irq = wake_irq;
host->mapbase = res->start + pdata->reg_offset;
host->base = base + pdata->reg_offset;
host->power_mode = MMC_POWER_OFF;
@@ -1820,9 +1826,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, host);
- if (pdev->dev.of_node)
- host->wake_irq = irq_of_parse_and_map(pdev->dev.of_node, 1);
-
mmc->ops = &omap_hsmmc_ops;
mmc->f_min = OMAP_MMC_MIN_CLOCK;
@@ -1915,10 +1918,8 @@ static int omap_hsmmc_probe(struct platform_device *pdev)
/* Request IRQ for MMC operations */
ret = devm_request_irq(&pdev->dev, host->irq, omap_hsmmc_irq, 0,
mmc_hostname(mmc), host);
- if (ret) {
- dev_err(mmc_dev(host->mmc), "Unable to grab HSMMC IRQ\n");
+ if (ret)
goto err_irq;
- }
ret = omap_hsmmc_reg_get(host);
if (ret)
diff --git a/drivers/mmc/host/owl-mmc.c b/drivers/mmc/host/owl-mmc.c
index 349082d76a99..d5b8a110267b 100644
--- a/drivers/mmc/host/owl-mmc.c
+++ b/drivers/mmc/host/owl-mmc.c
@@ -635,11 +635,8 @@ static int owl_mmc_probe(struct platform_device *pdev)
ret = devm_request_irq(&pdev->dev, owl_host->irq, owl_irq_handler,
0, dev_name(&pdev->dev), owl_host);
- if (ret) {
- dev_err(&pdev->dev, "Failed to request irq %d\n",
- owl_host->irq);
+ if (ret)
goto err_release_channel;
- }
ret = mmc_add_host(mmc);
if (ret) {
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index b5ea058ed467..f8427f071c00 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -43,8 +43,7 @@
#define NR_SG 1
#define CLKRT_OFF (~0)
-#define mmc_has_26MHz() (cpu_is_pxa300() || cpu_is_pxa310() \
- || cpu_is_pxa935())
+#define mmc_has_26MHz() (cpu_is_pxa300() || cpu_is_pxa310())
struct pxamci_host {
struct mmc_host *mmc;
diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c
index 84674659a84d..bf37fab233cf 100644
--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
+++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
@@ -44,6 +44,7 @@ struct rtsx_usb_sdmmc {
bool double_clk;
bool host_removal;
bool card_exist;
+ bool suppress_cd;
bool initial_mode;
bool ddr_mode;
@@ -774,6 +775,7 @@ static int sdmmc_get_cd(struct mmc_host *mmc)
struct rtsx_ucr *ucr = host->ucr;
int err;
u16 val;
+ bool cd;
if (host->host_removal)
return -ENOMEDIUM;
@@ -791,8 +793,14 @@ static int sdmmc_get_cd(struct mmc_host *mmc)
/* get OCP status */
host->ocp_stat = (val >> 4) & 0x03;
+ cd = val & SD_CD;
- if (val & SD_CD) {
+ if (!cd) {
+ WRITE_ONCE(host->suppress_cd, false);
+ goto no_card;
+ }
+
+ if (!READ_ONCE(host->suppress_cd)) {
host->card_exist = true;
return 1;
}
@@ -874,6 +882,8 @@ finish_detect_card:
* detect card when fail to update card existence state and
* speed up card removal when retry
*/
+ if (!mmc->card && cmd->error == -ETIMEDOUT)
+ WRITE_ONCE(host->suppress_cd, true);
sdmmc_get_cd(mmc);
dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error);
}
@@ -1359,6 +1369,7 @@ static void rtsx_usb_init_host(struct rtsx_usb_sdmmc *host)
host->power_mode = MMC_POWER_OFF;
host->ocp_stat = 0;
+ host->suppress_cd = false;
}
static int rtsx_usb_sdmmc_drv_probe(struct platform_device *pdev)
diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c
index 57e45951644e..1de2f05fd958 100644
--- a/drivers/mmc/host/sdhci-brcmstb.c
+++ b/drivers/mmc/host/sdhci-brcmstb.c
@@ -430,7 +430,7 @@ static u32 sdhci_brcmstb_cqhci_irq(struct sdhci_host *host, u32 intmask)
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
return intmask;
- cqhci_irq(host->mmc, intmask, cmd_error, data_error);
+ cqhci_irq(host->mmc, cmd_error, data_error);
return 0;
}
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 18f4905c15b9..6ab59d3e346f 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -1513,7 +1513,7 @@ static u32 esdhc_cqhci_irq(struct sdhci_host *host, u32 intmask)
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
return intmask;
- cqhci_irq(host->mmc, intmask, cmd_error, data_error);
+ cqhci_irq(host->mmc, cmd_error, data_error);
return 0;
}
diff --git a/drivers/mmc/host/sdhci-esdhc-mcf.c b/drivers/mmc/host/sdhci-esdhc-mcf.c
index 375fce5639d7..6853521e8b2c 100644
--- a/drivers/mmc/host/sdhci-esdhc-mcf.c
+++ b/drivers/mmc/host/sdhci-esdhc-mcf.c
@@ -55,7 +55,7 @@ static inline void esdhc_clrset_be(struct sdhci_host *host,
if (reg == SDHCI_HOST_CONTROL)
val |= ESDHC_PROCTL_D3CD;
- writel((readl(base) & ~mask) | val, base);
+ mcf_write32((mcf_read32(base) & ~mask) | val, base);
}
/*
@@ -71,7 +71,7 @@ static void esdhc_mcf_writeb_be(struct sdhci_host *host, u8 val, int reg)
if (reg == SDHCI_HOST_CONTROL) {
u32 host_ctrl = ESDHC_DEFAULT_HOST_CONTROL;
u8 dma_bits = (val & SDHCI_CTRL_DMA_MASK) >> 3;
- u8 tmp = readb(host->ioaddr + SDHCI_HOST_CONTROL + 1);
+ u8 tmp = mcf_read8(host->ioaddr + SDHCI_HOST_CONTROL + 1);
tmp &= ~0x03;
tmp |= dma_bits;
@@ -82,12 +82,12 @@ static void esdhc_mcf_writeb_be(struct sdhci_host *host, u8 val, int reg)
*/
host_ctrl |= val;
host_ctrl |= (dma_bits << 8);
- writel(host_ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+ mcf_write32(host_ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
return;
}
- writel((readl(base) & mask) | (val << shift), base);
+ mcf_write32((mcf_read32(base) & mask) | (val << shift), base);
}
static void esdhc_mcf_writew_be(struct sdhci_host *host, u16 val, int reg)
@@ -110,24 +110,24 @@ static void esdhc_mcf_writew_be(struct sdhci_host *host, u16 val, int reg)
* As for the fsl driver,
* we have to set the mode in a single write here.
*/
- writel(val << 16 | mcf_data->aside,
+ mcf_write32(val << 16 | mcf_data->aside,
host->ioaddr + SDHCI_TRANSFER_MODE);
return;
}
- writel((readl(base) & mask) | (val << shift), base);
+ mcf_write32((mcf_read32(base) & mask) | (val << shift), base);
}
static void esdhc_mcf_writel_be(struct sdhci_host *host, u32 val, int reg)
{
- writel(val, host->ioaddr + reg);
+ mcf_write32(val, host->ioaddr + reg);
}
static u8 esdhc_mcf_readb_be(struct sdhci_host *host, int reg)
{
if (reg == SDHCI_HOST_CONTROL) {
u8 __iomem *base = host->ioaddr + (reg & ~3);
- u16 val = readw(base + 2);
+ u16 val = mcf_read16(base + 2);
u8 dma_bits = (val >> 5) & SDHCI_CTRL_DMA_MASK;
u8 host_ctrl = val & 0xff;
@@ -137,7 +137,7 @@ static u8 esdhc_mcf_readb_be(struct sdhci_host *host, int reg)
return host_ctrl;
}
- return readb(host->ioaddr + (reg ^ 0x3));
+ return mcf_read8(host->ioaddr + (reg ^ 0x3));
}
static u16 esdhc_mcf_readw_be(struct sdhci_host *host, int reg)
@@ -149,14 +149,14 @@ static u16 esdhc_mcf_readw_be(struct sdhci_host *host, int reg)
if (reg == SDHCI_HOST_VERSION)
reg -= 2;
- return readw(host->ioaddr + (reg ^ 0x2));
+ return mcf_read16(host->ioaddr + (reg ^ 0x2));
}
static u32 esdhc_mcf_readl_be(struct sdhci_host *host, int reg)
{
u32 val;
- val = readl(host->ioaddr + reg);
+ val = mcf_read32(host->ioaddr + reg);
/*
* RM (25.3.9) sd pin clock must never exceed 25Mhz.
@@ -245,7 +245,7 @@ static void esdhc_mcf_pltfm_set_clock(struct sdhci_host *host,
* fvco = fsys * outdvi1 + 1
* fshdc = fvco / outdiv3 + 1
*/
- temp = readl(pll_dr);
+ temp = mcf_read32(pll_dr);
fsys = pltfm_host->clock;
fvco = fsys * ((temp & 0x1f) + 1);
fesdhc = fvco / (((temp >> 10) & 0x1f) + 1);
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 0882ce74e0c9..4aff965f0e2e 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -2165,7 +2165,7 @@ static u32 sdhci_msm_cqe_irq(struct sdhci_host *host, u32 intmask)
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
return intmask;
- cqhci_irq(host->mmc, intmask, cmd_error, data_error);
+ cqhci_irq(host->mmc, cmd_error, data_error);
return 0;
}
@@ -2864,10 +2864,8 @@ static int sdhci_msm_probe(struct platform_device *pdev)
ret = devm_request_threaded_irq(&pdev->dev, msm_host->pwr_irq, NULL,
sdhci_msm_pwr_irq, IRQF_ONESHOT,
dev_name(&pdev->dev), host);
- if (ret) {
- dev_err(&pdev->dev, "Request IRQ failed (%d)\n", ret);
+ if (ret)
goto clk_disable;
- }
msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY;
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c
index 785d3acb18c5..4ca73e7d799e 100644
--- a/drivers/mmc/host/sdhci-of-arasan.c
+++ b/drivers/mmc/host/sdhci-of-arasan.c
@@ -555,7 +555,7 @@ static u32 sdhci_arasan_cqhci_irq(struct sdhci_host *host, u32 intmask)
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
return intmask;
- cqhci_irq(host->mmc, intmask, cmd_error, data_error);
+ cqhci_irq(host->mmc, cmd_error, data_error);
return 0;
}
diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
index c688f3eaf468..1baa2379c9c3 100644
--- a/drivers/mmc/host/sdhci-of-dwcmshc.c
+++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
@@ -624,7 +624,7 @@ static u32 dwcmshc_cqe_irq_handler(struct sdhci_host *host, u32 intmask)
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
return intmask;
- cqhci_irq(host->mmc, intmask, cmd_error, data_error);
+ cqhci_irq(host->mmc, cmd_error, data_error);
return 0;
}
@@ -2013,6 +2013,7 @@ static void dwcmshc_bf3_hw_reset(struct sdhci_host *host)
{
struct arm_smccc_res res = { 0 };
+ pr_debug("%s: resetting...\n", __func__);
arm_smccc_smc(BLUEFIELD_SMC_SET_EMMC_RST_N, 0, 0, 0, 0, 0, 0, 0, &res);
if (res.a0)
diff --git a/drivers/mmc/host/sdhci-of-ma35d1.c b/drivers/mmc/host/sdhci-of-ma35d1.c
index a3b676894838..2a826de97779 100644
--- a/drivers/mmc/host/sdhci-of-ma35d1.c
+++ b/drivers/mmc/host/sdhci-of-ma35d1.c
@@ -290,6 +290,7 @@ static const struct of_device_id sdhci_ma35_dt_ids[] = {
{ .compatible = "nuvoton,ma35d1-sdhci" },
{}
};
+MODULE_DEVICE_TABLE(of, sdhci_ma35_dt_ids);
static struct platform_driver sdhci_ma35_driver = {
.driver = {
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
index c347fac24515..b121d896a804 100644
--- a/drivers/mmc/host/sdhci-pci-core.c
+++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -215,7 +215,7 @@ static u32 sdhci_cqhci_irq(struct sdhci_host *host, u32 intmask)
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
return intmask;
- cqhci_irq(host->mmc, intmask, cmd_error, data_error);
+ cqhci_irq(host->mmc, cmd_error, data_error);
return 0;
}
diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c
index 6e4084407662..b55618566d65 100644
--- a/drivers/mmc/host/sdhci-pci-gli.c
+++ b/drivers/mmc/host/sdhci-pci-gli.c
@@ -1760,7 +1760,7 @@ static u32 sdhci_gl9763e_cqhci_irq(struct sdhci_host *host, u32 intmask)
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
return intmask;
- cqhci_irq(host->mmc, intmask, cmd_error, data_error);
+ cqhci_irq(host->mmc, cmd_error, data_error);
return 0;
}
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 820ce4dae58b..5c5efb62d7ec 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -1280,7 +1280,7 @@ static u32 sdhci_tegra_cqhci_irq(struct sdhci_host *host, u32 intmask)
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
return intmask;
- cqhci_irq(host->mmc, intmask, cmd_error, data_error);
+ cqhci_irq(host->mmc, cmd_error, data_error);
return 0;
}
@@ -1572,7 +1572,37 @@ static const struct sdhci_tegra_soc_data soc_data_tegra234 = {
.max_tap_delay = 111,
};
+static const struct sdhci_tegra_soc_data soc_data_tegra264 = {
+ .pdata = &sdhci_tegra186_pdata,
+ .dma_mask = DMA_BIT_MASK(39),
+ .nvquirks = NVQUIRK_NEEDS_PAD_CONTROL |
+ NVQUIRK_HAS_PADCALIB |
+ NVQUIRK_DIS_CARD_CLK_CONFIG_TAP |
+ NVQUIRK_ENABLE_SDR50 |
+ NVQUIRK_ENABLE_SDR104 |
+ NVQUIRK_PROGRAM_STREAMID |
+ NVQUIRK_HAS_TMCLK,
+ .min_tap_delay = 95,
+ .max_tap_delay = 111,
+};
+
+static const struct sdhci_tegra_soc_data soc_data_tegra238 = {
+ .pdata = &sdhci_tegra186_pdata,
+ .dma_mask = DMA_BIT_MASK(39),
+ .nvquirks = NVQUIRK_NEEDS_PAD_CONTROL |
+ NVQUIRK_HAS_PADCALIB |
+ NVQUIRK_DIS_CARD_CLK_CONFIG_TAP |
+ NVQUIRK_ENABLE_SDR50 |
+ NVQUIRK_ENABLE_SDR104 |
+ NVQUIRK_PROGRAM_STREAMID |
+ NVQUIRK_HAS_TMCLK,
+ .min_tap_delay = 95,
+ .max_tap_delay = 111,
+};
+
static const struct of_device_id sdhci_tegra_dt_match[] = {
+ { .compatible = "nvidia,tegra264-sdhci", .data = &soc_data_tegra264 },
+ { .compatible = "nvidia,tegra238-sdhci", .data = &soc_data_tegra238 },
{ .compatible = "nvidia,tegra234-sdhci", .data = &soc_data_tegra234 },
{ .compatible = "nvidia,tegra194-sdhci", .data = &soc_data_tegra194 },
{ .compatible = "nvidia,tegra186-sdhci", .data = &soc_data_tegra186 },
diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c
index d235b0aecfdb..2a27db2f558b 100644
--- a/drivers/mmc/host/sdhci_am654.c
+++ b/drivers/mmc/host/sdhci_am654.c
@@ -462,7 +462,7 @@ static u32 sdhci_am654_cqhci_irq(struct sdhci_host *host, u32 intmask)
if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
return intmask;
- cqhci_irq(host->mmc, intmask, cmd_error, data_error);
+ cqhci_irq(host->mmc, cmd_error, data_error);
return 0;
}
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 9831956de1c8..7706d01b149e 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -1505,18 +1505,14 @@ static int sh_mmcif_probe(struct platform_device *pdev)
name = irq[1] < 0 ? dev_name(dev) : "sh_mmc:error";
ret = devm_request_threaded_irq(dev, irq[0], sh_mmcif_intr,
sh_mmcif_irqt, 0, name, host);
- if (ret) {
- dev_err(dev, "request_irq error (%s)\n", name);
+ if (ret)
goto err_clk;
- }
if (irq[1] >= 0) {
ret = devm_request_threaded_irq(dev, irq[1],
sh_mmcif_intr, sh_mmcif_irqt,
0, "sh_mmc:int", host);
- if (ret) {
- dev_err(dev, "request_irq error (sh_mmc:int)\n");
+ if (ret)
goto err_clk;
- }
}
mutex_init(&host->thread_lock);
diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
index 8c049f8355cd..4910d0f444ba 100644
--- a/drivers/mmc/host/via-sdmmc.c
+++ b/drivers/mmc/host/via-sdmmc.c
@@ -1153,10 +1153,16 @@ static int via_sd_probe(struct pci_dev *pcidev,
ret = mmc_add_host(mmc);
if (ret)
- goto unmap;
+ goto free_irq;
return 0;
+free_irq:
+ writeb(0x0, sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL);
+ free_irq(pcidev->irq, sdhost);
+ cancel_work_sync(&sdhost->carddet_work);
+ /* carddet_work may re-enable the interrupt via via_reset_pcictrl(). */
+ writeb(0x0, sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL);
unmap:
iounmap(sdhost->mmiobase);
release:
@@ -1199,6 +1205,10 @@ static void via_sd_remove(struct pci_dev *pcidev)
free_irq(pcidev->irq, sdhost);
+ cancel_work_sync(&sdhost->carddet_work);
+ /* carddet_work may re-enable the interrupt via via_reset_pcictrl(). */
+ writeb(0x0, sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL);
+
timer_delete_sync(&sdhost->timer);
cancel_work_sync(&sdhost->finish_bh_work);
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index c33a0223ce7f..51706898239e 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -52,9 +52,9 @@
#ifdef CONFIG_PNP
static const struct pnp_device_id pnp_dev_table[] = {
- { "WEC0517", 0 },
- { "WEC0518", 0 },
- { "", 0 },
+ { .id = "WEC0517" },
+ { .id = "WEC0518" },
+ { }
};
MODULE_DEVICE_TABLE(pnp, pnp_dev_table);