mmc: mxs-mmc: Fix merge issue causing build error
[firefly-linux-kernel-4.4.55.git] / drivers / mmc / host / mxs-mmc.c
index a51f9309ffbb1e49947939fb60d6c6dcc8e3be93..80d1e6d4b0ae2272588b8860f91527d02358dbf4 100644 (file)
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
 #include <linux/module.h>
-#include <linux/fsl/mxs-dma.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/stmp_device.h>
 #include <linux/mmc/mxs-mmc.h>
+#include <linux/spi/mxs-spi.h>
 
 #define DRIVER_NAME    "mxs-mmc"
 
-/* card detect polling timeout */
-#define MXS_MMC_DETECT_TIMEOUT                 (HZ/2)
-
-#define ssp_is_old(host)       ((host)->devid == IMX23_MMC)
-
-/* SSP registers */
-#define HW_SSP_CTRL0                           0x000
-#define  BM_SSP_CTRL0_RUN                      (1 << 29)
-#define  BM_SSP_CTRL0_SDIO_IRQ_CHECK           (1 << 28)
-#define  BM_SSP_CTRL0_IGNORE_CRC               (1 << 26)
-#define  BM_SSP_CTRL0_READ                     (1 << 25)
-#define  BM_SSP_CTRL0_DATA_XFER                        (1 << 24)
-#define  BP_SSP_CTRL0_BUS_WIDTH                        (22)
-#define  BM_SSP_CTRL0_BUS_WIDTH                        (0x3 << 22)
-#define  BM_SSP_CTRL0_WAIT_FOR_IRQ             (1 << 21)
-#define  BM_SSP_CTRL0_LONG_RESP                        (1 << 19)
-#define  BM_SSP_CTRL0_GET_RESP                 (1 << 17)
-#define  BM_SSP_CTRL0_ENABLE                   (1 << 16)
-#define  BP_SSP_CTRL0_XFER_COUNT               (0)
-#define  BM_SSP_CTRL0_XFER_COUNT               (0xffff)
-#define HW_SSP_CMD0                            0x010
-#define  BM_SSP_CMD0_DBL_DATA_RATE_EN          (1 << 25)
-#define  BM_SSP_CMD0_SLOW_CLKING_EN            (1 << 22)
-#define  BM_SSP_CMD0_CONT_CLKING_EN            (1 << 21)
-#define  BM_SSP_CMD0_APPEND_8CYC               (1 << 20)
-#define  BP_SSP_CMD0_BLOCK_SIZE                        (16)
-#define  BM_SSP_CMD0_BLOCK_SIZE                        (0xf << 16)
-#define  BP_SSP_CMD0_BLOCK_COUNT               (8)
-#define  BM_SSP_CMD0_BLOCK_COUNT               (0xff << 8)
-#define  BP_SSP_CMD0_CMD                       (0)
-#define  BM_SSP_CMD0_CMD                       (0xff)
-#define HW_SSP_CMD1                            0x020
-#define HW_SSP_XFER_SIZE                       0x030
-#define HW_SSP_BLOCK_SIZE                      0x040
-#define  BP_SSP_BLOCK_SIZE_BLOCK_COUNT         (4)
-#define  BM_SSP_BLOCK_SIZE_BLOCK_COUNT         (0xffffff << 4)
-#define  BP_SSP_BLOCK_SIZE_BLOCK_SIZE          (0)
-#define  BM_SSP_BLOCK_SIZE_BLOCK_SIZE          (0xf)
-#define HW_SSP_TIMING(h)                       (ssp_is_old(h) ? 0x050 : 0x070)
-#define  BP_SSP_TIMING_TIMEOUT                 (16)
-#define  BM_SSP_TIMING_TIMEOUT                 (0xffff << 16)
-#define  BP_SSP_TIMING_CLOCK_DIVIDE            (8)
-#define  BM_SSP_TIMING_CLOCK_DIVIDE            (0xff << 8)
-#define  BP_SSP_TIMING_CLOCK_RATE              (0)
-#define  BM_SSP_TIMING_CLOCK_RATE              (0xff)
-#define HW_SSP_CTRL1(h)                                (ssp_is_old(h) ? 0x060 : 0x080)
-#define  BM_SSP_CTRL1_SDIO_IRQ                 (1 << 31)
-#define  BM_SSP_CTRL1_SDIO_IRQ_EN              (1 << 30)
-#define  BM_SSP_CTRL1_RESP_ERR_IRQ             (1 << 29)
-#define  BM_SSP_CTRL1_RESP_ERR_IRQ_EN          (1 << 28)
-#define  BM_SSP_CTRL1_RESP_TIMEOUT_IRQ         (1 << 27)
-#define  BM_SSP_CTRL1_RESP_TIMEOUT_IRQ_EN      (1 << 26)
-#define  BM_SSP_CTRL1_DATA_TIMEOUT_IRQ         (1 << 25)
-#define  BM_SSP_CTRL1_DATA_TIMEOUT_IRQ_EN      (1 << 24)
-#define  BM_SSP_CTRL1_DATA_CRC_IRQ             (1 << 23)
-#define  BM_SSP_CTRL1_DATA_CRC_IRQ_EN          (1 << 22)
-#define  BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ                (1 << 21)
-#define  BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ_EN     (1 << 20)
-#define  BM_SSP_CTRL1_RECV_TIMEOUT_IRQ         (1 << 17)
-#define  BM_SSP_CTRL1_RECV_TIMEOUT_IRQ_EN      (1 << 16)
-#define  BM_SSP_CTRL1_FIFO_OVERRUN_IRQ         (1 << 15)
-#define  BM_SSP_CTRL1_FIFO_OVERRUN_IRQ_EN      (1 << 14)
-#define  BM_SSP_CTRL1_DMA_ENABLE               (1 << 13)
-#define  BM_SSP_CTRL1_POLARITY                 (1 << 9)
-#define  BP_SSP_CTRL1_WORD_LENGTH              (4)
-#define  BM_SSP_CTRL1_WORD_LENGTH              (0xf << 4)
-#define  BP_SSP_CTRL1_SSP_MODE                 (0)
-#define  BM_SSP_CTRL1_SSP_MODE                 (0xf)
-#define HW_SSP_SDRESP0(h)                      (ssp_is_old(h) ? 0x080 : 0x0a0)
-#define HW_SSP_SDRESP1(h)                      (ssp_is_old(h) ? 0x090 : 0x0b0)
-#define HW_SSP_SDRESP2(h)                      (ssp_is_old(h) ? 0x0a0 : 0x0c0)
-#define HW_SSP_SDRESP3(h)                      (ssp_is_old(h) ? 0x0b0 : 0x0d0)
-#define HW_SSP_STATUS(h)                       (ssp_is_old(h) ? 0x0c0 : 0x100)
-#define  BM_SSP_STATUS_CARD_DETECT             (1 << 28)
-#define  BM_SSP_STATUS_SDIO_IRQ                        (1 << 17)
-
-#define BF_SSP(value, field)   (((value) << BP_SSP_##field) & BM_SSP_##field)
-
 #define MXS_MMC_IRQ_BITS       (BM_SSP_CTRL1_SDIO_IRQ          | \
                                 BM_SSP_CTRL1_RESP_ERR_IRQ      | \
                                 BM_SSP_CTRL1_RESP_TIMEOUT_IRQ  | \
                                 BM_SSP_CTRL1_RECV_TIMEOUT_IRQ  | \
                                 BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
 
