#define xbwprintk(n, arg...)
#endif
-#define RK29_SDMMC_ERROR_FLAGS (SDMMC_INT_FRUN | SDMMC_INT_RTO | SDMMC_INT_HLE )
+#define RK29_SDMMC_ERROR_FLAGS (SDMMC_INT_FRUN /*| SDMMC_INT_RTO*/ | SDMMC_INT_HLE )
#define RK29_SDMMC_INTMASK_USEDMA (SDMMC_INT_CMD_DONE | SDMMC_INT_DTO | RK29_SDMMC_ERROR_FLAGS | SDMMC_INT_CD)
#define RK29_SDMMC_INTMASK_USEIO (SDMMC_INT_CMD_DONE | SDMMC_INT_DTO | RK29_SDMMC_ERROR_FLAGS | SDMMC_INT_CD| SDMMC_INT_TXDR | SDMMC_INT_RXDR )
#define RK29_SDMMC_WAIT_DTO_INTERNVAL 1500 //The time interval from the CMD_DONE_INT to DTO_INT
#define RK29_SDMMC_REMOVAL_DELAY 2000 //The time interval from the CD_INT to detect_timer react.
-#define RK29_SDMMC_VERSION "Ver.2.05 The last modify date is 2011-08-29,modifyed by XBW."
+#define RK29_SDMMC_VERSION "Ver.2.06 The last modify date is 2011-09-01,modifyed by XBW."
#define RK29_CTRL_SDMMC_ID 0 //mainly used by SDMMC
#define RK29_CTRL_SDIO1_ID 1 //mainly used by sdio-wifi
__LINE__, unmounting_times, host->dma_name);
}
host->mmc->re_initialized_flags = 0;
- mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_REMOVAL_DELAY));
+ mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_REMOVAL_DELAY*2));
}
else if( !strncmp(buf, "sd-No-Media", strlen("sd-No-Media")))
{
xbwprintk(5, "\n%s..%d..************.start cmd=%d, arg=0x%x ********=====xbw[%s]=======\n", \
__FUNCTION__, __LINE__, cmd->opcode, cmd->arg, host->dma_name);
+ host->mmc->doneflag = 1;
+
/* wait until CIU accepts the command */
while (--tmo && (rk29_sdmmc_read(host->regs, SDMMC_CMD) & SDMMC_CMD_START))
{
host->errorstep = 0x1;
return SDM_WAIT_FOR_CMDSTART_TIMEOUT;
}
- host->mmc->doneflag = 1;
return SDM_SUCCESS;
}
host->state = STATE_IDLE; //modifyed by xbw at 2011-08-15
spin_unlock_irqrestore(&host->lock, iflags);
-
- mmc_request_done(host->mmc, host->mrq);
+
+ if(host->mrq && host->mmc->doneflag)
+ {
+ mmc_request_done(host->mmc, host->mrq);
+ }
return ret;
if(!( (MMC_READ_SINGLE_BLOCK == host->cmd->opcode)&&( -EIO == data->error))) //deal with START_BIT_ERROR
{
- host->complete_done = 1;
+ host->complete_done = 2;
break;//goto unlock;
}
del_timer_sync(&host->request_timer); //delete the timer for INT_CMD_DONE int CMD12
rk29_sdmmc_request_end(host, host->cmd);
- host->complete_done = 1;
+ host->complete_done = 3;
break;//goto unlock;
}
}
- pending_flag = (1==host->complete_done) && (host->retryfunc<50) \
+ pending_flag = (host->complete_done > 0) && (host->retryfunc<50) \
&& (rk29_sdmmc_test_pending(host, EVENT_CMD_COMPLETE)|| rk29_sdmmc_test_pending(host, EVENT_DATA_COMPLETE) );
if(pending_flag)
{
- printk("%s..%d... cmd=%d(arg=0x%x),retrycount=%d, host->state=0x%x,\n pendingEvent=0x%lu, completeEvents=0x%lu ====xbw[%s]====\n",\
- __FUNCTION__, __LINE__,host->cmd->opcode,host->cmd->arg, host->retryfunc, host->state, \
- host->pending_events,host->completed_events,host->dma_name);
+ printk("%s..%d... cmd=%d(arg=0x%x),completedone=%d, retrycount=%d, doneflag=%d, \n \
+ host->state=0x%x, switchstate=%x, \n \
+ pendingEvent=0x%lu, completeEvents=0x%lu, \n \
+ mrqCMD=%d, arg=0x%x \n ====xbw[%s]====\n",\
+
+ __FUNCTION__, __LINE__,host->cmd->opcode, host->cmd->arg, host->complete_done,\
+ host->retryfunc, host->mmc->doneflag,host->state, state, \
+ host->pending_events,host->completed_events,host->dma_name, \
+ host->mrq->cmd->opcode, host->mrq->cmd->arg);
+
cpu_relax();
}
pending = rk29_sdmmc_read(host->regs, SDMMC_MINTSTS);// read only mask reg
if (!pending)
{
- spin_unlock_irqrestore(&host->lock, iflags);
- return IRQ_HANDLED;
+ goto Exit_INT;
}
if(host->mmc->re_initialized_flags)
{
- mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_REMOVAL_DELAY/2));
+ mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(RK29_SDMMC_REMOVAL_DELAY));
}
else
{
}
- spin_unlock_irqrestore(&host->lock, iflags);
- return IRQ_HANDLED;
+ goto Exit_INT;
}
rk29_sdmmc_write(host->regs, SDMMC_RINTSTS,SDMMC_INT_CMD_DONE); // clear interrupt
rk29_sdmmc_cmd_interrupt(host, status);
+
+ goto Exit_INT;
}
if(pending & SDMMC_INT_SDIO)
rk29_sdmmc_write(host->regs, SDMMC_RINTSTS,SDMMC_INT_SDIO);
mmc_signal_sdio_irq(host->mmc);
- spin_unlock_irqrestore(&host->lock, iflags);
- return IRQ_HANDLED;
+ goto Exit_INT;
}
if(!(pending & SDMMC_INT_CMD_DONE))
tasklet_schedule(&host->tasklet);
- spin_unlock_irqrestore(&host->lock, iflags);
- return IRQ_HANDLED;
+ goto Exit_INT;
}
__FUNCTION__, pending,host->cmd->opcode, host->cmd->arg, host->cmd->retries, host->dma_name);
rk29_sdmmc_write(host->regs, SDMMC_RINTSTS,SDMMC_INT_HLE);
- spin_unlock_irqrestore(&host->lock, iflags);
- return IRQ_HANDLED;
+ goto Exit_INT;
}
rk29_sdmmc_set_pending(host, EVENT_DATA_COMPLETE);
tasklet_schedule(&host->tasklet);
-
- spin_unlock_irqrestore(&host->lock, iflags);
- return IRQ_HANDLED;
+ goto Exit_INT;
}
__FUNCTION__, pending, host->cmd->opcode, host->cmd->arg, host->cmd->retries,host->dma_name);
rk29_sdmmc_write(host->regs, SDMMC_RINTSTS,SDMMC_INT_FRUN);
- spin_unlock_irqrestore(&host->lock, iflags);
- return IRQ_HANDLED;
+ goto Exit_INT;
}
if (pending & SDMMC_INT_RXDR)
rk29_sdmmc_write(host->regs, SDMMC_RINTSTS,SDMMC_INT_TXDR); // clear interrupt
}
+Exit_INT:
+
spin_unlock_irqrestore(&host->lock, iflags);
return IRQ_HANDLED;
}