mmc: sh-mmcif: simplify IRQ processing
The classical way to process IRQs is read out the status, ack all triggered IRQs, possibly mask them, then process them. Follow this simple procesure instead of the current complex custom algorithm. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Chris Ball <cjb@laptop.org>
This commit is contained in:
committed by
Chris Ball
parent
30e531a545
commit
aa11d6d892
@@ -129,6 +129,10 @@
|
|||||||
INT_CCSTO | INT_CRCSTO | INT_WDATTO | \
|
INT_CCSTO | INT_CRCSTO | INT_WDATTO | \
|
||||||
INT_RDATTO | INT_RBSYTO | INT_RSPTO)
|
INT_RDATTO | INT_RBSYTO | INT_RSPTO)
|
||||||
|
|
||||||
|
#define INT_ALL (INT_RBSYE | INT_CRSPE | INT_BUFREN | \
|
||||||
|
INT_BUFWEN | INT_CMD12DRE | INT_BUFRE | \
|
||||||
|
INT_DTRANE | INT_CMD12RBE | INT_CMD12CRE)
|
||||||
|
|
||||||
/* CE_INT_MASK */
|
/* CE_INT_MASK */
|
||||||
#define MASK_ALL 0x00000000
|
#define MASK_ALL 0x00000000
|
||||||
#define MASK_MCCSDE (1 << 29)
|
#define MASK_MCCSDE (1 << 29)
|
||||||
@@ -160,6 +164,11 @@
|
|||||||
MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | \
|
MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | \
|
||||||
MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO)
|
MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO)
|
||||||
|
|
||||||
|
#define MASK_CLEAN (INT_ERR_STS | MASK_MRBSYE | MASK_MCRSPE | \
|
||||||
|
MASK_MBUFREN | MASK_MBUFWEN | \
|
||||||
|
MASK_MCMD12DRE | MASK_MBUFRE | MASK_MDTRANE | \
|
||||||
|
MASK_MCMD12RBE | MASK_MCMD12CRE)
|
||||||
|
|
||||||
/* CE_HOST_STS1 */
|
/* CE_HOST_STS1 */
|
||||||
#define STS1_CMDSEQ (1 << 31)
|
#define STS1_CMDSEQ (1 << 31)
|
||||||
|
|
||||||
@@ -1233,58 +1242,22 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
|
|||||||
{
|
{
|
||||||
struct sh_mmcif_host *host = dev_id;
|
struct sh_mmcif_host *host = dev_id;
|
||||||
u32 state;
|
u32 state;
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
state = sh_mmcif_readl(host->addr, MMCIF_CE_INT);
|
state = sh_mmcif_readl(host->addr, MMCIF_CE_INT);
|
||||||
|
sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
|
||||||
|
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state & MASK_CLEAN);
|
||||||
|
|
||||||
if (state & INT_ERR_STS) {
|
if (state & ~MASK_CLEAN)
|
||||||
/* error interrupts - process first */
|
dev_dbg(&host->pd->dev, "IRQ state = 0x%08x incompletely cleared\n",
|
||||||
sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
|
state);
|
||||||
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
|
|
||||||
err = 1;
|
if (state & INT_ERR_STS || state & ~INT_ALL) {
|
||||||
} else if (state & INT_RBSYE) {
|
|
||||||
sh_mmcif_writel(host->addr, MMCIF_CE_INT,
|
|
||||||
~(INT_RBSYE | INT_CRSPE));
|
|
||||||
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE);
|
|
||||||
} else if (state & INT_CRSPE) {
|
|
||||||
sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_CRSPE);
|
|
||||||
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCRSPE);
|
|
||||||
} else if (state & INT_BUFREN) {
|
|
||||||
sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFREN);
|
|
||||||
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
|
|
||||||
} else if (state & INT_BUFWEN) {
|
|
||||||
sh_mmcif_writel(host->addr, MMCIF_CE_INT,
|
|
||||||
~(INT_BUFWEN | INT_DTRANE | INT_CMD12DRE |
|
|
||||||
INT_CMD12RBE | INT_CMD12CRE));
|
|
||||||
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
|
|
||||||
} else if (state & INT_CMD12DRE) {
|
|
||||||
sh_mmcif_writel(host->addr, MMCIF_CE_INT,
|
|
||||||
~(INT_CMD12DRE | INT_CMD12RBE |
|
|
||||||
INT_CMD12CRE | INT_BUFRE));
|
|
||||||
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE);
|
|
||||||
} else if (state & INT_BUFRE) {
|
|
||||||
sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFRE);
|
|
||||||
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
|
|
||||||
} else if (state & INT_DTRANE) {
|
|
||||||
sh_mmcif_writel(host->addr, MMCIF_CE_INT,
|
|
||||||
~(INT_CMD12DRE | INT_CMD12RBE |
|
|
||||||
INT_CMD12CRE | INT_DTRANE));
|
|
||||||
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
|
|
||||||
} else if (state & INT_CMD12RBE) {
|
|
||||||
sh_mmcif_writel(host->addr, MMCIF_CE_INT,
|
|
||||||
~(INT_CMD12RBE | INT_CMD12CRE));
|
|
||||||
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE);
|
|
||||||
} else {
|
|
||||||
dev_dbg(&host->pd->dev, "Unsupported interrupt: 0x%x\n", state);
|
|
||||||
sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
|
|
||||||
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
|
|
||||||
err = 1;
|
|
||||||
}
|
|
||||||
if (err) {
|
|
||||||
host->sd_error = true;
|
host->sd_error = true;
|
||||||
dev_dbg(&host->pd->dev, "int err state = %08x\n", state);
|
dev_dbg(&host->pd->dev, "int err state = 0x%08x\n", state);
|
||||||
}
|
}
|
||||||
if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) {
|
if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) {
|
||||||
|
if (!host->mrq)
|
||||||
|
dev_dbg(&host->pd->dev, "NULL IRQ state = 0x%08x\n", state);
|
||||||
if (!host->dma_active)
|
if (!host->dma_active)
|
||||||
return IRQ_WAKE_THREAD;
|
return IRQ_WAKE_THREAD;
|
||||||
else if (host->sd_error)
|
else if (host->sd_error)
|
||||||
|
Reference in New Issue
Block a user