Commit 2a85ef25 authored by Adrian Hunter's avatar Adrian Hunter Committed by Ulf Hansson

mmc: sdhci: Reduce spin lock usage in sdhci_execute_tuning

Tuning execution is already synchronized with respect to other host
operations by upper layers "claiming" the host, which also takes care of
runtime pm. There can be no requests in progress. Retain the spin lock
usage only for ensuring that sending tuning commands is synchronized with
respect to the interrupt handler.
Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Tested-by: default avatarLudovic Desroches <ludovic.desroches@microchip.com>
parent d1e4f74f
...@@ -1993,8 +1993,7 @@ static void sdhci_reset_tuning(struct sdhci_host *host) ...@@ -1993,8 +1993,7 @@ static void sdhci_reset_tuning(struct sdhci_host *host)
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
} }
static void sdhci_abort_tuning(struct sdhci_host *host, u32 opcode, static void sdhci_abort_tuning(struct sdhci_host *host, u32 opcode)
unsigned long flags)
{ {
sdhci_reset_tuning(host); sdhci_reset_tuning(host);
...@@ -2003,9 +2002,7 @@ static void sdhci_abort_tuning(struct sdhci_host *host, u32 opcode, ...@@ -2003,9 +2002,7 @@ static void sdhci_abort_tuning(struct sdhci_host *host, u32 opcode,
sdhci_end_tuning(host); sdhci_end_tuning(host);
spin_unlock_irqrestore(&host->lock, flags);
mmc_abort_tuning(host->mmc, opcode); mmc_abort_tuning(host->mmc, opcode);
spin_lock_irqsave(&host->lock, flags);
} }
/* /*
...@@ -2015,12 +2012,14 @@ static void sdhci_abort_tuning(struct sdhci_host *host, u32 opcode, ...@@ -2015,12 +2012,14 @@ static void sdhci_abort_tuning(struct sdhci_host *host, u32 opcode,
* interrupt setup is different to other commands and there is no timeout * interrupt setup is different to other commands and there is no timeout
* interrupt so special handling is needed. * interrupt so special handling is needed.
*/ */
static void sdhci_send_tuning(struct sdhci_host *host, u32 opcode, static void sdhci_send_tuning(struct sdhci_host *host, u32 opcode)
unsigned long flags)
{ {
struct mmc_host *mmc = host->mmc; struct mmc_host *mmc = host->mmc;
struct mmc_command cmd = {}; struct mmc_command cmd = {};
struct mmc_request mrq = {}; struct mmc_request mrq = {};
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
cmd.opcode = opcode; cmd.opcode = opcode;
cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
...@@ -2054,17 +2053,16 @@ static void sdhci_send_tuning(struct sdhci_host *host, u32 opcode, ...@@ -2054,17 +2053,16 @@ static void sdhci_send_tuning(struct sdhci_host *host, u32 opcode,
host->tuning_done = 0; host->tuning_done = 0;
mmiowb();
spin_unlock_irqrestore(&host->lock, flags); spin_unlock_irqrestore(&host->lock, flags);
/* Wait for Buffer Read Ready interrupt */ /* Wait for Buffer Read Ready interrupt */
wait_event_timeout(host->buf_ready_int, (host->tuning_done == 1), wait_event_timeout(host->buf_ready_int, (host->tuning_done == 1),
msecs_to_jiffies(50)); msecs_to_jiffies(50));
spin_lock_irqsave(&host->lock, flags);
} }
static void __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode, static void __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
unsigned long flags)
{ {
int i; int i;
...@@ -2075,12 +2073,12 @@ static void __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode, ...@@ -2075,12 +2073,12 @@ static void __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode,
for (i = 0; i < MAX_TUNING_LOOP; i++) { for (i = 0; i < MAX_TUNING_LOOP; i++) {
u16 ctrl; u16 ctrl;
sdhci_send_tuning(host, opcode, flags); sdhci_send_tuning(host, opcode);
if (!host->tuning_done) { if (!host->tuning_done) {
pr_info("%s: Tuning timeout, falling back to fixed sampling clock\n", pr_info("%s: Tuning timeout, falling back to fixed sampling clock\n",
mmc_hostname(host->mmc)); mmc_hostname(host->mmc));
sdhci_abort_tuning(host, opcode, flags); sdhci_abort_tuning(host, opcode);
return; return;
} }
...@@ -2105,12 +2103,9 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) ...@@ -2105,12 +2103,9 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
{ {
struct sdhci_host *host = mmc_priv(mmc); struct sdhci_host *host = mmc_priv(mmc);
int err = 0; int err = 0;
unsigned long flags;
unsigned int tuning_count = 0; unsigned int tuning_count = 0;
bool hs400_tuning; bool hs400_tuning;
spin_lock_irqsave(&host->lock, flags);
hs400_tuning = host->flags & SDHCI_HS400_TUNING; hs400_tuning = host->flags & SDHCI_HS400_TUNING;
if (host->tuning_mode == SDHCI_TUNING_MODE_1) if (host->tuning_mode == SDHCI_TUNING_MODE_1)
...@@ -2127,7 +2122,7 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) ...@@ -2127,7 +2122,7 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
/* HS400 tuning is done in HS200 mode */ /* HS400 tuning is done in HS200 mode */
case MMC_TIMING_MMC_HS400: case MMC_TIMING_MMC_HS400:
err = -EINVAL; err = -EINVAL;
goto out_unlock; goto out;
case MMC_TIMING_MMC_HS200: case MMC_TIMING_MMC_HS200:
/* /*
...@@ -2148,26 +2143,23 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) ...@@ -2148,26 +2143,23 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
goto out_unlock; goto out;
} }
if (host->ops->platform_execute_tuning) { if (host->ops->platform_execute_tuning) {
spin_unlock_irqrestore(&host->lock, flags);
err = host->ops->platform_execute_tuning(host, opcode); err = host->ops->platform_execute_tuning(host, opcode);
spin_lock_irqsave(&host->lock, flags); goto out;
goto out_unlock;
} }
host->mmc->retune_period = tuning_count; host->mmc->retune_period = tuning_count;
sdhci_start_tuning(host); sdhci_start_tuning(host);
__sdhci_execute_tuning(host, opcode, flags); __sdhci_execute_tuning(host, opcode);
sdhci_end_tuning(host); sdhci_end_tuning(host);
out_unlock: out:
host->flags &= ~SDHCI_HS400_TUNING; host->flags &= ~SDHCI_HS400_TUNING;
spin_unlock_irqrestore(&host->lock, flags);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment