mmc: rk29: clean up & use udelay instead of mdelay
author黄涛 <huangtao@rock-chips.com>
Mon, 10 Jan 2011 10:31:09 +0000 (18:31 +0800)
committer黄涛 <huangtao@rock-chips.com>
Mon, 10 Jan 2011 10:33:43 +0000 (18:33 +0800)
before use 18% __delay while play video, after only 1.6%.

drivers/mmc/host/rk29_sdmmc.c

index 8c5fb1656f79b4b1f5bf90ee376e907f55d1f960..4ab9a1f603d074291e2c9d1c335c247e608b6442 100755 (executable)
@@ -353,35 +353,43 @@ static void rk29_sdmmc_start_command(struct rk29_sdmmc *host,
        }
 }
 
-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);
 }
@@ -554,34 +562,13 @@ static void rk29_sdmmc_start_request(struct rk29_sdmmc *host)
        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);
@@ -726,35 +713,15 @@ static void rk29_sdmmc_request_end(struct rk29_sdmmc *host, struct mmc_request *
        __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,