lkml.org 
[lkml]   [2006]   [Jun]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 04/21] [MMC] Fix timeout loops in sdhci
    Date
    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>
    ---

    drivers/mmc/sdhci.c | 29 ++++++++++++++++-------------
    1 files changed, 16 insertions(+), 13 deletions(-)

    diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
    index a6238b2..b68ca02 100644
    --- a/drivers/mmc/sdhci.c
    +++ b/drivers/mmc/sdhci.c
    @@ -371,17 +371,17 @@ static void sdhci_finish_data(struct sdh
    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));
    @@ -390,8 +390,9 @@ static void sdhci_send_command(struct sd
    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);

    @@ -490,7 +491,7 @@ static void sdhci_set_clock(struct sdhci
    {
    int div;
    u16 clk;
    - unsigned long max_jiffies;
    + unsigned long timeout;

    if (clock == host->clock)
    return;
    @@ -511,17 +512,19 @@ static void sdhci_set_clock(struct sdhci
    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);
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2006-06-21 16:34    [W:0.027 / U:1.936 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site