diff options
author | Adrian Hunter <adrian.hunter@intel.com> | 2020-04-12 12:03:49 +0300 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2020-05-28 11:20:59 +0200 |
commit | 845c939ee22943786a6eb1d13d03c77b19fcc2c8 (patch) | |
tree | e79a4bd1046c0989ef265d2394377d163df510e8 /drivers/mmc/host/sdhci.h | |
parent | e872f1e22ea5f678ae42812949477387fda6725b (diff) | |
download | linux-845c939ee22943786a6eb1d13d03c77b19fcc2c8.tar.bz2 |
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.h | 1 |
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 */ |