Commit 182c9081 authored by Seungwon Jeon's avatar Seungwon Jeon Committed by Chris Ball

mmc: dw_mmc: amend using error interrupt status

RINTSTS status includes masked interrupts as well as unmasked.
data_status and cmd_status are set by value of RINTSTS in interrupt handler
and tasklet finally uses it to decide whether error is happened or not.
In addition, MINTSTS status is used for setting data_status in PIO.
Masked error interrupt will not be handled and that status can be considered
non-error case.
Signed-off-by: default avatarSeungwon Jeon <tgih.jun@samsung.com>
Reviewed By: Girish K S <girish.shivananjappa@linaro.org>
Acked-by: default avatarJaehoon Chung <jh80.chung@samsung.com>
Acked-by: default avatarWill Newton <will.newton@imgtec.com>
Signed-off-by: default avatarChris Ball <cjb@laptop.org>
parent 077d4073
...@@ -1547,12 +1547,11 @@ static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status) ...@@ -1547,12 +1547,11 @@ static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status)
static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
{ {
struct dw_mci *host = dev_id; struct dw_mci *host = dev_id;
u32 status, pending; u32 pending;
unsigned int pass_count = 0; unsigned int pass_count = 0;
int i; int i;
do { do {
status = mci_readl(host, RINTSTS);
pending = mci_readl(host, MINTSTS); /* read-only mask reg */ pending = mci_readl(host, MINTSTS); /* read-only mask reg */
/* /*
...@@ -1570,7 +1569,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) ...@@ -1570,7 +1569,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
if (pending & DW_MCI_CMD_ERROR_FLAGS) { if (pending & DW_MCI_CMD_ERROR_FLAGS) {
mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS); mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS);
host->cmd_status = status; host->cmd_status = pending;
smp_wmb(); smp_wmb();
set_bit(EVENT_CMD_COMPLETE, &host->pending_events); set_bit(EVENT_CMD_COMPLETE, &host->pending_events);
} }
...@@ -1578,7 +1577,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) ...@@ -1578,7 +1577,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
if (pending & DW_MCI_DATA_ERROR_FLAGS) { if (pending & DW_MCI_DATA_ERROR_FLAGS) {
/* if there is an error report DATA_ERROR */ /* if there is an error report DATA_ERROR */
mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS); mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS);
host->data_status = status; host->data_status = pending;
smp_wmb(); smp_wmb();
set_bit(EVENT_DATA_ERROR, &host->pending_events); set_bit(EVENT_DATA_ERROR, &host->pending_events);
if (!(pending & (SDMMC_INT_DTO | SDMMC_INT_DCRC | if (!(pending & (SDMMC_INT_DTO | SDMMC_INT_DCRC |
...@@ -1589,7 +1588,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) ...@@ -1589,7 +1588,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
if (pending & SDMMC_INT_DATA_OVER) { if (pending & SDMMC_INT_DATA_OVER) {
mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER); mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER);
if (!host->data_status) if (!host->data_status)
host->data_status = status; host->data_status = pending;
smp_wmb(); smp_wmb();
if (host->dir_status == DW_MCI_RECV_STATUS) { if (host->dir_status == DW_MCI_RECV_STATUS) {
if (host->sg != NULL) if (host->sg != NULL)
...@@ -1613,7 +1612,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) ...@@ -1613,7 +1612,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id)
if (pending & SDMMC_INT_CMD_DONE) { if (pending & SDMMC_INT_CMD_DONE) {
mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE); mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE);
dw_mci_cmd_interrupt(host, status); dw_mci_cmd_interrupt(host, pending);
} }
if (pending & SDMMC_INT_CD) { if (pending & SDMMC_INT_CD) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment