aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/sdio.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-05 19:11:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-05 19:11:43 -0400
commitf60342fac9fae20ada2cd5faadbc2a1337cae03f (patch)
treefe64b1cb3ea699d819e5e808264903aee2d8dc9a /drivers/mmc/core/sdio.c
parent5231804cf9e584f3e7e763a0d6d2fffe011c1bce (diff)
parentef5332c10d4f332a2ac79e9ad5452f4e89d1815a (diff)
Merge tag 'mmc-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson: "MMC core: - Decrease polling rate for erase/trim/discard - Allow non-sleeping GPIOs for card detect - Improve mmc block removal path - Enable support for mmc_sw_reset() for SDIO cards - Add mmc_sw_reset() to allow users to do a soft reset of the card - Allow power delay to be tunable via DT - Allow card detect debounce delay to be tunable via DT - Enable new quirk to limit clock rate for Marvell 8887 chip - Don't show eMMC RPMB and BOOT areas in /proc/partitions - Add capability to avoid 3.3V signaling for fragile HWs MMC host: - Improve/fixup support for handle highmem pages - Remove depends on HAS_DMA in case of platform dependency - mvsdio: Enable support for erase/trim/discard - rtsx_usb: Enable support for erase/trim/discard - renesas_sdhi: Fix WP logic regressions - renesas_sdhi: Add r8a77965 support - renesas_sdhi: Add R8A77980 to whitelist - meson: Add optional support for device reset - meson: Add support for the Meson-AXG platform - dw_mmc: Add new driver for BlueField DW variant - mediatek: Add support for 64G DRAM DMA - sunxi: Deploy runtime PM support - jz4740: Add support for JZ4780 - jz4740: Enable support for DT based platforms - sdhci: Various improvement to timeout handling - sdhci: Disable support for HS200/HS400/UHS when no 1.8V support - sdhci-omap: Add support for controller in k2g SoC - sdhci-omap: Add workarounds for a couple of Erratas - sdhci-omap: Enable support for generic sdhci DT properties - sdhci-cadence: Re-send tune request to deal with errata - sdhci-pci: Fix 3.3V voltage switch for some BYT-based Intel controllers - sdhci-pci: Avoid 3.3V signaling on some NI 904x - sdhci-esdhc-imx: Use watermark levels for PIO access - sdhci-msm: Improve card detection handling - sdhci-msm: Add support voltage pad switching" * tag 'mmc-v4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (104 commits) mmc: renesas_sdhi: really fix WP logic regressions mmc: mvsdio: Enable MMC_CAP_ERASE mmc: mvsdio: Respect card busy time out from mmc core mmc: sdhci-msm: Remove NO_CARD_NO_RESET quirk mmc: sunxi: Use ifdef rather than __maybe_unused mmc: mxmmc: Use ifdef rather than __maybe_unused mmc: mxmmc: include linux/highmem.h mmc: sunxi: mark PM functions as __maybe_unused mmc: Throttle calls to MMC_SEND_STATUS during mmc_do_erase() mmc: au1xmmc: handle highmem pages mmc: Allow non-sleeping GPIO cd mmc: sdhci-*: Don't emit error msg if sdhci_add_host() fails mmc: sd: Define name for default speed dtr mmc: core: Move calls to ->prepare_hs400_tuning() closer to mmc code mmc: sdhci-xenon: use match_string() helper mmc: wbsd: handle highmem pages mmc: ushc: handle highmem pages mmc: mxcmmc: handle highmem pages mmc: atmel-mci: use sg_copy_{from,to}_buffer mmc: android-goldfish: use sg_copy_{from,to}_buffer ...
Diffstat (limited to 'drivers/mmc/core/sdio.c')
-rw-r--r--drivers/mmc/core/sdio.c70
1 files changed, 47 insertions, 23 deletions
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index c599a628a387..a86490dbca70 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -444,6 +444,7 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card)
444 unsigned int bus_speed, timing; 444 unsigned int bus_speed, timing;
445 int err; 445 int err;
446 unsigned char speed; 446 unsigned char speed;
447 unsigned int max_rate;
447 448
448 /* 449 /*
449 * If the host doesn't support any of the UHS-I modes, fallback on 450 * If the host doesn't support any of the UHS-I modes, fallback on
@@ -500,9 +501,12 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card)
500 if (err) 501 if (err)
501 return err; 502 return err;
502 503
504 max_rate = min_not_zero(card->quirk_max_rate,
505 card->sw_caps.uhs_max_dtr);
506
503 if (bus_speed) { 507 if (bus_speed) {
504 mmc_set_timing(card->host, timing); 508 mmc_set_timing(card->host, timing);
505 mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr); 509 mmc_set_clock(card->host, max_rate);
506 } 510 }
507 511
508 return 0; 512 return 0;
@@ -788,6 +792,14 @@ try_again:
788 if (err) 792 if (err)
789 goto remove; 793 goto remove;
790 } 794 }
795
796 if (host->caps2 & MMC_CAP2_AVOID_3_3V &&
797 host->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
798 pr_err("%s: Host failed to negotiate down from 3.3V\n",
799 mmc_hostname(host));
800 err = -EINVAL;
801 goto remove;
802 }
791finish: 803finish:
792 if (!oldcard) 804 if (!oldcard)
793 host->card = card; 805 host->card = card;
@@ -801,6 +813,22 @@ err:
801 return err; 813 return err;
802} 814}
803 815
816static int mmc_sdio_reinit_card(struct mmc_host *host, bool powered_resume)
817{
818 int ret;
819
820 sdio_reset(host);
821 mmc_go_idle(host);
822 mmc_send_if_cond(host, host->card->ocr);
823
824 ret = mmc_send_io_op_cond(host, 0, NULL);
825 if (ret)
826 return ret;
827
828 return mmc_sdio_init_card(host, host->card->ocr, host->card,
829 powered_resume);
830}
831
804/* 832/*
805 * Host is being removed. Free up the current card. 833 * Host is being removed. Free up the current card.
806 */ 834 */
@@ -948,14 +976,7 @@ static int mmc_sdio_resume(struct mmc_host *host)
948 976
949 /* No need to reinitialize powered-resumed nonremovable cards */ 977 /* No need to reinitialize powered-resumed nonremovable cards */
950 if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) { 978 if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) {
951 sdio_reset(host); 979 err = mmc_sdio_reinit_card(host, mmc_card_keep_power(host));
952 mmc_go_idle(host);
953 mmc_send_if_cond(host, host->card->ocr);
954 err = mmc_send_io_op_cond(host, 0, NULL);
955 if (!err)
956 err = mmc_sdio_init_card(host, host->card->ocr,
957 host->card,
958 mmc_card_keep_power(host));
959 } else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { 980 } else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) {
960 /* We may have switched to 1-bit mode during suspend */ 981 /* We may have switched to 1-bit mode during suspend */
961 err = sdio_enable_4bit_bus(host->card); 982 err = sdio_enable_4bit_bus(host->card);
@@ -978,8 +999,6 @@ static int mmc_sdio_power_restore(struct mmc_host *host)
978{ 999{
979 int ret; 1000 int ret;
980 1001
981 mmc_claim_host(host);
982
983 /* 1002 /*
984 * Reset the card by performing the same steps that are taken by 1003 * Reset the card by performing the same steps that are taken by
985 * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe. 1004 * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe.
@@ -997,20 +1016,12 @@ static int mmc_sdio_power_restore(struct mmc_host *host)
997 * 1016 *
998 */ 1017 */
999 1018
1000 sdio_reset(host); 1019 mmc_claim_host(host);
1001 mmc_go_idle(host);
1002 mmc_send_if_cond(host, host->card->ocr);
1003
1004 ret = mmc_send_io_op_cond(host, 0, NULL);
1005 if (ret)
1006 goto out;
1007 1020
1008 ret = mmc_sdio_init_card(host, host->card->ocr, host->card, 1021 ret = mmc_sdio_reinit_card(host, mmc_card_keep_power(host));
1009 mmc_card_keep_power(host));
1010 if (!ret && host->sdio_irqs) 1022 if (!ret && host->sdio_irqs)
1011 mmc_signal_sdio_irq(host); 1023 mmc_signal_sdio_irq(host);
1012 1024
1013out:
1014 mmc_release_host(host); 1025 mmc_release_host(host);
1015 1026
1016 return ret; 1027 return ret;
@@ -1039,12 +1050,24 @@ static int mmc_sdio_runtime_resume(struct mmc_host *host)
1039 return ret; 1050 return ret;
1040} 1051}
1041 1052
1042static int mmc_sdio_reset(struct mmc_host *host) 1053static int mmc_sdio_hw_reset(struct mmc_host *host)
1043{ 1054{
1044 mmc_power_cycle(host, host->card->ocr); 1055 mmc_power_cycle(host, host->card->ocr);
1045 return mmc_sdio_power_restore(host); 1056 return mmc_sdio_power_restore(host);
1046} 1057}
1047 1058
1059static int mmc_sdio_sw_reset(struct mmc_host *host)
1060{
1061 mmc_set_clock(host, host->f_init);
1062 sdio_reset(host);
1063 mmc_go_idle(host);
1064
1065 mmc_set_initial_state(host);
1066 mmc_set_initial_signal_voltage(host);
1067
1068 return mmc_sdio_reinit_card(host, 0);
1069}
1070
1048static const struct mmc_bus_ops mmc_sdio_ops = { 1071static const struct mmc_bus_ops mmc_sdio_ops = {
1049 .remove = mmc_sdio_remove, 1072 .remove = mmc_sdio_remove,
1050 .detect = mmc_sdio_detect, 1073 .detect = mmc_sdio_detect,
@@ -1055,7 +1078,8 @@ static const struct mmc_bus_ops mmc_sdio_ops = {
1055 .runtime_resume = mmc_sdio_runtime_resume, 1078 .runtime_resume = mmc_sdio_runtime_resume,
1056 .power_restore = mmc_sdio_power_restore, 1079 .power_restore = mmc_sdio_power_restore,
1057 .alive = mmc_sdio_alive, 1080 .alive = mmc_sdio_alive,
1058 .reset = mmc_sdio_reset, 1081 .hw_reset = mmc_sdio_hw_reset,
1082 .sw_reset = mmc_sdio_sw_reset,
1059}; 1083};
1060 1084
1061 1085