diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-08-05 13:23:24 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-08-05 13:23:24 -0700 |
commit | 8f7be6291529011a58856bf178f52ed5751c68ac (patch) | |
tree | ab0e58a5ff58e6c713e7abfa97c815be1bcc44e4 /drivers/mmc/core | |
parent | 9aebd3254c184fb6c731548b8347193bf882b6f7 (diff) | |
parent | 7f4bc2e8687ecea52177aac30fb153cc076f7022 (diff) |
Merge tag 'mmc-v5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson:
"MMC core:
- Add a new host cap bit and a corresponding DT property, to support
power cycling of the card by FW at system suspend/resume.
- Fix clock rate setting for SDIO in SDR12/SDR25 speed-mode
- Fix switch to 1/4-bit mode at system suspend/resume for SD-combo
cards
- Convert the mmc-pwrseq DT bindings to the json-schema
- Always allow the card detect uevent to be consumed by userspace
MMC host controllers:
- Convert a few DT bindings to the json-schema
- mtk-sd:
- Add support for command queue through cqhci
- Add support for the MT6779 variant
- renesas_sdhi_internal_dmac:
- Fix dma unmapping in the error path
- sdhci_am654:
- Add support for the AM65x PG2.0 variant
- Extend support for phys/clocks
- sdhci-cadence:
- Drop incorrect HW tuning for SD mode
- sdhci-msm:
- Add support for interconnect bandwidth scaling
- Enable internal voltage control
- Enable low power state for pinctrls
- sdhci-of-at91:
- Ludovic Desroches handovers maintenance to Eugen Hristev
- sdhci-pci-gli:
- Improve clock handling for GL975x
- sdhci-pci-o2micro:
- Add HW tuning for SDR104 mode
- Fix support for O2 host controller Seabird1"
* tag 'mmc-v5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (66 commits)
mmc: mediatek: make function msdc_cqe_disable() static
MAINTAINERS: mmc: sdhci-of-at91: handover maintenance to Eugen Hristev
dt-bindings: mmc: mediatek: Add document for mt6779
mmc: mediatek: command queue support
mmc: mediatek: refine msdc timeout api
mmc: mediatek: add MT6779 MMC driver support
mmc: sdhci-pci-o2micro: Add HW tuning for SDR104 mode
mmc: sdhci-pci-o2micro: Bug fix for O2 host controller Seabird1
mmc: via-sdmmc: use generic power management
memstick: jmb38x_ms: use generic power management
mmc: sdhci-cadence: do not use hardware tuning for SD mode
mmc: sdhci-pci-gli: Set SDR104's clock to 205MHz and enable SSC for GL975x
mmc: cqhci: Fix a print format for the task descriptor
mmc: sdhci-of-arasan: fix timings allocation code
mmc: sdhci: Fix a potential uninitialized variable
dt-bindings: mmc: renesas,sdhi: convert to YAML
dt-bindings: mmc: convert arasan sdhci bindings to yaml
mmc: sdhci: Fix potential null pointer access while accessing vqmmc
mmc: core: Add MMC_CAP2_FULL_PWR_CYCLE_IN_SUSPEND
dt-bindings: mmc: Add full-pwr-cycle-in-suspend property
...
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r-- | drivers/mmc/core/core.c | 11 | ||||
-rw-r--r-- | drivers/mmc/core/host.c | 6 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 3 | ||||
-rw-r--r-- | drivers/mmc/core/queue.c | 2 | ||||
-rw-r--r-- | drivers/mmc/core/quirks.h | 6 | ||||
-rw-r--r-- | drivers/mmc/core/regulator.c | 2 | ||||
-rw-r--r-- | drivers/mmc/core/sdio.c | 64 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_io.c | 3 |
8 files changed, 63 insertions, 34 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 8d2b808e9b58..8ccae6452b9c 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1455,12 +1455,12 @@ void mmc_detach_bus(struct mmc_host *host) void _mmc_detect_change(struct mmc_host *host, unsigned long delay, bool cd_irq) { /* - * If the device is configured as wakeup, we prevent a new sleep for - * 5 s to give provision for user space to consume the event. + * Prevent system sleep for 5s to allow user space to consume the + * corresponding uevent. This is especially useful, when CD irq is used + * as a system wakeup, but doesn't hurt in other cases. */ - if (cd_irq && !(host->caps & MMC_CAP_NEEDS_POLL) && - device_can_wakeup(mmc_dev(host))) - pm_wakeup_event(mmc_dev(host), 5000); + if (cd_irq && !(host->caps & MMC_CAP_NEEDS_POLL)) + __pm_wakeup_event(host->ws, 5000); host->detect_change = 1; mmc_schedule_delayed_work(&host->detect, delay); @@ -2303,7 +2303,6 @@ void mmc_start_host(struct mmc_host *host) { host->f_init = max(min(freqs[0], host->f_max), host->f_min); host->rescan_disable = 0; - host->ios.power_mode = MMC_POWER_UNDEFINED; if (!(host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)) { mmc_claim_host(host); diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index c8768726d925..ce43f7573d80 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -15,6 +15,7 @@ #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/pagemap.h> +#include <linux/pm_wakeup.h> #include <linux/export.h> #include <linux/leds.h> #include <linux/slab.h> @@ -36,6 +37,7 @@ static DEFINE_IDA(mmc_host_ida); static void mmc_host_classdev_release(struct device *dev) { struct mmc_host *host = cls_dev_to_mmc_host(dev); + wakeup_source_unregister(host->ws); ida_simple_remove(&mmc_host_ida, host->index); kfree(host); } @@ -275,6 +277,8 @@ int mmc_of_parse(struct mmc_host *host) host->caps |= MMC_CAP_SDIO_IRQ; if (device_property_read_bool(dev, "full-pwr-cycle")) host->caps2 |= MMC_CAP2_FULL_PWR_CYCLE; + if (device_property_read_bool(dev, "full-pwr-cycle-in-suspend")) + host->caps2 |= MMC_CAP2_FULL_PWR_CYCLE_IN_SUSPEND; if (device_property_read_bool(dev, "keep-power-in-suspend")) host->pm_caps |= MMC_PM_KEEP_POWER; if (device_property_read_bool(dev, "wakeup-source") || @@ -400,6 +404,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) host->index = err; dev_set_name(&host->class_dev, "mmc%d", host->index); + host->ws = wakeup_source_register(NULL, dev_name(&host->class_dev)); host->parent = dev; host->class_dev.parent = dev; @@ -431,6 +436,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) host->fixed_drv_type = -EINVAL; host->ios.power_delay_ms = 10; + host->ios.power_mode = MMC_POWER_UNDEFINED; return host; } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 4203303f946a..b3fa193de846 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -2038,7 +2038,8 @@ static int _mmc_suspend(struct mmc_host *host, bool is_suspend) goto out; if (mmc_can_poweroff_notify(host->card) && - ((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend)) + ((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend || + (host->caps2 & MMC_CAP2_FULL_PWR_CYCLE_IN_SUSPEND))) err = mmc_poweroff_notify(host->card, notify_type); else if (mmc_can_sleep(host->card)) err = mmc_sleep(host); diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index 4b1eb89b401d..6c022ef0f84d 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -203,7 +203,7 @@ static unsigned int mmc_get_max_segments(struct mmc_host *host) /** * mmc_init_request() - initialize the MMC-specific per-request data - * @q: the request queue + * @mq: the request queue * @req: the request * @gfp: memory allocation policy */ diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index 472fa2fdcf13..d68e6e513a4f 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h @@ -14,7 +14,7 @@ #include "card.h" -static const struct mmc_fixup mmc_blk_fixups[] = { +static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = { #define INAND_CMD38_ARG_EXT_CSD 113 #define INAND_CMD38_ARG_ERASE 0x00 #define INAND_CMD38_ARG_TRIM 0x01 @@ -102,7 +102,7 @@ static const struct mmc_fixup mmc_blk_fixups[] = { END_FIXUP }; -static const struct mmc_fixup mmc_ext_csd_fixups[] = { +static const struct mmc_fixup __maybe_unused mmc_ext_csd_fixups[] = { /* * Certain Hynix eMMC 4.41 cards might get broken when HPI feature * is used so disable the HPI feature for such buggy cards. @@ -120,7 +120,7 @@ static const struct mmc_fixup mmc_ext_csd_fixups[] = { }; -static const struct mmc_fixup sdio_fixup_methods[] = { +static const struct mmc_fixup __maybe_unused sdio_fixup_methods[] = { SDIO_FIXUP(SDIO_VENDOR_ID_TI_WL1251, SDIO_DEVICE_ID_TI_WL1251, add_quirk, MMC_QUIRK_NONSTD_FUNC_IF), diff --git a/drivers/mmc/core/regulator.c b/drivers/mmc/core/regulator.c index 96b1d15045d6..609201a467ef 100644 --- a/drivers/mmc/core/regulator.c +++ b/drivers/mmc/core/regulator.c @@ -159,6 +159,8 @@ static int mmc_regulator_set_voltage_if_supported(struct regulator *regulator, /** * mmc_regulator_set_vqmmc - Set VQMMC as per the ios + * @mmc: the host to regulate + * @ios: io bus settings * * For 3.3V signaling, we try to match VQMMC to VMMC as closely as possible. * That will match the behavior of old boards where VQMMC and VMMC were supplied diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index b65b26f76d71..7b40553d3934 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -176,15 +176,18 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr) if (mmc_host_uhs(card->host)) { if (data & SDIO_UHS_DDR50) card->sw_caps.sd3_bus_mode - |= SD_MODE_UHS_DDR50; + |= SD_MODE_UHS_DDR50 | SD_MODE_UHS_SDR50 + | SD_MODE_UHS_SDR25 | SD_MODE_UHS_SDR12; if (data & SDIO_UHS_SDR50) card->sw_caps.sd3_bus_mode - |= SD_MODE_UHS_SDR50; + |= SD_MODE_UHS_SDR50 | SD_MODE_UHS_SDR25 + | SD_MODE_UHS_SDR12; if (data & SDIO_UHS_SDR104) card->sw_caps.sd3_bus_mode - |= SD_MODE_UHS_SDR104; + |= SD_MODE_UHS_SDR104 | SD_MODE_UHS_SDR50 + | SD_MODE_UHS_SDR25 | SD_MODE_UHS_SDR12; } ret = mmc_io_rw_direct(card, 0, 0, @@ -303,30 +306,49 @@ static int sdio_disable_wide(struct mmc_card *card) return 0; } +static int sdio_disable_4bit_bus(struct mmc_card *card) +{ + int err; + + if (card->type == MMC_TYPE_SDIO) + goto out; + + if (!(card->host->caps & MMC_CAP_4_BIT_DATA)) + return 0; + + if (!(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) + return 0; + + err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_1); + if (err) + return err; + +out: + return sdio_disable_wide(card); +} + static int sdio_enable_4bit_bus(struct mmc_card *card) { int err; + err = sdio_enable_wide(card); + if (err <= 0) + return err; if (card->type == MMC_TYPE_SDIO) - err = sdio_enable_wide(card); - else if ((card->host->caps & MMC_CAP_4_BIT_DATA) && - (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { + goto out; + + if (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4) { err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); - if (err) + if (err) { + sdio_disable_wide(card); return err; - err = sdio_enable_wide(card); - if (err <= 0) - mmc_app_set_bus_width(card, MMC_BUS_WIDTH_1); - } else - return 0; - - if (err > 0) { - mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); - err = 0; + } } +out: + mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); - return err; + return 0; } @@ -518,10 +540,8 @@ static int sdio_set_bus_speed_mode(struct mmc_card *card) max_rate = min_not_zero(card->quirk_max_rate, card->sw_caps.uhs_max_dtr); - if (bus_speed) { - mmc_set_timing(card->host, timing); - mmc_set_clock(card->host, max_rate); - } + mmc_set_timing(card->host, timing); + mmc_set_clock(card->host, max_rate); return 0; } @@ -972,7 +992,7 @@ static int mmc_sdio_suspend(struct mmc_host *host) mmc_claim_host(host); if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) - sdio_disable_wide(host->card); + sdio_disable_4bit_bus(host->card); if (!mmc_card_keep_power(host)) { mmc_power_off(host); diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index 2ba00acf64e6..79dbf90216b5 100644 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c @@ -133,7 +133,7 @@ int sdio_disable_func(struct sdio_func *func) err: pr_debug("SDIO: Failed to disable device %s\n", sdio_func_id(func)); - return -EIO; + return ret; } EXPORT_SYMBOL_GPL(sdio_disable_func); @@ -709,6 +709,7 @@ EXPORT_SYMBOL_GPL(sdio_get_host_pm_caps); /** * sdio_set_host_pm_flags - set wanted host power management capabilities * @func: SDIO function attached to host + * @flags: Power Management flags to set * * Set a capability bitmask corresponding to wanted host controller * power management features for the upcoming suspend state. |