ARM: 7719/1: mmc: mmci: Support for CMD23
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / mmc / host / mmci.c
index 375c109..9df8b84 100644 (file)
@@ -196,6 +196,9 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
        struct variant_data *variant = host->variant;
        u32 clk = variant->clkreg;
 
+       /* Make sure cclk reflects the current calculated clock */
+       host->cclk = 0;
+
        if (desired) {
                if (desired >= host->mclk) {
                        clk = MCI_CLK_BYPASS;
@@ -230,6 +233,9 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
                /* clk |= MCI_CLK_PWRSAVE; */
        }
 
+       /* Set actual clock for debug */
+       host->mmc->actual_clock = host->cclk;
+
        if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4)
                clk |= MCI_4BIT_BUS;
        if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8)
@@ -842,7 +848,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
                        /* The error clause is handled above, success! */
                        data->bytes_xfered = data->blksz * data->blocks;
 
-               if (!data->stop) {
+               if (!data->stop || host->mrq->sbc) {
                        mmci_request_end(host, data->mrq);
                } else {
                        mmci_start_command(host, data->stop, 0);
@@ -855,6 +861,7 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
             unsigned int status)
 {
        void __iomem *base = host->base;
+       bool sbc = (cmd == host->mrq->sbc);
 
        host->cmd = NULL;
 
@@ -869,7 +876,7 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
                cmd->resp[3] = readl(base + MMCIRESPONSE3);
        }
 
-       if (!cmd->data || cmd->error) {
+       if ((!sbc && !cmd->data) || cmd->error) {
                if (host->data) {
                        /* Terminate the DMA transfer */
                        if (dma_inprogress(host)) {
@@ -878,7 +885,9 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
                        }
                        mmci_stop_data(host);
                }
-               mmci_request_end(host, cmd->mrq);
+               mmci_request_end(host, host->mrq);
+       } else if (sbc) {
+               mmci_start_command(host, host->mrq->cmd, 0);
        } else if (!(cmd->data->flags & MMC_DATA_READ)) {
                mmci_start_data(host, cmd->data);
        }
@@ -1119,7 +1128,10 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
        if (mrq->data && mrq->data->flags & MMC_DATA_READ)
                mmci_start_data(host, mrq->data);
 
-       mmci_start_command(host, mrq->cmd, 0);
+       if (mrq->sbc)
+               mmci_start_command(host, mrq->sbc, 0);
+       else
+               mmci_start_command(host, mrq->cmd, 0);
 
        spin_unlock_irqrestore(&host->lock, flags);
 }
@@ -1130,6 +1142,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        struct variant_data *variant = host->variant;
        u32 pwr = 0;
        unsigned long flags;
+       int ret;
 
        pm_runtime_get_sync(mmc_dev(mmc));
 
@@ -1161,8 +1174,12 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                break;
        case MMC_POWER_ON:
                if (!IS_ERR(mmc->supply.vqmmc) &&
-                   !regulator_is_enabled(mmc->supply.vqmmc))
-                       regulator_enable(mmc->supply.vqmmc);
+                   !regulator_is_enabled(mmc->supply.vqmmc)) {
+                       ret = regulator_enable(mmc->supply.vqmmc);
+                       if (ret < 0)
+                               dev_err(mmc_dev(mmc),
+                                       "failed to enable vqmmc regulator\n");
+               }
 
                pwr |= MCI_PWR_ON;
                break;
@@ -1357,16 +1374,15 @@ static int mmci_probe(struct amba_device *dev,
        dev_dbg(mmc_dev(mmc), "designer ID = 0x%02x\n", host->hw_designer);
        dev_dbg(mmc_dev(mmc), "revision = 0x%01x\n", host->hw_revision);
 
-       host->clk = clk_get(&dev->dev, NULL);
+       host->clk = devm_clk_get(&dev->dev, NULL);
        if (IS_ERR(host->clk)) {
                ret = PTR_ERR(host->clk);
-               host->clk = NULL;
                goto host_free;
        }
 
        ret = clk_prepare_enable(host->clk);
        if (ret)
-               goto clk_free;
+               goto host_free;
 
        host->plat = plat;
        host->variant = variant;
@@ -1571,8 +1587,6 @@ static int mmci_probe(struct amba_device *dev,
        iounmap(host->base);
  clk_disable:
        clk_disable_unprepare(host->clk);
- clk_free:
-       clk_put(host->clk);
  host_free:
        mmc_free_host(mmc);
  rel_regions:
@@ -1618,7 +1632,6 @@ static int mmci_remove(struct amba_device *dev)
 
                iounmap(host->base);
                clk_disable_unprepare(host->clk);
-               clk_put(host->clk);
 
                mmc_free_host(mmc);