Skip to content

Commit

Permalink
[PATCH] MMC: wbsd delayed insertion
Browse files Browse the repository at this point in the history
Wait 0.5 seconds before scanning for cards after an insertion interrupt.
The electrical connection needs this time to stabilise for some cards.

Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Pierre Ossman authored and Russell King committed Jul 1, 2005
1 parent 7b09cda commit 6e6293d
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 10 deletions.
51 changes: 41 additions & 10 deletions drivers/mmc/wbsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,20 @@ static struct mmc_host_ops wbsd_ops = {
* *
\*****************************************************************************/

/*
* Helper function for card detection
*/
static void wbsd_detect_card(unsigned long data)
{
struct wbsd_host *host = (struct wbsd_host*)data;

BUG_ON(host == NULL);

DBG("Executing card detection\n");

mmc_detect_change(host->mmc);
}

/*
* Tasklets
*/
Expand All @@ -1075,7 +1089,6 @@ static void wbsd_tasklet_card(unsigned long param)
{
struct wbsd_host* host = (struct wbsd_host*)param;
u8 csr;
int change = 0;

spin_lock(&host->lock);

Expand All @@ -1094,14 +1107,20 @@ static void wbsd_tasklet_card(unsigned long param)
{
DBG("Card inserted\n");
host->flags |= WBSD_FCARD_PRESENT;
change = 1;

/*
* Delay card detection to allow electrical connections
* to stabilise.
*/
mod_timer(&host->timer, jiffies + HZ/2);
}

spin_unlock(&host->lock);
}
else if (host->flags & WBSD_FCARD_PRESENT)
{
DBG("Card removed\n");
host->flags &= ~WBSD_FCARD_PRESENT;
change = 1;

if (host->mrq)
{
Expand All @@ -1112,15 +1131,14 @@ static void wbsd_tasklet_card(unsigned long param)
host->mrq->cmd->error = MMC_ERR_FAILED;
tasklet_schedule(&host->finish_tasklet);
}
}

/*
* Unlock first since we might get a call back.
*/
spin_unlock(&host->lock);

/*
* Unlock first since we might get a call back.
*/
spin_unlock(&host->lock);

if (change)
mmc_detect_change(host->mmc);
}
}

static void wbsd_tasklet_fifo(unsigned long param)
Expand Down Expand Up @@ -1324,6 +1342,13 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)

spin_lock_init(&host->lock);

/*
* Set up detection timer
*/
init_timer(&host->timer);
host->timer.data = (unsigned long)host;
host->timer.function = wbsd_detect_card;

/*
* Maximum number of segments. Worst case is one sector per segment
* so this will be 64kB/512.
Expand Down Expand Up @@ -1351,11 +1376,17 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
static void __devexit wbsd_free_mmc(struct device* dev)
{
struct mmc_host* mmc;
struct wbsd_host* host;

mmc = dev_get_drvdata(dev);
if (!mmc)
return;

host = mmc_priv(mmc);
BUG_ON(host == NULL);

del_timer_sync(&host->timer);

mmc_free_host(mmc);

dev_set_drvdata(dev, NULL);
Expand Down
2 changes: 2 additions & 0 deletions drivers/mmc/wbsd.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,6 @@ struct wbsd_host
struct tasklet_struct timeout_tasklet;
struct tasklet_struct finish_tasklet;
struct tasklet_struct block_tasklet;

struct timer_list timer; /* Card detection timer */
};

0 comments on commit 6e6293d

Please sign in to comment.