diff options
author | Linus Torvalds | 2017-07-04 20:11:56 +0200 |
---|---|---|
committer | Linus Torvalds | 2017-07-04 20:11:56 +0200 |
commit | 17ece345a042347224e50032e959ad3959638b21 (patch) | |
tree | fd9dd89cce014a4088fda9aee837f2ac6e47ade8 /drivers/mmc/core/core.c | |
parent | Merge tag 'docs-4.13' of git://git.lwn.net/linux (diff) | |
parent | mmc: dw_mmc: remove the unnecessary slot variable (diff) | |
download | kernel-qcow2-linux-17ece345a042347224e50032e959ad3959638b21.tar.gz kernel-qcow2-linux-17ece345a042347224e50032e959ad3959638b21.tar.xz kernel-qcow2-linux-17ece345a042347224e50032e959ad3959638b21.zip |
Merge tag 'mmc-v4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
Pull MMC updates from Ulf Hansson:
"MMC core:
- Add support to enable irq wake for slot gpio
- Remove MMC_CAP2_HC_ERASE_SZ and make it the default behaviour
- Improve R1 response error checks for stop commands
- Cleanup and clarify some MMC specific code
- Keep card runtime resumed while adding SDIO function devices
- Use device_property_read instead of of_property_read in mmc_of_parse()
- Move boot partition locking into a driver op to enable proper I/O scheduling
- Move multi/single-ioctl() to use block layer to enable proper I/O scheduling
- Delete bounce buffer Kconfig option
- Improve the eMMC HW reset support provided via the eMMC pwrseq
- Add host API to manage SDIO IRQs from a workqueue
MMC host:
- dw_mmc: Drop support for multiple slots
- dw_mmc: Use device_property_read instead of of_property_read
- dw_mmc-rockchip: Optional improved tuning to greatly decrease tuning time
- dw_mmc: Prevent rpm suspend for SDIO IRQs instead of always for SDIO cards
- dw_mmc: Convert to use MMC_CAP2_SDIO_IRQ_NOTHREAD for SDIO IRQs
- omap_hsmmc: Convert to mmc regulator APIs to consolidate code
- omap_hsmmc: Deprecate "vmmc_aux" in DT and use "vqmmc" instead
- tmio: make sure SDIO gets reinitialized after resume
- sdhi: add CMD23 support to R-Car Gen2 & Gen3
- tmio: add CMD23 support
- sdhi/tmio: Refactor code and rename files to simplify Kconfig options
- sdhci-pci: Enable card detect wake for Intel BYT-related SD controllers
- sdhci-pci: Add support for Intel CNP
- sdhci-esdhc-imx: Remove ENGcm07207 workaround - allow multi block transfers
- sdhci-esdhc-imx: Allow all supported prescaler values
- sdhci-esdhc-imx: Fix DAT line software reset
- sdhci-esdhc: Add SDHCI_QUIRK_32BIT_DMA_ADDR
- atmel-mci: Drop AVR32 support"
* tag 'mmc-v4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (86 commits)
mmc: dw_mmc: remove the unnecessary slot variable
mmc: dw_mmc: use the 'slot' instead of 'cur_slot'
mmc: dw_mmc: remove the 'id' arguments about functions relevant to slot
mmc: dw_mmc: change the array of slots
mmc: dw_mmc: remove the loop about finding slots
mmc: dw_mmc: deprecated the "num-slots" property
mmc: dw_mmc-rockchip: parse rockchip, desired-num-phases from DT
dt-bindings: rockchip-dw-mshc: add optional rockchip, desired-num-phases
mmc: renesas-sdhi: improve checkpatch cleanness
mmc: tmio: improve checkpatch cleanness
mmc: sdhci-pci: Enable card detect wake for Intel BYT-related SD controllers
mmc: slot-gpio: Add support to enable irq wake on cd_irq
mmc: core: Remove MMC_CAP2_HC_ERASE_SZ
mmc: core: for data errors, take response of stop cmd into account
mmc: core: check also R1 response for stop commands
mmc: core: Clarify code for sending CSD
mmc: core: Drop mmc_all_send_cid() and use mmc_send_cxd_native() instead
mmc: core: Re-factor code for sending CID
mmc: core: Remove redundant code in mmc_send_cid()
mmc: core: Make mmc_can_reset() static
...
Diffstat (limited to 'drivers/mmc/core/core.c')
-rw-r--r-- | drivers/mmc/core/core.c | 214 |
1 files changed, 6 insertions, 208 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 82c45ddfa202..26431267a3e2 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -53,12 +53,6 @@ /* If the device is not responding */ #define MMC_CORE_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ -/* - * Background operations can take a long time, depending on the housekeeping - * operations the card has to perform. - */ -#define MMC_BKOPS_MAX_TIMEOUT (4 * 60 * 1000) /* max time to wait in ms */ - /* The max erase timeout, used when host->max_busy_timeout isn't specified */ #define MMC_ERASE_TIMEOUT_MS (60 * 1000) /* 60 s */ @@ -362,74 +356,6 @@ static int mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) return 0; } -/** - * mmc_start_bkops - start BKOPS for supported cards - * @card: MMC card to start BKOPS - * @form_exception: A flag to indicate if this function was - * called due to an exception raised by the card - * - * Start background operations whenever requested. - * When the urgent BKOPS bit is set in a R1 command response - * then background operations should be started immediately. -*/ -void mmc_start_bkops(struct mmc_card *card, bool from_exception) -{ - int err; - int timeout; - bool use_busy_signal; - - if (!card->ext_csd.man_bkops_en || mmc_card_doing_bkops(card)) - return; - - err = mmc_read_bkops_status(card); - if (err) { - pr_err("%s: Failed to read bkops status: %d\n", - mmc_hostname(card->host), err); - return; - } - - if (!card->ext_csd.raw_bkops_status) - return; - - if (card->ext_csd.raw_bkops_status < EXT_CSD_BKOPS_LEVEL_2 && - from_exception) - return; - - mmc_claim_host(card->host); - if (card->ext_csd.raw_bkops_status >= EXT_CSD_BKOPS_LEVEL_2) { - timeout = MMC_BKOPS_MAX_TIMEOUT; - use_busy_signal = true; - } else { - timeout = 0; - use_busy_signal = false; - } - - mmc_retune_hold(card->host); - - err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BKOPS_START, 1, timeout, 0, - use_busy_signal, true, false); - if (err) { - pr_warn("%s: Error %d starting bkops\n", - mmc_hostname(card->host), err); - mmc_retune_release(card->host); - goto out; - } - - /* - * For urgent bkops status (LEVEL_2 and more) - * bkops executed synchronously, otherwise - * the operation is in progress - */ - if (!use_busy_signal) - mmc_card_set_doing_bkops(card); - else - mmc_retune_release(card->host); -out: - mmc_release_host(card->host); -} -EXPORT_SYMBOL(mmc_start_bkops); - /* * mmc_wait_data_done() - done callback for data request * @mrq: done data request @@ -749,71 +675,6 @@ void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) EXPORT_SYMBOL(mmc_wait_for_req); /** - * mmc_interrupt_hpi - Issue for High priority Interrupt - * @card: the MMC card associated with the HPI transfer - * - * Issued High Priority Interrupt, and check for card status - * until out-of prg-state. - */ -int mmc_interrupt_hpi(struct mmc_card *card) -{ - int err; - u32 status; - unsigned long prg_wait; - - if (!card->ext_csd.hpi_en) { - pr_info("%s: HPI enable bit unset\n", mmc_hostname(card->host)); - return 1; - } - - mmc_claim_host(card->host); - err = mmc_send_status(card, &status); - if (err) { - pr_err("%s: Get card status fail\n", mmc_hostname(card->host)); - goto out; - } - - switch (R1_CURRENT_STATE(status)) { - case R1_STATE_IDLE: - case R1_STATE_READY: - case R1_STATE_STBY: - case R1_STATE_TRAN: - /* - * In idle and transfer states, HPI is not needed and the caller - * can issue the next intended command immediately - */ - goto out; - case R1_STATE_PRG: - break; - default: - /* In all other states, it's illegal to issue HPI */ - pr_debug("%s: HPI cannot be sent. Card state=%d\n", - mmc_hostname(card->host), R1_CURRENT_STATE(status)); - err = -EINVAL; - goto out; - } - - err = mmc_send_hpi_cmd(card, &status); - if (err) - goto out; - - prg_wait = jiffies + msecs_to_jiffies(card->ext_csd.out_of_int_time); - do { - err = mmc_send_status(card, &status); - - if (!err && R1_CURRENT_STATE(status) == R1_STATE_TRAN) - break; - if (time_after(jiffies, prg_wait)) - err = -ETIMEDOUT; - } while (!err); - -out: - mmc_release_host(card->host); - return err; -} -EXPORT_SYMBOL(mmc_interrupt_hpi); - -/** * mmc_wait_for_cmd - start a command and wait for completion * @host: MMC host to start command * @cmd: MMC command to start @@ -843,53 +704,6 @@ int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries EXPORT_SYMBOL(mmc_wait_for_cmd); /** - * mmc_stop_bkops - stop ongoing BKOPS - * @card: MMC card to check BKOPS - * - * Send HPI command to stop ongoing background operations to - * allow rapid servicing of foreground operations, e.g. read/ - * writes. Wait until the card comes out of the programming state - * to avoid errors in servicing read/write requests. - */ -int mmc_stop_bkops(struct mmc_card *card) -{ - int err = 0; - - err = mmc_interrupt_hpi(card); - - /* - * If err is EINVAL, we can't issue an HPI. - * It should complete the BKOPS. - */ - if (!err || (err == -EINVAL)) { - mmc_card_clr_doing_bkops(card); - mmc_retune_release(card->host); - err = 0; - } - - return err; -} -EXPORT_SYMBOL(mmc_stop_bkops); - -int mmc_read_bkops_status(struct mmc_card *card) -{ - int err; - u8 *ext_csd; - - mmc_claim_host(card->host); - err = mmc_get_ext_csd(card, &ext_csd); - mmc_release_host(card->host); - if (err) - return err; - - card->ext_csd.raw_bkops_status = ext_csd[EXT_CSD_BKOPS_STATUS]; - card->ext_csd.raw_exception_status = ext_csd[EXT_CSD_EXP_EVENTS_STATUS]; - kfree(ext_csd); - return 0; -} -EXPORT_SYMBOL(mmc_read_bkops_status); - -/** * mmc_set_data_timeout - set the timeout for a data command * @data: data phase for command * @card: the MMC card associated with the data transfer @@ -2597,6 +2411,8 @@ EXPORT_SYMBOL(mmc_set_blockcount); static void mmc_hw_reset_for_init(struct mmc_host *host) { + mmc_pwrseq_reset(host); + if (!(host->caps & MMC_CAP_HW_RESET) || !host->ops->hw_reset) return; host->ops->hw_reset(host); @@ -2836,8 +2652,11 @@ void mmc_stop_host(struct mmc_host *host) host->removed = 1; spin_unlock_irqrestore(&host->lock, flags); #endif - if (host->slot.cd_irq >= 0) + if (host->slot.cd_irq >= 0) { + if (host->slot.cd_wake_enabled) + disable_irq_wake(host->slot.cd_irq); disable_irq(host->slot.cd_irq); + } host->rescan_disable = 1; cancel_delayed_work_sync(&host->detect); @@ -2913,27 +2732,6 @@ int mmc_power_restore_host(struct mmc_host *host) } EXPORT_SYMBOL(mmc_power_restore_host); -/* - * Flush the cache to the non-volatile storage. - */ -int mmc_flush_cache(struct mmc_card *card) -{ - int err = 0; - - if (mmc_card_mmc(card) && - (card->ext_csd.cache_size > 0) && - (card->ext_csd.cache_ctrl & 1)) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_FLUSH_CACHE, 1, 0); - if (err) - pr_err("%s: cache flush error %d\n", - mmc_hostname(card->host), err); - } - - return err; -} -EXPORT_SYMBOL(mmc_flush_cache); - #ifdef CONFIG_PM_SLEEP /* Do the card removal on suspend if card is assumed removeable * Do that in pm notifier while userspace isn't yet frozen, so we will be able |