public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Carlos Aguiar <carlos.aguiar@indt.org.br>
To: ext Pierre Ossman <drzeus-list@drzeus.cx>
Cc: Tony Lindgren <tony@atomide.com>, linux-kernel@vger.kernel.org
Subject: [PATCH 15/18] MMC: OMAP: Move failing command abortion to workqueue
Date: Wed, 26 Mar 2008 16:09:48 -0400	[thread overview]
Message-ID: <47EAAD8C.3090101@indt.org.br> (raw)
In-Reply-To: <20080324132631.1e0d2125@mjolnir.drzeus.cx>

From: Jarkko Lavinen <jarkko.lavinen@nokia.com>

Abort failed command from workqueue rather than from an interrupt,
allowing longer delays in abortion.

Signed-off-by: Jarkko Lavinen <jarkko.lavinen@nokia.com>
---
 drivers/mmc/host/omap.c |   82 ++++++++++++++++++++++++++++-------------------
 1 files changed, 49 insertions(+), 33 deletions(-)

diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index f97f390..aaecf4d 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -134,8 +134,9 @@ struct mmc_omap_host {
 	unsigned char		bus_mode;
 	unsigned char		hw_bus_mode;
 
-	struct work_struct	cmd_abort;
-	struct timer_list	cmd_timer;
+	struct work_struct	cmd_abort_work;
+	unsigned		abort:1;
+	struct timer_list	cmd_abort_timer;
 
 	unsigned int		sg_len;
 	int			sg_idx;
@@ -320,7 +321,7 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd)
 	if (host->data && !(host->data->flags & MMC_DATA_WRITE))
 		cmdreg |= 1 << 15;
 
-	mod_timer(&host->cmd_timer, jiffies + HZ/2);
+	mod_timer(&host->cmd_abort_timer, jiffies + HZ/2);
 
 	OMAP_MMC_WRITE(host, CTO, 200);
 	OMAP_MMC_WRITE(host, ARGL, cmd->arg & 0xffff);
@@ -381,7 +382,7 @@ mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
 }
 
 static void
-mmc_omap_send_abort(struct mmc_omap_host *host)
+mmc_omap_send_abort(struct mmc_omap_host *host, int maxloops)
 {
 	struct mmc_omap_slot *slot = host->current_slot;
 	unsigned int restarts, passes, timeout;
@@ -390,7 +391,7 @@ mmc_omap_send_abort(struct mmc_omap_host *host)
 	/* Sending abort takes 80 clocks. Have some extra and round up */
 	timeout = (120*1000000 + slot->fclk_freq - 1)/slot->fclk_freq;
 	restarts = 0;
-	while (restarts < 10000) {
+	while (restarts < maxloops) {
 		OMAP_MMC_WRITE(host, STAT, 0xFFFF);
 		OMAP_MMC_WRITE(host, CMD, (3 << 12) | (1 << 7));
 
@@ -412,18 +413,13 @@ out:
 static void
 mmc_omap_abort_xfer(struct mmc_omap_host *host, struct mmc_data *data)
 {
-	u16 ie;
-
 	if (host->dma_in_use)
 		mmc_omap_release_dma(host, data, 1);
 
 	host->data = NULL;
 	host->sg_len = 0;
 
-	ie = OMAP_MMC_READ(host, IE);
-	OMAP_MMC_WRITE(host, IE, 0);
-	OMAP_MMC_WRITE(host, IE, ie);
-	mmc_omap_send_abort(host);
+	mmc_omap_send_abort(host, 10000);
 }
 
 static void
@@ -479,7 +475,7 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
 {
 	host->cmd = NULL;
 
-	del_timer(&host->cmd_timer);
+	del_timer(&host->cmd_abort_timer);
 
 	if (cmd->flags & MMC_RSP_PRESENT) {
 		if (cmd->flags & MMC_RSP_136) {
@@ -523,38 +519,48 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
 static void mmc_omap_abort_command(struct work_struct *work)
 {
 	struct mmc_omap_host *host = container_of(work, struct mmc_omap_host,
-						  cmd_abort);
-	u16 ie;
-
-	ie = OMAP_MMC_READ(host, IE);
-	OMAP_MMC_WRITE(host, IE, 0);
-
-	if (!host->cmd) {
-		OMAP_MMC_WRITE(host, IE, ie);
-		return;
-	}
+						  cmd_abort_work);
+	BUG_ON(!host->cmd);
 
 	dev_dbg(mmc_dev(host->mmc), "Aborting stuck command CMD%d\n",
 		host->cmd->opcode);
 
-	if (host->data && host->dma_in_use)
-		mmc_omap_release_dma(host, host->data, 1);
+	if (host->cmd->error == 0)
+		host->cmd->error = -ETIMEDOUT;
 
-	host->data = NULL;
-	host->sg_len = 0;
+	if (host->data == NULL) {
+		struct mmc_command *cmd;
+		struct mmc_host    *mmc;
+
+		cmd = host->cmd;
+		host->cmd = NULL;
+		mmc_omap_send_abort(host, 10000);
+
+		host->mrq = NULL;
+		mmc = host->mmc;
+		mmc_omap_release_slot(host->current_slot);
+		mmc_request_done(mmc, cmd->mrq);
+	} else
+		mmc_omap_cmd_done(host, host->cmd);
 
-	mmc_omap_send_abort(host);
-	host->cmd->error = -ETIMEDOUT;
-	mmc_omap_cmd_done(host, host->cmd);
-	OMAP_MMC_WRITE(host, IE, ie);
+	host->abort = 0;
+	enable_irq(host->irq);
 }
 
 static void
 mmc_omap_cmd_timer(unsigned long data)
 {
 	struct mmc_omap_host *host = (struct mmc_omap_host *) data;
+	unsigned long flags;
 
-	schedule_work(&host->cmd_abort);
+	spin_lock_irqsave(&host->slot_lock, flags);
+	if (host->cmd != NULL && !host->abort) {
+		OMAP_MMC_WRITE(host, IE, 0);
+		disable_irq(host->irq);
+		host->abort = 1;
+		schedule_work(&host->cmd_abort_work);
+	}
+	spin_unlock_irqrestore(&host->slot_lock, flags);
 }
 
 /* PIO only */
@@ -728,6 +734,15 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
 		}
 	}
 
+	if (cmd_error && host->data) {
+		del_timer(&host->cmd_abort_timer);
+		host->abort = 1;
+		OMAP_MMC_WRITE(host, IE, 0);
+		disable_irq(host->irq);
+		schedule_work(&host->cmd_abort_work);
+		return IRQ_HANDLED;
+	}
+
 	if (end_command)
 		mmc_omap_cmd_done(host, host->cmd);
 	if (host->data != NULL) {
@@ -1316,8 +1331,9 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
 		goto err_free_mem_region;
 	}
 
-	INIT_WORK(&host->cmd_abort, mmc_omap_abort_command);
-	setup_timer(&host->cmd_timer, mmc_omap_cmd_timer, (unsigned long) host);
+	INIT_WORK(&host->cmd_abort_work, mmc_omap_abort_command);
+	setup_timer(&host->cmd_abort_timer, mmc_omap_cmd_timer,
+		    (unsigned long) host);
 
 	spin_lock_init(&host->dma_lock);
 	setup_timer(&host->dma_timer, mmc_omap_dma_timer, (unsigned long) host);
-- 1.5.3.GIT


  parent reply	other threads:[~2008-03-26 20:17 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-14 19:35 [PATCH 00/18] MMC: OMAP: Sync MMC OMAP driver with mainline tree Carlos Aguiar
2008-03-24 12:26 ` Pierre Ossman
2008-03-26 20:08   ` Carlos Aguiar
2008-03-30 16:10     ` Pierre Ossman
2008-03-26 20:08   ` [PATCH 01/18] MMC: OMAP: Remove some opcodes from host driver Carlos Aguiar
2008-03-26 20:08   ` [PATCH 02/18] MMC: OMAP: Remove extra divisor increase Carlos Aguiar
2008-03-26 20:08   ` [PATCH 03/18] MMC: OMAP: Fix the BYTEBLOCK capability removal Carlos Aguiar
2008-03-26 20:08   ` [PATCH 04/18] MMC: OMAP: Remove cover switch handling to allow adding multislot support Carlos Aguiar
2008-03-26 20:08   ` [PATCH 05/18] MMC: OMAP: Introduce new multislot structure and change driver to use it Carlos Aguiar
2008-03-26 20:09   ` [PATCH 06/18] MMC: OMAP: Add back cover switch support Carlos Aguiar
2008-03-26 20:09   ` [PATCH 07/18] MMC: OMAP: New release dma and abort xfer functions Carlos Aguiar
2008-03-26 20:09   ` [PATCH 08/18] MMC: OMAP: Fix timeout calculation for MMC multislot support Carlos Aguiar
2008-03-26 20:09   ` [PATCH 09/18] MMC: OMAP: Power functions modified to " Carlos Aguiar
2008-03-26 20:09   ` [PATCH 10/18] MMC: OMAP: General cleanup for " Carlos Aguiar
2008-03-26 20:09   ` [PATCH 11/18] MMC: OMAP: Abort stuck commands Carlos Aguiar
2008-03-26 20:09   ` [PATCH 12/18] MMC: OMAP: Using setup_timer instead of init_timer Carlos Aguiar
2008-03-26 20:09   ` [PATCH 13/18] MMC: OMAP: Check the get_cover_state function pointer if not set Carlos Aguiar
2008-03-26 20:09   ` [PATCH 14/18] MMC: OMAP: Use tasklet instead of workqueue for cover switch notification Carlos Aguiar
2008-03-26 20:09   ` Carlos Aguiar [this message]
2008-03-26 20:09   ` [PATCH 16/18] MMC: OMAP: Lazy clock shutdown Carlos Aguiar
2008-03-26 20:09   ` [PATCH 17/18] MMC: OMAP: Start new commands from work queue instead of irq Carlos Aguiar
2008-03-26 20:10   ` [PATCH 18/18] MMC: OMAP: Do not busy wait for end of command for ever Carlos Aguiar
  -- strict thread matches above, loose matches on Subject: below --
2008-03-14 19:36 [PATCH 15/18] MMC: OMAP: Move failing command abortion to workqueue Carlos Aguiar
2008-01-28 19:08 Carlos Aguiar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=47EAAD8C.3090101@indt.org.br \
    --to=carlos.aguiar@indt.org.br \
    --cc=drzeus-list@drzeus.cx \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tony@atomide.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox