|
@@ -547,11 +547,12 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
|
|
u16 status;
|
|
u16 status;
|
|
int end_command;
|
|
int end_command;
|
|
int end_transfer;
|
|
int end_transfer;
|
|
- int transfer_error;
|
|
|
|
|
|
+ int transfer_error, cmd_error;
|
|
|
|
|
|
if (host->cmd == NULL && host->data == NULL) {
|
|
if (host->cmd == NULL && host->data == NULL) {
|
|
status = OMAP_MMC_READ(host, STAT);
|
|
status = OMAP_MMC_READ(host, STAT);
|
|
- dev_info(mmc_dev(host->mmc),"spurious irq 0x%04x\n", status);
|
|
|
|
|
|
+ dev_info(mmc_dev(host->slots[0]->mmc),
|
|
|
|
+ "Spurious IRQ 0x%04x\n", status);
|
|
if (status != 0) {
|
|
if (status != 0) {
|
|
OMAP_MMC_WRITE(host, STAT, status);
|
|
OMAP_MMC_WRITE(host, STAT, status);
|
|
OMAP_MMC_WRITE(host, IE, 0);
|
|
OMAP_MMC_WRITE(host, IE, 0);
|
|
@@ -562,12 +563,19 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
|
|
end_command = 0;
|
|
end_command = 0;
|
|
end_transfer = 0;
|
|
end_transfer = 0;
|
|
transfer_error = 0;
|
|
transfer_error = 0;
|
|
|
|
+ cmd_error = 0;
|
|
|
|
|
|
while ((status = OMAP_MMC_READ(host, STAT)) != 0) {
|
|
while ((status = OMAP_MMC_READ(host, STAT)) != 0) {
|
|
|
|
+ int cmd;
|
|
|
|
+
|
|
OMAP_MMC_WRITE(host, STAT, status);
|
|
OMAP_MMC_WRITE(host, STAT, status);
|
|
|
|
+ if (host->cmd != NULL)
|
|
|
|
+ cmd = host->cmd->opcode;
|
|
|
|
+ else
|
|
|
|
+ cmd = -1;
|
|
#ifdef CONFIG_MMC_DEBUG
|
|
#ifdef CONFIG_MMC_DEBUG
|
|
dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ",
|
|
dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ",
|
|
- status, host->cmd != NULL ? host->cmd->opcode : -1);
|
|
|
|
|
|
+ status, cmd);
|
|
mmc_omap_report_irq(status);
|
|
mmc_omap_report_irq(status);
|
|
printk("\n");
|
|
printk("\n");
|
|
#endif
|
|
#endif
|
|
@@ -579,12 +587,12 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
|
|
mmc_omap_xfer_data(host, 1);
|
|
mmc_omap_xfer_data(host, 1);
|
|
}
|
|
}
|
|
|
|
|
|
- if (status & OMAP_MMC_STAT_END_OF_DATA) {
|
|
|
|
|
|
+ if (status & OMAP_MMC_STAT_END_OF_DATA)
|
|
end_transfer = 1;
|
|
end_transfer = 1;
|
|
- }
|
|
|
|
|
|
|
|
if (status & OMAP_MMC_STAT_DATA_TOUT) {
|
|
if (status & OMAP_MMC_STAT_DATA_TOUT) {
|
|
- dev_dbg(mmc_dev(host->mmc), "data timeout\n");
|
|
|
|
|
|
+ dev_dbg(mmc_dev(host->mmc), "data timeout (CMD%d)\n",
|
|
|
|
+ cmd);
|
|
if (host->data) {
|
|
if (host->data) {
|
|
host->data->error = -ETIMEDOUT;
|
|
host->data->error = -ETIMEDOUT;
|
|
transfer_error = 1;
|
|
transfer_error = 1;
|
|
@@ -608,12 +616,14 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
|
|
if (host->cmd) {
|
|
if (host->cmd) {
|
|
struct mmc_omap_slot *slot =
|
|
struct mmc_omap_slot *slot =
|
|
host->current_slot;
|
|
host->current_slot;
|
|
- if (!mmc_omap_cover_is_open(slot))
|
|
|
|
|
|
+ if (slot == NULL ||
|
|
|
|
+ !mmc_omap_cover_is_open(slot))
|
|
dev_err(mmc_dev(host->mmc),
|
|
dev_err(mmc_dev(host->mmc),
|
|
- "command timeout, CMD %d\n",
|
|
|
|
- host->cmd->opcode);
|
|
|
|
|
|
+ "command timeout (CMD%d)\n",
|
|
|
|
+ cmd);
|
|
host->cmd->error = -ETIMEDOUT;
|
|
host->cmd->error = -ETIMEDOUT;
|
|
end_command = 1;
|
|
end_command = 1;
|
|
|
|
+ cmd_error = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -621,9 +631,10 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
|
|
if (host->cmd) {
|
|
if (host->cmd) {
|
|
dev_err(mmc_dev(host->mmc),
|
|
dev_err(mmc_dev(host->mmc),
|
|
"command CRC error (CMD%d, arg 0x%08x)\n",
|
|
"command CRC error (CMD%d, arg 0x%08x)\n",
|
|
- host->cmd->opcode, host->cmd->arg);
|
|
|
|
|
|
+ cmd, host->cmd->arg);
|
|
host->cmd->error = -EILSEQ;
|
|
host->cmd->error = -EILSEQ;
|
|
end_command = 1;
|
|
end_command = 1;
|
|
|
|
+ cmd_error = 1;
|
|
} else
|
|
} else
|
|
dev_err(mmc_dev(host->mmc),
|
|
dev_err(mmc_dev(host->mmc),
|
|
"command CRC error without cmd?\n");
|
|
"command CRC error without cmd?\n");
|
|
@@ -632,13 +643,13 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
|
|
if (status & OMAP_MMC_STAT_CARD_ERR) {
|
|
if (status & OMAP_MMC_STAT_CARD_ERR) {
|
|
dev_dbg(mmc_dev(host->mmc),
|
|
dev_dbg(mmc_dev(host->mmc),
|
|
"ignoring card status error (CMD%d)\n",
|
|
"ignoring card status error (CMD%d)\n",
|
|
- host->cmd->opcode);
|
|
|
|
|
|
+ cmd);
|
|
end_command = 1;
|
|
end_command = 1;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
* NOTE: On 1610 the END_OF_CMD may come too early when
|
|
* NOTE: On 1610 the END_OF_CMD may come too early when
|
|
- * starting a write
|
|
|
|
|
|
+ * starting a write
|
|
*/
|
|
*/
|
|
if ((status & OMAP_MMC_STAT_END_OF_CMD) &&
|
|
if ((status & OMAP_MMC_STAT_END_OF_CMD) &&
|
|
(!(status & OMAP_MMC_STAT_A_EMPTY))) {
|
|
(!(status & OMAP_MMC_STAT_A_EMPTY))) {
|
|
@@ -646,13 +657,14 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if (end_command) {
|
|
|
|
|
|
+ if (end_command)
|
|
mmc_omap_cmd_done(host, host->cmd);
|
|
mmc_omap_cmd_done(host, host->cmd);
|
|
|
|
+ if (host->data != NULL) {
|
|
|
|
+ if (transfer_error)
|
|
|
|
+ mmc_omap_xfer_done(host, host->data);
|
|
|
|
+ else if (end_transfer)
|
|
|
|
+ mmc_omap_end_of_data(host, host->data);
|
|
}
|
|
}
|
|
- if (transfer_error)
|
|
|
|
- mmc_omap_xfer_done(host, host->data);
|
|
|
|
- else if (end_transfer)
|
|
|
|
- mmc_omap_end_of_data(host, host->data);
|
|
|
|
|
|
|
|
return IRQ_HANDLED;
|
|
return IRQ_HANDLED;
|
|
}
|
|
}
|