Merge tag 'iwlwifi-next-for-kalle-2016-07-01' of git://git.kernel.org/pub/scm/linux...
[deliverable/linux.git] / drivers / mmc / host / tmio_mmc_pio.c
index 0521b466274804d03718f592b7b49a9ee3670037..f44e2ab7aea2bab15ade6e1104e4bc80eeb3d633 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/slot-gpio.h>
-#include <linux/mmc/tmio.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
 #include <linux/platform_device.h>
 void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
 {
        host->sdcard_irq_mask &= ~(i & TMIO_MASK_IRQ);
-       sd_ctrl_write32(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
+       sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
 }
 
 void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
 {
        host->sdcard_irq_mask |= (i & TMIO_MASK_IRQ);
-       sd_ctrl_write32(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
+       sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask);
 }
 
 static void tmio_mmc_ack_mmc_irqs(struct tmio_mmc_host *host, u32 i)
 {
-       sd_ctrl_write32(host, CTL_STATUS, ~i);
+       sd_ctrl_write32_as_16_and_16(host, CTL_STATUS, ~i);
 }
 
 static void tmio_mmc_init_sg(struct tmio_mmc_host *host, struct mmc_data *data)
@@ -154,31 +153,16 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
        }
 }
 
-static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
-                               unsigned int new_clock)
+static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
 {
-       u32 clk = 0, clock;
-
-       if (new_clock) {
-               for (clock = host->mmc->f_min, clk = 0x80000080;
-                    new_clock >= (clock << 1);
-                    clk >>= 1)
-                       clock <<= 1;
-
-               /* 1/1 clock is option */
-               if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) &&
-                  ((clk >> 22) & 0x1))
-                       clk |= 0xff;
-       }
-
-       if (host->set_clk_div)
-               host->set_clk_div(host->pdev, (clk >> 22) & 1);
+       sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
+               sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+       msleep(host->pdata->flags & TMIO_MMC_MIN_RCAR2 ? 1 : 10);
 
-       sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
-                       sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
-       sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK);
-       if (!(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG))
+       if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) {
+               sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
                msleep(10);
+       }
 }
 
 static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
@@ -190,19 +174,41 @@ static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
 
        sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
                sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
-       msleep(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG ? 5 : 10);
+       msleep(host->pdata->flags & TMIO_MMC_MIN_RCAR2 ? 5 : 10);
 }
 
-static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
+static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
+                               unsigned int new_clock)
 {
-       sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
-               sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
-       msleep(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG ? 1 : 10);
+       u32 clk = 0, clock;
 
-       if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) {
-               sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
-               msleep(10);
+       if (new_clock == 0) {
+               tmio_mmc_clk_stop(host);
+               return;
        }
+
+       if (host->clk_update)
+               clock = host->clk_update(host, new_clock) / 512;
+       else
+               clock = host->mmc->f_min;
+
+       for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1)
+               clock <<= 1;
+
+       /* 1/1 clock is option */
+       if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) && ((clk >> 22) & 0x1))
+               clk |= 0xff;
+
+       if (host->set_clk_div)
+               host->set_clk_div(host->pdev, (clk >> 22) & 1);
+
+       sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
+                       sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+       sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK);
+       if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2))
+               msleep(10);
+
+       tmio_mmc_clk_start(host);
 }
 
 static void tmio_mmc_reset(struct tmio_mmc_host *host)
@@ -264,9 +270,6 @@ static void tmio_mmc_reset_work(struct work_struct *work)
 
        tmio_mmc_abort_dma(host);
        mmc_request_done(host->mmc, mrq);
-
-       pm_runtime_mark_last_busy(mmc_dev(host->mmc));
-       pm_runtime_put_autosuspend(mmc_dev(host->mmc));
 }
 
 /* called with host->lock held, interrupts disabled */
@@ -296,9 +299,6 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host)
                tmio_mmc_abort_dma(host);
 
        mmc_request_done(host->mmc, mrq);
-
-       pm_runtime_mark_last_busy(mmc_dev(host->mmc));
-       pm_runtime_put_autosuspend(mmc_dev(host->mmc));
 }
 
 static void tmio_mmc_done_work(struct work_struct *work)
@@ -375,7 +375,7 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command
        tmio_mmc_enable_mmc_irqs(host, irq_mask);
 
        /* Fire off the command */
-       sd_ctrl_write32(host, CTL_ARG_REG, cmd->arg);
+       sd_ctrl_write32_as_16_and_16(host, CTL_ARG_REG, cmd->arg);
        sd_ctrl_write16(host, CTL_SD_CMD, c);
 
        return 0;
@@ -530,7 +530,7 @@ 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);
+               u32 status = sd_ctrl_read16_and_16_as_32(host, CTL_STATUS);
                bool done = false;
 
                /*
@@ -542,7 +542,7 @@ static void tmio_mmc_data_irq(struct tmio_mmc_host *host)
                 * waiting for one more interrupt fixes the problem.
                 */
                if (host->pdata->flags & TMIO_MMC_HAS_IDLE_WAIT) {
-                       if (status & TMIO_STAT_ILL_FUNC)
+                       if (status & TMIO_STAT_SCLKDIVEN)
                                done = true;
                } else {
                        if (!(status & TMIO_STAT_CMD_BUSY))
@@ -585,7 +585,7 @@ static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,
         */
 
        for (i = 3, addr = CTL_RESPONSE ; i >= 0 ; i--, addr += 4)
-               cmd->resp[i] = sd_ctrl_read32(host, addr);
+               cmd->resp[i] = sd_ctrl_read16_and_16_as_32(host, addr);
 
        if (cmd->flags &  MMC_RSP_136) {
                cmd->resp[0] = (cmd->resp[0] << 8) | (cmd->resp[1] >> 24);
@@ -625,19 +625,6 @@ out:
        spin_unlock(&host->lock);
 }
 
-static void tmio_mmc_card_irq_status(struct tmio_mmc_host *host,
-                                      int *ireg, int *status)
-{
-       *status = sd_ctrl_read32(host, CTL_STATUS);
-       *ireg = *status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;
-
-       pr_debug_status(*status);
-       pr_debug_status(*ireg);
-
-       /* Clear the status except the interrupt status */
-       sd_ctrl_write32(host, CTL_STATUS, TMIO_MASK_IRQ);
-}
-
 static bool __tmio_mmc_card_detect_irq(struct tmio_mmc_host *host,
                                      int ireg, int status)
 {
@@ -657,18 +644,6 @@ static bool __tmio_mmc_card_detect_irq(struct tmio_mmc_host *host,
        return false;
 }
 
-irqreturn_t tmio_mmc_card_detect_irq(int irq, void *devid)
-{
-       unsigned int ireg, status;
-       struct tmio_mmc_host *host = devid;
-
-       tmio_mmc_card_irq_status(host, &ireg, &status);
-       __tmio_mmc_card_detect_irq(host, ireg, status);
-
-       return IRQ_HANDLED;
-}
-EXPORT_SYMBOL(tmio_mmc_card_detect_irq);
-
 static bool __tmio_mmc_sdcard_irq(struct tmio_mmc_host *host,
                                 int ireg, int status)
 {
@@ -698,19 +673,7 @@ static bool __tmio_mmc_sdcard_irq(struct tmio_mmc_host *host,
        return false;
 }
 
-irqreturn_t tmio_mmc_sdcard_irq(int irq, void *devid)
-{
-       unsigned int ireg, status;
-       struct tmio_mmc_host *host = devid;
-
-       tmio_mmc_card_irq_status(host, &ireg, &status);
-       __tmio_mmc_sdcard_irq(host, ireg, status);
-
-       return IRQ_HANDLED;
-}
-EXPORT_SYMBOL(tmio_mmc_sdcard_irq);
-
-irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid)
+static void tmio_mmc_sdio_irq(int irq, void *devid)
 {
        struct tmio_mmc_host *host = devid;
        struct mmc_host *mmc = host->mmc;
@@ -719,7 +682,7 @@ irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid)
        unsigned int sdio_status;
 
        if (!(pdata->flags & TMIO_MMC_SDIO_IRQ))
-               return IRQ_HANDLED;
+               return;
 
        status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
        ireg = status & TMIO_SDIO_MASK_ALL & ~host->sdcard_irq_mask;
@@ -732,19 +695,22 @@ irqreturn_t tmio_mmc_sdio_irq(int irq, void *devid)
 
        if (mmc->caps & MMC_CAP_SDIO_IRQ && ireg & TMIO_SDIO_STAT_IOIRQ)
                mmc_signal_sdio_irq(mmc);
-
-       return IRQ_HANDLED;
 }
-EXPORT_SYMBOL(tmio_mmc_sdio_irq);
 
 irqreturn_t tmio_mmc_irq(int irq, void *devid)
 {
        struct tmio_mmc_host *host = devid;
        unsigned int ireg, status;
 
-       pr_debug("MMC IRQ begin\n");
+       status = sd_ctrl_read16_and_16_as_32(host, CTL_STATUS);
+       ireg = status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask;
+
+       pr_debug_status(status);
+       pr_debug_status(ireg);
+
+       /* Clear the status except the interrupt status */
+       sd_ctrl_write32_as_16_and_16(host, CTL_STATUS, TMIO_MASK_IRQ);
 
-       tmio_mmc_card_irq_status(host, &ireg, &status);
        if (__tmio_mmc_card_detect_irq(host, ireg, status))
                return IRQ_HANDLED;
        if (__tmio_mmc_sdcard_irq(host, ireg, status))
@@ -812,8 +778,6 @@ static void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 
        spin_unlock_irqrestore(&host->lock, flags);
 
-       pm_runtime_get_sync(mmc_dev(mmc));
-
        if (mrq->data) {
                ret = tmio_mmc_start_data(host, mrq->data);
                if (ret)
@@ -832,24 +796,14 @@ fail:
        host->mrq = NULL;
        mrq->cmd->error = ret;
        mmc_request_done(mmc, mrq);
-
-       pm_runtime_mark_last_busy(mmc_dev(mmc));
-       pm_runtime_put_autosuspend(mmc_dev(mmc));
 }
 
-static int tmio_mmc_clk_update(struct tmio_mmc_host *host)
+static int tmio_mmc_clk_enable(struct tmio_mmc_host *host)
 {
-       struct mmc_host *mmc = host->mmc;
-       int ret;
-
        if (!host->clk_enable)
                return -ENOTSUPP;
 
-       ret = host->clk_enable(host->pdev, &mmc->f_max);
-       if (!ret)
-               mmc->f_min = mmc->f_max / 512;
-
-       return ret;
+       return host->clk_enable(host);
 }
 
 static void tmio_mmc_power_on(struct tmio_mmc_host *host, unsigned short vdd)
@@ -925,8 +879,6 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        struct device *dev = &host->pdev->dev;
        unsigned long flags;
 
-       pm_runtime_get_sync(mmc_dev(mmc));
-
        mutex_lock(&host->ios_lock);
 
        spin_lock_irqsave(&host->lock, flags);
@@ -959,14 +911,12 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                tmio_mmc_clk_stop(host);
                break;
        case MMC_POWER_UP:
-               tmio_mmc_set_clock(host, ios->clock);
                tmio_mmc_power_on(host, ios->vdd);
-               tmio_mmc_clk_start(host);
+               tmio_mmc_set_clock(host, ios->clock);
                tmio_mmc_set_bus_width(host, ios->bus_width);
                break;
        case MMC_POWER_ON:
                tmio_mmc_set_clock(host, ios->clock);
-               tmio_mmc_clk_start(host);
                tmio_mmc_set_bus_width(host, ios->bus_width);
                break;
        }
@@ -983,9 +933,6 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        host->clk_cache = ios->clock;
 
        mutex_unlock(&host->ios_lock);
-
-       pm_runtime_mark_last_busy(mmc_dev(mmc));
-       pm_runtime_put_autosuspend(mmc_dev(mmc));
 }
 
 static int tmio_mmc_get_ro(struct mmc_host *mmc)
