aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2012-12-12 09:45:14 -0500
committerChris Ball <cjb@laptop.org>2013-02-11 13:28:45 -0500
commit8af5075088a0aaa64caed5ed212b485b5760bf0b (patch)
tree5d636a3b625bf7a998a21b66f8ec63632de4f4da /drivers/mmc/host
parente475b2702f612901772d12110614ad8c3fb5d89b (diff)
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>
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/sh_mmcif.c65
1 files changed, 19 insertions, 46 deletions
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index b4180c7bffc4..0189efcb9e12 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -129,6 +129,10 @@
129 INT_CCSTO | INT_CRCSTO | INT_WDATTO | \ 129 INT_CCSTO | INT_CRCSTO | INT_WDATTO | \
130 INT_RDATTO | INT_RBSYTO | INT_RSPTO) 130 INT_RDATTO | INT_RBSYTO | INT_RSPTO)
131 131
132#define INT_ALL (INT_RBSYE | INT_CRSPE | INT_BUFREN | \
133 INT_BUFWEN | INT_CMD12DRE | INT_BUFRE | \
134 INT_DTRANE | INT_CMD12RBE | INT_CMD12CRE)
135
132/* CE_INT_MASK */ 136/* CE_INT_MASK */
133#define MASK_ALL 0x00000000 137#define MASK_ALL 0x00000000
134#define MASK_MCCSDE (1 << 29) 138#define MASK_MCCSDE (1 << 29)
@@ -160,6 +164,11 @@
160 MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | \ 164 MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | \
161 MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO) 165 MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO)
162 166
167#define MASK_CLEAN (INT_ERR_STS | MASK_MRBSYE | MASK_MCRSPE | \
168 MASK_MBUFREN | MASK_MBUFWEN | \
169 MASK_MCMD12DRE | MASK_MBUFRE | MASK_MDTRANE | \
170 MASK_MCMD12RBE | MASK_MCMD12CRE)
171
163/* CE_HOST_STS1 */ 172/* CE_HOST_STS1 */
164#define STS1_CMDSEQ (1 << 31) 173#define STS1_CMDSEQ (1 << 31)
165 174
@@ -1233,58 +1242,22 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
1233{ 1242{
1234 struct sh_mmcif_host *host = dev_id; 1243 struct sh_mmcif_host *host = dev_id;
1235 u32 state; 1244 u32 state;
1236 int err = 0;
1237 1245
1238 state = sh_mmcif_readl(host->addr, MMCIF_CE_INT); 1246 state = sh_mmcif_readl(host->addr, MMCIF_CE_INT);
1247 sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
1248 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state & MASK_CLEAN);
1239 1249
1240 if (state & INT_ERR_STS) { 1250 if (state & ~MASK_CLEAN)
1241 /* error interrupts - process first */ 1251 dev_dbg(&host->pd->dev, "IRQ state = 0x%08x incompletely cleared\n",
1242 sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state); 1252 state);
1243 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); 1253
1244 err = 1; 1254 if (state & INT_ERR_STS || state & ~INT_ALL) {
1245 } else if (state & INT_RBSYE) {
1246 sh_mmcif_writel(host->addr, MMCIF_CE_INT,
1247 ~(INT_RBSYE | INT_CRSPE));
1248 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE);
1249 } else if (state & INT_CRSPE) {
1250 sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_CRSPE);
1251 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCRSPE);
1252 } else if (state & INT_BUFREN) {
1253 sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFREN);
1254 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
1255 } else if (state & INT_BUFWEN) {
1256 sh_mmcif_writel(host->addr, MMCIF_CE_INT,
1257 ~(INT_BUFWEN | INT_DTRANE | INT_CMD12DRE |
1258 INT_CMD12RBE | INT_CMD12CRE));
1259 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
1260 } else if (state & INT_CMD12DRE) {
1261 sh_mmcif_writel(host->addr, MMCIF_CE_INT,
1262 ~(INT_CMD12DRE | INT_CMD12RBE |
1263 INT_CMD12CRE | INT_BUFRE));
1264 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE);
1265 } else if (state & INT_BUFRE) {
1266 sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFRE);
1267 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
1268 } else if (state & INT_DTRANE) {
1269 sh_mmcif_writel(host->addr, MMCIF_CE_INT,
1270 ~(INT_CMD12DRE | INT_CMD12RBE |
1271 INT_CMD12CRE | INT_DTRANE));
1272 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
1273 } else if (state & INT_CMD12RBE) {
1274 sh_mmcif_writel(host->addr, MMCIF_CE_INT,
1275 ~(INT_CMD12RBE | INT_CMD12CRE));
1276 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE);
1277 } else {
1278 dev_dbg(&host->pd->dev, "Unsupported interrupt: 0x%x\n", state);
1279 sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
1280 sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
1281 err = 1;
1282 }
1283 if (err) {
1284 host->sd_error = true; 1255 host->sd_error = true;
1285 dev_dbg(&host->pd->dev, "int err state = %08x\n", state); 1256 dev_dbg(&host->pd->dev, "int err state = 0x%08x\n", state);
1286 } 1257 }
1287 if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) { 1258 if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) {
1259 if (!host->mrq)
1260 dev_dbg(&host->pd->dev, "NULL IRQ state = 0x%08x\n", state);
1288 if (!host->dma_active) 1261 if (!host->dma_active)
1289 return IRQ_WAKE_THREAD; 1262 return IRQ_WAKE_THREAD;
1290 else if (host->sd_error) 1263 else if (host->sd_error)