Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e6293dd authored by Pierre Ossman's avatar Pierre Ossman Committed by Russell King
Browse files

[PATCH] MMC: wbsd delayed insertion



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: default avatarPierre Ossman <drzeus@drzeus.cx>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 7b09cdac
Loading
Loading
Loading
Loading
+41 −10
Original line number Diff line number Diff line
@@ -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,16 +1131,15 @@ 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);

	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);
+2 −0
Original line number Diff line number Diff line
@@ -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 */
};