@@ -996,11 +943,8 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc)
        if (ret >= 0)
                return ret;
 
-       pm_runtime_get_sync(mmc_dev(mmc));
        ret = !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
-               (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
-       pm_runtime_mark_last_busy(mmc_dev(mmc));
-       pm_runtime_put_autosuspend(mmc_dev(mmc));
+               (sd_ctrl_read16_and_16_as_32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
 
        return ret;
 }
@@ -1016,12 +960,20 @@ static int tmio_multi_io_quirk(struct mmc_card *card,
        return blk_size;
 }
 
-static const struct mmc_host_ops tmio_mmc_ops = {
+static int tmio_mmc_card_busy(struct mmc_host *mmc)
+{
+       struct tmio_mmc_host *host = mmc_priv(mmc);
+
+       return !(sd_ctrl_read16_and_16_as_32(host, CTL_STATUS) & TMIO_STAT_DAT0);
+}
+
+static struct mmc_host_ops tmio_mmc_ops = {
        .request        = tmio_mmc_request,
        .set_ios        = tmio_mmc_set_ios,
        .get_ro         = tmio_mmc_get_ro,
        .get_cd         = mmc_gpio_get_cd,
        .enable_sdio_irq = tmio_mmc_enable_sdio_irq,
+       .card_busy      = tmio_mmc_card_busy,
        .multi_io_quirk = tmio_multi_io_quirk,
 };
 
@@ -1120,7 +1072,9 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
                goto host_free;
        }
 
+       tmio_mmc_ops.start_signal_voltage_switch = _host->start_signal_voltage_switch;
        mmc->ops = &tmio_mmc_ops;
+
        mmc->caps |= MMC_CAP_4_BIT_DATA | pdata->capabilities;
        mmc->caps2 |= pdata->capabilities2;
        mmc->max_segs = 32;
@@ -1135,7 +1089,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
                                  mmc->caps & MMC_CAP_NONREMOVABLE ||
                                  mmc->slot.cd_irq >= 0);
 