-#define SSP_PIO_NUM    3
-
-enum mxs_mmc_id {
-       IMX23_MMC,
-       IMX28_MMC,
-};
+/* card detect polling timeout */
+#define MXS_MMC_DETECT_TIMEOUT                 (HZ/2)
 
 struct mxs_mmc_host {
+       struct mxs_ssp                  ssp;
+
        struct mmc_host                 *mmc;
        struct mmc_request              *mrq;
        struct mmc_command              *cmd;
        struct mmc_data                 *data;
 
-       void __iomem                    *base;
-       int                             dma_channel;
-       struct clk                      *clk;
-       unsigned int                    clk_rate;
-
-       struct dma_chan                 *dmach;
-       struct mxs_dma_data             dma_data;
-       unsigned int                    dma_dir;
-       enum dma_transfer_direction     slave_dirn;
-       u32                             ssp_pio_words[SSP_PIO_NUM];
-
-       enum mxs_mmc_id                 devid;
        unsigned char                   bus_width;
        spinlock_t                      lock;
        int                             sdio_irq_en;
@@ -186,16 +94,18 @@ static int mxs_mmc_get_ro(struct mmc_host *mmc)
 static int mxs_mmc_get_cd(struct mmc_host *mmc)
 {
        struct mxs_mmc_host *host = mmc_priv(mmc);
+       struct mxs_ssp *ssp = &host->ssp;
 
-       return !(readl(host->base + HW_SSP_STATUS(host)) &
+       return !(readl(ssp->base + HW_SSP_STATUS(ssp)) &
                 BM_SSP_STATUS_CARD_DETECT);
 }
 
 static void mxs_mmc_reset(struct mxs_mmc_host *host)
 {
+       struct mxs_ssp *ssp = &host->ssp;
        u32 ctrl0, ctrl1;
 
-       stmp_reset_block(host->base);
+       stmp_reset_block(ssp->base);
 
        ctrl0 = BM_SSP_CTRL0_IGNORE_CRC;
        ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) |
@@ -211,15 +121,15 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
        writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
               BF_SSP(2, TIMING_CLOCK_DIVIDE) |
               BF_SSP(0, TIMING_CLOCK_RATE),
-              host->base + HW_SSP_TIMING(host));
+              ssp->base + HW_SSP_TIMING(ssp));
 
        if (host->sdio_irq_en) {
                ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
                ctrl1 |= BM_SSP_CTRL1_SDIO_IRQ_EN;
        }
 
-       writel(ctrl0, host->base + HW_SSP_CTRL0);
-       writel(ctrl1, host->base + HW_SSP_CTRL1(host));
+       writel(ctrl0, ssp->base + HW_SSP_CTRL0);
+       writel(ctrl1, ssp->base + HW_SSP_CTRL1(ssp));
 }
 
 static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
@@ -230,21 +140,22 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
        struct mmc_command *cmd = host->cmd;
        struct mmc_data *data = host->data;
        struct mmc_request *mrq = host->mrq;
+       struct mxs_ssp *ssp = &host->ssp;
 
        if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) {
                if (mmc_resp_type(cmd) & MMC_RSP_136) {
-                       cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0(host));
-                       cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1(host));
-                       cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2(host));
-                       cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3(host));
+                       cmd->resp[3] = readl(ssp->base + HW_SSP_SDRESP0(ssp));
+                       cmd->resp[2] = readl(ssp->base + HW_SSP_SDRESP1(ssp));
+                       cmd->resp[1] = readl(ssp->base + HW_SSP_SDRESP2(ssp));
+                       cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP3(ssp));
                } else {
-                       cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0(host));
+                       cmd->resp[0] = readl(ssp->base + HW_SSP_SDRESP0(ssp));
                }
        }
 
        if (data) {
                dma_unmap_sg(mmc_dev(host->mmc), data->sg,
-                            data->sg_len, host->dma_dir);
+                            data->sg_len, ssp->dma_dir);
                /*
                 * If there was an error on any block, we mark all
                 * data blocks as being in error.
@@ -277,19 +188,20 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
        struct mxs_mmc_host *host = dev_id;
        struct mmc_command *cmd = host->cmd;
        struct mmc_data *data = host->data;
+       struct mxs_ssp *ssp = &host->ssp;
        u32 stat;
 
        spin_lock(&host->lock);
 
-       stat = readl(host->base + HW_SSP_CTRL1(host));
+       stat = readl(ssp->base + HW_SSP_CTRL1(ssp));
        writel(stat & MXS_MMC_IRQ_BITS,
-              host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
+              ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_CLR);
+
+       spin_unlock(&host->lock);
 
        if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
                mmc_signal_sdio_irq(host->mmc);
 
-       spin_unlock(&host->lock);
-
        if (stat & BM_SSP_CTRL1_RESP_TIMEOUT_IRQ)
                cmd->error = -ETIMEDOUT;
        else if (stat & BM_SSP_CTRL1_RESP_ERR_IRQ)
@@ -312,6 +224,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
 static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
        struct mxs_mmc_host *host, unsigned long flags)
 {
+       struct mxs_ssp *ssp = &host->ssp;
        struct dma_async_tx_descriptor *desc;
        struct mmc_data *data = host->data;
        struct scatterlist * sgl;
@@ -320,24 +233,24 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
        if (data) {
                /* data */
                dma_map_sg(mmc_dev(host->mmc), data->sg,
-                          data->sg_len, host->dma_dir);
+                          data->sg_len, ssp->dma_dir);
                sgl = data->sg;
                sg_len = data->sg_len;
        } else {
                /* pio */
-               sgl = (struct scatterlist *) host->ssp_pio_words;
+               sgl = (struct scatterlist *) ssp->ssp_pio_words;
                sg_len = SSP_PIO_NUM;
        }
 
-       desc = dmaengine_prep_slave_sg(host->dmach,
-                               sgl, sg_len, host->slave_dirn, flags);
+       desc = dmaengine_prep_slave_sg(ssp->dmach,
+                               sgl, sg_len, ssp->slave_dirn, flags);
        if (desc) {
                desc->callback = mxs_mmc_dma_irq_callback;
                desc->callback_param = host;
        } else {
                if (data)
                        dma_unmap_sg(mmc_dev(host->mmc), data->sg,
-                                    data->sg_len, host->dma_dir);
+                                    data->sg_len, ssp->dma_dir);
        }
 
        return desc;
@@ -345,6 +258,7 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
 
 static void mxs_mmc_bc(struct mxs_mmc_host *host)
 {
+       struct mxs_ssp *ssp = &host->ssp;
        struct mmc_command *cmd = host->cmd;
        struct dma_async_tx_descriptor *desc;
        u32 ctrl0, cmd0, cmd1;
@@ -358,17 +272,17 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host)
                cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN;
        }
 
-       host->ssp_pio_words[0] = ctrl0;
-       host->ssp_pio_words[1] = cmd0;
-       host->ssp_pio_words[2] = cmd1;
-       host->dma_dir = DMA_NONE;
-       host->slave_dirn = DMA_TRANS_NONE;
+       ssp->ssp_pio_words[0] = ctrl0;
+       ssp->ssp_pio_words[1] = cmd0;
+       ssp->ssp_pio_words[2] = cmd1;
+       ssp->dma_dir = DMA_NONE;
+       ssp->slave_dirn = DMA_TRANS_NONE;
        desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK);
        if (!desc)
                goto out;
 
        dmaengine_submit(desc);
-       dma_async_issue_pending(host->dmach);
+       dma_async_issue_pending(ssp->dmach);
        return;
 
 out:
@@ -378,6 +292,7 @@ out:
 
 static void mxs_mmc_ac(struct mxs_mmc_host *host)
 {
+       struct mxs_ssp *ssp = &host->ssp;
        struct mmc_command *cmd = host->cmd;
        struct dma_async_tx_descriptor *desc;
        u32 ignore_crc, get_resp, long_resp;
@@ -399,17 +314,17 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host)
                cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN;
        }
 
-       host->ssp_pio_words[0] = ctrl0;
-       host->ssp_pio_words[1] = cmd0;
-       host->ssp_pio_words[2] = cmd1;
-       host->dma_dir = DMA_NONE;
-       host->slave_dirn = DMA_TRANS_NONE;
+       ssp->ssp_pio_words[0] = ctrl0;
+       ssp->ssp_pio_words[1] = cmd0;
+       ssp->ssp_pio_words[2] = cmd1;
+       ssp->dma_dir = DMA_NONE;
+       ssp->slave_dirn = DMA_TRANS_NONE;
        desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK);
        if (!desc)
                goto out;
 
        dmaengine_submit(desc);
-       dma_async_issue_pending(host->dmach);
+       dma_async_issue_pending(ssp->dmach);
        return;
 
 out:
@@ -447,6 +362,8 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
        unsigned int data_size = 0, log2_blksz;
        unsigned int blocks = data->blocks;
 
+       struct mxs_ssp *ssp = &host->ssp;
+
        u32 ignore_crc, get_resp, long_resp, read;
        u32 ctrl0, cmd0, cmd1, val;
 
@@ -489,15 +406,15 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
                blocks = 1;
 
        /* xfer count, block size and count need to be set differently */
-       if (ssp_is_old(host)) {
+       if (ssp_is_old(ssp)) {
                ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT);
                cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) |
                        BF_SSP(blocks - 1, CMD0_BLOCK_COUNT);
        } else {
-               writel(data_size, host->base + HW_SSP_XFER_SIZE);
+               writel(data_size, ssp->base + HW_SSP_XFER_SIZE);
                writel(BF_SSP(log2_blksz, BLOCK_SIZE_BLOCK_SIZE) |
                       BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT),
-                      host->base + HW_SSP_BLOCK_SIZE);
+                      ssp->base + HW_SSP_BLOCK_SIZE);
        }
 
        if ((cmd->opcode == MMC_STOP_TRANSMISSION) ||
@@ -512,18 +429,18 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
        }
 
        /* set the timeout count */
