summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/sdhci.h
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2020-04-12 12:03:49 +0300
committerUlf Hansson <ulf.hansson@linaro.org>2020-05-28 12:20:59 +0300
commit845c939ee22943786a6eb1d13d03c77b19fcc2c8 (patch)
treee79a4bd1046c0989ef265d2394377d163df510e8 /drivers/mmc/host/sdhci.h
parente872f1e22ea5f678ae42812949477387fda6725b (diff)
downloadlinux-845c939ee22943786a6eb1d13d03c77b19fcc2c8.tar.xz
mmc: sdhci: Reduce maximum time under spinlock in sdhci_send_command()
Spending time under spinlock increases IRQ latencies and also response times because preemption is disabled. sdhci_send_command() waits up to 10 ms under spinlock for inhibit bits to clear. In general inhibit bits will not be set, but there may be corner cases, especially in the face of errors, where waiting helps. There might also be dysfunctional hardware that needs the waiting. So retain the legacy behaviour but do not wait for inhibit bits while under spinlock. Instead adjust the logic to enable waiting while not under spinlock. That is mostly straight forward, but in the interrupt handler it requires deferring an "inhibited" command to the IRQ thread where sleeping is allowed. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Tested-by: Baolin Wang <baolin.wang7@gmail.com> Link: https://lore.kernel.org/r/20200412090349.1607-6-adrian.hunter@intel.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/host/sdhci.h')
-rw-r--r--drivers/mmc/host/sdhci.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 1f5a46eaab8f..8483419a937e 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -534,6 +534,7 @@ struct sdhci_host {
struct mmc_request *mrqs_done[SDHCI_MAX_MRQS]; /* Requests done */
struct mmc_command *cmd; /* Current command */
struct mmc_command *data_cmd; /* Current data command */
+ struct mmc_command *deferred_cmd; /* Deferred command */
struct mmc_data *data; /* Current data request */
unsigned int data_early:1; /* Data finished before cmd */