-       if (tmio_mmc_clk_update(_host) < 0) {
+       if (tmio_mmc_clk_enable(_host) < 0) {
                mmc->f_max = pdata->hclk;
                mmc->f_min = mmc->f_max / 512;
        }
@@ -1159,7 +1113,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
        tmio_mmc_clk_stop(_host);
        tmio_mmc_reset(_host);
 
-       _host->sdcard_irq_mask = sd_ctrl_read32(_host, CTL_IRQ_MASK);
+       _host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, CTL_IRQ_MASK);
        tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
 
        /* Unmask the IRQs we want to know about */
@@ -1251,7 +1205,7 @@ int tmio_mmc_host_runtime_suspend(struct device *dev)
                tmio_mmc_clk_stop(host);
 
        if (host->clk_disable)
-               host->clk_disable(host->pdev);
+               host->clk_disable(host);
 
        return 0;
 }
@@ -1263,12 +1217,10 @@ int tmio_mmc_host_runtime_resume(struct device *dev)
        struct tmio_mmc_host *host = mmc_priv(mmc);
 
        tmio_mmc_reset(host);
-       tmio_mmc_clk_update(host);
+       tmio_mmc_clk_enable(host);
 
-       if (host->clk_cache) {
+       if (host->clk_cache)
                tmio_mmc_set_clock(host, host->clk_cache);
-               tmio_mmc_clk_start(host);
-       }
 
        tmio_mmc_enable_dma(host, true);
 
This page took 0.029352 seconds and 5 git commands to generate.