-       timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns);
-       val = readl(host->base + HW_SSP_TIMING(host));
+       timeout = mxs_ns_to_ssp_ticks(ssp->clk_rate, data->timeout_ns);
+       val = readl(ssp->base + HW_SSP_TIMING(ssp));
        val &= ~(BM_SSP_TIMING_TIMEOUT);
        val |= BF_SSP(timeout, TIMING_TIMEOUT);
-       writel(val, host->base + HW_SSP_TIMING(host));
+       writel(val, ssp->base + HW_SSP_TIMING(ssp));
 
        /* pio */
-       host->ssp_pio_words[0] = ctrl0;
-       host->ssp_pio_words[1] = cmd0;
-       host->ssp_pio_words[2] = cmd1;
-       host->dma_dir = DMA_NONE;
-       host->slave_dirn = DMA_TRANS_NONE;
+       ssp->ssp_pio_words[0] = ctrl0;
+       ssp->ssp_pio_words[1] = cmd0;
+       ssp->ssp_pio_words[2] = cmd1;
+       ssp->dma_dir = DMA_NONE;
+       ssp->slave_dirn = DMA_TRANS_NONE;
        desc = mxs_mmc_prep_dma(host, 0);
        if (!desc)
                goto out;
@@ -531,14 +448,14 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
        /* append data sg */
        WARN_ON(host->data != NULL);
        host->data = data;
-       host->dma_dir = dma_data_dir;
-       host->slave_dirn = slave_dirn;
+       ssp->dma_dir = dma_data_dir;
+       ssp->slave_dirn = slave_dirn;
        desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!desc)
                goto out;
 
        dmaengine_submit(desc);
-       dma_async_issue_pending(host->dmach);
+       dma_async_issue_pending(ssp->dmach);
        return;
 out:
        dev_warn(mmc_dev(host->mmc),
@@ -579,42 +496,6 @@ static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
        mxs_mmc_start_cmd(host, mrq->cmd);
 }
 
-static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
-{
-       unsigned int ssp_clk, ssp_sck;
-       u32 clock_divide, clock_rate;
-       u32 val;
-
-       ssp_clk = clk_get_rate(host->clk);
-
-       for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) {
-               clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide);
-               clock_rate = (clock_rate > 0) ? clock_rate - 1 : 0;
-               if (clock_rate <= 255)
-                       break;
-       }
-
-       if (clock_divide > 254) {
-               dev_err(mmc_dev(host->mmc),
-                       "%s: cannot set clock to %d\n", __func__, rate);
-               return;
-       }
-
-       ssp_sck = ssp_clk / clock_divide / (1 + clock_rate);
-
-       val = readl(host->base + HW_SSP_TIMING(host));
-       val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
-       val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE);
-       val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE);
-       writel(val, host->base + HW_SSP_TIMING(host));
-
-       host->clk_rate = ssp_sck;
-
-       dev_dbg(mmc_dev(host->mmc),
-               "%s: clock_divide %d, clock_rate %d, ssp_clk %d, rate_actual %d, rate_requested %d\n",
-               __func__, clock_divide, clock_rate, ssp_clk, ssp_sck, rate);
-}
-
 static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
        struct mxs_mmc_host *host = mmc_priv(mmc);
@@ -627,12 +508,13 @@ static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
                host->bus_width = 0;
 
        if (ios->clock)
-               mxs_mmc_set_clk_rate(host, ios->clock);
+               mxs_ssp_set_clk_rate(&host->ssp, ios->clock);
 }
 
 static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
 {
        struct mxs_mmc_host *host = mmc_priv(mmc);
+       struct mxs_ssp *ssp = &host->ssp;
        unsigned long flags;
 
        spin_lock_irqsave(&host->lock, flags);
@@ -641,22 +523,22 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
 
        if (enable) {
                writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
-                      host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
+                      ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
                writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
-                      host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET);
-
-               if (readl(host->base + HW_SSP_STATUS(host)) &
-                               BM_SSP_STATUS_SDIO_IRQ)
-                       mmc_signal_sdio_irq(host->mmc);
-
+                      ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_SET);
        } else {
                writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
-                      host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
+                      ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
                writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
-                      host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
+                      ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_CLR);
        }
 
        spin_unlock_irqrestore(&host->lock, flags);
