mmc: tmio: check ILL_FUNC instead of CBSY
authorShinobu Uehara <shinobu.uehara.xc@renesas.com>
Mon, 25 Aug 2014 03:01:32 +0000 (20:01 -0700)
committerUlf Hansson <ulf.hansson@linaro.org>
Tue, 9 Sep 2014 11:59:15 +0000 (13:59 +0200)
Some controllers need to check SD bus status when writing data.
Then, it checks ILL_FUNC bit on SD_INFO2 register,
and this method is controlled via TMIO_MMC_HAS_IDLE_WAIT flags.
Same method is required on tmio_mmc_data_irq() which will
be called after writing data.

Current driver is checking CBSY bit for this purpose,
but, some controllers doesn't have CBSY bit.
This patch checks ILL_FUNC bit instead of CBSY bit
if it has TMIO_MMC_HAS_IDLE_WAIT flags

[Kuninori Morimoto: tidyuped for upstreaming]

Tested-by: Nguyen Xuan Nui <nx-nui@jinso.co.jp>
Tested-by: Hiep Cao Minh <cm-hiep@jinso.co.jp>
Signed-off-by: Shinobu Uehara <shinobu.uehara.xc@renesas.com>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/tmio_mmc_pio.c

index c5ffa92ccb1803e513def0875752dcfd5deb87a9..10b3144930e2bd6c03c8871dce58e04b02f66302 100644 (file)
@@ -490,6 +490,9 @@ static void tmio_mmc_data_irq(struct tmio_mmc_host *host)
                goto out;
 
        if (host->chan_tx && (data->flags & MMC_DATA_WRITE) && !host->force_pio) {
+               u32 status = sd_ctrl_read32(host, CTL_STATUS);
+               bool done = false;
+
                /*
                 * Has all data been written out yet? Testing on SuperH showed,
                 * that in most cases the first interrupt comes already with the
@@ -498,7 +501,15 @@ static void tmio_mmc_data_irq(struct tmio_mmc_host *host)
                 * DATAEND interrupt with the BUSY bit set, in this cases
                 * waiting for one more interrupt fixes the problem.
                 */
-               if (!(sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_CMD_BUSY)) {
+               if (host->pdata->flags & TMIO_MMC_HAS_IDLE_WAIT) {
+                       if (status & TMIO_STAT_ILL_FUNC)
+                               done = true;
+               } else {
+                       if (!(status & TMIO_STAT_CMD_BUSY))
+                               done = true;
+               }
+
+               if (done) {
                        tmio_mmc_disable_mmc_irqs(host, TMIO_STAT_DATAEND);
                        tasklet_schedule(&host->dma_complete);
                }