提交 182c9081 编写于 作者: S Seungwon Jeon 提交者: 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: NSeungwon Jeon <tgih.jun@samsung.com>
Reviewed By: Girish K S <girish.shivananjappa@linaro.org>
Acked-by: NJaehoon Chung <jh80.chung@samsung.com>
Acked-by: NWill Newton <will.newton@imgtec.com>
Signed-off-by: NChris Ball <cjb@laptop.org>
上级 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% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册