summaryrefslogtreecommitdiff
path: root/drivers/mmc/core
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-03 12:17:25 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-03 12:17:25 -0700
commitdc73d6a8d42d208c027b4bcca59a77d045895977 (patch)
tree1c6e135caa45d2e085ec0e5b106459a73359905c /drivers/mmc/core
parentdabe51840e2790aa7e66c53990d15c663b0d628a (diff)
parent4472f0fc248e3f0573301f725eff9dc9cde5cb62 (diff)
downloadlinux-next-dc73d6a8d42d208c027b4bcca59a77d045895977.tar.gz
linux-next-dc73d6a8d42d208c027b4bcca59a77d045895977.zip
Merge tag 'mmc-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson: "MMC core: - Export host capabilities through debugfs - Export card RCA register via sysfs - Improve card initializing sequence while enabling 4-bit bus - Export a function to enable/disable wakeup for card detect IRQ MMC host: - dw_mmc: Add support for new hi3798cv200 variant - dw_mmc: Remove support for some deprecated DT properties - mediatek: Add support for new variant used on MT7622 SoC - sdhci: Improve wakeup support for SDIO IRQs - sdhci: Improve wakeup support for card detect IRQs - sdhci-omap: Add tuning support - sdhci_omap: Add UHS-I mode support - sunxi: Prepare for runtime PM support via a few re-factorings - tmio: deprecate "toshiba,mmc-wrprotect-disable" DT property - tmio/renesas_sdhi: Consolidate code supporting write protect - tmio: Improve DMA vs PIO handling - tmio: Add support for IP-builtin card detection logic" * tag 'mmc-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (55 commits) mmc: renesas_sdhi: replace EXT_ACC with HOST_MODE mmc: update sdio_claim_irq documentation mmc: Export host capabilities to debugfs. mmc: core: Disable HPI for certain Micron (Numonyx) eMMC cards mmc: block: fix updating ext_csd caches on ioctl call mmc: sunxi: Set our device drvdata earlier mmc: sunxi: Move the reset deassertion before enabling the clocks mmc: sunxi: Move resources management to separate functions mmc: dw_mmc: add support for hi3798cv200 specific extensions of dw-mshc dt-bindings: mmc: add bindings for hi3798cv200-dw-mshc mmc: core: Export card RCA register via sysfs mmc: renesas_sdhi: fix WP detection mmc: core: Use memdup_user() rather than duplicating its implementation mmc: dw_mmc-rockchip: correct property names in debug mmc: sd: Remove redundant err assignment from mmc_read_switch mmc: sdio: Check the return value of sdio_enable_4bit_bus mmc: core: Don't try UHS-I mode if 4-bit mode isn't supported arm64: dts: hi3660: remove 'num-slots' property for dwmmc ARM: dts: lpc18xx: remove 'num-slots' property for dwmmc arm64: dts: stratix10: remove 'num-slots' property for dwmmc ...
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r--drivers/mmc/core/block.c15
-rw-r--r--drivers/mmc/core/core.c5
-rw-r--r--drivers/mmc/core/debugfs.c19
-rw-r--r--drivers/mmc/core/host.h3
-rw-r--r--drivers/mmc/core/mmc.c2
-rw-r--r--drivers/mmc/core/sd.c20
-rw-r--r--drivers/mmc/core/sdio.c9
-rw-r--r--drivers/mmc/core/sdio_irq.c4
-rw-r--r--drivers/mmc/core/slot-gpio.c23
9 files changed, 51 insertions, 49 deletions
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 2cfb963d9f37..a2b9c2500c4c 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -376,22 +376,15 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user(
return idata;
}
- idata->buf = kmalloc(idata->buf_bytes, GFP_KERNEL);
- if (!idata->buf) {
- err = -ENOMEM;
+ idata->buf = memdup_user((void __user *)(unsigned long)
+ idata->ic.data_ptr, idata->buf_bytes);
+ if (IS_ERR(idata->buf)) {
+ err = PTR_ERR(idata->buf);
goto idata_err;
}
- if (copy_from_user(idata->buf, (void __user *)(unsigned long)
- idata->ic.data_ptr, idata->buf_bytes)) {
- err = -EFAULT;
- goto copy_err;
- }
-
return idata;
-copy_err:
- kfree(idata->buf);
idata_err:
kfree(idata);
out:
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index c0ba6d8823b7..121ce50b6d5e 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2369,7 +2369,7 @@ unsigned int mmc_calc_max_discard(struct mmc_card *card)
return card->pref_erase;
max_discard = mmc_do_calc_max_discard(card, MMC_ERASE_ARG);
- if (mmc_can_trim(card)) {
+ if (max_discard && mmc_can_trim(card)) {
max_trim = mmc_do_calc_max_discard(card, MMC_TRIM_ARG);
if (max_trim < max_discard)
max_discard = max_trim;
@@ -2655,8 +2655,7 @@ void mmc_start_host(struct mmc_host *host)
void mmc_stop_host(struct mmc_host *host)
{
if (host->slot.cd_irq >= 0) {
- if (host->slot.cd_wake_enabled)
- disable_irq_wake(host->slot.cd_irq);
+ mmc_gpio_set_cd_wake(host, false);
disable_irq(host->slot.cd_irq);
}
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 0f4a7d7b2626..d2275c5a2311 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -196,18 +196,7 @@ static int mmc_ios_show(struct seq_file *s, void *data)
return 0;
}
-
-static int mmc_ios_open(struct inode *inode, struct file *file)
-{
- return single_open(file, mmc_ios_show, inode->i_private);
-}
-
-static const struct file_operations mmc_ios_fops = {
- .open = mmc_ios_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(mmc_ios);
static int mmc_clock_opt_get(void *data, u64 *val)
{
@@ -254,6 +243,12 @@ void mmc_add_host_debugfs(struct mmc_host *host)
if (!debugfs_create_file("ios", S_IRUSR, root, host, &mmc_ios_fops))
goto err_node;
+ if (!debugfs_create_x32("caps", S_IRUSR, root, &host->caps))
+ goto err_node;
+
+ if (!debugfs_create_x32("caps2", S_IRUSR, root, &host->caps2))
+ goto err_node;
+
if (!debugfs_create_file("clock", S_IRUSR | S_IWUSR, root, host,
&mmc_clock_fops))
goto err_node;
diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h
index 06ec19b5bf9f..4805438c02ff 100644
--- a/drivers/mmc/core/host.h
+++ b/drivers/mmc/core/host.h
@@ -56,7 +56,8 @@ static inline int mmc_host_uhs(struct mmc_host *host)
return host->caps &
(MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
- MMC_CAP_UHS_DDR50);
+ MMC_CAP_UHS_DDR50) &&
+ host->caps & MMC_CAP_4_BIT_DATA;
}
static inline bool mmc_card_hs200(struct mmc_card *card)
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 208a762b87ef..6f8ebd6caa4c 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -792,6 +792,7 @@ MMC_DEV_ATTR(enhanced_area_size, "%u\n", card->ext_csd.enhanced_area_size);
MMC_DEV_ATTR(raw_rpmb_size_mult, "%#x\n", card->ext_csd.raw_rpmb_size_mult);
MMC_DEV_ATTR(rel_sectors, "%#x\n", card->ext_csd.rel_sectors);
MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
+MMC_DEV_ATTR(rca, "0x%04x\n", card->rca);
MMC_DEV_ATTR(cmdq_en, "%d\n", card->ext_csd.cmdq_en);
static ssize_t mmc_fwrev_show(struct device *dev,
@@ -848,6 +849,7 @@ static struct attribute *mmc_std_attrs[] = {
&dev_attr_raw_rpmb_size_mult.attr,
&dev_attr_rel_sectors.attr,
&dev_attr_ocr.attr,
+ &dev_attr_rca.attr,
&dev_attr_dsr.attr,
&dev_attr_cmdq_en.attr,
NULL,
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 62b84dd8f9fe..baf3d5da4ccb 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -291,8 +291,6 @@ static int mmc_read_switch(struct mmc_card *card)
return 0;
}
- err = -EIO;
-
status = kmalloc(64, GFP_KERNEL);
if (!status)
return -ENOMEM;
@@ -582,9 +580,6 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
int err;
u8 *status;
- if (!card->scr.sda_spec3)
- return 0;
-
if (!(card->csd.cmdclass & CCC_SWITCH))
return 0;
@@ -593,14 +588,11 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
return -ENOMEM;
/* Set 4-bit bus width */
- if ((card->host->caps & MMC_CAP_4_BIT_DATA) &&
- (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
- err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
- if (err)
- goto out;
+ err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
+ if (err)
+ goto out;
- mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
- }
+ mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
/*
* Select the bus speed mode depending on host
@@ -676,6 +668,7 @@ MMC_DEV_ATTR(name, "%s\n", card->cid.prod_name);
MMC_DEV_ATTR(oemid, "0x%04x\n", card->cid.oemid);
MMC_DEV_ATTR(serial, "0x%08x\n", card->cid.serial);
MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr);
+MMC_DEV_ATTR(rca, "0x%04x\n", card->rca);
static ssize_t mmc_dsr_show(struct device *dev,
@@ -709,6 +702,7 @@ static struct attribute *sd_std_attrs[] = {
&dev_attr_oemid.attr,
&dev_attr_serial.attr,
&dev_attr_ocr.attr,
+ &dev_attr_rca.attr,
&dev_attr_dsr.attr,
NULL,
};
@@ -1033,7 +1027,7 @@ retry:
}
/* Initialization sequence for UHS-I cards */
- if (rocr & SD_ROCR_S18A) {
+ if (rocr & SD_ROCR_S18A && mmc_host_uhs(host)) {
err = mmc_sd_init_uhs_card(card);
if (err)
goto free_card;
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index cc43687ca241..c599a628a387 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -518,11 +518,10 @@ static int mmc_sdio_init_uhs_card(struct mmc_card *card)
if (!card->scr.sda_spec3)
return 0;
- /*
- * Switch to wider bus (if supported).
- */
- if (card->host->caps & MMC_CAP_4_BIT_DATA)
- err = sdio_enable_4bit_bus(card);
+ /* Switch to wider bus */
+ err = sdio_enable_4bit_bus(card);
+ if (err)
+ goto out;
/* Set the driver strength for the card */
sdio_select_driver_type(card);
diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c
index 7a2eaf8410a3..7ca7b99413f0 100644
--- a/drivers/mmc/core/sdio_irq.c
+++ b/drivers/mmc/core/sdio_irq.c
@@ -277,8 +277,8 @@ static void sdio_single_irq_set(struct mmc_card *card)
*
* Claim and activate the IRQ for the given SDIO function. The provided
* handler will be called when that IRQ is asserted. The host is always
- * claimed already when the handler is called so the handler must not
- * call sdio_claim_host() nor sdio_release_host().
+ * claimed already when the handler is called so the handler should not
+ * call sdio_claim_host() or sdio_release_host().
*/
int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler)
{
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 3698b0576009..31f7dbb15668 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -149,11 +149,30 @@ void mmc_gpiod_request_cd_irq(struct mmc_host *host)
if (irq < 0)
host->caps |= MMC_CAP_NEEDS_POLL;
- else if ((host->caps & MMC_CAP_CD_WAKE) && !enable_irq_wake(irq))
- host->slot.cd_wake_enabled = true;
}
EXPORT_SYMBOL(mmc_gpiod_request_cd_irq);
+int mmc_gpio_set_cd_wake(struct mmc_host *host, bool on)
+{
+ int ret = 0;
+
+ if (!(host->caps & MMC_CAP_CD_WAKE) ||
+ host->slot.cd_irq < 0 ||
+ on == host->slot.cd_wake_enabled)
+ return 0;
+
+ if (on) {
+ ret = enable_irq_wake(host->slot.cd_irq);
+ host->slot.cd_wake_enabled = !ret;
+ } else {
+ disable_irq_wake(host->slot.cd_irq);
+ host->slot.cd_wake_enabled = false;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(mmc_gpio_set_cd_wake);
+
/* Register an alternate interrupt service routine for
* the card-detect GPIO.
*/