davinci-mmc: handle fifo before other interrupt sources
Signed-off-by: Troy Kisky <[EMAIL PROTECTED]>
Note: this goes on top of previous patches
Most of the changes are annoying indentation changes.
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 615b5eb..2c6f3f5 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -958,7 +958,8 @@ static void mmc_davinci_cmd_done(struct mmc_davinci_host
*host,
static irqreturn_t mmc_davinci_irq(int irq, void *dev_id)
{
struct mmc_davinci_host *host = (struct mmc_davinci_host *)dev_id;
- u16 status;
+ unsigned int status;
+ unsigned int qstatus;
int end_command;
int end_transfer;
unsigned long flags;
@@ -973,63 +974,70 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
}
- end_command = 0;
- end_transfer = 0;
+ do {
+ end_command = 0;
+ end_transfer = 0;
- status = mmcsd_regs->mmc_st0;
- if (status == 0)
- return IRQ_HANDLED;
+ status = mmcsd_regs->mmc_st0;
+ if (status == 0) break;
- if (host->is_core_command) {
- if (is_card_initialized) {
- if (new_card_state == 0) {
- if (host->cmd) {
- host->cmd->error = -ETIMEDOUT;
- mmc_davinci_cmd_done(host, host->cmd);
+ if (host->is_core_command) {
+ if (is_card_initialized) {
+ if (new_card_state == 0) {
+ if (host->cmd) {
+ host->cmd->error = -ETIMEDOUT;
+ mmc_davinci_cmd_done(host,
host->cmd);
+ }
+ dev_dbg(&mmc_dev,
+ "From code segment excuted when card
removed\n");
+ return IRQ_HANDLED;
}
- dev_dbg(&mmc_dev,
- "From code segment excuted when card
removed\n");
- return IRQ_HANDLED;
}
- }
- while (status != 0) {
- if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) {
+ qstatus = status;
+ while (1) {
if (status & MMCSD_EVENT_WRITE) {
- /* Buffer almost empty */
- if (host->bytes_left > 0)
-
davinci_fifo_data_trans(host,mmcsd_cfg.rw_threshold);
+ if (host->data_dir ==
DAVINCI_MMC_DATADIR_WRITE) {
+ /* Buffer almost empty */
+ if (host->bytes_left > 0)
+
davinci_fifo_data_trans(host,mmcsd_cfg.rw_threshold);
+ }
}
- }
- if (host->data_dir == DAVINCI_MMC_DATADIR_READ) {
if (status & MMCSD_EVENT_READ) {
- /* Buffer almost empty */
- if (host->bytes_left > 0)
-
davinci_fifo_data_trans(host,mmcsd_cfg.rw_threshold);
+ if (host->data_dir ==
DAVINCI_MMC_DATADIR_READ) {
+ /* Buffer almost empty */
+ if (host->bytes_left > 0)
+
davinci_fifo_data_trans(host,mmcsd_cfg.rw_threshold);
+ }
+ }
+ status = mmcsd_regs->mmc_st0;
+ if (!status) break;
+ qstatus |= status;
+ if (host->data == NULL) {
+ dev_dbg(&mmc_dev,
+ "Status is %x at end of ISR when
host->data is NULL",status);
+ break;
}
}
- if (status & MMCSD_EVENT_BLOCK_XFERRED) {
+ if (qstatus & MMCSD_EVENT_BLOCK_XFERRED) {
/* Block sent/received */
if (host->data != NULL) {
- if (host->do_dma == 1) {
- end_transfer = 1;
- } else {
- /* if datasize<32 no RX ints
are generated */
+ if (host->do_dma == 0) {
+ /* if
datasize<mmcsd_cfg.rw_threshold no RX ints are generated */
if (host->bytes_left > 0) {
- davinci_fifo_data_trans
-
(host,mmcsd_cfg.rw_threshold);
+
davinci_fifo_data_trans(host,mmcsd_cfg.rw_threshold);
}
- end_transfer = 1;
}
+ end_transfer = 1;
} else {
dev_warn(&mmc_dev,
"TC:host->data is NULL\n");
}
}
- if (status & MMCSD_EVENT_ERROR_DATATIMEOUT) {
+ if (qstatus & MMCSD_EVENT_ERROR_DATATIMEOUT) {
/* Data timeout */
if ((host->data) && (new_card_state != 0)) {
host->data->error = -ETIMEDOUT;
@@ -1050,8 +1058,8 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id)
}
}
- if (status & MMCSD_EVENT_ERROR_DATACRC) {
- /* DAT line portion is diabled and in reset
state */
+ if (qstatus & MMCSD_EVENT_ERROR_DATACRC) {
+ /* DAT line portion is disabled and in reset
state */
mmcsd_regs->mmc_ctl =
mmcsd_regs->mmc_ctl | (1 << 1);
udelay(10);
@@ -1071,7 +1079,7 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id)
}
}
- if (status & MMCSD_EVENT_ERROR_CMDTIMEOUT) {
+ if (qstatus & MMCSD_EVENT_ERROR_CMDTIMEOUT) {
if (host->do_dma)
/* abort DMA transfer */
davinci_abort_dma(host);
@@ -1101,7 +1109,7 @@ static irqreturn_t mmc_davinci_irq(int irq, void *dev_id)
}
}
- if (status & MMCSD_EVENT_ERROR_CMDCRC) {
+ if (qstatus & MMCSD_EVENT_ERROR_CMDCRC) {
/* Command CRC error */
dev_dbg(&mmc_dev, "Command CRC error\r\n");
if (host->cmd) {
@@ -1113,121 +1121,108 @@ static irqreturn_t mmc_davinci_irq(int irq, void
*dev_id)
}
}
- if (status & MMCSD_EVENT_EOFCMD) {
+ if (qstatus & MMCSD_EVENT_EOFCMD) {
/* End of command phase */
end_command = 1;
}
- if (host->data == NULL) {
- status = mmcsd_regs->mmc_st0;
- if (status != 0) {
- dev_dbg(&mmc_dev,
- "Status is %x at end of ISR when
host->data is NULL",
- status);
- status = 0;
-
- }
- } else {
- status = mmcsd_regs->mmc_st0;
- }
- }
+ if (end_command)
+ mmc_davinci_cmd_done(host, host->cmd);
+ if (end_transfer)
+ mmc_davinci_xfer_done(host, host->data);
- if (end_command)
- mmc_davinci_cmd_done(host, host->cmd);
- if (end_transfer)
- mmc_davinci_xfer_done(host, host->data);
+ } else {
+ if (host->cmd_code == 13) {
+ if (status & MMCSD_EVENT_EOFCMD) {
+ spin_lock_irqsave(&mmc_lock, flags);
+ new_card_state = 1;
+ spin_unlock_irqrestore(&mmc_lock,
flags);
- } else {
- if (host->cmd_code == 13) {
- if (status & MMCSD_EVENT_EOFCMD) {
- spin_lock_irqsave(&mmc_lock, flags);
- new_card_state = 1;
- spin_unlock_irqrestore(&mmc_lock, flags);
+ } else {
+ spin_lock_irqsave(&mmc_lock, flags);
+ is_card_removed = 1;
+ new_card_state = 0;
+ is_card_initialized = 0;
+ spin_unlock_irqrestore(&mmc_lock,
flags);
+ }
- } else {
spin_lock_irqsave(&mmc_lock, flags);
- is_card_removed = 1;
- new_card_state = 0;
- is_card_initialized = 0;
+ is_card_detect_progress = 0;
spin_unlock_irqrestore(&mmc_lock, flags);
- }
-
- spin_lock_irqsave(&mmc_lock, flags);
- is_card_detect_progress = 0;
- spin_unlock_irqrestore(&mmc_lock, flags);
- if (is_req_queued_up) {
- mmc_davinci_request(que_mmc_host,
+ if (is_req_queued_up) {
+ mmc_davinci_request(que_mmc_host,
que_mmc_request);
- spin_lock_irqsave(&mmc_lock, flags);
- is_req_queued_up = 0;
- spin_unlock_irqrestore(&mmc_lock, flags);
+ spin_lock_irqsave(&mmc_lock, flags);
+ is_req_queued_up = 0;
+ spin_unlock_irqrestore(&mmc_lock,
flags);
+ }
+
}
- }
+ if (host->cmd_code == 1 || host->cmd_code == 55) {
+ if (status & MMCSD_EVENT_EOFCMD) {
+ spin_lock_irqsave(&mmc_lock, flags);
+ is_card_removed = 0;
+ new_card_state = 1;
+ is_card_initialized = 0;
+ spin_unlock_irqrestore(&mmc_lock,
flags);
+ } else {
- if (host->cmd_code == 1 || host->cmd_code == 55) {
- if (status & MMCSD_EVENT_EOFCMD) {
- spin_lock_irqsave(&mmc_lock, flags);
- is_card_removed = 0;
- new_card_state = 1;
- is_card_initialized = 0;
- spin_unlock_irqrestore(&mmc_lock, flags);
- } else {
+ spin_lock_irqsave(&mmc_lock, flags);
+ is_card_removed = 1;
+ new_card_state = 0;
+ is_card_initialized = 0;
+ spin_unlock_irqrestore(&mmc_lock,
flags);
+ }
spin_lock_irqsave(&mmc_lock, flags);
- is_card_removed = 1;
- new_card_state = 0;
- is_card_initialized = 0;
+ is_card_detect_progress = 0;
spin_unlock_irqrestore(&mmc_lock, flags);
- }
-
- spin_lock_irqsave(&mmc_lock, flags);
- is_card_detect_progress = 0;
- spin_unlock_irqrestore(&mmc_lock, flags);
- if (is_req_queued_up) {
- mmc_davinci_request(que_mmc_host,
+ if (is_req_queued_up) {
+ mmc_davinci_request(que_mmc_host,
que_mmc_request);
- spin_lock_irqsave(&mmc_lock, flags);
- is_req_queued_up = 0;
- spin_unlock_irqrestore(&mmc_lock, flags);
+ spin_lock_irqsave(&mmc_lock, flags);
+ is_req_queued_up = 0;
+ spin_unlock_irqrestore(&mmc_lock,
flags);
+ }
}
- }
- if (host->cmd_code == 0) {
- if (status & MMCSD_EVENT_EOFCMD) {
- static int flag_sd_mmc;
- host->is_core_command = 0;
-
- if (flag_sd_mmc) {
- flag_sd_mmc = 0;
- host->cmd_code = 1;
- /* Issue cmd1 */
- mmcsd_regs->mmc_arghl = 0x80300000;
- mmcsd_regs->mmc_cmd = 0x00000601;
+ if (host->cmd_code == 0) {
+ if (status & MMCSD_EVENT_EOFCMD) {
+ static int flag_sd_mmc;
+ host->is_core_command = 0;
+
+ if (flag_sd_mmc) {
+ flag_sd_mmc = 0;
+ host->cmd_code = 1;
+ /* Issue cmd1 */
+ mmcsd_regs->mmc_arghl =
0x80300000;
+ mmcsd_regs->mmc_cmd =
0x00000601;
+ } else {
+ flag_sd_mmc = 1;
+ host->cmd_code = 55;
+ /* Issue cmd55 */
+ mmcsd_regs->mmc_arghl = 0x0;
+ mmcsd_regs->mmc_cmd =
+ ((0x0 | (1 << 9) | 55));
+ }
+
+ dev_dbg(&mmc_dev,
+ "MMC-Probing mmc with cmd%d\n",
+ host->cmd_code);
} else {
- flag_sd_mmc = 1;
- host->cmd_code = 55;
- /* Issue cmd55 */
- mmcsd_regs->mmc_arghl = 0x0;
- mmcsd_regs->mmc_cmd =
- ((0x0 | (1 << 9) | 55));
+ spin_lock_irqsave(&mmc_lock, flags);
+ new_card_state = 0;
+ is_card_initialized = 0;
+ is_card_detect_progress = 0;
+ spin_unlock_irqrestore(&mmc_lock,
flags);
}
-
- dev_dbg(&mmc_dev,
- "MMC-Probing mmc with cmd%d\n",
- host->cmd_code);
- } else {
- spin_lock_irqsave(&mmc_lock, flags);
- new_card_state = 0;
- is_card_initialized = 0;
- is_card_detect_progress = 0;
- spin_unlock_irqrestore(&mmc_lock, flags);
}
- }
- }
+ }
+ } while (1);
return IRQ_HANDLED;
}
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