+
+       if (enable && readl(ssp->base + HW_SSP_STATUS(ssp)) &
+                       BM_SSP_STATUS_SDIO_IRQ)
+               mmc_signal_sdio_irq(host->mmc);
+
 }
 
 static const struct mmc_host_ops mxs_mmc_ops = {
@@ -670,34 +552,35 @@ static const struct mmc_host_ops mxs_mmc_ops = {
 static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
 {
        struct mxs_mmc_host *host = param;
+       struct mxs_ssp *ssp = &host->ssp;
 
        if (!mxs_dma_is_apbh(chan))
                return false;
 
-       if (chan->chan_id != host->dma_channel)
+       if (chan->chan_id != ssp->dma_channel)
                return false;
 
-       chan->private = &host->dma_data;
+       chan->private = &ssp->dma_data;
 
        return true;
 }
 
-static struct platform_device_id mxs_mmc_ids[] = {
+static struct platform_device_id mxs_ssp_ids[] = {
        {
                .name = "imx23-mmc",
-               .driver_data = IMX23_MMC,
+               .driver_data = IMX23_SSP,
        }, {
                .name = "imx28-mmc",
-               .driver_data = IMX28_MMC,
+               .driver_data = IMX28_SSP,
        }, {
                /* sentinel */
        }
 };
-MODULE_DEVICE_TABLE(platform, mxs_mmc_ids);
+MODULE_DEVICE_TABLE(platform, mxs_ssp_ids);
 
 static const struct of_device_id mxs_mmc_dt_ids[] = {
-       { .compatible = "fsl,imx23-mmc", .data = (void *) IMX23_MMC, },
-       { .compatible = "fsl,imx28-mmc", .data = (void *) IMX28_MMC, },
+       { .compatible = "fsl,imx23-mmc", .data = (void *) IMX23_SSP, },
+       { .compatible = "fsl,imx28-mmc", .data = (void *) IMX28_SSP, },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mxs_mmc_dt_ids);
@@ -716,6 +599,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
        dma_cap_mask_t mask;
        struct regulator *reg_vmmc;
        enum of_gpio_flags flags;
+       struct mxs_ssp *ssp;
 
        iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -729,28 +613,30 @@ static int mxs_mmc_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        host = mmc_priv(mmc);
-       host->base = devm_request_and_ioremap(&pdev->dev, iores);
-       if (!host->base) {
+       ssp = &host->ssp;
+       ssp->dev = &pdev->dev;
+       ssp->base = devm_request_and_ioremap(&pdev->dev, iores);
+       if (!ssp->base) {
                ret = -EADDRNOTAVAIL;
                goto out_mmc_free;
        }
 
        if (np) {
-               host->devid = (enum mxs_mmc_id) of_id->data;
+               ssp->devid = (enum mxs_ssp_id) of_id->data;
                /*
                 * TODO: This is a temporary solution and should be changed
                 * to use generic DMA binding later when the helpers get in.
                 */
                ret = of_property_read_u32(np, "fsl,ssp-dma-channel",
-                                          &host->dma_channel);
+                                          &ssp->dma_channel);
                if (ret) {
                        dev_err(mmc_dev(host->mmc),
                                "failed to get dma channel\n");
                        goto out_mmc_free;
                }
        } else {
-               host->devid = pdev->id_entry->driver_data;
-               host->dma_channel = dmares->start;
+               ssp->devid = pdev->id_entry->driver_data;
+               ssp->dma_channel = dmares->start;
        }
 
        host->mmc = mmc;
@@ -772,20 +658,20 @@ static int mxs_mmc_probe(struct platform_device *pdev)
                goto out_mmc_free;
        }
 
-       host->clk = clk_get(&pdev->dev, NULL);
-       if (IS_ERR(host->clk)) {
-               ret = PTR_ERR(host->clk);
+       ssp->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(ssp->clk)) {
+               ret = PTR_ERR(ssp->clk);
                goto out_mmc_free;
        }
-       clk_prepare_enable(host->clk);
+       clk_prepare_enable(ssp->clk);
 
        mxs_mmc_reset(host);
 
        dma_cap_zero(mask);
        dma_cap_set(DMA_SLAVE, mask);
-       host->dma_data.chan_irq = irq_dma;
-       host->dmach = dma_request_channel(mask, mxs_mmc_dma_filter, host);
-       if (!host->dmach) {
+       ssp->dma_data.chan_irq = irq_dma;
+       ssp->dmach = dma_request_channel(mask, mxs_mmc_dma_filter, host);
+       if (!ssp->dmach) {
                dev_err(mmc_dev(host->mmc),
                        "%s: failed to request dma\n", __func__);
                goto out_clk_put;
@@ -822,9 +708,9 @@ static int mxs_mmc_probe(struct platform_device *pdev)
 
        mmc->max_segs = 52;
        mmc->max_blk_size = 1 << 0xf;
-       mmc->max_blk_count = (ssp_is_old(host)) ? 0xff : 0xffffff;
-       mmc->max_req_size = (ssp_is_old(host)) ? 0xffff : 0xffffffff;
-       mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev);
+       mmc->max_blk_count = (ssp_is_old(ssp)) ? 0xff : 0xffffff;
+       mmc->max_req_size = (ssp_is_old(ssp)) ? 0xffff : 0xffffffff;
+       mmc->max_seg_size = dma_get_max_seg_size(ssp->dmach->device->dev);
 
        platform_set_drvdata(pdev, mmc);
 
@@ -844,11 +730,11 @@ static int mxs_mmc_probe(struct platform_device *pdev)
        return 0;
 
 out_free_dma:
-       if (host->dmach)
-               dma_release_channel(host->dmach);
+       if (ssp->dmach)
+               dma_release_channel(ssp->dmach);
 out_clk_put:
-       clk_disable_unprepare(host->clk);
-       clk_put(host->clk);
+       clk_disable_unprepare(ssp->clk);
+       clk_put(ssp->clk);
 out_mmc_free:
        mmc_free_host(mmc);
        return ret;
@@ -858,16 +744,17 @@ static int mxs_mmc_remove(struct platform_device *pdev)
 {
        struct mmc_host *mmc = platform_get_drvdata(pdev);
        struct mxs_mmc_host *host = mmc_priv(mmc);
+       struct mxs_ssp *ssp = &host->ssp;
 
        mmc_remove_host(mmc);
 
        platform_set_drvdata(pdev, NULL);
 
-       if (host->dmach)
-               dma_release_channel(host->dmach);
+       if (ssp->dmach)
+               dma_release_channel(ssp->dmach);
 
-       clk_disable_unprepare(host->clk);
-       clk_put(host->clk);
+       clk_disable_unprepare(ssp->clk);
+       clk_put(ssp->clk);
 
        mmc_free_host(mmc);
 
@@ -879,11 +766,12 @@ static int mxs_mmc_suspend(struct device *dev)
 {
        struct mmc_host *mmc = dev_get_drvdata(dev);
        struct mxs_mmc_host *host = mmc_priv(mmc);
+       struct mxs_ssp *ssp = &host->ssp;
        int ret = 0;
 
        ret = mmc_suspend_host(mmc);
 
-       clk_disable_unprepare(host->clk);
+       clk_disable_unprepare(ssp->clk);
 
        return ret;
 }
@@ -892,9 +780,10 @@ static int mxs_mmc_resume(struct device *dev)
 {
        struct mmc_host *mmc = dev_get_drvdata(dev);
        struct mxs_mmc_host *host = mmc_priv(mmc);
+       struct mxs_ssp *ssp = &host->ssp;
        int ret = 0;
 
-       clk_prepare_enable(host->clk);
+       clk_prepare_enable(ssp->clk);
 
        ret = mmc_resume_host(mmc);
 
@@ -910,7 +799,7 @@ static const struct dev_pm_ops mxs_mmc_pm_ops = {
 static struct platform_driver mxs_mmc_driver = {
        .probe          = mxs_mmc_probe,
        .remove         = mxs_mmc_remove,
-       .id_table       = mxs_mmc_ids,
+       .id_table       = mxs_ssp_ids,
        .driver         = {
                .name   = DRIVER_NAME,
                .owner  = THIS_MODULE,