From 65f39060a227fe15ce1cf8af512632c897f32fcb Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 1 Jul 2005 12:13:55 +0100 Subject: [PATCH] --- yaml --- r: 4061 b: refs/heads/master c: 6e6293dd3d4372c114674266158053d049366a0d h: refs/heads/master i: 4059: 2a5b855c255e52cf074c37c00e0e2c1ede7b8251 v: v3 --- [refs] | 2 +- trunk/drivers/mmc/wbsd.c | 51 ++++++++++++++++++++++++++++++++-------- trunk/drivers/mmc/wbsd.h | 2 ++ 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/[refs] b/[refs] index 26d14d807ad2..6b55cf96633f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7b09cdac5af1e13ab4b30421ae5c4b7953c26841 +refs/heads/master: 6e6293dd3d4372c114674266158053d049366a0d diff --git a/trunk/drivers/mmc/wbsd.c b/trunk/drivers/mmc/wbsd.c index b7fbd30b49a0..0bd9b53fa898 100644 --- a/trunk/drivers/mmc/wbsd.c +++ b/trunk/drivers/mmc/wbsd.c @@ -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 */ @@ -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); @@ -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) { @@ -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) @@ -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. @@ -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); diff --git a/trunk/drivers/mmc/wbsd.h b/trunk/drivers/mmc/wbsd.h index 864f30828d01..9f5383e6e593 100644 --- a/trunk/drivers/mmc/wbsd.h +++ b/trunk/drivers/mmc/wbsd.h @@ -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 */ };