}
}
-static void send_stop_cmd(struct rk29_sdmmc *host, struct mmc_data *data)
+static void rk29_sdmmc_reset_fifo(struct rk29_sdmmc *host)
{
- int time_out=100, time_out2=3;
unsigned long flags;
-
-
- while(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & (SDMMC_STAUTS_DATA_BUSY)) {
- mdelay(5);
- time_out --;
- if(!time_out){
- time_out =60;
- local_irq_save(flags);
- rk29_sdmmc_write( host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | ( SDMMC_CTRL_FIFO_RESET ));
- /* wait till resets clear */
- while (rk29_sdmmc_read(host->regs, SDMMC_CTRL) & ( SDMMC_CTRL_FIFO_RESET));
- local_irq_restore(flags);
+
+ local_irq_save(flags);
+ rk29_sdmmc_write(host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | SDMMC_CTRL_FIFO_RESET);
+ /* wait till resets clear */
+ while (rk29_sdmmc_read(host->regs, SDMMC_CTRL) & SDMMC_CTRL_FIFO_RESET);
+ local_irq_restore(flags);
+}
+
+static int rk29_sdmmc_wait_unbusy(struct rk29_sdmmc *host)
+{
+ const int time_out_us = 500000;
+ int time_out = time_out_us, time_out2 = 3;
+
+ while (rk29_sdmmc_read(host->regs, SDMMC_STATUS) & SDMMC_STAUTS_DATA_BUSY) {
+ udelay(1);
+ time_out--;
+ if (!time_out) {
+ time_out = time_out_us;
+ rk29_sdmmc_reset_fifo(host);
time_out2--;
- if(!time_out2)
+ if (!time_out2)
break;
-
}
}
-
+
+ return time_out_us - time_out;
+}
+
+static void send_stop_cmd(struct rk29_sdmmc *host, struct mmc_data *data)
+{
+ rk29_sdmmc_wait_unbusy(host);
+
if(!(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & SDMMC_STAUTS_FIFO_EMPTY)) {
- local_irq_save(flags);
- rk29_sdmmc_write(host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | ( SDMMC_CTRL_FIFO_RESET ));
- /* wait till resets clear */
- while (readl(host->regs + SDMMC_CTRL) & ( SDMMC_CTRL_FIFO_RESET));
- local_irq_restore(flags);
+ rk29_sdmmc_reset_fifo(host);
}
rk29_sdmmc_start_command(host, data->stop, host->stop_cmdr);
}
struct mmc_command *cmd;
struct mmc_data *data;
u32 cmdflags;
- int time_out=100, time_out2=3;
- unsigned long flags;
mrq = host->mrq;
-
- while(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & (SDMMC_STAUTS_DATA_BUSY)) {
- mdelay(5);
- time_out --;
- if(!time_out){
- time_out =60;
- local_irq_save(flags);
- rk29_sdmmc_write( host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | ( SDMMC_CTRL_FIFO_RESET ));
- /* wait till resets clear */
- while (rk29_sdmmc_read(host->regs, SDMMC_CTRL) & ( SDMMC_CTRL_FIFO_RESET));
- local_irq_restore(flags);
- time_out2--;
- if(!time_out2)
- break;
-
- }
- }
+
+ rk29_sdmmc_wait_unbusy(host);
if(!(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & SDMMC_STAUTS_FIFO_EMPTY)) {
- local_irq_save(flags);
- rk29_sdmmc_write(host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | ( SDMMC_CTRL_FIFO_RESET ));
- /* wait till resets clear */
- while (readl(host->regs + SDMMC_CTRL) & ( SDMMC_CTRL_FIFO_RESET));
- local_irq_restore(flags);
+ rk29_sdmmc_reset_fifo(host);
}
/* Slot specific timing and width adjustment */
rk29_sdmmc_setup_bus(host);
__acquires(&host->lock)
{
struct mmc_host *prev_mmc = host->mmc;
- unsigned long flags;
- int time_out=100, time_out2=3;
WARN_ON(host->cmd || host->data);
host->curr_mrq = NULL;
host->mrq = NULL;
- while(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & (SDMMC_STAUTS_DATA_BUSY)) {
- mdelay(5);
- time_out --;
- if(!time_out){
- time_out =60;
- local_irq_save(flags);
- rk29_sdmmc_write( host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | ( SDMMC_CTRL_FIFO_RESET ));
- /* wait till resets clear */
- while (rk29_sdmmc_read(host->regs, SDMMC_CTRL) & ( SDMMC_CTRL_FIFO_RESET));
- local_irq_restore(flags);
- time_out2--;
- if(!time_out2)
- break;
- }
- }
-
+ rk29_sdmmc_wait_unbusy(host);
+
if(!(rk29_sdmmc_read(host->regs, SDMMC_STATUS) & SDMMC_STAUTS_FIFO_EMPTY)) {
- local_irq_save(flags);
- rk29_sdmmc_write(host->regs, SDMMC_CTRL, rk29_sdmmc_read(host->regs, SDMMC_CTRL) | ( SDMMC_CTRL_FIFO_RESET ));
- /* wait till resets clear */
- while (readl(host->regs + SDMMC_CTRL) & ( SDMMC_CTRL_FIFO_RESET));
- local_irq_restore(flags);
+ rk29_sdmmc_reset_fifo(host);
}
if (!list_empty(&host->queue)) {
host = list_entry(host->queue.next,