mmc: spi: Pull out parts shared between MMC and SPI

Abstract out the common part of private data shared between MMC
and SPI. These shall later allow to use common clock configuration
function.

Signed-off-by: Marek Vasut <marex@denx.de>
Acked-by: Chris Ball <cjb@laptop.org>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index e80c2b6..7b85e03 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -62,23 +62,20 @@
 #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_ssp_id			devid;
 	unsigned char			bus_width;
 	spinlock_t			lock;
 	int				sdio_irq_en;
@@ -105,16 +102,18 @@
 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) |
@@ -130,15 +129,15 @@
 	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,
@@ -149,15 +148,16 @@
 	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));
 		}
 	}
 
@@ -196,13 +196,14 @@
 	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);
 
 	if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
 		mmc_signal_sdio_irq(host->mmc);
@@ -366,6 +367,8 @@
 	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;
 
@@ -408,15 +411,15 @@
 		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) ||
@@ -431,11 +434,11 @@
 	}
 
 	/* 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;
@@ -500,11 +503,12 @@
 
 static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
 {
+	struct mxs_ssp *ssp = &host->ssp;
 	unsigned int ssp_clk, ssp_sck;
 	u32 clock_divide, clock_rate;
 	u32 val;
 
-	ssp_clk = clk_get_rate(host->clk);
+	ssp_clk = clk_get_rate(ssp->clk);
 
 	for (clock_divide = 2; clock_divide <= 254; clock_divide += 2) {
 		clock_rate = DIV_ROUND_UP(ssp_clk, rate * clock_divide);
@@ -521,13 +525,13 @@
 
 	ssp_sck = ssp_clk / clock_divide / (1 + clock_rate);
 
-	val = readl(host->base + HW_SSP_TIMING(host));
+	val = readl(ssp->base + HW_SSP_TIMING(ssp));
 	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));
+	writel(val, ssp->base + HW_SSP_TIMING(ssp));
 
-	host->clk_rate = ssp_sck;
+	ssp->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",
@@ -552,6 +556,7 @@
 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);
@@ -560,19 +565,19 @@
 
 	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);
+		       ssp->base + HW_SSP_CTRL1(ssp) + STMP_OFFSET_REG_SET);
 
-		if (readl(host->base + HW_SSP_STATUS(host)) &
+		if (readl(ssp->base + HW_SSP_STATUS(ssp)) &
 				BM_SSP_STATUS_SDIO_IRQ)
 			mmc_signal_sdio_irq(host->mmc);
 
 	} 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);
@@ -635,6 +640,7 @@
 	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);
@@ -648,14 +654,16 @@
 		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_ssp_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.
@@ -668,7 +676,7 @@
 			goto out_mmc_free;
 		}
 	} else {
-		host->devid = pdev->id_entry->driver_data;
+		ssp->devid = pdev->id_entry->driver_data;
 		host->dma_channel = dmares->start;
 	}
 
@@ -691,12 +699,12 @@
 		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);
 
@@ -741,8 +749,8 @@
 
 	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_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(host->dmach->device->dev);
 
 	platform_set_drvdata(pdev, mmc);
@@ -766,8 +774,8 @@
 	if (host->dmach)
 		dma_release_channel(host->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;
@@ -777,6 +785,7 @@
 {
 	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);
 
@@ -785,8 +794,8 @@
 	if (host->dmach)
 		dma_release_channel(host->dmach);
 
-	clk_disable_unprepare(host->clk);
-	clk_put(host->clk);
+	clk_disable_unprepare(ssp->clk);
+	clk_put(ssp->clk);
 
 	mmc_free_host(mmc);
 
@@ -798,11 +807,12 @@
 {
 	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;
 }
@@ -811,9 +821,10 @@
 {
 	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);
 
diff --git a/include/linux/spi/mxs-spi.h b/include/linux/spi/mxs-spi.h
index 7dfa1d7..475f69f 100644
--- a/include/linux/spi/mxs-spi.h
+++ b/include/linux/spi/mxs-spi.h
@@ -128,4 +128,12 @@
 	IMX28_SSP,
 };
 
+struct mxs_ssp {
+	struct device			*dev;
+	void __iomem			*base;
+	struct clk			*clk;
+	unsigned int			clk_rate;
+	enum mxs_ssp_id			devid;
+};
+
 #endif	/* __LINUX_SPI_MXS_SPI_H__ */