Skip to content

Commit

Permalink
[MMC] sdhci: fix timeout loops in sdhci
Browse files Browse the repository at this point in the history
The current timeout loop assume that jiffies are updated.  This might not be
the case depending on locks and if the kernel is compiled without preemption.
Change the system to use a counter and fixed delays.

Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Pierre Ossman authored and Russell King committed Jul 2, 2006
1 parent 146ad66 commit 7cb2c76
Showing 1 changed file with 16 additions and 13 deletions.
29 changes: 16 additions & 13 deletions drivers/mmc/sdhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,17 +371,17 @@ static void sdhci_finish_data(struct sdhci_host *host)
static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
{
int flags;
u32 present;
unsigned long max_jiffies;
unsigned long timeout;

WARN_ON(host->cmd);

DBG("Sending cmd (%x)\n", cmd->opcode);

/* Wait max 10 ms */
max_jiffies = jiffies + (HZ + 99)/100;
do {
if (time_after(jiffies, max_jiffies)) {
timeout = 10;
while (readl(host->ioaddr + SDHCI_PRESENT_STATE) &
(SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT)) {
if (timeout == 0) {
printk(KERN_ERR "%s: Controller never released "
"inhibit bits. Please report this to "
BUGMAIL ".\n", mmc_hostname(host->mmc));
Expand All @@ -390,8 +390,9 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
tasklet_schedule(&host->finish_tasklet);
return;
}
present = readl(host->ioaddr + SDHCI_PRESENT_STATE);
} while (present & (SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT));
timeout--;
mdelay(1);
}

mod_timer(&host->timer, jiffies + 10 * HZ);

Expand Down Expand Up @@ -490,7 +491,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
{
int div;
u16 clk;
unsigned long max_jiffies;
unsigned long timeout;

if (clock == host->clock)
return;
Expand All @@ -511,17 +512,19 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);

/* Wait max 10 ms */
max_jiffies = jiffies + (HZ + 99)/100;
do {
if (time_after(jiffies, max_jiffies)) {
timeout = 10;
while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL))
& SDHCI_CLOCK_INT_STABLE)) {
if (timeout == 0) {
printk(KERN_ERR "%s: Internal clock never stabilised. "
"Please report this to " BUGMAIL ".\n",
mmc_hostname(host->mmc));
sdhci_dumpregs(host);
return;
}
clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL);
} while (!(clk & SDHCI_CLOCK_INT_STABLE));
timeout--;
mdelay(1);
}

clk |= SDHCI_CLOCK_CARD_EN;
writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
Expand Down

0 comments on commit 7cb2c76

Please sign in to comment.