All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-14  2:32   ` Shawn Guo
@ 2011-02-13 19:26     ` Chris Ball
  -1 siblings, 0 replies; 64+ messages in thread
From: Chris Ball @ 2011-02-13 19:26 UTC (permalink / raw)
  To: Shawn Guo; +Cc: s.hauer, arnd, LW, linux-mmc, linux-arm-kernel

Hi Shawn,

On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
> The driver calls into mxs-dma via generic dmaengine api for both pio
> and data transfer.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>

Please add a Reviewed-by: from Arnd and a Tested-by: from Lothar.
Could you add a MODULE_AUTHOR() field, too?

I could take the drivers/mmc files through the MMC tree and have you
submit the architecture patches separately, or you can send everything
through an ARM tree with my ACK -- whichever you prefer.

Here's an indentation patch:

diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index f359093..3a609f9 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -127,13 +127,13 @@
 #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_DATA_TIMEOUT_IRQ	| \
-				BM_SSP_CTRL1_DATA_CRC_IRQ	| \
-				BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ	| \
-				BM_SSP_CTRL1_RECV_TIMEOUT_IRQ   | \
-				BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
+				 BM_SSP_CTRL1_RESP_ERR_IRQ	| \
+				 BM_SSP_CTRL1_RESP_TIMEOUT_IRQ	| \
+				 BM_SSP_CTRL1_DATA_TIMEOUT_IRQ	| \
+				 BM_SSP_CTRL1_DATA_CRC_IRQ	| \
+				 BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ	| \
+				 BM_SSP_CTRL1_RECV_TIMEOUT_IRQ  | \
+				 BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
 
 #define SSP_PIO_NUM	3
 
@@ -165,7 +165,7 @@ static int mxs_mmc_get_ro(struct mmc_host *mmc)
 {
 	struct mxs_mmc_host *host = mmc_priv(mmc);
 	struct mxs_mmc_platform_data *pdata =
-			mmc_dev(host->mmc)->platform_data;
+		mmc_dev(host->mmc)->platform_data;
 
 	if (!pdata)
 		return -EFAULT;
@@ -181,7 +181,7 @@ static int mxs_mmc_get_cd(struct mmc_host *mmc)
 	struct mxs_mmc_host *host = mmc_priv(mmc);
 
 	return !(readl(host->base + HW_SSP_STATUS) &
-			BM_SSP_STATUS_CARD_DETECT);
+		 BM_SSP_STATUS_CARD_DETECT);
 }
 
 static void mxs_mmc_reset(struct mxs_mmc_host *host)
@@ -202,21 +202,21 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
 		BM_SSP_CTRL1_RESP_ERR_IRQ_EN;
 
 	writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
-		     BF_SSP(2, TIMING_CLOCK_DIVIDE) |
-		     BF_SSP(0, TIMING_CLOCK_RATE),
-		     host->base + HW_SSP_TIMING);
+	       BF_SSP(2, TIMING_CLOCK_DIVIDE) |
+	       BF_SSP(0, TIMING_CLOCK_RATE),
+	       host->base + HW_SSP_TIMING);
 
 	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);
 }
 
 static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
-				struct mmc_command *cmd);
+			      struct mmc_command *cmd);
 
 static void mxs_mmc_request_done(struct mxs_mmc_host *host)
 {
@@ -240,13 +240,13 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
 		break;
 	default:
 		dev_warn(mmc_dev(host->mmc),
-			"%s: unsupported response type 0x%x\n",
-			__func__, mmc_resp_type(cmd));
+			 "%s: unsupported response type 0x%x\n",
+			 __func__, mmc_resp_type(cmd));
 	}
 
 	if (data) {
 		dma_unmap_sg(mmc_dev(host->mmc), data->sg,
-				data->sg_len, host->dma_dir);
+			     data->sg_len, host->dma_dir);
 		/*
 		 * If there was an error on any block, we mark all
 		 * data blocks as being in error.
@@ -285,7 +285,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
 
 	stat = readl(host->base + HW_SSP_CTRL1);
 	writel(stat & MXS_MMC_IRQ_BITS,
-		host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
+	       host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
 
 	if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
 		mmc_signal_sdio_irq(host->mmc);
@@ -299,7 +299,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
 
 	if (data) {
 		if (stat & (BM_SSP_CTRL1_DATA_TIMEOUT_IRQ |
-				BM_SSP_CTRL1_RECV_TIMEOUT_IRQ))
+			    BM_SSP_CTRL1_RECV_TIMEOUT_IRQ))
 			data->error = -ETIMEDOUT;
 		else if (stat & BM_SSP_CTRL1_DATA_CRC_IRQ)
 			data->error = -EILSEQ;
@@ -313,7 +313,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 int append)
+	struct mxs_mmc_host *host, unsigned int append)
 {
 	struct dma_async_tx_descriptor *desc;
 	struct mmc_data *data = host->data;
@@ -323,7 +323,7 @@ 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, host->dma_dir);
 		sgl = data->sg;
 		sg_len = data->sg_len;
 	} else {
@@ -340,7 +340,7 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
 	} else {
 		if (data)
 			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
-					data->sg_len, host->dma_dir);
+				     data->sg_len, host->dma_dir);
 	}
 
 	return desc;
@@ -374,7 +374,7 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host)
 
 out:
 	dev_warn(mmc_dev(host->mmc),
-		"%s: failed to prep dma\n", __func__);
+		 "%s: failed to prep dma\n", __func__);
 }
 
 static void mxs_mmc_ac(struct mxs_mmc_host *host)
@@ -413,7 +413,7 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host)
 
 out:
 	dev_warn(mmc_dev(host->mmc),
-		"%s: failed to prep dma\n", __func__);
+		 "%s: failed to prep dma\n", __func__);
 }
 
 static unsigned short mxs_ns_to_ssp_ticks(unsigned clock_rate, unsigned ns)
@@ -492,12 +492,12 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
 	} else {
 		writel(data_size, host->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);
+		       BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT),
+		       host->base + HW_SSP_BLOCK_SIZE);
 	}
 
 	if ((cmd->opcode == MMC_STOP_TRANSMISSION) ||
-			(cmd->opcode == SD_IO_RW_EXTENDED))
+	    (cmd->opcode == SD_IO_RW_EXTENDED))
 		cmd0 |= BM_SSP_CMD0_APPEND_8CYC;
 
 	cmd1 = cmd->arg;
@@ -535,11 +535,11 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
 	return;
 out:
 	dev_warn(mmc_dev(host->mmc),
-		"%s: failed to prep dma\n", __func__);
+		 "%s: failed to prep dma\n", __func__);
 }
 
 static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
-				   struct mmc_command *cmd)
+			      struct mmc_command *cmd)
 {
 	host->cmd = cmd;
 
@@ -558,7 +558,7 @@ static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
 		break;
 	default:
 		dev_warn(mmc_dev(host->mmc),
-			"%s: unknown MMC command\n", __func__);
+			 "%s: unknown MMC command\n", __func__);
 		break;
 	}
 }
@@ -636,18 +636,18 @@ 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 + MXS_SET_ADDR);
+		       host->base + HW_SSP_CTRL0 + MXS_SET_ADDR);
 		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
-			host->base + HW_SSP_CTRL1 + MXS_SET_ADDR);
+		       host->base + HW_SSP_CTRL1 + MXS_SET_ADDR);
 
 		if (readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ)
 			mmc_signal_sdio_irq(host->mmc);
 
 	} else {
 		writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
-			host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR);
+		       host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR);
 		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
-			host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
+		       host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
 	}
 
 	spin_unlock_irqrestore(&host->lock, flags);
@@ -710,7 +710,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
 
 	/* only major verion does matter */
 	host->version = readl(host->base + HW_SSP_VERSION) >>
-				BP_SSP_VERSION_MAJOR;
+			BP_SSP_VERSION_MAJOR;
 
 	host->mmc = mmc;
 	host->res = r;
@@ -755,8 +755,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, mmc);
 
-	ret = request_irq(host->irq, mxs_mmc_irq_handler, 0,
-				DRIVER_NAME, host);
+	ret = request_irq(host->irq, mxs_mmc_irq_handler, 0, DRIVER_NAME, host);
 	if (ret)
 		goto out_free_dma;
 
-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-13 19:26     ` Chris Ball
  0 siblings, 0 replies; 64+ messages in thread
From: Chris Ball @ 2011-02-13 19:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Shawn,

On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
> The driver calls into mxs-dma via generic dmaengine api for both pio
> and data transfer.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>

Please add a Reviewed-by: from Arnd and a Tested-by: from Lothar.
Could you add a MODULE_AUTHOR() field, too?

I could take the drivers/mmc files through the MMC tree and have you
submit the architecture patches separately, or you can send everything
through an ARM tree with my ACK -- whichever you prefer.

Here's an indentation patch:

diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index f359093..3a609f9 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -127,13 +127,13 @@
 #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_DATA_TIMEOUT_IRQ	| \
-				BM_SSP_CTRL1_DATA_CRC_IRQ	| \
-				BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ	| \
-				BM_SSP_CTRL1_RECV_TIMEOUT_IRQ   | \
-				BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
+				 BM_SSP_CTRL1_RESP_ERR_IRQ	| \
+				 BM_SSP_CTRL1_RESP_TIMEOUT_IRQ	| \
+				 BM_SSP_CTRL1_DATA_TIMEOUT_IRQ	| \
+				 BM_SSP_CTRL1_DATA_CRC_IRQ	| \
+				 BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ	| \
+				 BM_SSP_CTRL1_RECV_TIMEOUT_IRQ  | \
+				 BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
 
 #define SSP_PIO_NUM	3
 
@@ -165,7 +165,7 @@ static int mxs_mmc_get_ro(struct mmc_host *mmc)
 {
 	struct mxs_mmc_host *host = mmc_priv(mmc);
 	struct mxs_mmc_platform_data *pdata =
-			mmc_dev(host->mmc)->platform_data;
+		mmc_dev(host->mmc)->platform_data;
 
 	if (!pdata)
 		return -EFAULT;
@@ -181,7 +181,7 @@ static int mxs_mmc_get_cd(struct mmc_host *mmc)
 	struct mxs_mmc_host *host = mmc_priv(mmc);
 
 	return !(readl(host->base + HW_SSP_STATUS) &
-			BM_SSP_STATUS_CARD_DETECT);
+		 BM_SSP_STATUS_CARD_DETECT);
 }
 
 static void mxs_mmc_reset(struct mxs_mmc_host *host)
@@ -202,21 +202,21 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
 		BM_SSP_CTRL1_RESP_ERR_IRQ_EN;
 
 	writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
-		     BF_SSP(2, TIMING_CLOCK_DIVIDE) |
-		     BF_SSP(0, TIMING_CLOCK_RATE),
-		     host->base + HW_SSP_TIMING);
+	       BF_SSP(2, TIMING_CLOCK_DIVIDE) |
+	       BF_SSP(0, TIMING_CLOCK_RATE),
+	       host->base + HW_SSP_TIMING);
 
 	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);
 }
 
 static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
-				struct mmc_command *cmd);
+			      struct mmc_command *cmd);
 
 static void mxs_mmc_request_done(struct mxs_mmc_host *host)
 {
@@ -240,13 +240,13 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
 		break;
 	default:
 		dev_warn(mmc_dev(host->mmc),
-			"%s: unsupported response type 0x%x\n",
-			__func__, mmc_resp_type(cmd));
+			 "%s: unsupported response type 0x%x\n",
+			 __func__, mmc_resp_type(cmd));
 	}
 
 	if (data) {
 		dma_unmap_sg(mmc_dev(host->mmc), data->sg,
-				data->sg_len, host->dma_dir);
+			     data->sg_len, host->dma_dir);
 		/*
 		 * If there was an error on any block, we mark all
 		 * data blocks as being in error.
@@ -285,7 +285,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
 
 	stat = readl(host->base + HW_SSP_CTRL1);
 	writel(stat & MXS_MMC_IRQ_BITS,
-		host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
+	       host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
 
 	if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
 		mmc_signal_sdio_irq(host->mmc);
@@ -299,7 +299,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
 
 	if (data) {
 		if (stat & (BM_SSP_CTRL1_DATA_TIMEOUT_IRQ |
-				BM_SSP_CTRL1_RECV_TIMEOUT_IRQ))
+			    BM_SSP_CTRL1_RECV_TIMEOUT_IRQ))
 			data->error = -ETIMEDOUT;
 		else if (stat & BM_SSP_CTRL1_DATA_CRC_IRQ)
 			data->error = -EILSEQ;
@@ -313,7 +313,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 int append)
+	struct mxs_mmc_host *host, unsigned int append)
 {
 	struct dma_async_tx_descriptor *desc;
 	struct mmc_data *data = host->data;
@@ -323,7 +323,7 @@ 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, host->dma_dir);
 		sgl = data->sg;
 		sg_len = data->sg_len;
 	} else {
@@ -340,7 +340,7 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
 	} else {
 		if (data)
 			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
-					data->sg_len, host->dma_dir);
+				     data->sg_len, host->dma_dir);
 	}
 
 	return desc;
@@ -374,7 +374,7 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host)
 
 out:
 	dev_warn(mmc_dev(host->mmc),
-		"%s: failed to prep dma\n", __func__);
+		 "%s: failed to prep dma\n", __func__);
 }
 
 static void mxs_mmc_ac(struct mxs_mmc_host *host)
@@ -413,7 +413,7 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host)
 
 out:
 	dev_warn(mmc_dev(host->mmc),
-		"%s: failed to prep dma\n", __func__);
+		 "%s: failed to prep dma\n", __func__);
 }
 
 static unsigned short mxs_ns_to_ssp_ticks(unsigned clock_rate, unsigned ns)
@@ -492,12 +492,12 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
 	} else {
 		writel(data_size, host->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);
+		       BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT),
+		       host->base + HW_SSP_BLOCK_SIZE);
 	}
 
 	if ((cmd->opcode == MMC_STOP_TRANSMISSION) ||
-			(cmd->opcode == SD_IO_RW_EXTENDED))
+	    (cmd->opcode == SD_IO_RW_EXTENDED))
 		cmd0 |= BM_SSP_CMD0_APPEND_8CYC;
 
 	cmd1 = cmd->arg;
@@ -535,11 +535,11 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
 	return;
 out:
 	dev_warn(mmc_dev(host->mmc),
-		"%s: failed to prep dma\n", __func__);
+		 "%s: failed to prep dma\n", __func__);
 }
 
 static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
-				   struct mmc_command *cmd)
+			      struct mmc_command *cmd)
 {
 	host->cmd = cmd;
 
@@ -558,7 +558,7 @@ static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
 		break;
 	default:
 		dev_warn(mmc_dev(host->mmc),
-			"%s: unknown MMC command\n", __func__);
+			 "%s: unknown MMC command\n", __func__);
 		break;
 	}
 }
@@ -636,18 +636,18 @@ 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 + MXS_SET_ADDR);
+		       host->base + HW_SSP_CTRL0 + MXS_SET_ADDR);
 		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
-			host->base + HW_SSP_CTRL1 + MXS_SET_ADDR);
+		       host->base + HW_SSP_CTRL1 + MXS_SET_ADDR);
 
 		if (readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ)
 			mmc_signal_sdio_irq(host->mmc);
 
 	} else {
 		writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
-			host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR);
+		       host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR);
 		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
-			host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
+		       host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
 	}
 
 	spin_unlock_irqrestore(&host->lock, flags);
@@ -710,7 +710,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
 
 	/* only major verion does matter */
 	host->version = readl(host->base + HW_SSP_VERSION) >>
-				BP_SSP_VERSION_MAJOR;
+			BP_SSP_VERSION_MAJOR;
 
 	host->mmc = mmc;
 	host->res = r;
@@ -755,8 +755,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, mmc);
 
-	ret = request_irq(host->irq, mxs_mmc_irq_handler, 0,
-				DRIVER_NAME, host);
+	ret = request_irq(host->irq, mxs_mmc_irq_handler, 0, DRIVER_NAME, host);
 	if (ret)
 		goto out_free_dma;
 
-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-13 19:26     ` Chris Ball
@ 2011-02-13 22:35       ` Arnd Bergmann
  -1 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2011-02-13 22:35 UTC (permalink / raw)
  To: Chris Ball; +Cc: Shawn Guo, s.hauer, LW, linux-mmc, linux-arm-kernel

On Sunday 13 February 2011, Chris Ball wrote:
> On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> > This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
> > The driver calls into mxs-dma via generic dmaengine api for both pio
> > and data transfer.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> 
> Please add a Reviewed-by: from Arnd and a Tested-by: from Lothar.
> Could you add a MODULE_AUTHOR() field, too?

In general, these tags should not simply be added by the author without
having the person who did the reviewing or testing specifically provide
them!

In this particular case, I'm happy with the driver in version 2, good job!
Please do add my

Reviewed-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-13 22:35       ` Arnd Bergmann
  0 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2011-02-13 22:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Sunday 13 February 2011, Chris Ball wrote:
> On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> > This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
> > The driver calls into mxs-dma via generic dmaengine api for both pio
> > and data transfer.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> 
> Please add a Reviewed-by: from Arnd and a Tested-by: from Lothar.
> Could you add a MODULE_AUTHOR() field, too?

In general, these tags should not simply be added by the author without
having the person who did the reviewing or testing specifically provide
them!

In this particular case, I'm happy with the driver in version 2, good job!
Please do add my

Reviewed-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-13 22:35       ` Arnd Bergmann
@ 2011-02-14  0:25         ` Chris Ball
  -1 siblings, 0 replies; 64+ messages in thread
From: Chris Ball @ 2011-02-14  0:25 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: Shawn Guo, s.hauer, LW, linux-mmc, linux-arm-kernel

Hi Arnd,

On Sun, Feb 13, 2011 at 11:35:54PM +0100, Arnd Bergmann wrote:
> > Please add a Reviewed-by: from Arnd and a Tested-by: from Lothar.
> > Could you add a MODULE_AUTHOR() field, too?
> 
> In general, these tags should not simply be added by the author without
> having the person who did the reviewing or testing specifically provide
> them!
> 
> In this particular case, I'm happy with the driver in version 2, good job!
> Please do add my
> 
> Reviewed-by: Arnd Bergmann <arnd@arndb.de>

Ah, okay, sorry.  I do behave that way with S-o-b, but in this case I
wanted to make sure people who put effort into reviewing/testing didn't
go uncredited -- next time I'll send mail to the reviewer/tester
reminding them to add a tag if they're happy.

Thanks,

-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-14  0:25         ` Chris Ball
  0 siblings, 0 replies; 64+ messages in thread
From: Chris Ball @ 2011-02-14  0:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,

On Sun, Feb 13, 2011 at 11:35:54PM +0100, Arnd Bergmann wrote:
> > Please add a Reviewed-by: from Arnd and a Tested-by: from Lothar.
> > Could you add a MODULE_AUTHOR() field, too?
> 
> In general, these tags should not simply be added by the author without
> having the person who did the reviewing or testing specifically provide
> them!
> 
> In this particular case, I'm happy with the driver in version 2, good job!
> Please do add my
> 
> Reviewed-by: Arnd Bergmann <arnd@arndb.de>

Ah, okay, sorry.  I do behave that way with S-o-b, but in this case I
wanted to make sure people who put effort into reviewing/testing didn't
go uncredited -- next time I'll send mail to the reviewer/tester
reminding them to add a tag if they're happy.

Thanks,

-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 0/7] Add mmc driver for i.MX23/28
@ 2011-02-14  2:32 ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel

The v2 is to address the comments given by Arnd and Lothar on v1.
It also passes mmc host test driver (MMC_TEST).

Thanks for review.

Regards,
Shawn


^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 0/7] Add mmc driver for i.MX23/28
@ 2011-02-14  2:32 ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: linux-arm-kernel

The v2 is to address the comments given by Arnd and Lothar on v1.
It also passes mmc host test driver (MMC_TEST).

Thanks for review.

Regards,
Shawn

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-14  2:32 ` Shawn Guo
@ 2011-02-14  2:32   ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel; +Cc: Shawn Guo

This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
The driver calls into mxs-dma via generic dmaengine api for both pio
and data transfer.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/include/mach/mmc.h |   15 +
 drivers/mmc/host/Kconfig             |    9 +
 drivers/mmc/host/Makefile            |    1 +
 drivers/mmc/host/mxs-mmc.c           |  876 ++++++++++++++++++++++++++++++++++
 4 files changed, 901 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/mmc.h
 create mode 100644 drivers/mmc/host/mxs-mmc.c

diff --git a/arch/arm/mach-mxs/include/mach/mmc.h b/arch/arm/mach-mxs/include/mach/mmc.h
new file mode 100644
index 0000000..42a1842
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mmc.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_MMC_H__
+#define __MACH_MXS_MMC_H__
+
+struct mxs_mmc_platform_data {
+	int wp_gpio;	/* write protect pin */
+};
+#endif /* __MACH_MXS_MMC_H__ */
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index afe8c6f..42a9e21 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -319,6 +319,15 @@ config MMC_MXC
 
 	  If unsure, say N.
 
+config MMC_MXS
+	tristate "Freescale MXS Multimedia Card Interface support"
+	depends on ARCH_MXS
+	help
+	  This selects the Freescale SSP MMC controller found on MXS based
+	  platforms like mx23/28.
+
+	  If unsure, say N.
+
 config MMC_TIFM_SD
 	tristate "TI Flash Media MMC/SD Interface support  (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index e834fb2..30aa686 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_MMC_ARMMMCI)	+= mmci.o
 obj-$(CONFIG_MMC_PXA)		+= pxamci.o
 obj-$(CONFIG_MMC_IMX)		+= imxmmc.o
 obj-$(CONFIG_MMC_MXC)		+= mxcmmc.o
+obj-$(CONFIG_MMC_MXS)		+= mxs-mmc.o
 obj-$(CONFIG_MMC_SDHCI)		+= sdhci.o
 obj-$(CONFIG_MMC_SDHCI_PCI)	+= sdhci-pci.o
 obj-$(CONFIG_MMC_SDHCI_PXA)	+= sdhci-pxa.o
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
new file mode 100644
index 0000000..f359093
--- /dev/null
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -0,0 +1,876 @@
+/*
+ * Portions copyright (C) 2003 Russell King, PXA MMCI Driver
+ * Portions copyright (C) 2004-2005 Pierre Ossman, W83L51xD SD/MMC driver
+ *
+ * Copyright 2008 Embedded Alley Solutions, Inc.
+ * Copyright 2009-2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/highmem.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/completion.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sdio.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/mxs.h>
+#include <mach/common.h>
+#include <mach/dma.h>
+#include <mach/mmc.h>
+
+#define DRIVER_NAME	"mxs-mmc"
+
+/* card detect polling timeout */
+#define MXS_MMC_DETECT_TIMEOUT			(HZ/2)
+
+#define SSP_VERSION_LATEST	4
+#define ssp_is_old()		(host->version < SSP_VERSION_LATEST)
+
+/* 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				(ssp_is_old() ? 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				(ssp_is_old() ? 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				(ssp_is_old() ? 0x080 : 0x0a0)
+#define HW_SSP_SDRESP1				(ssp_is_old() ? 0x090 : 0x0b0)
+#define HW_SSP_SDRESP2				(ssp_is_old() ? 0x0a0 : 0x0c0)
+#define HW_SSP_SDRESP3				(ssp_is_old() ? 0x0b0 : 0x0d0)
+#define HW_SSP_STATUS				(ssp_is_old() ? 0x0c0 : 0x100)
+#define  BM_SSP_STATUS_CARD_DETECT		(1 << 28)
+#define  BM_SSP_STATUS_SDIO_IRQ			(1 << 17)
+#define HW_SSP_VERSION				(cpu_is_mx23() ? 0x110 : 0x130)
+#define  BP_SSP_VERSION_MAJOR			(24)
+
+#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_DATA_TIMEOUT_IRQ	| \
+				BM_SSP_CTRL1_DATA_CRC_IRQ	| \
+				BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ	| \
+				BM_SSP_CTRL1_RECV_TIMEOUT_IRQ   | \
+				BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
+
+#define SSP_PIO_NUM	3
+
+struct mxs_mmc_host {
+	struct mmc_host			*mmc;
+	struct mmc_request		*mrq;
+	struct mmc_command		*cmd;
+	struct mmc_data			*data;
+
+	void __iomem			*base;
+	int				irq;
+	struct resource			*res;
+	struct resource			*dma_res;
+	struct clk			*clk;
+	unsigned int			clk_rate;
+
+	struct dma_chan         	*dmach;
+	struct mxs_dma_data		dma_data;
+	unsigned int			dma_dir;
+	u32				ssp_pio_words[SSP_PIO_NUM];
+
+	unsigned int			version;
+	unsigned char			bus_width;
+	spinlock_t			lock;
+	int				sdio_irq_en;
+};
+
+static int mxs_mmc_get_ro(struct mmc_host *mmc)
+{
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+	struct mxs_mmc_platform_data *pdata =
+			mmc_dev(host->mmc)->platform_data;
+
+	if (!pdata)
+		return -EFAULT;
+
+	if (!gpio_is_valid(pdata->wp_gpio))
+		return -EINVAL;
+
+	return gpio_get_value(pdata->wp_gpio);
+}
+
+static int mxs_mmc_get_cd(struct mmc_host *mmc)
+{
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+
+	return !(readl(host->base + HW_SSP_STATUS) &
+			BM_SSP_STATUS_CARD_DETECT);
+}
+
+static void mxs_mmc_reset(struct mxs_mmc_host *host)
+{
+	u32 ctrl0, ctrl1;
+
+	mxs_reset_block(host->base);
+
+	ctrl0 = BM_SSP_CTRL0_IGNORE_CRC;
+	ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) |
+		BF_SSP(0x7, CTRL1_WORD_LENGTH) |
+		BM_SSP_CTRL1_DMA_ENABLE |
+		BM_SSP_CTRL1_POLARITY |
+		BM_SSP_CTRL1_RECV_TIMEOUT_IRQ_EN |
+		BM_SSP_CTRL1_DATA_CRC_IRQ_EN |
+		BM_SSP_CTRL1_DATA_TIMEOUT_IRQ_EN |
+		BM_SSP_CTRL1_RESP_TIMEOUT_IRQ_EN |
+		BM_SSP_CTRL1_RESP_ERR_IRQ_EN;
+
+	writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
+		     BF_SSP(2, TIMING_CLOCK_DIVIDE) |
+		     BF_SSP(0, TIMING_CLOCK_RATE),
+		     host->base + HW_SSP_TIMING);
+
+	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);
+}
+
+static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
+				struct mmc_command *cmd);
+
+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;
+
+	switch (mmc_resp_type(cmd)) {
+	case MMC_RSP_NONE:
+		break;
+	case MMC_RSP_R1:
+	case MMC_RSP_R1B:
+	case MMC_RSP_R3:
+		cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0);
+		break;
+	case MMC_RSP_R2:
+		cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0);
+		cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1);
+		cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2);
+		cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3);
+		break;
+	default:
+		dev_warn(mmc_dev(host->mmc),
+			"%s: unsupported response type 0x%x\n",
+			__func__, mmc_resp_type(cmd));
+	}
+
+	if (data) {
+		dma_unmap_sg(mmc_dev(host->mmc), data->sg,
+				data->sg_len, host->dma_dir);
+		/*
+		 * If there was an error on any block, we mark all
+		 * data blocks as being in error.
+		 */
+		if (!data->error)
+			data->bytes_xfered = data->blocks * data->blksz;
+		else
+			data->bytes_xfered = 0;
+
+		host->data = NULL;
+		if (mrq->stop) {
+			mxs_mmc_start_cmd(host, mrq->stop);
+			return;
+		}
+	}
+
+	host->mrq = NULL;
+	mmc_request_done(host->mmc, mrq);
+}
+
+static void mxs_mmc_dma_irq_callback(void *param)
+{
+	struct mxs_mmc_host *host = param;
+
+	mxs_mmc_request_done(host);
+}
+
+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;
+	u32 stat;
+
+	spin_lock(&host->lock);
+
+	stat = readl(host->base + HW_SSP_CTRL1);
+	writel(stat & MXS_MMC_IRQ_BITS,
+		host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
+
+	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)
+		cmd->error = -EIO;
+
+	if (data) {
+		if (stat & (BM_SSP_CTRL1_DATA_TIMEOUT_IRQ |
+				BM_SSP_CTRL1_RECV_TIMEOUT_IRQ))
+			data->error = -ETIMEDOUT;
+		else if (stat & BM_SSP_CTRL1_DATA_CRC_IRQ)
+			data->error = -EILSEQ;
+		else if (stat & BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ)
+			data->error = -ENODATA;
+		else if (stat & BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
+			data->error = -EOVERFLOW;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
+		struct mxs_mmc_host *host, unsigned int append)
+{
+	struct dma_async_tx_descriptor *desc;
+	struct mmc_data *data = host->data;
+	struct scatterlist * sgl;
+	unsigned int sg_len;
+
+	if (data) {
+		/* data */
+		dma_map_sg(mmc_dev(host->mmc), data->sg,
+				data->sg_len, host->dma_dir);
+		sgl = data->sg;
+		sg_len = data->sg_len;
+	} else {
+		/* pio */
+		sgl = (struct scatterlist *) host->ssp_pio_words;
+		sg_len = SSP_PIO_NUM;
+	}
+
+	desc = host->dmach->device->device_prep_slave_sg(host->dmach,
+				sgl, sg_len, host->dma_dir, append);
+	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);
+	}
+
+	return desc;
+}
+
+static void mxs_mmc_bc(struct mxs_mmc_host *host)
+{
+	struct mmc_command *cmd = host->cmd;
+	struct dma_async_tx_descriptor *desc;
+	u32 ctrl0, cmd0, cmd1;
+
+	ctrl0 = BM_SSP_CTRL0_ENABLE | BM_SSP_CTRL0_IGNORE_CRC;
+	cmd0 = BF_SSP(cmd->opcode, CMD0_CMD) | BM_SSP_CMD0_APPEND_8CYC;
+	cmd1 = cmd->arg;
+
+	if (host->sdio_irq_en) {
+		ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
+		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;
+	desc = mxs_mmc_prep_dma(host, 0);
+	if (!desc)
+		goto out;
+
+	dmaengine_submit(desc);
+	return;
+
+out:
+	dev_warn(mmc_dev(host->mmc),
+		"%s: failed to prep dma\n", __func__);
+}
+
+static void mxs_mmc_ac(struct mxs_mmc_host *host)
+{
+	struct mmc_command *cmd = host->cmd;
+	struct dma_async_tx_descriptor *desc;
+	u32 ignore_crc, get_resp, long_resp;
+	u32 ctrl0, cmd0, cmd1;
+
+	ignore_crc = (mmc_resp_type(cmd) & MMC_RSP_CRC) ?
+			0 : BM_SSP_CTRL0_IGNORE_CRC;
+	get_resp = (mmc_resp_type(cmd) & MMC_RSP_PRESENT) ?
+			BM_SSP_CTRL0_GET_RESP : 0;
+	long_resp = (mmc_resp_type(cmd) & MMC_RSP_136) ?
+			BM_SSP_CTRL0_LONG_RESP : 0;
+
+	ctrl0 = BM_SSP_CTRL0_ENABLE | ignore_crc | get_resp | long_resp;
+	cmd0 = BF_SSP(cmd->opcode, CMD0_CMD);
+	cmd1 = cmd->arg;
+
+	if (host->sdio_irq_en) {
+		ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
+		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;
+	desc = mxs_mmc_prep_dma(host, 0);
+	if (!desc)
+		goto out;
+
+	dmaengine_submit(desc);
+	return;
+
+out:
+	dev_warn(mmc_dev(host->mmc),
+		"%s: failed to prep dma\n", __func__);
+}
+
+static unsigned short mxs_ns_to_ssp_ticks(unsigned clock_rate, unsigned ns)
+{
+	const unsigned int ssp_timeout_mul = 4096;
+	/*
+	 * Calculate ticks in ms since ns are large numbers
+	 * and might overflow
+	 */
+	const unsigned int clock_per_ms = clock_rate / 1000;
+	const unsigned int ms = ns / 1000;
+	const unsigned int ticks = ms * clock_per_ms;
+	const unsigned int ssp_ticks = ticks / ssp_timeout_mul;
+
+	WARN_ON(ssp_ticks == 0);
+	return ssp_ticks;
+}
+
+static void mxs_mmc_adtc(struct mxs_mmc_host *host)
+{
+	struct mmc_command *cmd = host->cmd;
+	struct mmc_data *data = cmd->data;
+	struct dma_async_tx_descriptor *desc;
+	struct scatterlist *sgl = data->sg, *sg;
+	unsigned int sg_len = data->sg_len;
+	int i;
+
+	unsigned short dma_data_dir, timeout;
+	unsigned int data_size = 0, log2_blksz;
+	unsigned int blocks = data->blocks;
+
+	u32 ignore_crc, get_resp, long_resp, read;
+	u32 ctrl0, cmd0, cmd1, val;
+
+	ignore_crc = (mmc_resp_type(cmd) & MMC_RSP_CRC) ?
+			0 : BM_SSP_CTRL0_IGNORE_CRC;
+	get_resp = (mmc_resp_type(cmd) & MMC_RSP_PRESENT) ?
+			BM_SSP_CTRL0_GET_RESP : 0;
+	long_resp = (mmc_resp_type(cmd) & MMC_RSP_136) ?
+			BM_SSP_CTRL0_LONG_RESP : 0;
+
+	if (data->flags & MMC_DATA_WRITE) {
+		dma_data_dir = DMA_TO_DEVICE;
+		read = 0;
+	} else {
+		dma_data_dir = DMA_FROM_DEVICE;
+		read = BM_SSP_CTRL0_READ;
+	}
+
+	ctrl0 = BF_SSP(host->bus_width, CTRL0_BUS_WIDTH) |
+		ignore_crc | get_resp | long_resp |
+		BM_SSP_CTRL0_DATA_XFER | read |
+		BM_SSP_CTRL0_WAIT_FOR_IRQ |
+		BM_SSP_CTRL0_ENABLE;
+
+	cmd0 = BF_SSP(cmd->opcode, CMD0_CMD);
+
+	/* get logarithm to base 2 of block size for setting register */
+	log2_blksz = ilog2(data->blksz);
+
+	/*
+	 * take special care of the case that data size from data->sg
+	 * is not equal to blocks x blksz
+	 */
+	for_each_sg(sgl, sg, sg_len, i)
+		data_size += sg->length;
+
+	if (data_size != data->blocks * data->blksz)
+		blocks = 1;
+
+	/* xfer count, block size and count need to be set differently */
+	if (ssp_is_old()) {
+		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(BF_SSP(log2_blksz, BLOCK_SIZE_BLOCK_SIZE) |
+			BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT),
+			host->base + HW_SSP_BLOCK_SIZE);
+	}
+
+	if ((cmd->opcode == MMC_STOP_TRANSMISSION) ||
+			(cmd->opcode == SD_IO_RW_EXTENDED))
+		cmd0 |= BM_SSP_CMD0_APPEND_8CYC;
+
+	cmd1 = cmd->arg;
+
+	if (host->sdio_irq_en) {
+		ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
+		cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN;
+	}
+
+	/* set the timeout count */
+	timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns);
+	val = readl(host->base + HW_SSP_TIMING);
+	val &= ~(BM_SSP_TIMING_TIMEOUT);
+	val |= BF_SSP(timeout, TIMING_TIMEOUT);
+	writel(val, host->base + HW_SSP_TIMING);
+
+	/* pio */
+	host->ssp_pio_words[0] = ctrl0;
+	host->ssp_pio_words[1] = cmd0;
+	host->ssp_pio_words[2] = cmd1;
+	host->dma_dir = DMA_NONE;
+	desc = mxs_mmc_prep_dma(host, 0);
+	if (!desc)
+		goto out;
+
+	/* append data sg */
+	WARN_ON(host->data != NULL);
+	host->data = data;
+	host->dma_dir = dma_data_dir;
+	desc = mxs_mmc_prep_dma(host, 1);
+	if (!desc)
+		goto out;
+
+	dmaengine_submit(desc);
+	return;
+out:
+	dev_warn(mmc_dev(host->mmc),
+		"%s: failed to prep dma\n", __func__);
+}
+
+static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
+				   struct mmc_command *cmd)
+{
+	host->cmd = cmd;
+
+	switch (mmc_cmd_type(cmd)) {
+	case MMC_CMD_BC:
+		mxs_mmc_bc(host);
+		break;
+	case MMC_CMD_BCR:
+		mxs_mmc_ac(host);
+		break;
+	case MMC_CMD_AC:
+		mxs_mmc_ac(host);
+		break;
+	case MMC_CMD_ADTC:
+		mxs_mmc_adtc(host);
+		break;
+	default:
+		dev_warn(mmc_dev(host->mmc),
+			"%s: unknown MMC command\n", __func__);
+		break;
+	}
+}
+
+static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+
+	WARN_ON(host->mrq != NULL);
+	host->mrq = 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_rate, bit_rate;
+	u32 div1, div2;
+	u32 val;
+
+	ssp_rate = clk_get_rate(host->clk);
+
+	for (div1 = 2; div1 < 254; div1 += 2) {
+		div2 = ssp_rate / rate / div1;
+		if (div2 < 0x100)
+			break;
+	}
+
+	if (div1 >= 254) {
+		dev_err(mmc_dev(host->mmc),
+			"%s: cannot set clock to %d\n", __func__, rate);
+		return;
+	}
+
+	if (div2 == 0)
+		bit_rate = ssp_rate / div1;
+	else
+		bit_rate = ssp_rate / div1 / div2;
+
+	val = readl(host->base + HW_SSP_TIMING);
+	val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
+	val |= BF_SSP(div1, TIMING_CLOCK_DIVIDE);
+	val |= BF_SSP(div2 - 1, TIMING_CLOCK_RATE);
+	writel(val, host->base + HW_SSP_TIMING);
+
+	host->clk_rate = bit_rate;
+
+	dev_dbg(mmc_dev(host->mmc),
+		"%s: div1 %d, div2 %d, ssp %d, bit %d, rate %d\n",
+		__func__, div1, div2, ssp_rate, bit_rate, rate);
+}
+
+static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+
+	if (ios->bus_width == MMC_BUS_WIDTH_8)
+		host->bus_width = 2;
+	else if (ios->bus_width == MMC_BUS_WIDTH_4)
+		host->bus_width = 1;
+	else
+		host->bus_width = 0;
+
+	if (ios->clock)
+		mxs_mmc_set_clk_rate(host, ios->clock);
+}
+
+static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	host->sdio_irq_en = enable;
+
+	if (enable) {
+		writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
+			host->base + HW_SSP_CTRL0 + MXS_SET_ADDR);
+		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
+			host->base + HW_SSP_CTRL1 + MXS_SET_ADDR);
+
+		if (readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ)
+			mmc_signal_sdio_irq(host->mmc);
+
+	} else {
+		writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
+			host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR);
+		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
+			host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
+	}
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static const struct mmc_host_ops mxs_mmc_ops = {
+	.request = mxs_mmc_request,
+	.get_ro = mxs_mmc_get_ro,
+	.get_cd = mxs_mmc_get_cd,
+	.set_ios = mxs_mmc_set_ios,
+	.enable_sdio_irq = mxs_mmc_enable_sdio_irq,
+};
+
+static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
+{
+	struct mxs_mmc_host *host = param;
+
+	if (!mxs_dma_is_apbh(chan))
+		return false;
+
+	if (chan->chan_id != host->dma_res->start)
+		return false;
+
+	chan->private = &host->dma_data;
+
+	return true;
+}
+
+static int mxs_mmc_probe(struct platform_device *pdev)
+{
+	struct mxs_mmc_host *host;
+	struct mmc_host *mmc;
+	struct resource *iores, *dmares, *r;
+	int ret = 0, irq_err, irq_dma;
+	dma_cap_mask_t mask;
+
+	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+	irq_err = platform_get_irq(pdev, 0);
+	irq_dma = platform_get_irq(pdev, 1);
+	if (!iores || !dmares || irq_err < 0 || irq_dma < 0)
+		return -EINVAL;
+
+	r = request_mem_region(iores->start, resource_size(iores), pdev->name);
+	if (!r)
+		return -EBUSY;
+
+	mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev);
+	if (!mmc) {
+		ret = -ENOMEM;
+		goto out_release_mem;
+	}
+
+	host = mmc_priv(mmc);
+	host->base = ioremap(r->start, resource_size(r));
+	if (!host->base) {
+		ret = -ENOMEM;
+		goto out_mmc_free;
+	}
+
+	/* only major verion does matter */
+	host->version = readl(host->base + HW_SSP_VERSION) >>
+				BP_SSP_VERSION_MAJOR;
+
+	host->mmc = mmc;
+	host->res = r;
+	host->dma_res = dmares;
+	host->irq = irq_err;
+	host->sdio_irq_en = 0;
+
+	host->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(host->clk)) {
+		ret = PTR_ERR(host->clk);
+		goto out_iounmap;
+	}
+	clk_enable(host->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) {
+		dev_err(mmc_dev(host->mmc),
+			"%s: failed to request dma\n", __func__);
+		goto out_clk_put;
+	}
+
+	/* set mmc core parameters */
+	mmc->ops = &mxs_mmc_ops;
+	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |
+		    MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED |
+		    MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL;
+
+	mmc->f_min = 400000;
+	mmc->f_max = 288000000;
+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+	mmc->max_segs = 52;
+	mmc->max_blk_size = 1 << 0xf;
+	mmc->max_blk_count = (ssp_is_old()) ? 0xff : 0xffffff;
+	mmc->max_req_size = (ssp_is_old()) ? 0xffff : 0xffffffff;
+	mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev);
+
+	platform_set_drvdata(pdev, mmc);
+
+	ret = request_irq(host->irq, mxs_mmc_irq_handler, 0,
+				DRIVER_NAME, host);
+	if (ret)
+		goto out_free_dma;
+
+	spin_lock_init(&host->lock);
+
+	ret = mmc_add_host(mmc);
+	if (ret)
+		goto out_free_irq;
+
+	dev_info(mmc_dev(host->mmc), "initialized\n");
+
+	return 0;
+
+out_free_irq:
+	free_irq(host->irq, host);
+out_free_dma:
+	if (host->dmach)
+		dma_release_channel(host->dmach);
+out_clk_put:
+	clk_disable(host->clk);
+	clk_put(host->clk);
+out_iounmap:
+	iounmap(host->base);
+out_mmc_free:
+	mmc_free_host(mmc);
+out_release_mem:
+	release_mem_region(iores->start, resource_size(iores));
+	return ret;
+}
+
+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 resource *res = host->res;
+
+	mmc_remove_host(mmc);
+
+	free_irq(host->irq, host);
+
+	platform_set_drvdata(pdev, NULL);
+
+	if (host->dmach)
+		dma_release_channel(host->dmach);
+
+	clk_disable(host->clk);
+	clk_put(host->clk);
+
+	iounmap(host->base);
+
+	mmc_free_host(mmc);
+
+	release_mem_region(res->start, resource_size(res));
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int mxs_mmc_suspend(struct device *dev)
+{
+	struct mmc_host *mmc = dev_get_drvdata(dev);
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+	int ret = 0;
+
+	ret = mmc_suspend_host(mmc);
+
+	clk_disable(host->clk);
+
+	return ret;
+}
+
+static int mxs_mmc_resume(struct device *dev)
+{
+	struct mmc_host *mmc = dev_get_drvdata(dev);
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+	int ret = 0;
+
+	clk_enable(host->clk);
+
+	ret = mmc_resume_host(mmc);
+
+	return ret;
+}
+
+static const struct dev_pm_ops mxs_mmc_pm_ops = {
+	.suspend	= mxs_mmc_suspend,
+	.resume		= mxs_mmc_resume,
+};
+#endif
+
+static struct platform_driver mxs_mmc_driver = {
+	.probe		= mxs_mmc_probe,
+	.remove		= mxs_mmc_remove,
+	.driver		= {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &mxs_mmc_pm_ops,
+#endif
+	},
+};
+
+static int __init mxs_mmc_init(void)
+{
+	return platform_driver_register(&mxs_mmc_driver);
+}
+
+static void __exit mxs_mmc_exit(void)
+{
+	platform_driver_unregister(&mxs_mmc_driver);
+}
+
+module_init(mxs_mmc_init);
+module_exit(mxs_mmc_exit);
+
+MODULE_DESCRIPTION("FREESCALE MXS MMC peripheral");
+MODULE_LICENSE("GPL");
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-14  2:32   ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: linux-arm-kernel

This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
The driver calls into mxs-dma via generic dmaengine api for both pio
and data transfer.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/include/mach/mmc.h |   15 +
 drivers/mmc/host/Kconfig             |    9 +
 drivers/mmc/host/Makefile            |    1 +
 drivers/mmc/host/mxs-mmc.c           |  876 ++++++++++++++++++++++++++++++++++
 4 files changed, 901 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/mmc.h
 create mode 100644 drivers/mmc/host/mxs-mmc.c

diff --git a/arch/arm/mach-mxs/include/mach/mmc.h b/arch/arm/mach-mxs/include/mach/mmc.h
new file mode 100644
index 0000000..42a1842
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mmc.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_MMC_H__
+#define __MACH_MXS_MMC_H__
+
+struct mxs_mmc_platform_data {
+	int wp_gpio;	/* write protect pin */
+};
+#endif /* __MACH_MXS_MMC_H__ */
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index afe8c6f..42a9e21 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -319,6 +319,15 @@ config MMC_MXC
 
 	  If unsure, say N.
 
+config MMC_MXS
+	tristate "Freescale MXS Multimedia Card Interface support"
+	depends on ARCH_MXS
+	help
+	  This selects the Freescale SSP MMC controller found on MXS based
+	  platforms like mx23/28.
+
+	  If unsure, say N.
+
 config MMC_TIFM_SD
 	tristate "TI Flash Media MMC/SD Interface support  (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index e834fb2..30aa686 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_MMC_ARMMMCI)	+= mmci.o
 obj-$(CONFIG_MMC_PXA)		+= pxamci.o
 obj-$(CONFIG_MMC_IMX)		+= imxmmc.o
 obj-$(CONFIG_MMC_MXC)		+= mxcmmc.o
+obj-$(CONFIG_MMC_MXS)		+= mxs-mmc.o
 obj-$(CONFIG_MMC_SDHCI)		+= sdhci.o
 obj-$(CONFIG_MMC_SDHCI_PCI)	+= sdhci-pci.o
 obj-$(CONFIG_MMC_SDHCI_PXA)	+= sdhci-pxa.o
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
new file mode 100644
index 0000000..f359093
--- /dev/null
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -0,0 +1,876 @@
+/*
+ * Portions copyright (C) 2003 Russell King, PXA MMCI Driver
+ * Portions copyright (C) 2004-2005 Pierre Ossman, W83L51xD SD/MMC driver
+ *
+ * Copyright 2008 Embedded Alley Solutions, Inc.
+ * Copyright 2009-2011 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/highmem.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/completion.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sdio.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/mxs.h>
+#include <mach/common.h>
+#include <mach/dma.h>
+#include <mach/mmc.h>
+
+#define DRIVER_NAME	"mxs-mmc"
+
+/* card detect polling timeout */
+#define MXS_MMC_DETECT_TIMEOUT			(HZ/2)
+
+#define SSP_VERSION_LATEST	4
+#define ssp_is_old()		(host->version < SSP_VERSION_LATEST)
+
+/* 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				(ssp_is_old() ? 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				(ssp_is_old() ? 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				(ssp_is_old() ? 0x080 : 0x0a0)
+#define HW_SSP_SDRESP1				(ssp_is_old() ? 0x090 : 0x0b0)
+#define HW_SSP_SDRESP2				(ssp_is_old() ? 0x0a0 : 0x0c0)
+#define HW_SSP_SDRESP3				(ssp_is_old() ? 0x0b0 : 0x0d0)
+#define HW_SSP_STATUS				(ssp_is_old() ? 0x0c0 : 0x100)
+#define  BM_SSP_STATUS_CARD_DETECT		(1 << 28)
+#define  BM_SSP_STATUS_SDIO_IRQ			(1 << 17)
+#define HW_SSP_VERSION				(cpu_is_mx23() ? 0x110 : 0x130)
+#define  BP_SSP_VERSION_MAJOR			(24)
+
+#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_DATA_TIMEOUT_IRQ	| \
+				BM_SSP_CTRL1_DATA_CRC_IRQ	| \
+				BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ	| \
+				BM_SSP_CTRL1_RECV_TIMEOUT_IRQ   | \
+				BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
+
+#define SSP_PIO_NUM	3
+
+struct mxs_mmc_host {
+	struct mmc_host			*mmc;
+	struct mmc_request		*mrq;
+	struct mmc_command		*cmd;
+	struct mmc_data			*data;
+
+	void __iomem			*base;
+	int				irq;
+	struct resource			*res;
+	struct resource			*dma_res;
+	struct clk			*clk;
+	unsigned int			clk_rate;
+
+	struct dma_chan         	*dmach;
+	struct mxs_dma_data		dma_data;
+	unsigned int			dma_dir;
+	u32				ssp_pio_words[SSP_PIO_NUM];
+
+	unsigned int			version;
+	unsigned char			bus_width;
+	spinlock_t			lock;
+	int				sdio_irq_en;
+};
+
+static int mxs_mmc_get_ro(struct mmc_host *mmc)
+{
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+	struct mxs_mmc_platform_data *pdata =
+			mmc_dev(host->mmc)->platform_data;
+
+	if (!pdata)
+		return -EFAULT;
+
+	if (!gpio_is_valid(pdata->wp_gpio))
+		return -EINVAL;
+
+	return gpio_get_value(pdata->wp_gpio);
+}
+
+static int mxs_mmc_get_cd(struct mmc_host *mmc)
+{
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+
+	return !(readl(host->base + HW_SSP_STATUS) &
+			BM_SSP_STATUS_CARD_DETECT);
+}
+
+static void mxs_mmc_reset(struct mxs_mmc_host *host)
+{
+	u32 ctrl0, ctrl1;
+
+	mxs_reset_block(host->base);
+
+	ctrl0 = BM_SSP_CTRL0_IGNORE_CRC;
+	ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) |
+		BF_SSP(0x7, CTRL1_WORD_LENGTH) |
+		BM_SSP_CTRL1_DMA_ENABLE |
+		BM_SSP_CTRL1_POLARITY |
+		BM_SSP_CTRL1_RECV_TIMEOUT_IRQ_EN |
+		BM_SSP_CTRL1_DATA_CRC_IRQ_EN |
+		BM_SSP_CTRL1_DATA_TIMEOUT_IRQ_EN |
+		BM_SSP_CTRL1_RESP_TIMEOUT_IRQ_EN |
+		BM_SSP_CTRL1_RESP_ERR_IRQ_EN;
+
+	writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
+		     BF_SSP(2, TIMING_CLOCK_DIVIDE) |
+		     BF_SSP(0, TIMING_CLOCK_RATE),
+		     host->base + HW_SSP_TIMING);
+
+	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);
+}
+
+static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
+				struct mmc_command *cmd);
+
+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;
+
+	switch (mmc_resp_type(cmd)) {
+	case MMC_RSP_NONE:
+		break;
+	case MMC_RSP_R1:
+	case MMC_RSP_R1B:
+	case MMC_RSP_R3:
+		cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0);
+		break;
+	case MMC_RSP_R2:
+		cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0);
+		cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1);
+		cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2);
+		cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3);
+		break;
+	default:
+		dev_warn(mmc_dev(host->mmc),
+			"%s: unsupported response type 0x%x\n",
+			__func__, mmc_resp_type(cmd));
+	}
+
+	if (data) {
+		dma_unmap_sg(mmc_dev(host->mmc), data->sg,
+				data->sg_len, host->dma_dir);
+		/*
+		 * If there was an error on any block, we mark all
+		 * data blocks as being in error.
+		 */
+		if (!data->error)
+			data->bytes_xfered = data->blocks * data->blksz;
+		else
+			data->bytes_xfered = 0;
+
+		host->data = NULL;
+		if (mrq->stop) {
+			mxs_mmc_start_cmd(host, mrq->stop);
+			return;
+		}
+	}
+
+	host->mrq = NULL;
+	mmc_request_done(host->mmc, mrq);
+}
+
+static void mxs_mmc_dma_irq_callback(void *param)
+{
+	struct mxs_mmc_host *host = param;
+
+	mxs_mmc_request_done(host);
+}
+
+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;
+	u32 stat;
+
+	spin_lock(&host->lock);
+
+	stat = readl(host->base + HW_SSP_CTRL1);
+	writel(stat & MXS_MMC_IRQ_BITS,
+		host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
+
+	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)
+		cmd->error = -EIO;
+
+	if (data) {
+		if (stat & (BM_SSP_CTRL1_DATA_TIMEOUT_IRQ |
+				BM_SSP_CTRL1_RECV_TIMEOUT_IRQ))
+			data->error = -ETIMEDOUT;
+		else if (stat & BM_SSP_CTRL1_DATA_CRC_IRQ)
+			data->error = -EILSEQ;
+		else if (stat & BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ)
+			data->error = -ENODATA;
+		else if (stat & BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
+			data->error = -EOVERFLOW;
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
+		struct mxs_mmc_host *host, unsigned int append)
+{
+	struct dma_async_tx_descriptor *desc;
+	struct mmc_data *data = host->data;
+	struct scatterlist * sgl;
+	unsigned int sg_len;
+
+	if (data) {
+		/* data */
+		dma_map_sg(mmc_dev(host->mmc), data->sg,
+				data->sg_len, host->dma_dir);
+		sgl = data->sg;
+		sg_len = data->sg_len;
+	} else {
+		/* pio */
+		sgl = (struct scatterlist *) host->ssp_pio_words;
+		sg_len = SSP_PIO_NUM;
+	}
+
+	desc = host->dmach->device->device_prep_slave_sg(host->dmach,
+				sgl, sg_len, host->dma_dir, append);
+	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);
+	}
+
+	return desc;
+}
+
+static void mxs_mmc_bc(struct mxs_mmc_host *host)
+{
+	struct mmc_command *cmd = host->cmd;
+	struct dma_async_tx_descriptor *desc;
+	u32 ctrl0, cmd0, cmd1;
+
+	ctrl0 = BM_SSP_CTRL0_ENABLE | BM_SSP_CTRL0_IGNORE_CRC;
+	cmd0 = BF_SSP(cmd->opcode, CMD0_CMD) | BM_SSP_CMD0_APPEND_8CYC;
+	cmd1 = cmd->arg;
+
+	if (host->sdio_irq_en) {
+		ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
+		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;
+	desc = mxs_mmc_prep_dma(host, 0);
+	if (!desc)
+		goto out;
+
+	dmaengine_submit(desc);
+	return;
+
+out:
+	dev_warn(mmc_dev(host->mmc),
+		"%s: failed to prep dma\n", __func__);
+}
+
+static void mxs_mmc_ac(struct mxs_mmc_host *host)
+{
+	struct mmc_command *cmd = host->cmd;
+	struct dma_async_tx_descriptor *desc;
+	u32 ignore_crc, get_resp, long_resp;
+	u32 ctrl0, cmd0, cmd1;
+
+	ignore_crc = (mmc_resp_type(cmd) & MMC_RSP_CRC) ?
+			0 : BM_SSP_CTRL0_IGNORE_CRC;
+	get_resp = (mmc_resp_type(cmd) & MMC_RSP_PRESENT) ?
+			BM_SSP_CTRL0_GET_RESP : 0;
+	long_resp = (mmc_resp_type(cmd) & MMC_RSP_136) ?
+			BM_SSP_CTRL0_LONG_RESP : 0;
+
+	ctrl0 = BM_SSP_CTRL0_ENABLE | ignore_crc | get_resp | long_resp;
+	cmd0 = BF_SSP(cmd->opcode, CMD0_CMD);
+	cmd1 = cmd->arg;
+
+	if (host->sdio_irq_en) {
+		ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
+		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;
+	desc = mxs_mmc_prep_dma(host, 0);
+	if (!desc)
+		goto out;
+
+	dmaengine_submit(desc);
+	return;
+
+out:
+	dev_warn(mmc_dev(host->mmc),
+		"%s: failed to prep dma\n", __func__);
+}
+
+static unsigned short mxs_ns_to_ssp_ticks(unsigned clock_rate, unsigned ns)
+{
+	const unsigned int ssp_timeout_mul = 4096;
+	/*
+	 * Calculate ticks in ms since ns are large numbers
+	 * and might overflow
+	 */
+	const unsigned int clock_per_ms = clock_rate / 1000;
+	const unsigned int ms = ns / 1000;
+	const unsigned int ticks = ms * clock_per_ms;
+	const unsigned int ssp_ticks = ticks / ssp_timeout_mul;
+
+	WARN_ON(ssp_ticks == 0);
+	return ssp_ticks;
+}
+
+static void mxs_mmc_adtc(struct mxs_mmc_host *host)
+{
+	struct mmc_command *cmd = host->cmd;
+	struct mmc_data *data = cmd->data;
+	struct dma_async_tx_descriptor *desc;
+	struct scatterlist *sgl = data->sg, *sg;
+	unsigned int sg_len = data->sg_len;
+	int i;
+
+	unsigned short dma_data_dir, timeout;
+	unsigned int data_size = 0, log2_blksz;
+	unsigned int blocks = data->blocks;
+
+	u32 ignore_crc, get_resp, long_resp, read;
+	u32 ctrl0, cmd0, cmd1, val;
+
+	ignore_crc = (mmc_resp_type(cmd) & MMC_RSP_CRC) ?
+			0 : BM_SSP_CTRL0_IGNORE_CRC;
+	get_resp = (mmc_resp_type(cmd) & MMC_RSP_PRESENT) ?
+			BM_SSP_CTRL0_GET_RESP : 0;
+	long_resp = (mmc_resp_type(cmd) & MMC_RSP_136) ?
+			BM_SSP_CTRL0_LONG_RESP : 0;
+
+	if (data->flags & MMC_DATA_WRITE) {
+		dma_data_dir = DMA_TO_DEVICE;
+		read = 0;
+	} else {
+		dma_data_dir = DMA_FROM_DEVICE;
+		read = BM_SSP_CTRL0_READ;
+	}
+
+	ctrl0 = BF_SSP(host->bus_width, CTRL0_BUS_WIDTH) |
+		ignore_crc | get_resp | long_resp |
+		BM_SSP_CTRL0_DATA_XFER | read |
+		BM_SSP_CTRL0_WAIT_FOR_IRQ |
+		BM_SSP_CTRL0_ENABLE;
+
+	cmd0 = BF_SSP(cmd->opcode, CMD0_CMD);
+
+	/* get logarithm to base 2 of block size for setting register */
+	log2_blksz = ilog2(data->blksz);
+
+	/*
+	 * take special care of the case that data size from data->sg
+	 * is not equal to blocks x blksz
+	 */
+	for_each_sg(sgl, sg, sg_len, i)
+		data_size += sg->length;
+
+	if (data_size != data->blocks * data->blksz)
+		blocks = 1;
+
+	/* xfer count, block size and count need to be set differently */
+	if (ssp_is_old()) {
+		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(BF_SSP(log2_blksz, BLOCK_SIZE_BLOCK_SIZE) |
+			BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT),
+			host->base + HW_SSP_BLOCK_SIZE);
+	}
+
+	if ((cmd->opcode == MMC_STOP_TRANSMISSION) ||
+			(cmd->opcode == SD_IO_RW_EXTENDED))
+		cmd0 |= BM_SSP_CMD0_APPEND_8CYC;
+
+	cmd1 = cmd->arg;
+
+	if (host->sdio_irq_en) {
+		ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
+		cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN;
+	}
+
+	/* set the timeout count */
+	timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns);
+	val = readl(host->base + HW_SSP_TIMING);
+	val &= ~(BM_SSP_TIMING_TIMEOUT);
+	val |= BF_SSP(timeout, TIMING_TIMEOUT);
+	writel(val, host->base + HW_SSP_TIMING);
+
+	/* pio */
+	host->ssp_pio_words[0] = ctrl0;
+	host->ssp_pio_words[1] = cmd0;
+	host->ssp_pio_words[2] = cmd1;
+	host->dma_dir = DMA_NONE;
+	desc = mxs_mmc_prep_dma(host, 0);
+	if (!desc)
+		goto out;
+
+	/* append data sg */
+	WARN_ON(host->data != NULL);
+	host->data = data;
+	host->dma_dir = dma_data_dir;
+	desc = mxs_mmc_prep_dma(host, 1);
+	if (!desc)
+		goto out;
+
+	dmaengine_submit(desc);
+	return;
+out:
+	dev_warn(mmc_dev(host->mmc),
+		"%s: failed to prep dma\n", __func__);
+}
+
+static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
+				   struct mmc_command *cmd)
+{
+	host->cmd = cmd;
+
+	switch (mmc_cmd_type(cmd)) {
+	case MMC_CMD_BC:
+		mxs_mmc_bc(host);
+		break;
+	case MMC_CMD_BCR:
+		mxs_mmc_ac(host);
+		break;
+	case MMC_CMD_AC:
+		mxs_mmc_ac(host);
+		break;
+	case MMC_CMD_ADTC:
+		mxs_mmc_adtc(host);
+		break;
+	default:
+		dev_warn(mmc_dev(host->mmc),
+			"%s: unknown MMC command\n", __func__);
+		break;
+	}
+}
+
+static void mxs_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+
+	WARN_ON(host->mrq != NULL);
+	host->mrq = 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_rate, bit_rate;
+	u32 div1, div2;
+	u32 val;
+
+	ssp_rate = clk_get_rate(host->clk);
+
+	for (div1 = 2; div1 < 254; div1 += 2) {
+		div2 = ssp_rate / rate / div1;
+		if (div2 < 0x100)
+			break;
+	}
+
+	if (div1 >= 254) {
+		dev_err(mmc_dev(host->mmc),
+			"%s: cannot set clock to %d\n", __func__, rate);
+		return;
+	}
+
+	if (div2 == 0)
+		bit_rate = ssp_rate / div1;
+	else
+		bit_rate = ssp_rate / div1 / div2;
+
+	val = readl(host->base + HW_SSP_TIMING);
+	val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
+	val |= BF_SSP(div1, TIMING_CLOCK_DIVIDE);
+	val |= BF_SSP(div2 - 1, TIMING_CLOCK_RATE);
+	writel(val, host->base + HW_SSP_TIMING);
+
+	host->clk_rate = bit_rate;
+
+	dev_dbg(mmc_dev(host->mmc),
+		"%s: div1 %d, div2 %d, ssp %d, bit %d, rate %d\n",
+		__func__, div1, div2, ssp_rate, bit_rate, rate);
+}
+
+static void mxs_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+
+	if (ios->bus_width == MMC_BUS_WIDTH_8)
+		host->bus_width = 2;
+	else if (ios->bus_width == MMC_BUS_WIDTH_4)
+		host->bus_width = 1;
+	else
+		host->bus_width = 0;
+
+	if (ios->clock)
+		mxs_mmc_set_clk_rate(host, ios->clock);
+}
+
+static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	host->sdio_irq_en = enable;
+
+	if (enable) {
+		writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
+			host->base + HW_SSP_CTRL0 + MXS_SET_ADDR);
+		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
+			host->base + HW_SSP_CTRL1 + MXS_SET_ADDR);
+
+		if (readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ)
+			mmc_signal_sdio_irq(host->mmc);
+
+	} else {
+		writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
+			host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR);
+		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
+			host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
+	}
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static const struct mmc_host_ops mxs_mmc_ops = {
+	.request = mxs_mmc_request,
+	.get_ro = mxs_mmc_get_ro,
+	.get_cd = mxs_mmc_get_cd,
+	.set_ios = mxs_mmc_set_ios,
+	.enable_sdio_irq = mxs_mmc_enable_sdio_irq,
+};
+
+static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
+{
+	struct mxs_mmc_host *host = param;
+
+	if (!mxs_dma_is_apbh(chan))
+		return false;
+
+	if (chan->chan_id != host->dma_res->start)
+		return false;
+
+	chan->private = &host->dma_data;
+
+	return true;
+}
+
+static int mxs_mmc_probe(struct platform_device *pdev)
+{
+	struct mxs_mmc_host *host;
+	struct mmc_host *mmc;
+	struct resource *iores, *dmares, *r;
+	int ret = 0, irq_err, irq_dma;
+	dma_cap_mask_t mask;
+
+	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+	irq_err = platform_get_irq(pdev, 0);
+	irq_dma = platform_get_irq(pdev, 1);
+	if (!iores || !dmares || irq_err < 0 || irq_dma < 0)
+		return -EINVAL;
+
+	r = request_mem_region(iores->start, resource_size(iores), pdev->name);
+	if (!r)
+		return -EBUSY;
+
+	mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev);
+	if (!mmc) {
+		ret = -ENOMEM;
+		goto out_release_mem;
+	}
+
+	host = mmc_priv(mmc);
+	host->base = ioremap(r->start, resource_size(r));
+	if (!host->base) {
+		ret = -ENOMEM;
+		goto out_mmc_free;
+	}
+
+	/* only major verion does matter */
+	host->version = readl(host->base + HW_SSP_VERSION) >>
+				BP_SSP_VERSION_MAJOR;
+
+	host->mmc = mmc;
+	host->res = r;
+	host->dma_res = dmares;
+	host->irq = irq_err;
+	host->sdio_irq_en = 0;
+
+	host->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(host->clk)) {
+		ret = PTR_ERR(host->clk);
+		goto out_iounmap;
+	}
+	clk_enable(host->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) {
+		dev_err(mmc_dev(host->mmc),
+			"%s: failed to request dma\n", __func__);
+		goto out_clk_put;
+	}
+
+	/* set mmc core parameters */
+	mmc->ops = &mxs_mmc_ops;
+	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |
+		    MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED |
+		    MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL;
+
+	mmc->f_min = 400000;
+	mmc->f_max = 288000000;
+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+	mmc->max_segs = 52;
+	mmc->max_blk_size = 1 << 0xf;
+	mmc->max_blk_count = (ssp_is_old()) ? 0xff : 0xffffff;
+	mmc->max_req_size = (ssp_is_old()) ? 0xffff : 0xffffffff;
+	mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev);
+
+	platform_set_drvdata(pdev, mmc);
+
+	ret = request_irq(host->irq, mxs_mmc_irq_handler, 0,
+				DRIVER_NAME, host);
+	if (ret)
+		goto out_free_dma;
+
+	spin_lock_init(&host->lock);
+
+	ret = mmc_add_host(mmc);
+	if (ret)
+		goto out_free_irq;
+
+	dev_info(mmc_dev(host->mmc), "initialized\n");
+
+	return 0;
+
+out_free_irq:
+	free_irq(host->irq, host);
+out_free_dma:
+	if (host->dmach)
+		dma_release_channel(host->dmach);
+out_clk_put:
+	clk_disable(host->clk);
+	clk_put(host->clk);
+out_iounmap:
+	iounmap(host->base);
+out_mmc_free:
+	mmc_free_host(mmc);
+out_release_mem:
+	release_mem_region(iores->start, resource_size(iores));
+	return ret;
+}
+
+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 resource *res = host->res;
+
+	mmc_remove_host(mmc);
+
+	free_irq(host->irq, host);
+
+	platform_set_drvdata(pdev, NULL);
+
+	if (host->dmach)
+		dma_release_channel(host->dmach);
+
+	clk_disable(host->clk);
+	clk_put(host->clk);
+
+	iounmap(host->base);
+
+	mmc_free_host(mmc);
+
+	release_mem_region(res->start, resource_size(res));
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int mxs_mmc_suspend(struct device *dev)
+{
+	struct mmc_host *mmc = dev_get_drvdata(dev);
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+	int ret = 0;
+
+	ret = mmc_suspend_host(mmc);
+
+	clk_disable(host->clk);
+
+	return ret;
+}
+
+static int mxs_mmc_resume(struct device *dev)
+{
+	struct mmc_host *mmc = dev_get_drvdata(dev);
+	struct mxs_mmc_host *host = mmc_priv(mmc);
+	int ret = 0;
+
+	clk_enable(host->clk);
+
+	ret = mmc_resume_host(mmc);
+
+	return ret;
+}
+
+static const struct dev_pm_ops mxs_mmc_pm_ops = {
+	.suspend	= mxs_mmc_suspend,
+	.resume		= mxs_mmc_resume,
+};
+#endif
+
+static struct platform_driver mxs_mmc_driver = {
+	.probe		= mxs_mmc_probe,
+	.remove		= mxs_mmc_remove,
+	.driver		= {
+		.name	= DRIVER_NAME,
+		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm	= &mxs_mmc_pm_ops,
+#endif
+	},
+};
+
+static int __init mxs_mmc_init(void)
+{
+	return platform_driver_register(&mxs_mmc_driver);
+}
+
+static void __exit mxs_mmc_exit(void)
+{
+	platform_driver_unregister(&mxs_mmc_driver);
+}
+
+module_init(mxs_mmc_init);
+module_exit(mxs_mmc_exit);
+
+MODULE_DESCRIPTION("FREESCALE MXS MMC peripheral");
+MODULE_LICENSE("GPL");
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 2/7] ARM: mxs/clock: fix base address missing in name##_set_parent
  2011-02-14  2:32 ` Shawn Guo
@ 2011-02-14  2:32   ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel; +Cc: Shawn Guo

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/clock-mx23.c |    2 +-
 arch/arm/mach-mxs/clock-mx28.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
index 350b28c..c19b69a 100644
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -347,7 +347,7 @@ static int name##_set_parent(struct clk *clk, struct clk *parent)	\
 {									\
 	if (parent != clk->parent) {					\
 		__raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit,		\
-			 HW_CLKCTRL_CLKSEQ_TOG);			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG);	\
 		clk->parent = parent;					\
 	}								\
 									\
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index a3b4787..9f4ee36 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -483,7 +483,7 @@ static int name##_set_parent(struct clk *clk, struct clk *parent)	\
 {									\
 	if (parent != clk->parent) {					\
 		__raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit,		\
-			 HW_CLKCTRL_CLKSEQ_TOG);			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG);	\
 		clk->parent = parent;					\
 	}								\
 									\
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 2/7] ARM: mxs/clock: fix base address missing in name##_set_parent
@ 2011-02-14  2:32   ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/clock-mx23.c |    2 +-
 arch/arm/mach-mxs/clock-mx28.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
index 350b28c..c19b69a 100644
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -347,7 +347,7 @@ static int name##_set_parent(struct clk *clk, struct clk *parent)	\
 {									\
 	if (parent != clk->parent) {					\
 		__raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit,		\
-			 HW_CLKCTRL_CLKSEQ_TOG);			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG);	\
 		clk->parent = parent;					\
 	}								\
 									\
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index a3b4787..9f4ee36 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -483,7 +483,7 @@ static int name##_set_parent(struct clk *clk, struct clk *parent)	\
 {									\
 	if (parent != clk->parent) {					\
 		__raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit,		\
-			 HW_CLKCTRL_CLKSEQ_TOG);			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ_TOG);	\
 		clk->parent = parent;					\
 	}								\
 									\
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 3/7] ARM: mxs: make ssp error irq definition consistent
  2011-02-14  2:32 ` Shawn Guo
@ 2011-02-14  2:32   ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel; +Cc: Shawn Guo

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/include/mach/mx23.h |    2 +-
 arch/arm/mach-mxs/include/mach/mx28.h |    8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
index 1730c9c..e858692 100644
--- a/arch/arm/mach-mxs/include/mach/mx23.h
+++ b/arch/arm/mach-mxs/include/mach/mx23.h
@@ -93,7 +93,7 @@
 #define MX23_INT_USB_WAKEUP		12
 #define MX23_INT_GPMI_DMA		13
 #define MX23_INT_SSP1_DMA		14
-#define MX23_INT_SSP_ERROR		15
+#define MX23_INT_SSP1_ERROR		15
 #define MX23_INT_GPIO0			16
 #define MX23_INT_GPIO1			17
 #define MX23_INT_GPIO2			18
diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
index 3f3485a..75d8611 100644
--- a/arch/arm/mach-mxs/include/mach/mx28.h
+++ b/arch/arm/mach-mxs/include/mach/mx28.h
@@ -163,10 +163,10 @@
 #define MX28_INT_USB0			93
 #define MX28_INT_USB1_WAKEUP		94
 #define MX28_INT_USB0_WAKEUP		95
-#define MX28_INT_SSP0			96
-#define MX28_INT_SSP1			97
-#define MX28_INT_SSP2			98
-#define MX28_INT_SSP3			99
+#define MX28_INT_SSP0_ERROR		96
+#define MX28_INT_SSP1_ERROR		97
+#define MX28_INT_SSP2_ERROR		98
+#define MX28_INT_SSP3_ERROR		99
 #define MX28_INT_ENET_SWI		100
 #define MX28_INT_ENET_MAC0		101
 #define MX28_INT_ENET_MAC1		102
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 3/7] ARM: mxs: make ssp error irq definition consistent
@ 2011-02-14  2:32   ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/include/mach/mx23.h |    2 +-
 arch/arm/mach-mxs/include/mach/mx28.h |    8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
index 1730c9c..e858692 100644
--- a/arch/arm/mach-mxs/include/mach/mx23.h
+++ b/arch/arm/mach-mxs/include/mach/mx23.h
@@ -93,7 +93,7 @@
 #define MX23_INT_USB_WAKEUP		12
 #define MX23_INT_GPMI_DMA		13
 #define MX23_INT_SSP1_DMA		14
-#define MX23_INT_SSP_ERROR		15
+#define MX23_INT_SSP1_ERROR		15
 #define MX23_INT_GPIO0			16
 #define MX23_INT_GPIO1			17
 #define MX23_INT_GPIO2			18
diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
index 3f3485a..75d8611 100644
--- a/arch/arm/mach-mxs/include/mach/mx28.h
+++ b/arch/arm/mach-mxs/include/mach/mx28.h
@@ -163,10 +163,10 @@
 #define MX28_INT_USB0			93
 #define MX28_INT_USB1_WAKEUP		94
 #define MX28_INT_USB0_WAKEUP		95
-#define MX28_INT_SSP0			96
-#define MX28_INT_SSP1			97
-#define MX28_INT_SSP2			98
-#define MX28_INT_SSP3			99
+#define MX28_INT_SSP0_ERROR		96
+#define MX28_INT_SSP1_ERROR		97
+#define MX28_INT_SSP2_ERROR		98
+#define MX28_INT_SSP3_ERROR		99
 #define MX28_INT_ENET_SWI		100
 #define MX28_INT_ENET_MAC0		101
 #define MX28_INT_ENET_MAC1		102
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 4/7] ARM: mxs: dynamically allocate mmc device
  2011-02-14  2:32 ` Shawn Guo
@ 2011-02-14  2:32   ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel; +Cc: Shawn Guo

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/clock-mx23.c                  |   16 +++++
 arch/arm/mach-mxs/clock-mx28.c                  |   18 +++++
 arch/arm/mach-mxs/devices-mx23.h                |    4 +
 arch/arm/mach-mxs/devices-mx28.h                |    4 +
 arch/arm/mach-mxs/devices/Kconfig               |    3 +
 arch/arm/mach-mxs/devices/Makefile              |    1 +
 arch/arm/mach-mxs/devices/platform-mmc.c        |   80 +++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/devices-common.h |   13 ++++
 8 files changed, 139 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/devices/platform-mmc.c

diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
index c19b69a..a1ed5f4 100644
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -445,6 +445,7 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
 	_REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
 	_REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
+	_REGISTER_CLOCK("mxs-mmc.0", NULL, ssp_clk)
 	_REGISTER_CLOCK(NULL, "usb", usb_clk)
 	_REGISTER_CLOCK(NULL, "audio", audio_clk)
 	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
@@ -515,6 +516,15 @@ static int clk_misc_init(void)
 	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
 			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
 
+	/*
+	 * 480 MHz seems too high to be ssp clock source directly,
+	 * so set frac to get a 288 MHz ref_io.
+	 */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+	reg &= ~BM_CLKCTRL_FRAC_IOFRAC;
+	reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+
 	return 0;
 }
 
@@ -522,6 +532,12 @@ int __init mx23_clocks_init(void)
 {
 	clk_misc_init();
 
+	/*
+	 * source ssp clock from ref_io than ref_xtal,
+	 * as ref_xtal only provides 24 MHz as maximum.
+	 */
+	clk_set_parent(&ssp_clk, &ref_io_clk);
+
 	clk_enable(&cpu_clk);
 	clk_enable(&hbus_clk);
 	clk_enable(&xbus_clk);
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index 9f4ee36..aeb7b2c 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -619,6 +619,8 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
 	_REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
 	_REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
+	_REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
+	_REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
 	_REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
 	_REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
 	_REGISTER_CLOCK(NULL, "usb0", usb0_clk)
@@ -730,6 +732,15 @@ static int clk_misc_init(void)
 	reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
 	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
 
+	/*
+	 * 480 MHz seems too high to be ssp clock source directly,
+	 * so set frac0 to get a 288 MHz ref_io0.
+	 */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
+	reg &= ~BM_CLKCTRL_FRAC0_IO0FRAC;
+	reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
+
 	return 0;
 }
 
@@ -737,6 +748,13 @@ int __init mx28_clocks_init(void)
 {
 	clk_misc_init();
 
+	/*
+	 * source ssp clock from ref_io0 than ref_xtal,
+	 * as ref_xtal only provides 24 MHz as maximum.
+	 */
+	clk_set_parent(&ssp0_clk, &ref_io0_clk);
+	clk_set_parent(&ssp1_clk, &ref_io0_clk);
+
 	clk_enable(&cpu_clk);
 	clk_enable(&hbus_clk);
 	clk_enable(&xbus_clk);
diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h
index 1256788..4419390 100644
--- a/arch/arm/mach-mxs/devices-mx23.h
+++ b/arch/arm/mach-mxs/devices-mx23.h
@@ -14,3 +14,7 @@
 extern const struct amba_device mx23_duart_device __initconst;
 #define mx23_add_duart() \
 	mxs_add_duart(&mx23_duart_device)
+
+extern const struct mxs_mmc_data mx23_mmc_data[] __initconst;
+#define mx23_add_mmc(id, pdata) \
+	mxs_add_mmc(&mx23_mmc_data[id], pdata)
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
index 3b18304..540639d 100644
--- a/arch/arm/mach-mxs/devices-mx28.h
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -32,3 +32,7 @@ extern const struct mxs_flexcan_data mx28_flexcan_data[] __initconst;
 	mxs_add_flexcan(&mx28_flexcan_data[id], pdata)
 #define mx28_add_flexcan0(pdata)	mx28_add_flexcan(0, pdata)
 #define mx28_add_flexcan1(pdata)	mx28_add_flexcan(1, pdata)
+
+extern const struct mxs_mmc_data mx28_mmc_data[] __initconst;
+#define mx28_add_mmc(id, pdata) \
+	mxs_add_mmc(&mx28_mmc_data[id], pdata)
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
index 6c65b67..49307f8 100644
--- a/arch/arm/mach-mxs/devices/Kconfig
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -11,3 +11,6 @@ config MXS_HAVE_PLATFORM_FEC
 config MXS_HAVE_PLATFORM_FLEXCAN
 	select HAVE_CAN_FLEXCAN if CAN
 	bool
+
+config MXS_HAVE_PLATFORM_MMC
+	bool
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
index ca7acc4..c0dacfd 100644
--- a/arch/arm/mach-mxs/devices/Makefile
+++ b/arch/arm/mach-mxs/devices/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_MXS_HAVE_PLATFORM_AUART) += platform-auart.o
 obj-y += platform-dma.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_MMC) += platform-mmc.o
diff --git a/arch/arm/mach-mxs/devices/platform-mmc.c b/arch/arm/mach-mxs/devices/platform-mmc.c
new file mode 100644
index 0000000..9065afa
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-mmc.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+/*
+ * mx23 reference manual is indexing all ssp resources, iomux, clock,
+ * dma channel etc from 1 than 0, while mx28 starts from 0 as normal.
+ */
+#define mx23_mmc_data_entry_single(_id)					\
+	{								\
+		.id = _id - 1,						\
+		.iobase = MX23_SSP ## _id ## _BASE_ADDR,		\
+		.dma = MX23_DMA_SSP ## _id,				\
+		.irq_err = MX23_INT_SSP ## _id ## _ERROR,		\
+		.irq_dma = MX23_INT_SSP ## _id ## _DMA,			\
+	}
+
+#define mx28_mmc_data_entry_single(_id)					\
+	{								\
+		.id = _id,						\
+		.iobase = MX28_SSP ## _id ## _BASE_ADDR,		\
+		.dma = MX28_DMA_SSP ## _id,				\
+		.irq_err = MX28_INT_SSP ## _id ## _ERROR,		\
+		.irq_dma = MX28_INT_SSP ## _id ## _DMA,			\
+	}
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_mmc_data mx23_mmc_data[] __initconst = {
+	mx23_mmc_data_entry_single(1),
+	mx23_mmc_data_entry_single(2),
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_mmc_data mx28_mmc_data[] __initconst = {
+	mx28_mmc_data_entry_single(0),
+	mx28_mmc_data_entry_single(1),
+};
+#endif
+
+struct platform_device *__init mxs_add_mmc(
+		const struct mxs_mmc_data *data,
+		const struct mxs_mmc_platform_data *pdata)
+{
+	struct resource res[] = {
+		{
+			.start	= data->iobase,
+			.end	= data->iobase + SZ_8K - 1,
+			.flags	= IORESOURCE_MEM,
+		}, {
+			.start	= data->dma,
+			.end	= data->dma,
+			.flags	= IORESOURCE_DMA,
+		}, {
+			.start	= data->irq_err,
+			.end	= data->irq_err,
+			.flags	= IORESOURCE_IRQ,
+		}, {
+			.start	= data->irq_dma,
+			.end	= data->irq_dma,
+			.flags	= IORESOURCE_IRQ,
+		},
+	};
+
+	return mxs_add_platform_device("mxs-mmc", data->id,
+			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index e7aefb4..54710c5 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -63,3 +63,16 @@ struct mxs_flexcan_data {
 struct platform_device *__init mxs_add_flexcan(
 		const struct mxs_flexcan_data *data,
 		const struct flexcan_platform_data *pdata);
+
+/* mmc */
+#include <mach/mmc.h>
+struct mxs_mmc_data {
+	int id;
+	resource_size_t iobase;
+	resource_size_t dma;
+	resource_size_t irq_err;
+	resource_size_t irq_dma;
+};
+struct platform_device *__init mxs_add_mmc(
+		const struct mxs_mmc_data *data,
+		const struct mxs_mmc_platform_data *pdata);
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 4/7] ARM: mxs: dynamically allocate mmc device
@ 2011-02-14  2:32   ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/clock-mx23.c                  |   16 +++++
 arch/arm/mach-mxs/clock-mx28.c                  |   18 +++++
 arch/arm/mach-mxs/devices-mx23.h                |    4 +
 arch/arm/mach-mxs/devices-mx28.h                |    4 +
 arch/arm/mach-mxs/devices/Kconfig               |    3 +
 arch/arm/mach-mxs/devices/Makefile              |    1 +
 arch/arm/mach-mxs/devices/platform-mmc.c        |   80 +++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/devices-common.h |   13 ++++
 8 files changed, 139 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/devices/platform-mmc.c

diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
index c19b69a..a1ed5f4 100644
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -445,6 +445,7 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
 	_REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
 	_REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
+	_REGISTER_CLOCK("mxs-mmc.0", NULL, ssp_clk)
 	_REGISTER_CLOCK(NULL, "usb", usb_clk)
 	_REGISTER_CLOCK(NULL, "audio", audio_clk)
 	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
@@ -515,6 +516,15 @@ static int clk_misc_init(void)
 	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
 			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
 
+	/*
+	 * 480 MHz seems too high to be ssp clock source directly,
+	 * so set frac to get a 288 MHz ref_io.
+	 */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+	reg &= ~BM_CLKCTRL_FRAC_IOFRAC;
+	reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+
 	return 0;
 }
 
@@ -522,6 +532,12 @@ int __init mx23_clocks_init(void)
 {
 	clk_misc_init();
 
+	/*
+	 * source ssp clock from ref_io than ref_xtal,
+	 * as ref_xtal only provides 24 MHz as maximum.
+	 */
+	clk_set_parent(&ssp_clk, &ref_io_clk);
+
 	clk_enable(&cpu_clk);
 	clk_enable(&hbus_clk);
 	clk_enable(&xbus_clk);
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index 9f4ee36..aeb7b2c 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -619,6 +619,8 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
 	_REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
 	_REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
+	_REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
+	_REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
 	_REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
 	_REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
 	_REGISTER_CLOCK(NULL, "usb0", usb0_clk)
@@ -730,6 +732,15 @@ static int clk_misc_init(void)
 	reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
 	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
 
+	/*
+	 * 480 MHz seems too high to be ssp clock source directly,
+	 * so set frac0 to get a 288 MHz ref_io0.
+	 */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
+	reg &= ~BM_CLKCTRL_FRAC0_IO0FRAC;
+	reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
+
 	return 0;
 }
 
@@ -737,6 +748,13 @@ int __init mx28_clocks_init(void)
 {
 	clk_misc_init();
 
+	/*
+	 * source ssp clock from ref_io0 than ref_xtal,
+	 * as ref_xtal only provides 24 MHz as maximum.
+	 */
+	clk_set_parent(&ssp0_clk, &ref_io0_clk);
+	clk_set_parent(&ssp1_clk, &ref_io0_clk);
+
 	clk_enable(&cpu_clk);
 	clk_enable(&hbus_clk);
 	clk_enable(&xbus_clk);
diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h
index 1256788..4419390 100644
--- a/arch/arm/mach-mxs/devices-mx23.h
+++ b/arch/arm/mach-mxs/devices-mx23.h
@@ -14,3 +14,7 @@
 extern const struct amba_device mx23_duart_device __initconst;
 #define mx23_add_duart() \
 	mxs_add_duart(&mx23_duart_device)
+
+extern const struct mxs_mmc_data mx23_mmc_data[] __initconst;
+#define mx23_add_mmc(id, pdata) \
+	mxs_add_mmc(&mx23_mmc_data[id], pdata)
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
index 3b18304..540639d 100644
--- a/arch/arm/mach-mxs/devices-mx28.h
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -32,3 +32,7 @@ extern const struct mxs_flexcan_data mx28_flexcan_data[] __initconst;
 	mxs_add_flexcan(&mx28_flexcan_data[id], pdata)
 #define mx28_add_flexcan0(pdata)	mx28_add_flexcan(0, pdata)
 #define mx28_add_flexcan1(pdata)	mx28_add_flexcan(1, pdata)
+
+extern const struct mxs_mmc_data mx28_mmc_data[] __initconst;
+#define mx28_add_mmc(id, pdata) \
+	mxs_add_mmc(&mx28_mmc_data[id], pdata)
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
index 6c65b67..49307f8 100644
--- a/arch/arm/mach-mxs/devices/Kconfig
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -11,3 +11,6 @@ config MXS_HAVE_PLATFORM_FEC
 config MXS_HAVE_PLATFORM_FLEXCAN
 	select HAVE_CAN_FLEXCAN if CAN
 	bool
+
+config MXS_HAVE_PLATFORM_MMC
+	bool
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
index ca7acc4..c0dacfd 100644
--- a/arch/arm/mach-mxs/devices/Makefile
+++ b/arch/arm/mach-mxs/devices/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_MXS_HAVE_PLATFORM_AUART) += platform-auart.o
 obj-y += platform-dma.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
 obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_MMC) += platform-mmc.o
diff --git a/arch/arm/mach-mxs/devices/platform-mmc.c b/arch/arm/mach-mxs/devices/platform-mmc.c
new file mode 100644
index 0000000..9065afa
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-mmc.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+/*
+ * mx23 reference manual is indexing all ssp resources, iomux, clock,
+ * dma channel etc from 1 than 0, while mx28 starts from 0 as normal.
+ */
+#define mx23_mmc_data_entry_single(_id)					\
+	{								\
+		.id = _id - 1,						\
+		.iobase = MX23_SSP ## _id ## _BASE_ADDR,		\
+		.dma = MX23_DMA_SSP ## _id,				\
+		.irq_err = MX23_INT_SSP ## _id ## _ERROR,		\
+		.irq_dma = MX23_INT_SSP ## _id ## _DMA,			\
+	}
+
+#define mx28_mmc_data_entry_single(_id)					\
+	{								\
+		.id = _id,						\
+		.iobase = MX28_SSP ## _id ## _BASE_ADDR,		\
+		.dma = MX28_DMA_SSP ## _id,				\
+		.irq_err = MX28_INT_SSP ## _id ## _ERROR,		\
+		.irq_dma = MX28_INT_SSP ## _id ## _DMA,			\
+	}
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_mmc_data mx23_mmc_data[] __initconst = {
+	mx23_mmc_data_entry_single(1),
+	mx23_mmc_data_entry_single(2),
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_mmc_data mx28_mmc_data[] __initconst = {
+	mx28_mmc_data_entry_single(0),
+	mx28_mmc_data_entry_single(1),
+};
+#endif
+
+struct platform_device *__init mxs_add_mmc(
+		const struct mxs_mmc_data *data,
+		const struct mxs_mmc_platform_data *pdata)
+{
+	struct resource res[] = {
+		{
+			.start	= data->iobase,
+			.end	= data->iobase + SZ_8K - 1,
+			.flags	= IORESOURCE_MEM,
+		}, {
+			.start	= data->dma,
+			.end	= data->dma,
+			.flags	= IORESOURCE_DMA,
+		}, {
+			.start	= data->irq_err,
+			.end	= data->irq_err,
+			.flags	= IORESOURCE_IRQ,
+		}, {
+			.start	= data->irq_dma,
+			.end	= data->irq_dma,
+			.flags	= IORESOURCE_IRQ,
+		},
+	};
+
+	return mxs_add_platform_device("mxs-mmc", data->id,
+			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index e7aefb4..54710c5 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -63,3 +63,16 @@ struct mxs_flexcan_data {
 struct platform_device *__init mxs_add_flexcan(
 		const struct mxs_flexcan_data *data,
 		const struct flexcan_platform_data *pdata);
+
+/* mmc */
+#include <mach/mmc.h>
+struct mxs_mmc_data {
+	int id;
+	resource_size_t iobase;
+	resource_size_t dma;
+	resource_size_t irq_err;
+	resource_size_t irq_dma;
+};
+struct platform_device *__init mxs_add_mmc(
+		const struct mxs_mmc_data *data,
+		const struct mxs_mmc_platform_data *pdata);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 5/7] ARM: mxs: fix typo "GPO" in iomux-mx23.h
  2011-02-14  2:32 ` Shawn Guo
@ 2011-02-14  2:32   ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel; +Cc: Shawn Guo

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/include/mach/iomux-mx23.h |  190 +++++++++++++-------------
 1 files changed, 95 insertions(+), 95 deletions(-)

diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx23.h b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
index 94e5dd8..b0190a4 100644
--- a/arch/arm/mach-mxs/include/mach/iomux-mx23.h
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
@@ -254,102 +254,102 @@
 #define MX23_PAD_ROTARYB__GPMI_CE3N		MXS_IOMUX_PAD_NAKED(2,  8, PAD_MUXSEL_2)
 
 /* MUXSEL_GPIO */
-#define MX23_PAD_GPMI_D00__GPO_0_0		MXS_IOMUX_PAD_NAKED(0,  0, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D01__GPO_0_1		MXS_IOMUX_PAD_NAKED(0,  1, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D02__GPO_0_2		MXS_IOMUX_PAD_NAKED(0,  2, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D03__GPO_0_3		MXS_IOMUX_PAD_NAKED(0,  3, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D04__GPO_0_4		MXS_IOMUX_PAD_NAKED(0,  4, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D05__GPO_0_5		MXS_IOMUX_PAD_NAKED(0,  5, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D06__GPO_0_6		MXS_IOMUX_PAD_NAKED(0,  6, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D07__GPO_0_7		MXS_IOMUX_PAD_NAKED(0,  7, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D08__GPO_0_8		MXS_IOMUX_PAD_NAKED(0,  8, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D09__GPO_0_9		MXS_IOMUX_PAD_NAKED(0,  9, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D10__GPO_0_10		MXS_IOMUX_PAD_NAKED(0, 10, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D11__GPO_0_11		MXS_IOMUX_PAD_NAKED(0, 11, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D12__GPO_0_12		MXS_IOMUX_PAD_NAKED(0, 12, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D13__GPO_0_13		MXS_IOMUX_PAD_NAKED(0, 13, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D14__GPO_0_14		MXS_IOMUX_PAD_NAKED(0, 14, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D15__GPO_0_15		MXS_IOMUX_PAD_NAKED(0, 15, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_CLE__GPO_0_16		MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_ALE__GPO_0_17		MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_CE2N__GPO_0_18		MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_RDY0__GPO_0_19		MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_RDY1__GPO_0_20		MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_RDY2__GPO_0_21		MXS_IOMUX_PAD_NAKED(0, 21, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_RDY3__GPO_0_22		MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_WPN__GPO_0_23		MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_WRN__GPO_0_24		MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_RDN__GPO_0_25		MXS_IOMUX_PAD_NAKED(0, 25, PAD_MUXSEL_GPIO)
-#define MX23_PAD_AUART1_CTS__GPO_0_26		MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_GPIO)
-#define MX23_PAD_AUART1_RTS__GPO_0_27		MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_GPIO)
-#define MX23_PAD_AUART1_RX__GPO_0_28		MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_GPIO)
-#define MX23_PAD_AUART1_TX__GPO_0_29		MXS_IOMUX_PAD_NAKED(0, 29, PAD_MUXSEL_GPIO)
-#define MX23_PAD_I2C_SCL__GPO_0_30		MXS_IOMUX_PAD_NAKED(0, 30, PAD_MUXSEL_GPIO)
-#define MX23_PAD_I2C_SDA__GPO_0_31		MXS_IOMUX_PAD_NAKED(0, 31, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D00__GPIO_0_0		MXS_IOMUX_PAD_NAKED(0,  0, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D01__GPIO_0_1		MXS_IOMUX_PAD_NAKED(0,  1, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D02__GPIO_0_2		MXS_IOMUX_PAD_NAKED(0,  2, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D03__GPIO_0_3		MXS_IOMUX_PAD_NAKED(0,  3, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D04__GPIO_0_4		MXS_IOMUX_PAD_NAKED(0,  4, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D05__GPIO_0_5		MXS_IOMUX_PAD_NAKED(0,  5, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D06__GPIO_0_6		MXS_IOMUX_PAD_NAKED(0,  6, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D07__GPIO_0_7		MXS_IOMUX_PAD_NAKED(0,  7, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D08__GPIO_0_8		MXS_IOMUX_PAD_NAKED(0,  8, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D09__GPIO_0_9		MXS_IOMUX_PAD_NAKED(0,  9, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D10__GPIO_0_10		MXS_IOMUX_PAD_NAKED(0, 10, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D11__GPIO_0_11		MXS_IOMUX_PAD_NAKED(0, 11, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D12__GPIO_0_12		MXS_IOMUX_PAD_NAKED(0, 12, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D13__GPIO_0_13		MXS_IOMUX_PAD_NAKED(0, 13, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D14__GPIO_0_14		MXS_IOMUX_PAD_NAKED(0, 14, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D15__GPIO_0_15		MXS_IOMUX_PAD_NAKED(0, 15, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CLE__GPIO_0_16		MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_ALE__GPIO_0_17		MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CE2N__GPIO_0_18		MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY0__GPIO_0_19		MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY1__GPIO_0_20		MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY2__GPIO_0_21		MXS_IOMUX_PAD_NAKED(0, 21, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY3__GPIO_0_22		MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_WPN__GPIO_0_23		MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_WRN__GPIO_0_24		MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDN__GPIO_0_25		MXS_IOMUX_PAD_NAKED(0, 25, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_CTS__GPIO_0_26		MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_RTS__GPIO_0_27		MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_RX__GPIO_0_28		MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_TX__GPIO_0_29		MXS_IOMUX_PAD_NAKED(0, 29, PAD_MUXSEL_GPIO)
+#define MX23_PAD_I2C_SCL__GPIO_0_30		MXS_IOMUX_PAD_NAKED(0, 30, PAD_MUXSEL_GPIO)
+#define MX23_PAD_I2C_SDA__GPIO_0_31		MXS_IOMUX_PAD_NAKED(0, 31, PAD_MUXSEL_GPIO)
 
-#define MX23_PAD_LCD_D00__GPO_1_0		MXS_IOMUX_PAD_NAKED(1,  0, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D01__GPO_1_1		MXS_IOMUX_PAD_NAKED(1,  1, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D02__GPO_1_2		MXS_IOMUX_PAD_NAKED(1,  2, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D03__GPO_1_3		MXS_IOMUX_PAD_NAKED(1,  3, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D04__GPO_1_4		MXS_IOMUX_PAD_NAKED(1,  4, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D05__GPO_1_5		MXS_IOMUX_PAD_NAKED(1,  5, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D06__GPO_1_6		MXS_IOMUX_PAD_NAKED(1,  6, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D07__GPO_1_7		MXS_IOMUX_PAD_NAKED(1,  7, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D08__GPO_1_8		MXS_IOMUX_PAD_NAKED(1,  8, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D09__GPO_1_9		MXS_IOMUX_PAD_NAKED(1,  9, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D10__GPO_1_10		MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D11__GPO_1_11		MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D12__GPO_1_12		MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D13__GPO_1_13		MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D14__GPO_1_14		MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D15__GPO_1_15		MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D16__GPO_1_16		MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D17__GPO_1_17		MXS_IOMUX_PAD_NAKED(1, 17, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_RESET__GPO_1_18		MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_RS__GPO_1_19		MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_WR__GPO_1_20		MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_CS__GPO_1_21		MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_DOTCK__GPO_1_22		MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_ENABLE__GPO_1_23		MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_HSYNC__GPO_1_24		MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_VSYNC__GPO_1_25		MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_GPIO)
-#define MX23_PAD_PWM0__GPO_1_26			MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_GPIO)
-#define MX23_PAD_PWM1__GPO_1_27			MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_GPIO)
-#define MX23_PAD_PWM2__GPO_1_28			MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_GPIO)
-#define MX23_PAD_PWM3__GPO_1_29			MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_GPIO)
-#define MX23_PAD_PWM4__GPO_1_30			MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D00__GPIO_1_0		MXS_IOMUX_PAD_NAKED(1,  0, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D01__GPIO_1_1		MXS_IOMUX_PAD_NAKED(1,  1, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D02__GPIO_1_2		MXS_IOMUX_PAD_NAKED(1,  2, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D03__GPIO_1_3		MXS_IOMUX_PAD_NAKED(1,  3, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D04__GPIO_1_4		MXS_IOMUX_PAD_NAKED(1,  4, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D05__GPIO_1_5		MXS_IOMUX_PAD_NAKED(1,  5, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D06__GPIO_1_6		MXS_IOMUX_PAD_NAKED(1,  6, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D07__GPIO_1_7		MXS_IOMUX_PAD_NAKED(1,  7, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D08__GPIO_1_8		MXS_IOMUX_PAD_NAKED(1,  8, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D09__GPIO_1_9		MXS_IOMUX_PAD_NAKED(1,  9, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D10__GPIO_1_10		MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D11__GPIO_1_11		MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D12__GPIO_1_12		MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D13__GPIO_1_13		MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D14__GPIO_1_14		MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D15__GPIO_1_15		MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D16__GPIO_1_16		MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D17__GPIO_1_17		MXS_IOMUX_PAD_NAKED(1, 17, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_RESET__GPIO_1_18		MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_RS__GPIO_1_19		MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_WR__GPIO_1_20		MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_CS__GPIO_1_21		MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_DOTCK__GPIO_1_22		MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_ENABLE__GPIO_1_23		MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_HSYNC__GPIO_1_24		MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_VSYNC__GPIO_1_25		MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM0__GPIO_1_26		MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM1__GPIO_1_27		MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM2__GPIO_1_28		MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM3__GPIO_1_29		MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM4__GPIO_1_30		MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_GPIO)
 
-#define MX23_PAD_SSP1_CMD__GPO_2_0		MXS_IOMUX_PAD_NAKED(2,  0, PAD_MUXSEL_GPIO)
-#define MX23_PAD_SSP1_DETECT__GPO_2_1		MXS_IOMUX_PAD_NAKED(2,  1, PAD_MUXSEL_GPIO)
-#define MX23_PAD_SSP1_DATA0__GPO_2_2		MXS_IOMUX_PAD_NAKED(2,  2, PAD_MUXSEL_GPIO)
-#define MX23_PAD_SSP1_DATA1__GPO_2_3		MXS_IOMUX_PAD_NAKED(2,  3, PAD_MUXSEL_GPIO)
-#define MX23_PAD_SSP1_DATA2__GPO_2_4		MXS_IOMUX_PAD_NAKED(2,  4, PAD_MUXSEL_GPIO)
-#define MX23_PAD_SSP1_DATA3__GPO_2_5		MXS_IOMUX_PAD_NAKED(2,  5, PAD_MUXSEL_GPIO)
-#define MX23_PAD_SSP1_SCK__GPO_2_6		MXS_IOMUX_PAD_NAKED(2,  6, PAD_MUXSEL_GPIO)
-#define MX23_PAD_ROTARYA__GPO_2_7		MXS_IOMUX_PAD_NAKED(2,  7, PAD_MUXSEL_GPIO)
-#define MX23_PAD_ROTARYB__GPO_2_8		MXS_IOMUX_PAD_NAKED(2,  8, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A00__GPO_2_9		MXS_IOMUX_PAD_NAKED(2,  9, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A01__GPO_2_10		MXS_IOMUX_PAD_NAKED(2, 10, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A02__GPO_2_11		MXS_IOMUX_PAD_NAKED(2, 11, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A03__GPO_2_12		MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A04__GPO_2_13		MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A05__GPO_2_14		MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A06__GPO_2_15		MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A07__GPO_2_16		MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A08__GPO_2_17		MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A09__GPO_2_18		MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A10__GPO_2_19		MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A11__GPO_2_20		MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A12__GPO_2_21		MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_BA0__GPO_2_22		MXS_IOMUX_PAD_NAKED(2, 22, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_BA1__GPO_2_23		MXS_IOMUX_PAD_NAKED(2, 23, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_CASN__GPO_2_24		MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_CE0N__GPO_2_25		MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_CE1N__GPO_2_26		MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_CE1N__GPO_2_27		MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_CE0N__GPO_2_28		MXS_IOMUX_PAD_NAKED(2, 28, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_CKE__GPO_2_29		MXS_IOMUX_PAD_NAKED(2, 29, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_RASN__GPO_2_30		MXS_IOMUX_PAD_NAKED(2, 30, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_WEN__GPO_2_31		MXS_IOMUX_PAD_NAKED(2, 31, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_CMD__GPIO_2_0		MXS_IOMUX_PAD_NAKED(2,  0, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DETECT__GPIO_2_1		MXS_IOMUX_PAD_NAKED(2,  1, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA0__GPIO_2_2		MXS_IOMUX_PAD_NAKED(2,  2, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA1__GPIO_2_3		MXS_IOMUX_PAD_NAKED(2,  3, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA2__GPIO_2_4		MXS_IOMUX_PAD_NAKED(2,  4, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA3__GPIO_2_5		MXS_IOMUX_PAD_NAKED(2,  5, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_SCK__GPIO_2_6		MXS_IOMUX_PAD_NAKED(2,  6, PAD_MUXSEL_GPIO)
+#define MX23_PAD_ROTARYA__GPIO_2_7		MXS_IOMUX_PAD_NAKED(2,  7, PAD_MUXSEL_GPIO)
+#define MX23_PAD_ROTARYB__GPIO_2_8		MXS_IOMUX_PAD_NAKED(2,  8, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A00__GPIO_2_9		MXS_IOMUX_PAD_NAKED(2,  9, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A01__GPIO_2_10		MXS_IOMUX_PAD_NAKED(2, 10, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A02__GPIO_2_11		MXS_IOMUX_PAD_NAKED(2, 11, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A03__GPIO_2_12		MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A04__GPIO_2_13		MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A05__GPIO_2_14		MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A06__GPIO_2_15		MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A07__GPIO_2_16		MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A08__GPIO_2_17		MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A09__GPIO_2_18		MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A10__GPIO_2_19		MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A11__GPIO_2_20		MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A12__GPIO_2_21		MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_BA0__GPIO_2_22		MXS_IOMUX_PAD_NAKED(2, 22, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_BA1__GPIO_2_23		MXS_IOMUX_PAD_NAKED(2, 23, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CASN__GPIO_2_24		MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CE0N__GPIO_2_25		MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CE1N__GPIO_2_26		MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CE1N__GPIO_2_27		MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CE0N__GPIO_2_28		MXS_IOMUX_PAD_NAKED(2, 28, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CKE__GPIO_2_29		MXS_IOMUX_PAD_NAKED(2, 29, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_RASN__GPIO_2_30		MXS_IOMUX_PAD_NAKED(2, 30, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_WEN__GPIO_2_31		MXS_IOMUX_PAD_NAKED(2, 31, PAD_MUXSEL_GPIO)
 
 #endif /* __MACH_IOMUX_MX23_H__ */
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 5/7] ARM: mxs: fix typo "GPO" in iomux-mx23.h
@ 2011-02-14  2:32   ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/include/mach/iomux-mx23.h |  190 +++++++++++++-------------
 1 files changed, 95 insertions(+), 95 deletions(-)

diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx23.h b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
index 94e5dd8..b0190a4 100644
--- a/arch/arm/mach-mxs/include/mach/iomux-mx23.h
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
@@ -254,102 +254,102 @@
 #define MX23_PAD_ROTARYB__GPMI_CE3N		MXS_IOMUX_PAD_NAKED(2,  8, PAD_MUXSEL_2)
 
 /* MUXSEL_GPIO */
-#define MX23_PAD_GPMI_D00__GPO_0_0		MXS_IOMUX_PAD_NAKED(0,  0, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D01__GPO_0_1		MXS_IOMUX_PAD_NAKED(0,  1, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D02__GPO_0_2		MXS_IOMUX_PAD_NAKED(0,  2, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D03__GPO_0_3		MXS_IOMUX_PAD_NAKED(0,  3, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D04__GPO_0_4		MXS_IOMUX_PAD_NAKED(0,  4, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D05__GPO_0_5		MXS_IOMUX_PAD_NAKED(0,  5, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D06__GPO_0_6		MXS_IOMUX_PAD_NAKED(0,  6, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D07__GPO_0_7		MXS_IOMUX_PAD_NAKED(0,  7, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D08__GPO_0_8		MXS_IOMUX_PAD_NAKED(0,  8, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D09__GPO_0_9		MXS_IOMUX_PAD_NAKED(0,  9, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D10__GPO_0_10		MXS_IOMUX_PAD_NAKED(0, 10, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D11__GPO_0_11		MXS_IOMUX_PAD_NAKED(0, 11, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D12__GPO_0_12		MXS_IOMUX_PAD_NAKED(0, 12, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D13__GPO_0_13		MXS_IOMUX_PAD_NAKED(0, 13, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D14__GPO_0_14		MXS_IOMUX_PAD_NAKED(0, 14, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_D15__GPO_0_15		MXS_IOMUX_PAD_NAKED(0, 15, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_CLE__GPO_0_16		MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_ALE__GPO_0_17		MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_CE2N__GPO_0_18		MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_RDY0__GPO_0_19		MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_RDY1__GPO_0_20		MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_RDY2__GPO_0_21		MXS_IOMUX_PAD_NAKED(0, 21, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_RDY3__GPO_0_22		MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_WPN__GPO_0_23		MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_WRN__GPO_0_24		MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_RDN__GPO_0_25		MXS_IOMUX_PAD_NAKED(0, 25, PAD_MUXSEL_GPIO)
-#define MX23_PAD_AUART1_CTS__GPO_0_26		MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_GPIO)
-#define MX23_PAD_AUART1_RTS__GPO_0_27		MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_GPIO)
-#define MX23_PAD_AUART1_RX__GPO_0_28		MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_GPIO)
-#define MX23_PAD_AUART1_TX__GPO_0_29		MXS_IOMUX_PAD_NAKED(0, 29, PAD_MUXSEL_GPIO)
-#define MX23_PAD_I2C_SCL__GPO_0_30		MXS_IOMUX_PAD_NAKED(0, 30, PAD_MUXSEL_GPIO)
-#define MX23_PAD_I2C_SDA__GPO_0_31		MXS_IOMUX_PAD_NAKED(0, 31, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D00__GPIO_0_0		MXS_IOMUX_PAD_NAKED(0,  0, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D01__GPIO_0_1		MXS_IOMUX_PAD_NAKED(0,  1, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D02__GPIO_0_2		MXS_IOMUX_PAD_NAKED(0,  2, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D03__GPIO_0_3		MXS_IOMUX_PAD_NAKED(0,  3, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D04__GPIO_0_4		MXS_IOMUX_PAD_NAKED(0,  4, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D05__GPIO_0_5		MXS_IOMUX_PAD_NAKED(0,  5, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D06__GPIO_0_6		MXS_IOMUX_PAD_NAKED(0,  6, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D07__GPIO_0_7		MXS_IOMUX_PAD_NAKED(0,  7, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D08__GPIO_0_8		MXS_IOMUX_PAD_NAKED(0,  8, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D09__GPIO_0_9		MXS_IOMUX_PAD_NAKED(0,  9, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D10__GPIO_0_10		MXS_IOMUX_PAD_NAKED(0, 10, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D11__GPIO_0_11		MXS_IOMUX_PAD_NAKED(0, 11, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D12__GPIO_0_12		MXS_IOMUX_PAD_NAKED(0, 12, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D13__GPIO_0_13		MXS_IOMUX_PAD_NAKED(0, 13, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D14__GPIO_0_14		MXS_IOMUX_PAD_NAKED(0, 14, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_D15__GPIO_0_15		MXS_IOMUX_PAD_NAKED(0, 15, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CLE__GPIO_0_16		MXS_IOMUX_PAD_NAKED(0, 16, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_ALE__GPIO_0_17		MXS_IOMUX_PAD_NAKED(0, 17, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CE2N__GPIO_0_18		MXS_IOMUX_PAD_NAKED(0, 18, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY0__GPIO_0_19		MXS_IOMUX_PAD_NAKED(0, 19, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY1__GPIO_0_20		MXS_IOMUX_PAD_NAKED(0, 20, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY2__GPIO_0_21		MXS_IOMUX_PAD_NAKED(0, 21, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDY3__GPIO_0_22		MXS_IOMUX_PAD_NAKED(0, 22, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_WPN__GPIO_0_23		MXS_IOMUX_PAD_NAKED(0, 23, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_WRN__GPIO_0_24		MXS_IOMUX_PAD_NAKED(0, 24, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_RDN__GPIO_0_25		MXS_IOMUX_PAD_NAKED(0, 25, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_CTS__GPIO_0_26		MXS_IOMUX_PAD_NAKED(0, 26, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_RTS__GPIO_0_27		MXS_IOMUX_PAD_NAKED(0, 27, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_RX__GPIO_0_28		MXS_IOMUX_PAD_NAKED(0, 28, PAD_MUXSEL_GPIO)
+#define MX23_PAD_AUART1_TX__GPIO_0_29		MXS_IOMUX_PAD_NAKED(0, 29, PAD_MUXSEL_GPIO)
+#define MX23_PAD_I2C_SCL__GPIO_0_30		MXS_IOMUX_PAD_NAKED(0, 30, PAD_MUXSEL_GPIO)
+#define MX23_PAD_I2C_SDA__GPIO_0_31		MXS_IOMUX_PAD_NAKED(0, 31, PAD_MUXSEL_GPIO)
 
-#define MX23_PAD_LCD_D00__GPO_1_0		MXS_IOMUX_PAD_NAKED(1,  0, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D01__GPO_1_1		MXS_IOMUX_PAD_NAKED(1,  1, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D02__GPO_1_2		MXS_IOMUX_PAD_NAKED(1,  2, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D03__GPO_1_3		MXS_IOMUX_PAD_NAKED(1,  3, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D04__GPO_1_4		MXS_IOMUX_PAD_NAKED(1,  4, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D05__GPO_1_5		MXS_IOMUX_PAD_NAKED(1,  5, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D06__GPO_1_6		MXS_IOMUX_PAD_NAKED(1,  6, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D07__GPO_1_7		MXS_IOMUX_PAD_NAKED(1,  7, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D08__GPO_1_8		MXS_IOMUX_PAD_NAKED(1,  8, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D09__GPO_1_9		MXS_IOMUX_PAD_NAKED(1,  9, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D10__GPO_1_10		MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D11__GPO_1_11		MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D12__GPO_1_12		MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D13__GPO_1_13		MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D14__GPO_1_14		MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D15__GPO_1_15		MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D16__GPO_1_16		MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_D17__GPO_1_17		MXS_IOMUX_PAD_NAKED(1, 17, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_RESET__GPO_1_18		MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_RS__GPO_1_19		MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_WR__GPO_1_20		MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_CS__GPO_1_21		MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_DOTCK__GPO_1_22		MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_ENABLE__GPO_1_23		MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_HSYNC__GPO_1_24		MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_GPIO)
-#define MX23_PAD_LCD_VSYNC__GPO_1_25		MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_GPIO)
-#define MX23_PAD_PWM0__GPO_1_26			MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_GPIO)
-#define MX23_PAD_PWM1__GPO_1_27			MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_GPIO)
-#define MX23_PAD_PWM2__GPO_1_28			MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_GPIO)
-#define MX23_PAD_PWM3__GPO_1_29			MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_GPIO)
-#define MX23_PAD_PWM4__GPO_1_30			MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D00__GPIO_1_0		MXS_IOMUX_PAD_NAKED(1,  0, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D01__GPIO_1_1		MXS_IOMUX_PAD_NAKED(1,  1, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D02__GPIO_1_2		MXS_IOMUX_PAD_NAKED(1,  2, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D03__GPIO_1_3		MXS_IOMUX_PAD_NAKED(1,  3, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D04__GPIO_1_4		MXS_IOMUX_PAD_NAKED(1,  4, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D05__GPIO_1_5		MXS_IOMUX_PAD_NAKED(1,  5, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D06__GPIO_1_6		MXS_IOMUX_PAD_NAKED(1,  6, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D07__GPIO_1_7		MXS_IOMUX_PAD_NAKED(1,  7, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D08__GPIO_1_8		MXS_IOMUX_PAD_NAKED(1,  8, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D09__GPIO_1_9		MXS_IOMUX_PAD_NAKED(1,  9, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D10__GPIO_1_10		MXS_IOMUX_PAD_NAKED(1, 10, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D11__GPIO_1_11		MXS_IOMUX_PAD_NAKED(1, 11, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D12__GPIO_1_12		MXS_IOMUX_PAD_NAKED(1, 12, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D13__GPIO_1_13		MXS_IOMUX_PAD_NAKED(1, 13, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D14__GPIO_1_14		MXS_IOMUX_PAD_NAKED(1, 14, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D15__GPIO_1_15		MXS_IOMUX_PAD_NAKED(1, 15, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D16__GPIO_1_16		MXS_IOMUX_PAD_NAKED(1, 16, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_D17__GPIO_1_17		MXS_IOMUX_PAD_NAKED(1, 17, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_RESET__GPIO_1_18		MXS_IOMUX_PAD_NAKED(1, 18, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_RS__GPIO_1_19		MXS_IOMUX_PAD_NAKED(1, 19, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_WR__GPIO_1_20		MXS_IOMUX_PAD_NAKED(1, 20, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_CS__GPIO_1_21		MXS_IOMUX_PAD_NAKED(1, 21, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_DOTCK__GPIO_1_22		MXS_IOMUX_PAD_NAKED(1, 22, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_ENABLE__GPIO_1_23		MXS_IOMUX_PAD_NAKED(1, 23, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_HSYNC__GPIO_1_24		MXS_IOMUX_PAD_NAKED(1, 24, PAD_MUXSEL_GPIO)
+#define MX23_PAD_LCD_VSYNC__GPIO_1_25		MXS_IOMUX_PAD_NAKED(1, 25, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM0__GPIO_1_26		MXS_IOMUX_PAD_NAKED(1, 26, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM1__GPIO_1_27		MXS_IOMUX_PAD_NAKED(1, 27, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM2__GPIO_1_28		MXS_IOMUX_PAD_NAKED(1, 28, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM3__GPIO_1_29		MXS_IOMUX_PAD_NAKED(1, 29, PAD_MUXSEL_GPIO)
+#define MX23_PAD_PWM4__GPIO_1_30		MXS_IOMUX_PAD_NAKED(1, 30, PAD_MUXSEL_GPIO)
 
-#define MX23_PAD_SSP1_CMD__GPO_2_0		MXS_IOMUX_PAD_NAKED(2,  0, PAD_MUXSEL_GPIO)
-#define MX23_PAD_SSP1_DETECT__GPO_2_1		MXS_IOMUX_PAD_NAKED(2,  1, PAD_MUXSEL_GPIO)
-#define MX23_PAD_SSP1_DATA0__GPO_2_2		MXS_IOMUX_PAD_NAKED(2,  2, PAD_MUXSEL_GPIO)
-#define MX23_PAD_SSP1_DATA1__GPO_2_3		MXS_IOMUX_PAD_NAKED(2,  3, PAD_MUXSEL_GPIO)
-#define MX23_PAD_SSP1_DATA2__GPO_2_4		MXS_IOMUX_PAD_NAKED(2,  4, PAD_MUXSEL_GPIO)
-#define MX23_PAD_SSP1_DATA3__GPO_2_5		MXS_IOMUX_PAD_NAKED(2,  5, PAD_MUXSEL_GPIO)
-#define MX23_PAD_SSP1_SCK__GPO_2_6		MXS_IOMUX_PAD_NAKED(2,  6, PAD_MUXSEL_GPIO)
-#define MX23_PAD_ROTARYA__GPO_2_7		MXS_IOMUX_PAD_NAKED(2,  7, PAD_MUXSEL_GPIO)
-#define MX23_PAD_ROTARYB__GPO_2_8		MXS_IOMUX_PAD_NAKED(2,  8, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A00__GPO_2_9		MXS_IOMUX_PAD_NAKED(2,  9, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A01__GPO_2_10		MXS_IOMUX_PAD_NAKED(2, 10, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A02__GPO_2_11		MXS_IOMUX_PAD_NAKED(2, 11, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A03__GPO_2_12		MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A04__GPO_2_13		MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A05__GPO_2_14		MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A06__GPO_2_15		MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A07__GPO_2_16		MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A08__GPO_2_17		MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A09__GPO_2_18		MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A10__GPO_2_19		MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A11__GPO_2_20		MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_A12__GPO_2_21		MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_BA0__GPO_2_22		MXS_IOMUX_PAD_NAKED(2, 22, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_BA1__GPO_2_23		MXS_IOMUX_PAD_NAKED(2, 23, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_CASN__GPO_2_24		MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_CE0N__GPO_2_25		MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_CE1N__GPO_2_26		MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_CE1N__GPO_2_27		MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_GPIO)
-#define MX23_PAD_GPMI_CE0N__GPO_2_28		MXS_IOMUX_PAD_NAKED(2, 28, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_CKE__GPO_2_29		MXS_IOMUX_PAD_NAKED(2, 29, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_RASN__GPO_2_30		MXS_IOMUX_PAD_NAKED(2, 30, PAD_MUXSEL_GPIO)
-#define MX23_PAD_EMI_WEN__GPO_2_31		MXS_IOMUX_PAD_NAKED(2, 31, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_CMD__GPIO_2_0		MXS_IOMUX_PAD_NAKED(2,  0, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DETECT__GPIO_2_1		MXS_IOMUX_PAD_NAKED(2,  1, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA0__GPIO_2_2		MXS_IOMUX_PAD_NAKED(2,  2, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA1__GPIO_2_3		MXS_IOMUX_PAD_NAKED(2,  3, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA2__GPIO_2_4		MXS_IOMUX_PAD_NAKED(2,  4, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_DATA3__GPIO_2_5		MXS_IOMUX_PAD_NAKED(2,  5, PAD_MUXSEL_GPIO)
+#define MX23_PAD_SSP1_SCK__GPIO_2_6		MXS_IOMUX_PAD_NAKED(2,  6, PAD_MUXSEL_GPIO)
+#define MX23_PAD_ROTARYA__GPIO_2_7		MXS_IOMUX_PAD_NAKED(2,  7, PAD_MUXSEL_GPIO)
+#define MX23_PAD_ROTARYB__GPIO_2_8		MXS_IOMUX_PAD_NAKED(2,  8, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A00__GPIO_2_9		MXS_IOMUX_PAD_NAKED(2,  9, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A01__GPIO_2_10		MXS_IOMUX_PAD_NAKED(2, 10, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A02__GPIO_2_11		MXS_IOMUX_PAD_NAKED(2, 11, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A03__GPIO_2_12		MXS_IOMUX_PAD_NAKED(2, 12, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A04__GPIO_2_13		MXS_IOMUX_PAD_NAKED(2, 13, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A05__GPIO_2_14		MXS_IOMUX_PAD_NAKED(2, 14, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A06__GPIO_2_15		MXS_IOMUX_PAD_NAKED(2, 15, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A07__GPIO_2_16		MXS_IOMUX_PAD_NAKED(2, 16, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A08__GPIO_2_17		MXS_IOMUX_PAD_NAKED(2, 17, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A09__GPIO_2_18		MXS_IOMUX_PAD_NAKED(2, 18, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A10__GPIO_2_19		MXS_IOMUX_PAD_NAKED(2, 19, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A11__GPIO_2_20		MXS_IOMUX_PAD_NAKED(2, 20, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_A12__GPIO_2_21		MXS_IOMUX_PAD_NAKED(2, 21, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_BA0__GPIO_2_22		MXS_IOMUX_PAD_NAKED(2, 22, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_BA1__GPIO_2_23		MXS_IOMUX_PAD_NAKED(2, 23, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CASN__GPIO_2_24		MXS_IOMUX_PAD_NAKED(2, 24, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CE0N__GPIO_2_25		MXS_IOMUX_PAD_NAKED(2, 25, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CE1N__GPIO_2_26		MXS_IOMUX_PAD_NAKED(2, 26, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CE1N__GPIO_2_27		MXS_IOMUX_PAD_NAKED(2, 27, PAD_MUXSEL_GPIO)
+#define MX23_PAD_GPMI_CE0N__GPIO_2_28		MXS_IOMUX_PAD_NAKED(2, 28, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_CKE__GPIO_2_29		MXS_IOMUX_PAD_NAKED(2, 29, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_RASN__GPIO_2_30		MXS_IOMUX_PAD_NAKED(2, 30, PAD_MUXSEL_GPIO)
+#define MX23_PAD_EMI_WEN__GPIO_2_31		MXS_IOMUX_PAD_NAKED(2, 31, PAD_MUXSEL_GPIO)
 
 #endif /* __MACH_IOMUX_MX23_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 6/7] ARM: mxs/mx23evk: add mmc device
  2011-02-14  2:32 ` Shawn Guo
@ 2011-02-14  2:32   ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel; +Cc: Shawn Guo

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/Kconfig        |    1 +
 arch/arm/mach-mxs/mach-mx23evk.c |   58 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index cd2fbdf..f47fae3 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -19,6 +19,7 @@ config MACH_MX23EVK
 	bool "Support MX23EVK Platform"
 	select SOC_IMX23
 	select MXS_HAVE_AMBA_DUART
+	select MXS_HAVE_PLATFORM_MMC
 	default y
 	help
 	  Include support for MX23EVK platform. This includes specific
diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
index aa06400..4d37d9c 100644
--- a/arch/arm/mach-mxs/mach-mx23evk.c
+++ b/arch/arm/mach-mxs/mach-mx23evk.c
@@ -26,10 +26,65 @@
 
 #include "devices-mx23.h"
 
+#define MX23EVK_MMC0_WRITE_PROTECT	MXS_GPIO_NR(1, 30)
+#define MX23EVK_MMC0_SLOT_POWER		MXS_GPIO_NR(1, 29)
+
 static const iomux_cfg_t mx23evk_pads[] __initconst = {
 	/* duart */
 	MX23_PAD_PWM0__DUART_RX | MXS_PAD_4MA,
 	MX23_PAD_PWM1__DUART_TX | MXS_PAD_4MA,
+
+	/* mmc */
+	MX23_PAD_SSP1_DATA0__SSP1_DATA0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DATA1__SSP1_DATA1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DATA2__SSP1_DATA2 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DATA3__SSP1_DATA3 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_GPMI_D08__SSP1_DATA4 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_GPMI_D09__SSP1_DATA5 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_GPMI_D10__SSP1_DATA6 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_GPMI_D11__SSP1_DATA7 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_CMD__SSP1_CMD |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DETECT__SSP1_DETECT |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX23_PAD_SSP1_SCK__SSP1_SCK |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* write protect */
+	MX23_PAD_PWM4__GPIO_1_30 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* slot power enable */
+	MX23_PAD_PWM3__GPIO_1_29 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+};
+
+/* mmc */
+static void __init mx23evk_mmc_slot_poweron(int gpio)
+{
+	int ret;
+
+	ret = gpio_request(gpio, "mmc-slot-power");
+	if (ret) {
+		pr_err("Failed to request gpio mmc-slot-power: %d\n", ret);
+		return;
+	}
+
+	ret = gpio_direction_output(gpio, 0);
+	if (ret) {
+		pr_err("Failed to drive gpio mmc-slot-power: %d\n", ret);
+		return;
+	}
+}
+
+static struct mxs_mmc_platform_data mx23_mmc_pdata __initdata = {
+	.wp_gpio = MX23EVK_MMC0_WRITE_PROTECT,
 };
 
 static void __init mx23evk_init(void)
@@ -37,6 +92,9 @@ static void __init mx23evk_init(void)
 	mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
 
 	mx23_add_duart();
+
+	mx23evk_mmc_slot_poweron(MX23EVK_MMC0_SLOT_POWER);
+	mx23_add_mmc(0, &mx23_mmc_pdata);
 }
 
 static void __init mx23evk_timer_init(void)
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 6/7] ARM: mxs/mx23evk: add mmc device
@ 2011-02-14  2:32   ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/Kconfig        |    1 +
 arch/arm/mach-mxs/mach-mx23evk.c |   58 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index cd2fbdf..f47fae3 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -19,6 +19,7 @@ config MACH_MX23EVK
 	bool "Support MX23EVK Platform"
 	select SOC_IMX23
 	select MXS_HAVE_AMBA_DUART
+	select MXS_HAVE_PLATFORM_MMC
 	default y
 	help
 	  Include support for MX23EVK platform. This includes specific
diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
index aa06400..4d37d9c 100644
--- a/arch/arm/mach-mxs/mach-mx23evk.c
+++ b/arch/arm/mach-mxs/mach-mx23evk.c
@@ -26,10 +26,65 @@
 
 #include "devices-mx23.h"
 
+#define MX23EVK_MMC0_WRITE_PROTECT	MXS_GPIO_NR(1, 30)
+#define MX23EVK_MMC0_SLOT_POWER		MXS_GPIO_NR(1, 29)
+
 static const iomux_cfg_t mx23evk_pads[] __initconst = {
 	/* duart */
 	MX23_PAD_PWM0__DUART_RX | MXS_PAD_4MA,
 	MX23_PAD_PWM1__DUART_TX | MXS_PAD_4MA,
+
+	/* mmc */
+	MX23_PAD_SSP1_DATA0__SSP1_DATA0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DATA1__SSP1_DATA1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DATA2__SSP1_DATA2 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DATA3__SSP1_DATA3 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_GPMI_D08__SSP1_DATA4 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_GPMI_D09__SSP1_DATA5 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_GPMI_D10__SSP1_DATA6 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_GPMI_D11__SSP1_DATA7 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_CMD__SSP1_CMD |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DETECT__SSP1_DETECT |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX23_PAD_SSP1_SCK__SSP1_SCK |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* write protect */
+	MX23_PAD_PWM4__GPIO_1_30 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* slot power enable */
+	MX23_PAD_PWM3__GPIO_1_29 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+};
+
+/* mmc */
+static void __init mx23evk_mmc_slot_poweron(int gpio)
+{
+	int ret;
+
+	ret = gpio_request(gpio, "mmc-slot-power");
+	if (ret) {
+		pr_err("Failed to request gpio mmc-slot-power: %d\n", ret);
+		return;
+	}
+
+	ret = gpio_direction_output(gpio, 0);
+	if (ret) {
+		pr_err("Failed to drive gpio mmc-slot-power: %d\n", ret);
+		return;
+	}
+}
+
+static struct mxs_mmc_platform_data mx23_mmc_pdata __initdata = {
+	.wp_gpio = MX23EVK_MMC0_WRITE_PROTECT,
 };
 
 static void __init mx23evk_init(void)
@@ -37,6 +92,9 @@ static void __init mx23evk_init(void)
 	mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
 
 	mx23_add_duart();
+
+	mx23evk_mmc_slot_poweron(MX23EVK_MMC0_SLOT_POWER);
+	mx23_add_mmc(0, &mx23_mmc_pdata);
 }
 
 static void __init mx23evk_timer_init(void)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 7/7] ARM: mxs/mx28evk: add mmc device
  2011-02-14  2:32 ` Shawn Guo
@ 2011-02-14  2:32   ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel; +Cc: Shawn Guo

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/Kconfig        |    1 +
 arch/arm/mach-mxs/mach-mx28evk.c |  102 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index f47fae3..287e0f8 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -30,6 +30,7 @@ config MACH_MX28EVK
 	select SOC_IMX28
 	select MXS_HAVE_AMBA_DUART
 	select MXS_HAVE_PLATFORM_FEC
+	select MXS_HAVE_PLATFORM_MMC
 	select MXS_OCOTP
 	default y
 	help
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index e8db99f..55a9b55 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -28,8 +28,13 @@
 #include "devices-mx28.h"
 #include "gpio.h"
 
-#define MX28EVK_FEC_PHY_POWER	MXS_GPIO_NR(2, 15)
-#define MX28EVK_FEC_PHY_RESET	MXS_GPIO_NR(4, 13)
+#define MX28EVK_FEC_PHY_POWER		MXS_GPIO_NR(2, 15)
+#define MX28EVK_FEC_PHY_RESET		MXS_GPIO_NR(4, 13)
+
+#define MX28EVK_MMC0_WRITE_PROTECT	MXS_GPIO_NR(2, 12)
+#define MX28EVK_MMC1_WRITE_PROTECT	MXS_GPIO_NR(0, 28)
+#define MX28EVK_MMC0_SLOT_POWER		MXS_GPIO_NR(3, 28)
+#define MX28EVK_MMC1_SLOT_POWER		MXS_GPIO_NR(3, 29)
 
 static const iomux_cfg_t mx28evk_pads[] __initconst = {
 	/* duart */
@@ -76,6 +81,66 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
 	/* phy reset line */
 	MX28_PAD_ENET0_RX_CLK__GPIO_4_13 |
 		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+
+	/* mmc0 */
+	MX28_PAD_SSP0_DATA0__SSP0_D0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA1__SSP0_D1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA2__SSP0_D2 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA3__SSP0_D3 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA4__SSP0_D4 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA5__SSP0_D5 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA6__SSP0_D6 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA7__SSP0_D7 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_CMD__SSP0_CMD |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX28_PAD_SSP0_SCK__SSP0_SCK |
+		(MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* write protect */
+	MX28_PAD_SSP1_SCK__GPIO_2_12 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* slot power enable */
+	MX28_PAD_PWM3__GPIO_3_28 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+
+	/* mmc1 */
+	MX28_PAD_GPMI_D00__SSP1_D0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D01__SSP1_D1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D02__SSP1_D2 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D03__SSP1_D3 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D04__SSP1_D4 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D05__SSP1_D5 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D06__SSP1_D6 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D07__SSP1_D7 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_RDY1__SSP1_CMD |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX28_PAD_GPMI_WRN__SSP1_SCK |
+		(MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* write protect */
+	MX28_PAD_GPMI_RESETN__GPIO_0_28 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* slot power enable */
+	MX28_PAD_PWM4__GPIO_3_29 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
 };
 
 /* fec */
@@ -159,12 +224,45 @@ error:
 	return -ETIMEDOUT;
 }
 
+/* mmc */
+static void __init mx28evk_mmc_slot_poweron(int gpio)
+{
+	int ret;
+
+	ret = gpio_request(gpio, "mmc-slot-power");
+	if (ret) {
+		pr_err("Failed to request gpio mmc-slot-power: %d\n", ret);
+		return;
+	}
+
+	ret = gpio_direction_output(gpio, 0);
+	if (ret) {
+		pr_err("Failed to drive gpio mmc-slot-power: %d\n", ret);
+		return;
+	}
+}
+
+static struct mxs_mmc_platform_data mx28_mmc_pdata[] __initdata = {
+	{
+		/* mmc0 */
+		.wp_gpio = MX28EVK_MMC0_WRITE_PROTECT,
+	}, {
+		/* mmc1 */
+		.wp_gpio = MX28EVK_MMC1_WRITE_PROTECT,
+	},
+};
+
 static void __init mx28evk_init(void)
 {
 	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
 
 	mx28_add_duart();
 
+	mx28evk_mmc_slot_poweron(MX28EVK_MMC0_SLOT_POWER);
+	mx28_add_mmc(0, &mx28_mmc_pdata[0]);
+	mx28evk_mmc_slot_poweron(MX28EVK_MMC1_SLOT_POWER);
+	mx28_add_mmc(1, &mx28_mmc_pdata[1]);
+
 	if (mx28evk_fec_get_mac())
 		pr_warn("%s: failed on fec mac setup\n", __func__);
 
-- 
1.7.1



^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v2 7/7] ARM: mxs/mx28evk: add mmc device
@ 2011-02-14  2:32   ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-14  2:32 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/Kconfig        |    1 +
 arch/arm/mach-mxs/mach-mx28evk.c |  102 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index f47fae3..287e0f8 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -30,6 +30,7 @@ config MACH_MX28EVK
 	select SOC_IMX28
 	select MXS_HAVE_AMBA_DUART
 	select MXS_HAVE_PLATFORM_FEC
+	select MXS_HAVE_PLATFORM_MMC
 	select MXS_OCOTP
 	default y
 	help
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index e8db99f..55a9b55 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -28,8 +28,13 @@
 #include "devices-mx28.h"
 #include "gpio.h"
 
-#define MX28EVK_FEC_PHY_POWER	MXS_GPIO_NR(2, 15)
-#define MX28EVK_FEC_PHY_RESET	MXS_GPIO_NR(4, 13)
+#define MX28EVK_FEC_PHY_POWER		MXS_GPIO_NR(2, 15)
+#define MX28EVK_FEC_PHY_RESET		MXS_GPIO_NR(4, 13)
+
+#define MX28EVK_MMC0_WRITE_PROTECT	MXS_GPIO_NR(2, 12)
+#define MX28EVK_MMC1_WRITE_PROTECT	MXS_GPIO_NR(0, 28)
+#define MX28EVK_MMC0_SLOT_POWER		MXS_GPIO_NR(3, 28)
+#define MX28EVK_MMC1_SLOT_POWER		MXS_GPIO_NR(3, 29)
 
 static const iomux_cfg_t mx28evk_pads[] __initconst = {
 	/* duart */
@@ -76,6 +81,66 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
 	/* phy reset line */
 	MX28_PAD_ENET0_RX_CLK__GPIO_4_13 |
 		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+
+	/* mmc0 */
+	MX28_PAD_SSP0_DATA0__SSP0_D0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA1__SSP0_D1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA2__SSP0_D2 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA3__SSP0_D3 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA4__SSP0_D4 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA5__SSP0_D5 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA6__SSP0_D6 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DATA7__SSP0_D7 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_CMD__SSP0_CMD |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX28_PAD_SSP0_SCK__SSP0_SCK |
+		(MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* write protect */
+	MX28_PAD_SSP1_SCK__GPIO_2_12 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* slot power enable */
+	MX28_PAD_PWM3__GPIO_3_28 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+
+	/* mmc1 */
+	MX28_PAD_GPMI_D00__SSP1_D0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D01__SSP1_D1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D02__SSP1_D2 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D03__SSP1_D3 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D04__SSP1_D4 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D05__SSP1_D5 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D06__SSP1_D6 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_D07__SSP1_D7 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_RDY1__SSP1_CMD |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX28_PAD_GPMI_WRN__SSP1_SCK |
+		(MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* write protect */
+	MX28_PAD_GPMI_RESETN__GPIO_0_28 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	/* slot power enable */
+	MX28_PAD_PWM4__GPIO_3_29 |
+		(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
 };
 
 /* fec */
@@ -159,12 +224,45 @@ error:
 	return -ETIMEDOUT;
 }
 
+/* mmc */
+static void __init mx28evk_mmc_slot_poweron(int gpio)
+{
+	int ret;
+
+	ret = gpio_request(gpio, "mmc-slot-power");
+	if (ret) {
+		pr_err("Failed to request gpio mmc-slot-power: %d\n", ret);
+		return;
+	}
+
+	ret = gpio_direction_output(gpio, 0);
+	if (ret) {
+		pr_err("Failed to drive gpio mmc-slot-power: %d\n", ret);
+		return;
+	}
+}
+
+static struct mxs_mmc_platform_data mx28_mmc_pdata[] __initdata = {
+	{
+		/* mmc0 */
+		.wp_gpio = MX28EVK_MMC0_WRITE_PROTECT,
+	}, {
+		/* mmc1 */
+		.wp_gpio = MX28EVK_MMC1_WRITE_PROTECT,
+	},
+};
+
 static void __init mx28evk_init(void)
 {
 	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
 
 	mx28_add_duart();
 
+	mx28evk_mmc_slot_poweron(MX28EVK_MMC0_SLOT_POWER);
+	mx28_add_mmc(0, &mx28_mmc_pdata[0]);
+	mx28evk_mmc_slot_poweron(MX28EVK_MMC1_SLOT_POWER);
+	mx28_add_mmc(1, &mx28_mmc_pdata[1]);
+
 	if (mx28evk_fec_get_mac())
 		pr_warn("%s: failed on fec mac setup\n", __func__);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 7/7] ARM: mxs/mx28evk: add mmc device
  2011-02-14  2:32   ` Shawn Guo
@ 2011-02-14 10:26     ` Wolfram Sang
  -1 siblings, 0 replies; 64+ messages in thread
From: Wolfram Sang @ 2011-02-14 10:26 UTC (permalink / raw)
  To: Shawn Guo; +Cc: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel

Shawn,

> +/* mmc */
> +static void __init mx28evk_mmc_slot_poweron(int gpio)
> +{
> +	int ret;
> +
> +	ret = gpio_request(gpio, "mmc-slot-power");
> +	if (ret) {
> +		pr_err("Failed to request gpio mmc-slot-power: %d\n", ret);
> +		return;
> +	}
> +
> +	ret = gpio_direction_output(gpio, 0);
> +	if (ret) {
> +		pr_err("Failed to drive gpio mmc-slot-power: %d\n", ret);
> +		return;
> +	}
> +}

Minor nit: You could use gpio_request_one(), and doing so maybe even get rid of
this function and simply do it the init-function. The advantage would be, that
you can name the two GPIOs independently.

Regards,

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 7/7] ARM: mxs/mx28evk: add mmc device
@ 2011-02-14 10:26     ` Wolfram Sang
  0 siblings, 0 replies; 64+ messages in thread
From: Wolfram Sang @ 2011-02-14 10:26 UTC (permalink / raw)
  To: linux-arm-kernel

Shawn,

> +/* mmc */
> +static void __init mx28evk_mmc_slot_poweron(int gpio)
> +{
> +	int ret;
> +
> +	ret = gpio_request(gpio, "mmc-slot-power");
> +	if (ret) {
> +		pr_err("Failed to request gpio mmc-slot-power: %d\n", ret);
> +		return;
> +	}
> +
> +	ret = gpio_direction_output(gpio, 0);
> +	if (ret) {
> +		pr_err("Failed to drive gpio mmc-slot-power: %d\n", ret);
> +		return;
> +	}
> +}

Minor nit: You could use gpio_request_one(), and doing so maybe even get rid of
this function and simply do it the init-function. The advantage would be, that
you can name the two GPIOs independently.

Regards,

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-14  2:32   ` Shawn Guo
@ 2011-02-14 15:39     ` Wolfram Sang
  -1 siblings, 0 replies; 64+ messages in thread
From: Wolfram Sang @ 2011-02-14 15:39 UTC (permalink / raw)
  To: Shawn Guo; +Cc: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel

> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index afe8c6f..42a9e21 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -319,6 +319,15 @@ config MMC_MXC
>  
>  	  If unsure, say N.
>  
> +config MMC_MXS
> +	tristate "Freescale MXS Multimedia Card Interface support"
> +	depends on ARCH_MXS
> +	help
> +	  This selects the Freescale SSP MMC controller found on MXS based
> +	  platforms like mx23/28.
> +
> +	  If unsure, say N.
> +

It should also depend on MXS_DMA?

Regards,

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-14 15:39     ` Wolfram Sang
  0 siblings, 0 replies; 64+ messages in thread
From: Wolfram Sang @ 2011-02-14 15:39 UTC (permalink / raw)
  To: linux-arm-kernel

> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index afe8c6f..42a9e21 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -319,6 +319,15 @@ config MMC_MXC
>  
>  	  If unsure, say N.
>  
> +config MMC_MXS
> +	tristate "Freescale MXS Multimedia Card Interface support"
> +	depends on ARCH_MXS
> +	help
> +	  This selects the Freescale SSP MMC controller found on MXS based
> +	  platforms like mx23/28.
> +
> +	  If unsure, say N.
> +

It should also depend on MXS_DMA?

Regards,

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-14  2:32   ` Shawn Guo
@ 2011-02-14 16:59     ` Wolfram Sang
  -1 siblings, 0 replies; 64+ messages in thread
From: Wolfram Sang @ 2011-02-14 16:59 UTC (permalink / raw)
  To: Shawn Guo; +Cc: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel

On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
> The driver calls into mxs-dma via generic dmaengine api for both pio
> and data transfer.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>

While trying, I got this lockdep-warning and BUG. It might be that my setup is
wrong, causing all these timeouts. But they probably are meant to be handled
more gracefully? I can continue testing tomorrow, maybe this report already
helps identifying a problem?

[    1.000000] mxs-mmc mxs-mmc.0: initialized
[    1.000000] mmc0: mmc_rescan_try_freq: trying to init card at 400000 Hz
[    1.010000] mmc0: clock 0Hz busmode 1 powermode 1 cs 0 Vdd 21 width 0 timing 0
[    1.030000] TCP cubic registered
[    1.030000] NET: Registered protocol family 17
[    1.030000] Registering the dns_resolver key type
[    1.040000] mmc0: clock 400000Hz busmode 1 powermode 2 cs 0 Vdd 21 width 0 timing 0
[    1.050000] mxs-mmc mxs-mmc.0: mxs_mmc_set_clk_rate: div1 2, div2 72, ssp 57600000, bit 400000, rate 400000
[    1.060000] registered taskstats version 1
[    1.070000] i2c i2c-0: master_xfer[0] W, addr=0x68, len=1
[    1.070000] i2c i2c-0: master_xfer[1] R, addr=0x68, len=7
[    1.080000] mmc0: starting CMD52 arg 00000c00 flags 00000195
[    1.080000] mmc0: req done (CMD52): -110: 00000000 00000000 00000000 00000000
[    1.090000] mmc0: starting CMD52 arg 80000c08 flags 00000195
[    1.100000] mmc0: req done (CMD52): -110: 00000000 00000000 00000000 00000000
[    1.110000] mmc0: clock 400000Hz busmode 1 powermode 2 cs 1 Vdd 21 width 0 timing 0
[    1.110000] mxs-mmc mxs-mmc.0: mxs_mmc_set_clk_rate: div1 2, div2 72, ssp 57600000, bit 400000, rate 400000
[    1.120000] rtc-ds1307 0-0068: setting system clock to 2000-01-01 00:00:06 UTC (946684806)
[    1.130000] mmc0: starting CMD0 arg 00000000 flags 000000c0
[    1.140000] mmc0: req done (CMD0): 0: 00000000 00000000 00000000 00000000
[    1.150000] mmc0: clock 400000Hz busmode 1 powermode 2 cs 0 Vdd 21 width 0 timing 0
[    1.150000] mxs-mmc mxs-mmc.0: mxs_mmc_set_clk_rate: div1 2, div2 72, ssp 57600000, bit 400000, rate 400000
[    1.170000] mmc0: starting CMD8 arg 000001aa flags 000002f5
[    1.170000] mmc0: req done (CMD8): -110: 00000000 00000000 00000000 00000000
[    1.180000] mmc0: starting CMD5 arg 00000000 flags 000002e1
[    1.180000] mmc0: req failed (CMD5): -110, retrying...
[    1.180000] 
[    1.180000] =============================================
[    1.180000] [ INFO: possible recursive locking detected ]
[    1.180000] 2.6.38-rc2-00375-gb26872a #134
[    1.180000] ---------------------------------------------
[    1.180000] swapper/0 is trying to acquire lock:
[    1.180000]  (&(&mxs_chan->lock)->rlock){..-...}, at: [<c01fd704>] mxs_dma_tx_submit+0x24/0xf0
[    1.180000] 
[    1.180000] but task is already holding lock:
[    1.180000]  (&(&mxs_chan->lock)->rlock){..-...}, at: [<c01fd7f4>] mxs_dma_tasklet+0x24/0x5c
[    1.180000] 
[    1.180000] other info that might help us debug this:
[    1.180000] 1 lock held by swapper/0:
[    1.180000]  #0:  (&(&mxs_chan->lock)->rlock){..-...}, at: [<c01fd7f4>] mxs_dma_tasklet+0x24/0x5c
[    1.180000] 
[    1.180000] stack backtrace:
[    1.180000] Backtrace: 
[    1.180000] [<c0039cd4>] (dump_backtrace+0x0/0x110) from [<c02a31ec>] (dump_stack+0x1c/0x20)
[    1.180000]  r7:00000000 r6:c0378fb8 r5:c0378fd0 r4:c0378cb0
[    1.180000] [<c02a31d0>] (dump_stack+0x0/0x20) from [<c007ecfc>] (print_deadlock_bug+0xa4/0xd0)
[    1.180000] [<c007ec58>] (print_deadlock_bug+0x0/0xd0) from [<c007ee9c>] (check_deadlock+0x174/0x1ac)
[    1.180000]  r6:c0378cb0 r5:c053783c r4:80000093
[    1.180000] [<c007ed28>] (check_deadlock+0x0/0x1ac) from [<c00804c8>] (validate_chain+0x480/0x6b4)
[    1.180000] [<c0080048>] (validate_chain+0x0/0x6b4) from [<c0080f44>] (__lock_acquire+0x848/0x924)
[    1.180000] [<c00806fc>] (__lock_acquire+0x0/0x924) from [<c0081104>] (lock_acquire+0xe4/0x104)
[    1.180000] [<c0081020>] (lock_acquire+0x0/0x104) from [<c02a5f40>] (_raw_spin_lock_irqsave+0x50/0x64)
[    1.180000] [<c02a5ef0>] (_raw_spin_lock_irqsave+0x0/0x64) from [<c01fd704>] (mxs_dma_tx_submit+0x24/0xf0)
[    1.180000]  r7:c78190dc r6:c798fe14 r5:c798fe14 r4:c7819084
[    1.180000] [<c01fd6e0>] (mxs_dma_tx_submit+0x0/0xf0) from [<c02092d4>] (mxs_mmc_ac+0x90/0xb4)
[    1.180000]  r8:c03a7120 r7:c037cc98 r6:c798fe14 r5:c798fe14 r4:c79972e0
[    1.180000] [<c0209244>] (mxs_mmc_ac+0x0/0xb4) from [<c0209640>] (mxs_mmc_start_cmd+0xb0/0xec)
[    1.180000]  r4:c79972e0
[    1.180000] [<c0209590>] (mxs_mmc_start_cmd+0x0/0xec) from [<c02096bc>] (mxs_mmc_request+0x40/0x4c)
[    1.180000]  r4:c79972e0
[    1.180000] [<c020967c>] (mxs_mmc_request+0x0/0x4c) from [<c01fe700>] (mmc_request_done+0x9c/0x18c)
[    1.180000]  r5:c7997000 r4:c798fe48
[    1.180000] [<c01fe664>] (mmc_request_done+0x0/0x18c) from [<c0209828>] (mxs_mmc_request_done+0x160/0x16c)
[    1.180000]  r6:c798fe14 r5:00000000 r4:c79972e0
[    1.180000] [<c02096c8>] (mxs_mmc_request_done+0x0/0x16c) from [<c0209848>] (mxs_mmc_dma_irq_callback+0x14/0x18)
[    1.180000]  r6:20000013 r5:c78190dc r4:c7819080
[    1.180000] [<c0209834>] (mxs_mmc_dma_irq_callback+0x0/0x18) from [<c01fd80c>] (mxs_dma_tasklet+0x3c/0x5c)
[    1.180000] [<c01fd7d0>] (mxs_dma_tasklet+0x0/0x5c) from [<c0052ea8>] (tasklet_action+0xac/0x148)
[    1.180000]  r6:c03cb340 r5:c78190c8 r4:00000000
[    1.180000] [<c0052dfc>] (tasklet_action+0x0/0x148) from [<c00536d0>] (__do_softirq+0xe0/0x204)
[    1.180000] [<c00535f0>] (__do_softirq+0x0/0x204) from [<c005384c>] (irq_exit+0x58/0xa0)
[    1.180000] [<c00537f4>] (irq_exit+0x0/0xa0) from [<c002f084>] (asm_do_IRQ+0x84/0xa4)
[    1.180000] [<c002f000>] (asm_do_IRQ+0x0/0xa4) from [<c0035ad8>] (__irq_svc+0x38/0x80)
[    1.180000] Exception stack(0xc0375f20 to 0xc0375f68)
[    1.180000] 5f20: 00000001 00000004 0005217f 20000013 c0374000 c037a210 c03aa768 00000002
[    1.180000] 5f40: 4001ee3c 41069265 4001ee08 c0375f74 c0375f38 c0375f68 c007ea54 c0037164
[    1.180000] 5f60: 20000013 ffffffff
[    1.180000]  r5:f5000000 r4:ffffffff
[    1.180000] [<c003712c>] (default_idle+0x0/0x3c) from [<c0037750>] (cpu_idle+0x78/0xc8)
[    1.180000] [<c00376d8>] (cpu_idle+0x0/0xc8) from [<c02a1330>] (rest_init+0xb0/0xd8)
[    1.180000]  r6:c037ed58 r5:00000001 r4:00000000
[    1.180000] [<c02a1280>] (rest_init+0x0/0xd8) from [<c0008b54>] (start_kernel+0x264/0x2b8)
[    1.180000]  r7:c037a198 r6:c002025c r5:c03aa6e0 r4:c0376ee8
[    1.180000] [<c00088f0>] (start_kernel+0x0/0x2b8) from [<40008034>] (0x40008034)
[    1.180000]  r6:c0020660 r5:c037602c r4:00053175
[    1.180000] BUG: spinlock lockup on CPU#0, swapper/0, c78190dc
[    1.180000] Backtrace: 
[    1.180000] [<c0039cd4>] (dump_backtrace+0x0/0x110) from [<c02a31ec>] (dump_stack+0x1c/0x20)
[    1.180000]  r7:c0374000 r6:c78190dc r5:00000000 r4:00000000
[    1.180000] [<c02a31d0>] (dump_stack+0x0/0x20) from [<c01bc8a4>] (do_raw_spin_lock+0x118/0x154)
[    1.180000] [<c01bc78c>] (do_raw_spin_lock+0x0/0x154) from [<c02a5f48>] (_raw_spin_lock_irqsave+0x58/0x64)
[    1.180000] [<c02a5ef0>] (_raw_spin_lock_irqsave+0x0/0x64) from [<c01fd704>] (mxs_dma_tx_submit+0x24/0xf0)
[    1.180000]  r7:c78190dc r6:c798fe14 r5:c798fe14 r4:c7819084
[    1.180000] [<c01fd6e0>] (mxs_dma_tx_submit+0x0/0xf0) from [<c02092d4>] (mxs_mmc_ac+0x90/0xb4)
[    1.180000]  r8:c03a7120 r7:c037cc98 r6:c798fe14 r5:c798fe14 r4:c79972e0
[    1.180000] [<c0209244>] (mxs_mmc_ac+0x0/0xb4) from [<c0209640>] (mxs_mmc_start_cmd+0xb0/0xec)
[    1.180000]  r4:c79972e0
[    1.180000] [<c0209590>] (mxs_mmc_start_cmd+0x0/0xec) from [<c02096bc>] (mxs_mmc_request+0x40/0x4c)
[    1.180000]  r4:c79972e0
[    1.180000] [<c020967c>] (mxs_mmc_request+0x0/0x4c) from [<c01fe700>] (mmc_request_done+0x9c/0x18c)
[    1.180000]  r5:c7997000 r4:c798fe48
[    1.180000] [<c01fe664>] (mmc_request_done+0x0/0x18c) from [<c0209828>] (mxs_mmc_request_done+0x160/0x16c)
[    1.180000]  r6:c798fe14 r5:00000000 r4:c79972e0
[    1.180000] [<c02096c8>] (mxs_mmc_request_done+0x0/0x16c) from [<c0209848>] (mxs_mmc_dma_irq_callback+0x14/0x18)
[    1.180000]  r6:20000013 r5:c78190dc r4:c7819080
[    1.180000] [<c0209834>] (mxs_mmc_dma_irq_callback+0x0/0x18) from [<c01fd80c>] (mxs_dma_tasklet+0x3c/0x5c)
[    1.180000] [<c01fd7d0>] (mxs_dma_tasklet+0x0/0x5c) from [<c0052ea8>] (tasklet_action+0xac/0x148)
[    1.180000]  r6:c03cb340 r5:c78190c8 r4:00000000
[    1.180000] [<c0052dfc>] (tasklet_action+0x0/0x148) from [<c00536d0>] (__do_softirq+0xe0/0x204)
[    1.180000] [<c00535f0>] (__do_softirq+0x0/0x204) from [<c005384c>] (irq_exit+0x58/0xa0)
[    1.180000] [<c00537f4>] (irq_exit+0x0/0xa0) from [<c002f084>] (asm_do_IRQ+0x84/0xa4)
[    1.180000] [<c002f000>] (asm_do_IRQ+0x0/0xa4) from [<c0035ad8>] (__irq_svc+0x38/0x80)
[    1.180000] Exception stack(0xc0375f20 to 0xc0375f68)
[    1.180000] 5f20: 00000001 00000004 0005217f 20000013 c0374000 c037a210 c03aa768 00000002
[    1.180000] 5f40: 4001ee3c 41069265 4001ee08 c0375f74 c0375f38 c0375f68 c007ea54 c0037164
[    1.180000] 5f60: 20000013 ffffffff
[    1.180000]  r5:f5000000 r4:ffffffff
[    1.180000] [<c003712c>] (default_idle+0x0/0x3c) from [<c0037750>] (cpu_idle+0x78/0xc8)
[    1.180000] [<c00376d8>] (cpu_idle+0x0/0xc8) from [<c02a1330>] (rest_init+0xb0/0xd8)
[    1.180000]  r6:c037ed58 r5:00000001 r4:00000000
[    1.180000] [<c02a1280>] (rest_init+0x0/0xd8) from [<c0008b54>] (start_kernel+0x264/0x2b8)
[    1.180000]  r7:c037a198 r6:c002025c r5:c03aa6e0 r4:c0376ee8
[    1.180000] [<c00088f0>] (start_kernel+0x0/0x2b8) from [<40008034>] (0x40008034)
[    1.180000]  r6:c0020660 r5:c037602c r4:00053175

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-14 16:59     ` Wolfram Sang
  0 siblings, 0 replies; 64+ messages in thread
From: Wolfram Sang @ 2011-02-14 16:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
> The driver calls into mxs-dma via generic dmaengine api for both pio
> and data transfer.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>

While trying, I got this lockdep-warning and BUG. It might be that my setup is
wrong, causing all these timeouts. But they probably are meant to be handled
more gracefully? I can continue testing tomorrow, maybe this report already
helps identifying a problem?

[    1.000000] mxs-mmc mxs-mmc.0: initialized
[    1.000000] mmc0: mmc_rescan_try_freq: trying to init card at 400000 Hz
[    1.010000] mmc0: clock 0Hz busmode 1 powermode 1 cs 0 Vdd 21 width 0 timing 0
[    1.030000] TCP cubic registered
[    1.030000] NET: Registered protocol family 17
[    1.030000] Registering the dns_resolver key type
[    1.040000] mmc0: clock 400000Hz busmode 1 powermode 2 cs 0 Vdd 21 width 0 timing 0
[    1.050000] mxs-mmc mxs-mmc.0: mxs_mmc_set_clk_rate: div1 2, div2 72, ssp 57600000, bit 400000, rate 400000
[    1.060000] registered taskstats version 1
[    1.070000] i2c i2c-0: master_xfer[0] W, addr=0x68, len=1
[    1.070000] i2c i2c-0: master_xfer[1] R, addr=0x68, len=7
[    1.080000] mmc0: starting CMD52 arg 00000c00 flags 00000195
[    1.080000] mmc0: req done (CMD52): -110: 00000000 00000000 00000000 00000000
[    1.090000] mmc0: starting CMD52 arg 80000c08 flags 00000195
[    1.100000] mmc0: req done (CMD52): -110: 00000000 00000000 00000000 00000000
[    1.110000] mmc0: clock 400000Hz busmode 1 powermode 2 cs 1 Vdd 21 width 0 timing 0
[    1.110000] mxs-mmc mxs-mmc.0: mxs_mmc_set_clk_rate: div1 2, div2 72, ssp 57600000, bit 400000, rate 400000
[    1.120000] rtc-ds1307 0-0068: setting system clock to 2000-01-01 00:00:06 UTC (946684806)
[    1.130000] mmc0: starting CMD0 arg 00000000 flags 000000c0
[    1.140000] mmc0: req done (CMD0): 0: 00000000 00000000 00000000 00000000
[    1.150000] mmc0: clock 400000Hz busmode 1 powermode 2 cs 0 Vdd 21 width 0 timing 0
[    1.150000] mxs-mmc mxs-mmc.0: mxs_mmc_set_clk_rate: div1 2, div2 72, ssp 57600000, bit 400000, rate 400000
[    1.170000] mmc0: starting CMD8 arg 000001aa flags 000002f5
[    1.170000] mmc0: req done (CMD8): -110: 00000000 00000000 00000000 00000000
[    1.180000] mmc0: starting CMD5 arg 00000000 flags 000002e1
[    1.180000] mmc0: req failed (CMD5): -110, retrying...
[    1.180000] 
[    1.180000] =============================================
[    1.180000] [ INFO: possible recursive locking detected ]
[    1.180000] 2.6.38-rc2-00375-gb26872a #134
[    1.180000] ---------------------------------------------
[    1.180000] swapper/0 is trying to acquire lock:
[    1.180000]  (&(&mxs_chan->lock)->rlock){..-...}, at: [<c01fd704>] mxs_dma_tx_submit+0x24/0xf0
[    1.180000] 
[    1.180000] but task is already holding lock:
[    1.180000]  (&(&mxs_chan->lock)->rlock){..-...}, at: [<c01fd7f4>] mxs_dma_tasklet+0x24/0x5c
[    1.180000] 
[    1.180000] other info that might help us debug this:
[    1.180000] 1 lock held by swapper/0:
[    1.180000]  #0:  (&(&mxs_chan->lock)->rlock){..-...}, at: [<c01fd7f4>] mxs_dma_tasklet+0x24/0x5c
[    1.180000] 
[    1.180000] stack backtrace:
[    1.180000] Backtrace: 
[    1.180000] [<c0039cd4>] (dump_backtrace+0x0/0x110) from [<c02a31ec>] (dump_stack+0x1c/0x20)
[    1.180000]  r7:00000000 r6:c0378fb8 r5:c0378fd0 r4:c0378cb0
[    1.180000] [<c02a31d0>] (dump_stack+0x0/0x20) from [<c007ecfc>] (print_deadlock_bug+0xa4/0xd0)
[    1.180000] [<c007ec58>] (print_deadlock_bug+0x0/0xd0) from [<c007ee9c>] (check_deadlock+0x174/0x1ac)
[    1.180000]  r6:c0378cb0 r5:c053783c r4:80000093
[    1.180000] [<c007ed28>] (check_deadlock+0x0/0x1ac) from [<c00804c8>] (validate_chain+0x480/0x6b4)
[    1.180000] [<c0080048>] (validate_chain+0x0/0x6b4) from [<c0080f44>] (__lock_acquire+0x848/0x924)
[    1.180000] [<c00806fc>] (__lock_acquire+0x0/0x924) from [<c0081104>] (lock_acquire+0xe4/0x104)
[    1.180000] [<c0081020>] (lock_acquire+0x0/0x104) from [<c02a5f40>] (_raw_spin_lock_irqsave+0x50/0x64)
[    1.180000] [<c02a5ef0>] (_raw_spin_lock_irqsave+0x0/0x64) from [<c01fd704>] (mxs_dma_tx_submit+0x24/0xf0)
[    1.180000]  r7:c78190dc r6:c798fe14 r5:c798fe14 r4:c7819084
[    1.180000] [<c01fd6e0>] (mxs_dma_tx_submit+0x0/0xf0) from [<c02092d4>] (mxs_mmc_ac+0x90/0xb4)
[    1.180000]  r8:c03a7120 r7:c037cc98 r6:c798fe14 r5:c798fe14 r4:c79972e0
[    1.180000] [<c0209244>] (mxs_mmc_ac+0x0/0xb4) from [<c0209640>] (mxs_mmc_start_cmd+0xb0/0xec)
[    1.180000]  r4:c79972e0
[    1.180000] [<c0209590>] (mxs_mmc_start_cmd+0x0/0xec) from [<c02096bc>] (mxs_mmc_request+0x40/0x4c)
[    1.180000]  r4:c79972e0
[    1.180000] [<c020967c>] (mxs_mmc_request+0x0/0x4c) from [<c01fe700>] (mmc_request_done+0x9c/0x18c)
[    1.180000]  r5:c7997000 r4:c798fe48
[    1.180000] [<c01fe664>] (mmc_request_done+0x0/0x18c) from [<c0209828>] (mxs_mmc_request_done+0x160/0x16c)
[    1.180000]  r6:c798fe14 r5:00000000 r4:c79972e0
[    1.180000] [<c02096c8>] (mxs_mmc_request_done+0x0/0x16c) from [<c0209848>] (mxs_mmc_dma_irq_callback+0x14/0x18)
[    1.180000]  r6:20000013 r5:c78190dc r4:c7819080
[    1.180000] [<c0209834>] (mxs_mmc_dma_irq_callback+0x0/0x18) from [<c01fd80c>] (mxs_dma_tasklet+0x3c/0x5c)
[    1.180000] [<c01fd7d0>] (mxs_dma_tasklet+0x0/0x5c) from [<c0052ea8>] (tasklet_action+0xac/0x148)
[    1.180000]  r6:c03cb340 r5:c78190c8 r4:00000000
[    1.180000] [<c0052dfc>] (tasklet_action+0x0/0x148) from [<c00536d0>] (__do_softirq+0xe0/0x204)
[    1.180000] [<c00535f0>] (__do_softirq+0x0/0x204) from [<c005384c>] (irq_exit+0x58/0xa0)
[    1.180000] [<c00537f4>] (irq_exit+0x0/0xa0) from [<c002f084>] (asm_do_IRQ+0x84/0xa4)
[    1.180000] [<c002f000>] (asm_do_IRQ+0x0/0xa4) from [<c0035ad8>] (__irq_svc+0x38/0x80)
[    1.180000] Exception stack(0xc0375f20 to 0xc0375f68)
[    1.180000] 5f20: 00000001 00000004 0005217f 20000013 c0374000 c037a210 c03aa768 00000002
[    1.180000] 5f40: 4001ee3c 41069265 4001ee08 c0375f74 c0375f38 c0375f68 c007ea54 c0037164
[    1.180000] 5f60: 20000013 ffffffff
[    1.180000]  r5:f5000000 r4:ffffffff
[    1.180000] [<c003712c>] (default_idle+0x0/0x3c) from [<c0037750>] (cpu_idle+0x78/0xc8)
[    1.180000] [<c00376d8>] (cpu_idle+0x0/0xc8) from [<c02a1330>] (rest_init+0xb0/0xd8)
[    1.180000]  r6:c037ed58 r5:00000001 r4:00000000
[    1.180000] [<c02a1280>] (rest_init+0x0/0xd8) from [<c0008b54>] (start_kernel+0x264/0x2b8)
[    1.180000]  r7:c037a198 r6:c002025c r5:c03aa6e0 r4:c0376ee8
[    1.180000] [<c00088f0>] (start_kernel+0x0/0x2b8) from [<40008034>] (0x40008034)
[    1.180000]  r6:c0020660 r5:c037602c r4:00053175
[    1.180000] BUG: spinlock lockup on CPU#0, swapper/0, c78190dc
[    1.180000] Backtrace: 
[    1.180000] [<c0039cd4>] (dump_backtrace+0x0/0x110) from [<c02a31ec>] (dump_stack+0x1c/0x20)
[    1.180000]  r7:c0374000 r6:c78190dc r5:00000000 r4:00000000
[    1.180000] [<c02a31d0>] (dump_stack+0x0/0x20) from [<c01bc8a4>] (do_raw_spin_lock+0x118/0x154)
[    1.180000] [<c01bc78c>] (do_raw_spin_lock+0x0/0x154) from [<c02a5f48>] (_raw_spin_lock_irqsave+0x58/0x64)
[    1.180000] [<c02a5ef0>] (_raw_spin_lock_irqsave+0x0/0x64) from [<c01fd704>] (mxs_dma_tx_submit+0x24/0xf0)
[    1.180000]  r7:c78190dc r6:c798fe14 r5:c798fe14 r4:c7819084
[    1.180000] [<c01fd6e0>] (mxs_dma_tx_submit+0x0/0xf0) from [<c02092d4>] (mxs_mmc_ac+0x90/0xb4)
[    1.180000]  r8:c03a7120 r7:c037cc98 r6:c798fe14 r5:c798fe14 r4:c79972e0
[    1.180000] [<c0209244>] (mxs_mmc_ac+0x0/0xb4) from [<c0209640>] (mxs_mmc_start_cmd+0xb0/0xec)
[    1.180000]  r4:c79972e0
[    1.180000] [<c0209590>] (mxs_mmc_start_cmd+0x0/0xec) from [<c02096bc>] (mxs_mmc_request+0x40/0x4c)
[    1.180000]  r4:c79972e0
[    1.180000] [<c020967c>] (mxs_mmc_request+0x0/0x4c) from [<c01fe700>] (mmc_request_done+0x9c/0x18c)
[    1.180000]  r5:c7997000 r4:c798fe48
[    1.180000] [<c01fe664>] (mmc_request_done+0x0/0x18c) from [<c0209828>] (mxs_mmc_request_done+0x160/0x16c)
[    1.180000]  r6:c798fe14 r5:00000000 r4:c79972e0
[    1.180000] [<c02096c8>] (mxs_mmc_request_done+0x0/0x16c) from [<c0209848>] (mxs_mmc_dma_irq_callback+0x14/0x18)
[    1.180000]  r6:20000013 r5:c78190dc r4:c7819080
[    1.180000] [<c0209834>] (mxs_mmc_dma_irq_callback+0x0/0x18) from [<c01fd80c>] (mxs_dma_tasklet+0x3c/0x5c)
[    1.180000] [<c01fd7d0>] (mxs_dma_tasklet+0x0/0x5c) from [<c0052ea8>] (tasklet_action+0xac/0x148)
[    1.180000]  r6:c03cb340 r5:c78190c8 r4:00000000
[    1.180000] [<c0052dfc>] (tasklet_action+0x0/0x148) from [<c00536d0>] (__do_softirq+0xe0/0x204)
[    1.180000] [<c00535f0>] (__do_softirq+0x0/0x204) from [<c005384c>] (irq_exit+0x58/0xa0)
[    1.180000] [<c00537f4>] (irq_exit+0x0/0xa0) from [<c002f084>] (asm_do_IRQ+0x84/0xa4)
[    1.180000] [<c002f000>] (asm_do_IRQ+0x0/0xa4) from [<c0035ad8>] (__irq_svc+0x38/0x80)
[    1.180000] Exception stack(0xc0375f20 to 0xc0375f68)
[    1.180000] 5f20: 00000001 00000004 0005217f 20000013 c0374000 c037a210 c03aa768 00000002
[    1.180000] 5f40: 4001ee3c 41069265 4001ee08 c0375f74 c0375f38 c0375f68 c007ea54 c0037164
[    1.180000] 5f60: 20000013 ffffffff
[    1.180000]  r5:f5000000 r4:ffffffff
[    1.180000] [<c003712c>] (default_idle+0x0/0x3c) from [<c0037750>] (cpu_idle+0x78/0xc8)
[    1.180000] [<c00376d8>] (cpu_idle+0x0/0xc8) from [<c02a1330>] (rest_init+0xb0/0xd8)
[    1.180000]  r6:c037ed58 r5:00000001 r4:00000000
[    1.180000] [<c02a1280>] (rest_init+0x0/0xd8) from [<c0008b54>] (start_kernel+0x264/0x2b8)
[    1.180000]  r7:c037a198 r6:c002025c r5:c03aa6e0 r4:c0376ee8
[    1.180000] [<c00088f0>] (start_kernel+0x0/0x2b8) from [<40008034>] (0x40008034)
[    1.180000]  r6:c0020660 r5:c037602c r4:00053175

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-14  2:32   ` Shawn Guo
@ 2011-02-14 16:59     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 64+ messages in thread
From: Russell King - ARM Linux @ 2011-02-14 16:59 UTC (permalink / raw)
  To: Shawn Guo; +Cc: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel

On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> +	switch (mmc_resp_type(cmd)) {
> +	case MMC_RSP_NONE:
> +		break;
> +	case MMC_RSP_R1:
> +	case MMC_RSP_R1B:
> +	case MMC_RSP_R3:
> +		cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0);
> +		break;
> +	case MMC_RSP_R2:
> +		cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0);
> +		cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1);
> +		cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2);
> +		cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3);

You really should be testing for MMC_RSP_PRESENT and MMC_RSP_136
here.  The response types are made up of a bitfield which allows
you to detect what's required rather than having to decode the
response type itself.

> +		else if (stat & BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ)
> +			data->error = -ENODATA;
> +		else if (stat & BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
> +			data->error = -EOVERFLOW;

Both of these have a common error code - -EIO.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-14 16:59     ` Russell King - ARM Linux
  0 siblings, 0 replies; 64+ messages in thread
From: Russell King - ARM Linux @ 2011-02-14 16:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> +	switch (mmc_resp_type(cmd)) {
> +	case MMC_RSP_NONE:
> +		break;
> +	case MMC_RSP_R1:
> +	case MMC_RSP_R1B:
> +	case MMC_RSP_R3:
> +		cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0);
> +		break;
> +	case MMC_RSP_R2:
> +		cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0);
> +		cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1);
> +		cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2);
> +		cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3);

You really should be testing for MMC_RSP_PRESENT and MMC_RSP_136
here.  The response types are made up of a bitfield which allows
you to detect what's required rather than having to decode the
response type itself.

> +		else if (stat & BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ)
> +			data->error = -ENODATA;
> +		else if (stat & BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
> +			data->error = -EOVERFLOW;

Both of these have a common error code - -EIO.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-15 22:03       ` Shawn Guo
@ 2011-02-15 14:13         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 64+ messages in thread
From: Russell King - ARM Linux @ 2011-02-15 14:13 UTC (permalink / raw)
  To: Shawn Guo; +Cc: arnd, s.hauer, linux-mmc, cjb, linux-arm-kernel, LW

On Wed, Feb 16, 2011 at 06:03:12AM +0800, Shawn Guo wrote:
> On Mon, Feb 14, 2011 at 04:59:59PM +0000, Russell King - ARM Linux wrote:
> > You really should be testing for MMC_RSP_PRESENT and MMC_RSP_136
> > here.  The response types are made up of a bitfield which allows
> > you to detect what's required rather than having to decode the
> > response type itself.
> > 
> Please review the update.
> 
>         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);
>                         cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1);
>                         cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2);
>                         cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3);
>                 } else {
>                         cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0);
>                 }
>         }

Looks right to me.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-15 14:13         ` Russell King - ARM Linux
  0 siblings, 0 replies; 64+ messages in thread
From: Russell King - ARM Linux @ 2011-02-15 14:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 16, 2011 at 06:03:12AM +0800, Shawn Guo wrote:
> On Mon, Feb 14, 2011 at 04:59:59PM +0000, Russell King - ARM Linux wrote:
> > You really should be testing for MMC_RSP_PRESENT and MMC_RSP_136
> > here.  The response types are made up of a bitfield which allows
> > you to detect what's required rather than having to decode the
> > response type itself.
> > 
> Please review the update.
> 
>         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);
>                         cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1);
>                         cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2);
>                         cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3);
>                 } else {
>                         cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0);
>                 }
>         }

Looks right to me.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-15 22:39       ` Shawn Guo
@ 2011-02-15 17:13         ` Wolfram Sang
  -1 siblings, 0 replies; 64+ messages in thread
From: Wolfram Sang @ 2011-02-15 17:13 UTC (permalink / raw)
  To: Shawn Guo; +Cc: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel


> Ah, yes.  I can also see the problem here after turning on
> DEBUG_SPINLOCK.

Ah, okay. After turning it off, it works a lot better :)

SD seems to work:

	mmc0: new high speed SD card at address b368
	mmcblk0: mmc0:b368 NCard 1.86 GiB 
	 mmcblk0: p1
	mmc0: card b368 removed

SDHC seems to work:

	mmc0: new high speed SDHC card at address 0007
	mmcblk0: mmc0:0007 SD04G 3.70 GiB 
	 mmcblk0: p1
	mmc0: card 0007 removed

MMC fails for me (note: the card works fine with an mx35-based board)

	mmc0: new high speed MMC card at address 0001
	mmcblk0: mmc0:0001 AF HMP 247 MiB 
	mmcblk0: retrying using single block read
	mmcblk0: error -84 transferring data, sector 0, nr 8, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 0
	mmcblk0: error -84 transferring data, sector 1, nr 7, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 1
	mmcblk0: error -84 transferring data, sector 2, nr 6, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 2
	mmcblk0: error -84 transferring data, sector 3, nr 5, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 3
	mmcblk0: error -84 transferring data, sector 4, nr 4, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 4
	mmcblk0: error -84 transferring data, sector 5, nr 3, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 5
	mmcblk0: error -84 transferring data, sector 6, nr 2, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 6
	mmcblk0: error -84 transferring data, sector 7, nr 1, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 7
	Buffer I/O error on device mmcblk0, logical block 0
	mmcblk0: retrying using single block read
	mmcblk0: error -84 transferring data, sector 0, nr 8, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 0
	mmcblk0: error -84 transferring data, sector 1, nr 7, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 1
	mmcblk0: error -84 transferring data, sector 2, nr 6, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 2
	mmcblk0: error -84 transferring data, sector 3, nr 5, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 3
	mmcblk0: error -84 transferring data, sector 4, nr 4, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 4
	mmcblk0: error -84 transferring data, sector 5, nr 3, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 5
	mmcblk0: error -84 transferring data, sector 6, nr 2, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 6
	mmcblk0: error -84 transferring data, sector 7, nr 1, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 7
	Buffer I/O error on device mmcblk0, logical block 0
	 mmcblk0: unable to read partition table
	mmc0: card 0001 removed

SDIO card locks the machine. Is it supposed to work already?

Regards,

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-15 17:13         ` Wolfram Sang
  0 siblings, 0 replies; 64+ messages in thread
From: Wolfram Sang @ 2011-02-15 17:13 UTC (permalink / raw)
  To: linux-arm-kernel


> Ah, yes.  I can also see the problem here after turning on
> DEBUG_SPINLOCK.

Ah, okay. After turning it off, it works a lot better :)

SD seems to work:

	mmc0: new high speed SD card at address b368
	mmcblk0: mmc0:b368 NCard 1.86 GiB 
	 mmcblk0: p1
	mmc0: card b368 removed

SDHC seems to work:

	mmc0: new high speed SDHC card at address 0007
	mmcblk0: mmc0:0007 SD04G 3.70 GiB 
	 mmcblk0: p1
	mmc0: card 0007 removed

MMC fails for me (note: the card works fine with an mx35-based board)

	mmc0: new high speed MMC card at address 0001
	mmcblk0: mmc0:0001 AF HMP 247 MiB 
	mmcblk0: retrying using single block read
	mmcblk0: error -84 transferring data, sector 0, nr 8, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 0
	mmcblk0: error -84 transferring data, sector 1, nr 7, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 1
	mmcblk0: error -84 transferring data, sector 2, nr 6, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 2
	mmcblk0: error -84 transferring data, sector 3, nr 5, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 3
	mmcblk0: error -84 transferring data, sector 4, nr 4, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 4
	mmcblk0: error -84 transferring data, sector 5, nr 3, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 5
	mmcblk0: error -84 transferring data, sector 6, nr 2, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 6
	mmcblk0: error -84 transferring data, sector 7, nr 1, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 7
	Buffer I/O error on device mmcblk0, logical block 0
	mmcblk0: retrying using single block read
	mmcblk0: error -84 transferring data, sector 0, nr 8, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 0
	mmcblk0: error -84 transferring data, sector 1, nr 7, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 1
	mmcblk0: error -84 transferring data, sector 2, nr 6, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 2
	mmcblk0: error -84 transferring data, sector 3, nr 5, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 3
	mmcblk0: error -84 transferring data, sector 4, nr 4, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 4
	mmcblk0: error -84 transferring data, sector 5, nr 3, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 5
	mmcblk0: error -84 transferring data, sector 6, nr 2, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 6
	mmcblk0: error -84 transferring data, sector 7, nr 1, card status 0x900
	end_request: I/O error, dev mmcblk0, sector 7
	Buffer I/O error on device mmcblk0, logical block 0
	 mmcblk0: unable to read partition table
	mmc0: card 0001 removed

SDIO card locks the machine. Is it supposed to work already?

Regards,

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-15 17:13         ` Wolfram Sang
@ 2011-02-15 17:19           ` Russell King - ARM Linux
  -1 siblings, 0 replies; 64+ messages in thread
From: Russell King - ARM Linux @ 2011-02-15 17:19 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Shawn Guo, arnd, s.hauer, linux-mmc, cjb, linux-arm-kernel, LW

On Tue, Feb 15, 2011 at 06:13:41PM +0100, Wolfram Sang wrote:
> 
> > Ah, yes.  I can also see the problem here after turning on
> > DEBUG_SPINLOCK.
> 
> Ah, okay. After turning it off, it works a lot better :)

That doesn't mean the problem is fixed.  The spinlock debugging is there
to find broken code, and it's saying that the code is broken, and in
this case its saying that there's potential for deadlock.

> MMC fails for me (note: the card works fine with an mx35-based board)
> 
> 	mmc0: new high speed MMC card at address 0001
> 	mmcblk0: mmc0:0001 AF HMP 247 MiB 
> 	mmcblk0: retrying using single block read
> 	mmcblk0: error -84 transferring data, sector 0, nr 8, card status 0x900
> 	end_request: I/O error, dev mmcblk0, sector 0

EILSEQ means CRC failure.  Probably unrelated.

> SDIO card locks the machine. Is it supposed to work already?

Guess it's the spinlock causing that problem.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-15 17:19           ` Russell King - ARM Linux
  0 siblings, 0 replies; 64+ messages in thread
From: Russell King - ARM Linux @ 2011-02-15 17:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 15, 2011 at 06:13:41PM +0100, Wolfram Sang wrote:
> 
> > Ah, yes.  I can also see the problem here after turning on
> > DEBUG_SPINLOCK.
> 
> Ah, okay. After turning it off, it works a lot better :)

That doesn't mean the problem is fixed.  The spinlock debugging is there
to find broken code, and it's saying that the code is broken, and in
this case its saying that there's potential for deadlock.

> MMC fails for me (note: the card works fine with an mx35-based board)
> 
> 	mmc0: new high speed MMC card at address 0001
> 	mmcblk0: mmc0:0001 AF HMP 247 MiB 
> 	mmcblk0: retrying using single block read
> 	mmcblk0: error -84 transferring data, sector 0, nr 8, card status 0x900
> 	end_request: I/O error, dev mmcblk0, sector 0

EILSEQ means CRC failure.  Probably unrelated.

> SDIO card locks the machine. Is it supposed to work already?

Guess it's the spinlock causing that problem.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-15 17:19           ` Russell King - ARM Linux
@ 2011-02-15 17:29             ` Wolfram Sang
  -1 siblings, 0 replies; 64+ messages in thread
From: Wolfram Sang @ 2011-02-15 17:29 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: Shawn Guo, arnd, s.hauer, linux-mmc, cjb, linux-arm-kernel, LW

On Tue, Feb 15, 2011 at 05:19:17PM +0000, Russell King - ARM Linux wrote:
> On Tue, Feb 15, 2011 at 06:13:41PM +0100, Wolfram Sang wrote:
> > 
> > > Ah, yes.  I can also see the problem here after turning on
> > > DEBUG_SPINLOCK.
> > 
> > Ah, okay. After turning it off, it works a lot better :)
> 
> That doesn't mean the problem is fixed. [...]

Yes, I know that. I should have put the 'works' above in quotes, sorry.

> > MMC fails for me (note: the card works fine with an mx35-based board)
> > 
> > 	mmc0: new high speed MMC card at address 0001
> > 	mmcblk0: mmc0:0001 AF HMP 247 MiB 
> > 	mmcblk0: retrying using single block read
> > 	mmcblk0: error -84 transferring data, sector 0, nr 8, card status 0x900
> > 	end_request: I/O error, dev mmcblk0, sector 0
> 
> EILSEQ means CRC failure.  Probably unrelated.

Even if it works in another setup? As a result of the above, I can't read the
partition table of that MMC. The mx35 can do so.

> > SDIO card locks the machine. Is it supposed to work already?
> 
> Guess it's the spinlock causing that problem.

Yeah, that could be. In addition, I was just generally interested if SDIO has
been tested by Shawn.

Regards,

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-15 17:29             ` Wolfram Sang
  0 siblings, 0 replies; 64+ messages in thread
From: Wolfram Sang @ 2011-02-15 17:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 15, 2011 at 05:19:17PM +0000, Russell King - ARM Linux wrote:
> On Tue, Feb 15, 2011 at 06:13:41PM +0100, Wolfram Sang wrote:
> > 
> > > Ah, yes.  I can also see the problem here after turning on
> > > DEBUG_SPINLOCK.
> > 
> > Ah, okay. After turning it off, it works a lot better :)
> 
> That doesn't mean the problem is fixed. [...]

Yes, I know that. I should have put the 'works' above in quotes, sorry.

> > MMC fails for me (note: the card works fine with an mx35-based board)
> > 
> > 	mmc0: new high speed MMC card at address 0001
> > 	mmcblk0: mmc0:0001 AF HMP 247 MiB 
> > 	mmcblk0: retrying using single block read
> > 	mmcblk0: error -84 transferring data, sector 0, nr 8, card status 0x900
> > 	end_request: I/O error, dev mmcblk0, sector 0
> 
> EILSEQ means CRC failure.  Probably unrelated.

Even if it works in another setup? As a result of the above, I can't read the
partition table of that MMC. The mx35 can do so.

> > SDIO card locks the machine. Is it supposed to work already?
> 
> Guess it's the spinlock causing that problem.

Yeah, that could be. In addition, I was just generally interested if SDIO has
been tested by Shawn.

Regards,

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-15 17:29             ` Wolfram Sang
@ 2011-02-15 17:32               ` Russell King - ARM Linux
  -1 siblings, 0 replies; 64+ messages in thread
From: Russell King - ARM Linux @ 2011-02-15 17:32 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Shawn Guo, arnd, s.hauer, linux-mmc, cjb, linux-arm-kernel, LW

On Tue, Feb 15, 2011 at 06:29:48PM +0100, Wolfram Sang wrote:
> On Tue, Feb 15, 2011 at 05:19:17PM +0000, Russell King - ARM Linux wrote:
> > On Tue, Feb 15, 2011 at 06:13:41PM +0100, Wolfram Sang wrote:
> > > MMC fails for me (note: the card works fine with an mx35-based board)
> > > 
> > > 	mmc0: new high speed MMC card at address 0001
> > > 	mmcblk0: mmc0:0001 AF HMP 247 MiB 
> > > 	mmcblk0: retrying using single block read
> > > 	mmcblk0: error -84 transferring data, sector 0, nr 8, card status 0x900
> > > 	end_request: I/O error, dev mmcblk0, sector 0
> > 
> > EILSEQ means CRC failure.  Probably unrelated.
> 
> Even if it works in another setup? As a result of the above, I can't read the
> partition table of that MMC. The mx35 can do so.

CRC is generated to protect the link between the card and the host.  It
means that the CRC computed by the card for the transfer and the CRC
computed by the host didn't match.

In other words, data was corrupted in some way between the card and the
MMC host.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-15 17:32               ` Russell King - ARM Linux
  0 siblings, 0 replies; 64+ messages in thread
From: Russell King - ARM Linux @ 2011-02-15 17:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 15, 2011 at 06:29:48PM +0100, Wolfram Sang wrote:
> On Tue, Feb 15, 2011 at 05:19:17PM +0000, Russell King - ARM Linux wrote:
> > On Tue, Feb 15, 2011 at 06:13:41PM +0100, Wolfram Sang wrote:
> > > MMC fails for me (note: the card works fine with an mx35-based board)
> > > 
> > > 	mmc0: new high speed MMC card at address 0001
> > > 	mmcblk0: mmc0:0001 AF HMP 247 MiB 
> > > 	mmcblk0: retrying using single block read
> > > 	mmcblk0: error -84 transferring data, sector 0, nr 8, card status 0x900
> > > 	end_request: I/O error, dev mmcblk0, sector 0
> > 
> > EILSEQ means CRC failure.  Probably unrelated.
> 
> Even if it works in another setup? As a result of the above, I can't read the
> partition table of that MMC. The mx35 can do so.

CRC is generated to protect the link between the card and the host.  It
means that the CRC computed by the card for the transfer and the CRC
computed by the host didn't match.

In other words, data was corrupted in some way between the card and the
MMC host.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-13 19:26     ` Chris Ball
@ 2011-02-15 21:26       ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-15 21:26 UTC (permalink / raw)
  To: Chris Ball; +Cc: s.hauer, arnd, LW, linux-mmc, linux-arm-kernel

Hi Chris,

On Sun, Feb 13, 2011 at 07:26:09PM +0000, Chris Ball wrote:
> Hi Shawn,
> 
> On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> > This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
> > The driver calls into mxs-dma via generic dmaengine api for both pio
> > and data transfer.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> 
> Please add a Reviewed-by: from Arnd and a Tested-by: from Lothar.
> Could you add a MODULE_AUTHOR() field, too?
> 
OK.  It will be - MODULE_AUTHOR("Freescale Semiconductor");

> I could take the drivers/mmc files through the MMC tree and have you
> submit the architecture patches separately, or you can send everything
> through an ARM tree with my ACK -- whichever you prefer.
> 
I will send this single patch in v3 with new comments/concerns
addressed for you to pick up on  MMC tree, and follow up others with
Sascha.

> Here's an indentation patch:
> 
Thanks.

Regards,
Shawn

> diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
> index f359093..3a609f9 100644
> --- a/drivers/mmc/host/mxs-mmc.c
> +++ b/drivers/mmc/host/mxs-mmc.c
> @@ -127,13 +127,13 @@
>  #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_DATA_TIMEOUT_IRQ	| \
> -				BM_SSP_CTRL1_DATA_CRC_IRQ	| \
> -				BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ	| \
> -				BM_SSP_CTRL1_RECV_TIMEOUT_IRQ   | \
> -				BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
> +				 BM_SSP_CTRL1_RESP_ERR_IRQ	| \
> +				 BM_SSP_CTRL1_RESP_TIMEOUT_IRQ	| \
> +				 BM_SSP_CTRL1_DATA_TIMEOUT_IRQ	| \
> +				 BM_SSP_CTRL1_DATA_CRC_IRQ	| \
> +				 BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ	| \
> +				 BM_SSP_CTRL1_RECV_TIMEOUT_IRQ  | \
> +				 BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
>  
>  #define SSP_PIO_NUM	3
>  
> @@ -165,7 +165,7 @@ static int mxs_mmc_get_ro(struct mmc_host *mmc)
>  {
>  	struct mxs_mmc_host *host = mmc_priv(mmc);
>  	struct mxs_mmc_platform_data *pdata =
> -			mmc_dev(host->mmc)->platform_data;
> +		mmc_dev(host->mmc)->platform_data;
>  
>  	if (!pdata)
>  		return -EFAULT;
> @@ -181,7 +181,7 @@ static int mxs_mmc_get_cd(struct mmc_host *mmc)
>  	struct mxs_mmc_host *host = mmc_priv(mmc);
>  
>  	return !(readl(host->base + HW_SSP_STATUS) &
> -			BM_SSP_STATUS_CARD_DETECT);
> +		 BM_SSP_STATUS_CARD_DETECT);
>  }
>  
>  static void mxs_mmc_reset(struct mxs_mmc_host *host)
> @@ -202,21 +202,21 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
>  		BM_SSP_CTRL1_RESP_ERR_IRQ_EN;
>  
>  	writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
> -		     BF_SSP(2, TIMING_CLOCK_DIVIDE) |
> -		     BF_SSP(0, TIMING_CLOCK_RATE),
> -		     host->base + HW_SSP_TIMING);
> +	       BF_SSP(2, TIMING_CLOCK_DIVIDE) |
> +	       BF_SSP(0, TIMING_CLOCK_RATE),
> +	       host->base + HW_SSP_TIMING);
>  
>  	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);
>  }
>  
>  static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
> -				struct mmc_command *cmd);
> +			      struct mmc_command *cmd);
>  
>  static void mxs_mmc_request_done(struct mxs_mmc_host *host)
>  {
> @@ -240,13 +240,13 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
>  		break;
>  	default:
>  		dev_warn(mmc_dev(host->mmc),
> -			"%s: unsupported response type 0x%x\n",
> -			__func__, mmc_resp_type(cmd));
> +			 "%s: unsupported response type 0x%x\n",
> +			 __func__, mmc_resp_type(cmd));
>  	}
>  
>  	if (data) {
>  		dma_unmap_sg(mmc_dev(host->mmc), data->sg,
> -				data->sg_len, host->dma_dir);
> +			     data->sg_len, host->dma_dir);
>  		/*
>  		 * If there was an error on any block, we mark all
>  		 * data blocks as being in error.
> @@ -285,7 +285,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
>  
>  	stat = readl(host->base + HW_SSP_CTRL1);
>  	writel(stat & MXS_MMC_IRQ_BITS,
> -		host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
> +	       host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
>  
>  	if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
>  		mmc_signal_sdio_irq(host->mmc);
> @@ -299,7 +299,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
>  
>  	if (data) {
>  		if (stat & (BM_SSP_CTRL1_DATA_TIMEOUT_IRQ |
> -				BM_SSP_CTRL1_RECV_TIMEOUT_IRQ))
> +			    BM_SSP_CTRL1_RECV_TIMEOUT_IRQ))
>  			data->error = -ETIMEDOUT;
>  		else if (stat & BM_SSP_CTRL1_DATA_CRC_IRQ)
>  			data->error = -EILSEQ;
> @@ -313,7 +313,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 int append)
> +	struct mxs_mmc_host *host, unsigned int append)
>  {
>  	struct dma_async_tx_descriptor *desc;
>  	struct mmc_data *data = host->data;
> @@ -323,7 +323,7 @@ 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, host->dma_dir);
>  		sgl = data->sg;
>  		sg_len = data->sg_len;
>  	} else {
> @@ -340,7 +340,7 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
>  	} else {
>  		if (data)
>  			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
> -					data->sg_len, host->dma_dir);
> +				     data->sg_len, host->dma_dir);
>  	}
>  
>  	return desc;
> @@ -374,7 +374,7 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host)
>  
>  out:
>  	dev_warn(mmc_dev(host->mmc),
> -		"%s: failed to prep dma\n", __func__);
> +		 "%s: failed to prep dma\n", __func__);
>  }
>  
>  static void mxs_mmc_ac(struct mxs_mmc_host *host)
> @@ -413,7 +413,7 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host)
>  
>  out:
>  	dev_warn(mmc_dev(host->mmc),
> -		"%s: failed to prep dma\n", __func__);
> +		 "%s: failed to prep dma\n", __func__);
>  }
>  
>  static unsigned short mxs_ns_to_ssp_ticks(unsigned clock_rate, unsigned ns)
> @@ -492,12 +492,12 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
>  	} else {
>  		writel(data_size, host->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);
> +		       BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT),
> +		       host->base + HW_SSP_BLOCK_SIZE);
>  	}
>  
>  	if ((cmd->opcode == MMC_STOP_TRANSMISSION) ||
> -			(cmd->opcode == SD_IO_RW_EXTENDED))
> +	    (cmd->opcode == SD_IO_RW_EXTENDED))
>  		cmd0 |= BM_SSP_CMD0_APPEND_8CYC;
>  
>  	cmd1 = cmd->arg;
> @@ -535,11 +535,11 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
>  	return;
>  out:
>  	dev_warn(mmc_dev(host->mmc),
> -		"%s: failed to prep dma\n", __func__);
> +		 "%s: failed to prep dma\n", __func__);
>  }
>  
>  static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
> -				   struct mmc_command *cmd)
> +			      struct mmc_command *cmd)
>  {
>  	host->cmd = cmd;
>  
> @@ -558,7 +558,7 @@ static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
>  		break;
>  	default:
>  		dev_warn(mmc_dev(host->mmc),
> -			"%s: unknown MMC command\n", __func__);
> +			 "%s: unknown MMC command\n", __func__);
>  		break;
>  	}
>  }
> @@ -636,18 +636,18 @@ 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 + MXS_SET_ADDR);
> +		       host->base + HW_SSP_CTRL0 + MXS_SET_ADDR);
>  		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
> -			host->base + HW_SSP_CTRL1 + MXS_SET_ADDR);
> +		       host->base + HW_SSP_CTRL1 + MXS_SET_ADDR);
>  
>  		if (readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ)
>  			mmc_signal_sdio_irq(host->mmc);
>  
>  	} else {
>  		writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
> -			host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR);
> +		       host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR);
>  		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
> -			host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
> +		       host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
>  	}
>  
>  	spin_unlock_irqrestore(&host->lock, flags);
> @@ -710,7 +710,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
>  
>  	/* only major verion does matter */
>  	host->version = readl(host->base + HW_SSP_VERSION) >>
> -				BP_SSP_VERSION_MAJOR;
> +			BP_SSP_VERSION_MAJOR;
>  
>  	host->mmc = mmc;
>  	host->res = r;
> @@ -755,8 +755,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
>  
>  	platform_set_drvdata(pdev, mmc);
>  
> -	ret = request_irq(host->irq, mxs_mmc_irq_handler, 0,
> -				DRIVER_NAME, host);
> +	ret = request_irq(host->irq, mxs_mmc_irq_handler, 0, DRIVER_NAME, host);
>  	if (ret)
>  		goto out_free_dma;
>  
> -- 
> Chris Ball   <cjb@laptop.org>   <http://printf.net/>
> One Laptop Per Child
> 


^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-15 21:26       ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-15 21:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Chris,

On Sun, Feb 13, 2011 at 07:26:09PM +0000, Chris Ball wrote:
> Hi Shawn,
> 
> On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> > This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
> > The driver calls into mxs-dma via generic dmaengine api for both pio
> > and data transfer.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> 
> Please add a Reviewed-by: from Arnd and a Tested-by: from Lothar.
> Could you add a MODULE_AUTHOR() field, too?
> 
OK.  It will be - MODULE_AUTHOR("Freescale Semiconductor");

> I could take the drivers/mmc files through the MMC tree and have you
> submit the architecture patches separately, or you can send everything
> through an ARM tree with my ACK -- whichever you prefer.
> 
I will send this single patch in v3 with new comments/concerns
addressed for you to pick up on  MMC tree, and follow up others with
Sascha.

> Here's an indentation patch:
> 
Thanks.

Regards,
Shawn

> diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
> index f359093..3a609f9 100644
> --- a/drivers/mmc/host/mxs-mmc.c
> +++ b/drivers/mmc/host/mxs-mmc.c
> @@ -127,13 +127,13 @@
>  #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_DATA_TIMEOUT_IRQ	| \
> -				BM_SSP_CTRL1_DATA_CRC_IRQ	| \
> -				BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ	| \
> -				BM_SSP_CTRL1_RECV_TIMEOUT_IRQ   | \
> -				BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
> +				 BM_SSP_CTRL1_RESP_ERR_IRQ	| \
> +				 BM_SSP_CTRL1_RESP_TIMEOUT_IRQ	| \
> +				 BM_SSP_CTRL1_DATA_TIMEOUT_IRQ	| \
> +				 BM_SSP_CTRL1_DATA_CRC_IRQ	| \
> +				 BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ	| \
> +				 BM_SSP_CTRL1_RECV_TIMEOUT_IRQ  | \
> +				 BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
>  
>  #define SSP_PIO_NUM	3
>  
> @@ -165,7 +165,7 @@ static int mxs_mmc_get_ro(struct mmc_host *mmc)
>  {
>  	struct mxs_mmc_host *host = mmc_priv(mmc);
>  	struct mxs_mmc_platform_data *pdata =
> -			mmc_dev(host->mmc)->platform_data;
> +		mmc_dev(host->mmc)->platform_data;
>  
>  	if (!pdata)
>  		return -EFAULT;
> @@ -181,7 +181,7 @@ static int mxs_mmc_get_cd(struct mmc_host *mmc)
>  	struct mxs_mmc_host *host = mmc_priv(mmc);
>  
>  	return !(readl(host->base + HW_SSP_STATUS) &
> -			BM_SSP_STATUS_CARD_DETECT);
> +		 BM_SSP_STATUS_CARD_DETECT);
>  }
>  
>  static void mxs_mmc_reset(struct mxs_mmc_host *host)
> @@ -202,21 +202,21 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
>  		BM_SSP_CTRL1_RESP_ERR_IRQ_EN;
>  
>  	writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
> -		     BF_SSP(2, TIMING_CLOCK_DIVIDE) |
> -		     BF_SSP(0, TIMING_CLOCK_RATE),
> -		     host->base + HW_SSP_TIMING);
> +	       BF_SSP(2, TIMING_CLOCK_DIVIDE) |
> +	       BF_SSP(0, TIMING_CLOCK_RATE),
> +	       host->base + HW_SSP_TIMING);
>  
>  	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);
>  }
>  
>  static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
> -				struct mmc_command *cmd);
> +			      struct mmc_command *cmd);
>  
>  static void mxs_mmc_request_done(struct mxs_mmc_host *host)
>  {
> @@ -240,13 +240,13 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
>  		break;
>  	default:
>  		dev_warn(mmc_dev(host->mmc),
> -			"%s: unsupported response type 0x%x\n",
> -			__func__, mmc_resp_type(cmd));
> +			 "%s: unsupported response type 0x%x\n",
> +			 __func__, mmc_resp_type(cmd));
>  	}
>  
>  	if (data) {
>  		dma_unmap_sg(mmc_dev(host->mmc), data->sg,
> -				data->sg_len, host->dma_dir);
> +			     data->sg_len, host->dma_dir);
>  		/*
>  		 * If there was an error on any block, we mark all
>  		 * data blocks as being in error.
> @@ -285,7 +285,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
>  
>  	stat = readl(host->base + HW_SSP_CTRL1);
>  	writel(stat & MXS_MMC_IRQ_BITS,
> -		host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
> +	       host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
>  
>  	if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
>  		mmc_signal_sdio_irq(host->mmc);
> @@ -299,7 +299,7 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
>  
>  	if (data) {
>  		if (stat & (BM_SSP_CTRL1_DATA_TIMEOUT_IRQ |
> -				BM_SSP_CTRL1_RECV_TIMEOUT_IRQ))
> +			    BM_SSP_CTRL1_RECV_TIMEOUT_IRQ))
>  			data->error = -ETIMEDOUT;
>  		else if (stat & BM_SSP_CTRL1_DATA_CRC_IRQ)
>  			data->error = -EILSEQ;
> @@ -313,7 +313,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 int append)
> +	struct mxs_mmc_host *host, unsigned int append)
>  {
>  	struct dma_async_tx_descriptor *desc;
>  	struct mmc_data *data = host->data;
> @@ -323,7 +323,7 @@ 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, host->dma_dir);
>  		sgl = data->sg;
>  		sg_len = data->sg_len;
>  	} else {
> @@ -340,7 +340,7 @@ static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
>  	} else {
>  		if (data)
>  			dma_unmap_sg(mmc_dev(host->mmc), data->sg,
> -					data->sg_len, host->dma_dir);
> +				     data->sg_len, host->dma_dir);
>  	}
>  
>  	return desc;
> @@ -374,7 +374,7 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host)
>  
>  out:
>  	dev_warn(mmc_dev(host->mmc),
> -		"%s: failed to prep dma\n", __func__);
> +		 "%s: failed to prep dma\n", __func__);
>  }
>  
>  static void mxs_mmc_ac(struct mxs_mmc_host *host)
> @@ -413,7 +413,7 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host)
>  
>  out:
>  	dev_warn(mmc_dev(host->mmc),
> -		"%s: failed to prep dma\n", __func__);
> +		 "%s: failed to prep dma\n", __func__);
>  }
>  
>  static unsigned short mxs_ns_to_ssp_ticks(unsigned clock_rate, unsigned ns)
> @@ -492,12 +492,12 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
>  	} else {
>  		writel(data_size, host->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);
> +		       BF_SSP(blocks - 1, BLOCK_SIZE_BLOCK_COUNT),
> +		       host->base + HW_SSP_BLOCK_SIZE);
>  	}
>  
>  	if ((cmd->opcode == MMC_STOP_TRANSMISSION) ||
> -			(cmd->opcode == SD_IO_RW_EXTENDED))
> +	    (cmd->opcode == SD_IO_RW_EXTENDED))
>  		cmd0 |= BM_SSP_CMD0_APPEND_8CYC;
>  
>  	cmd1 = cmd->arg;
> @@ -535,11 +535,11 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
>  	return;
>  out:
>  	dev_warn(mmc_dev(host->mmc),
> -		"%s: failed to prep dma\n", __func__);
> +		 "%s: failed to prep dma\n", __func__);
>  }
>  
>  static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
> -				   struct mmc_command *cmd)
> +			      struct mmc_command *cmd)
>  {
>  	host->cmd = cmd;
>  
> @@ -558,7 +558,7 @@ static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
>  		break;
>  	default:
>  		dev_warn(mmc_dev(host->mmc),
> -			"%s: unknown MMC command\n", __func__);
> +			 "%s: unknown MMC command\n", __func__);
>  		break;
>  	}
>  }
> @@ -636,18 +636,18 @@ 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 + MXS_SET_ADDR);
> +		       host->base + HW_SSP_CTRL0 + MXS_SET_ADDR);
>  		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
> -			host->base + HW_SSP_CTRL1 + MXS_SET_ADDR);
> +		       host->base + HW_SSP_CTRL1 + MXS_SET_ADDR);
>  
>  		if (readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ)
>  			mmc_signal_sdio_irq(host->mmc);
>  
>  	} else {
>  		writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
> -			host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR);
> +		       host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR);
>  		writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
> -			host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
> +		       host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR);
>  	}
>  
>  	spin_unlock_irqrestore(&host->lock, flags);
> @@ -710,7 +710,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
>  
>  	/* only major verion does matter */
>  	host->version = readl(host->base + HW_SSP_VERSION) >>
> -				BP_SSP_VERSION_MAJOR;
> +			BP_SSP_VERSION_MAJOR;
>  
>  	host->mmc = mmc;
>  	host->res = r;
> @@ -755,8 +755,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
>  
>  	platform_set_drvdata(pdev, mmc);
>  
> -	ret = request_irq(host->irq, mxs_mmc_irq_handler, 0,
> -				DRIVER_NAME, host);
> +	ret = request_irq(host->irq, mxs_mmc_irq_handler, 0, DRIVER_NAME, host);
>  	if (ret)
>  		goto out_free_dma;
>  
> -- 
> Chris Ball   <cjb@laptop.org>   <http://printf.net/>
> One Laptop Per Child
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-13 22:35       ` Arnd Bergmann
@ 2011-02-15 21:27         ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-15 21:27 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: s.hauer, Chris Ball, linux-mmc, linux-arm-kernel, LW

On Sun, Feb 13, 2011 at 11:35:54PM +0100, Arnd Bergmann wrote:
> On Sunday 13 February 2011, Chris Ball wrote:
> > On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> > > This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
> > > The driver calls into mxs-dma via generic dmaengine api for both pio
> > > and data transfer.
> > > 
> > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > 
> > Please add a Reviewed-by: from Arnd and a Tested-by: from Lothar.
> > Could you add a MODULE_AUTHOR() field, too?
> 
> In general, these tags should not simply be added by the author without
> having the person who did the reviewing or testing specifically provide
> them!
> 
> In this particular case, I'm happy with the driver in version 2, good job!
> Please do add my
> 
> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
> 
Will do.  Appreciate the review effort.

Regards,
Shawn

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-15 21:27         ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-15 21:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Sun, Feb 13, 2011 at 11:35:54PM +0100, Arnd Bergmann wrote:
> On Sunday 13 February 2011, Chris Ball wrote:
> > On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> > > This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
> > > The driver calls into mxs-dma via generic dmaengine api for both pio
> > > and data transfer.
> > > 
> > > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > 
> > Please add a Reviewed-by: from Arnd and a Tested-by: from Lothar.
> > Could you add a MODULE_AUTHOR() field, too?
> 
> In general, these tags should not simply be added by the author without
> having the person who did the reviewing or testing specifically provide
> them!
> 
> In this particular case, I'm happy with the driver in version 2, good job!
> Please do add my
> 
> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
> 
Will do.  Appreciate the review effort.

Regards,
Shawn

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-14 15:39     ` Wolfram Sang
@ 2011-02-15 21:28       ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-15 21:28 UTC (permalink / raw)
  To: Wolfram Sang; +Cc: arnd, s.hauer, linux-mmc, cjb, linux-arm-kernel, LW

Hi Wolfram,

On Mon, Feb 14, 2011 at 04:39:52PM +0100, Wolfram Sang wrote:
> > diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> > index afe8c6f..42a9e21 100644
> > --- a/drivers/mmc/host/Kconfig
> > +++ b/drivers/mmc/host/Kconfig
> > @@ -319,6 +319,15 @@ config MMC_MXC
> >  
> >  	  If unsure, say N.
> >  
> > +config MMC_MXS
> > +	tristate "Freescale MXS Multimedia Card Interface support"
> > +	depends on ARCH_MXS
> > +	help
> > +	  This selects the Freescale SSP MMC controller found on MXS based
> > +	  platforms like mx23/28.
> > +
> > +	  If unsure, say N.
> > +
> 
> It should also depend on MXS_DMA?
> 
Good point.  Will do.

Regards,
Shawn

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-15 21:28       ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-15 21:28 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Wolfram,

On Mon, Feb 14, 2011 at 04:39:52PM +0100, Wolfram Sang wrote:
> > diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> > index afe8c6f..42a9e21 100644
> > --- a/drivers/mmc/host/Kconfig
> > +++ b/drivers/mmc/host/Kconfig
> > @@ -319,6 +319,15 @@ config MMC_MXC
> >  
> >  	  If unsure, say N.
> >  
> > +config MMC_MXS
> > +	tristate "Freescale MXS Multimedia Card Interface support"
> > +	depends on ARCH_MXS
> > +	help
> > +	  This selects the Freescale SSP MMC controller found on MXS based
> > +	  platforms like mx23/28.
> > +
> > +	  If unsure, say N.
> > +
> 
> It should also depend on MXS_DMA?
> 
Good point.  Will do.

Regards,
Shawn

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-14 16:59     ` Russell King - ARM Linux
@ 2011-02-15 22:03       ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-15 22:03 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: arnd, s.hauer, linux-mmc, cjb, linux-arm-kernel, LW

On Mon, Feb 14, 2011 at 04:59:59PM +0000, Russell King - ARM Linux wrote:
> On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> > +	switch (mmc_resp_type(cmd)) {
> > +	case MMC_RSP_NONE:
> > +		break;
> > +	case MMC_RSP_R1:
> > +	case MMC_RSP_R1B:
> > +	case MMC_RSP_R3:
> > +		cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0);
> > +		break;
> > +	case MMC_RSP_R2:
> > +		cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0);
> > +		cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1);
> > +		cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2);
> > +		cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3);
> 
> You really should be testing for MMC_RSP_PRESENT and MMC_RSP_136
> here.  The response types are made up of a bitfield which allows
> you to detect what's required rather than having to decode the
> response type itself.
> 
Please review the update.

        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);
                        cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1);
                        cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2);
                        cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3);
                } else {
                        cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0);
                }
        }

> > +		else if (stat & BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ)
> > +			data->error = -ENODATA;
> > +		else if (stat & BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
> > +			data->error = -EOVERFLOW;
> 
> Both of these have a common error code - -EIO.
> 
OK.  Thanks for teaching.

Regards,
Shawn

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-15 22:03       ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-15 22:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Feb 14, 2011 at 04:59:59PM +0000, Russell King - ARM Linux wrote:
> On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> > +	switch (mmc_resp_type(cmd)) {
> > +	case MMC_RSP_NONE:
> > +		break;
> > +	case MMC_RSP_R1:
> > +	case MMC_RSP_R1B:
> > +	case MMC_RSP_R3:
> > +		cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0);
> > +		break;
> > +	case MMC_RSP_R2:
> > +		cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0);
> > +		cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1);
> > +		cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2);
> > +		cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3);
> 
> You really should be testing for MMC_RSP_PRESENT and MMC_RSP_136
> here.  The response types are made up of a bitfield which allows
> you to detect what's required rather than having to decode the
> response type itself.
> 
Please review the update.

        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);
                        cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1);
                        cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2);
                        cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3);
                } else {
                        cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0);
                }
        }

> > +		else if (stat & BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ)
> > +			data->error = -ENODATA;
> > +		else if (stat & BM_SSP_CTRL1_FIFO_OVERRUN_IRQ)
> > +			data->error = -EOVERFLOW;
> 
> Both of these have a common error code - -EIO.
> 
OK.  Thanks for teaching.

Regards,
Shawn

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-14 16:59     ` Wolfram Sang
@ 2011-02-15 22:39       ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-15 22:39 UTC (permalink / raw)
  To: Wolfram Sang; +Cc: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel

Hi Wolfram,

On Mon, Feb 14, 2011 at 05:59:58PM +0100, Wolfram Sang wrote:
> On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> > This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
> > The driver calls into mxs-dma via generic dmaengine api for both pio
> > and data transfer.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> 
> While trying, I got this lockdep-warning and BUG. It might be that my setup is
> wrong, causing all these timeouts. But they probably are meant to be handled
> more gracefully? I can continue testing tomorrow, maybe this report already
> helps identifying a problem?
> 
Ah, yes.  I can also see the problem here after turning on
DEBUG_SPINLOCK.  I really should always turn it on in daily
development.

Thanks for catching.  I will fix it in v3.

Regards,
Shawn


^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-15 22:39       ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-15 22:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Wolfram,

On Mon, Feb 14, 2011 at 05:59:58PM +0100, Wolfram Sang wrote:
> On Mon, Feb 14, 2011 at 10:32:20AM +0800, Shawn Guo wrote:
> > This adds the mmc host driver for Freescale MXS-based SoC i.MX23/28.
> > The driver calls into mxs-dma via generic dmaengine api for both pio
> > and data transfer.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> 
> While trying, I got this lockdep-warning and BUG. It might be that my setup is
> wrong, causing all these timeouts. But they probably are meant to be handled
> more gracefully? I can continue testing tomorrow, maybe this report already
> helps identifying a problem?
> 
Ah, yes.  I can also see the problem here after turning on
DEBUG_SPINLOCK.  I really should always turn it on in daily
development.

Thanks for catching.  I will fix it in v3.

Regards,
Shawn

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 7/7] ARM: mxs/mx28evk: add mmc device
  2011-02-14 10:26     ` Wolfram Sang
@ 2011-02-15 23:11       ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-15 23:11 UTC (permalink / raw)
  To: Wolfram Sang; +Cc: cjb, s.hauer, arnd, LW, linux-mmc, linux-arm-kernel

On Mon, Feb 14, 2011 at 11:26:46AM +0100, Wolfram Sang wrote:
> Shawn,
> 
> > +/* mmc */
> > +static void __init mx28evk_mmc_slot_poweron(int gpio)
> > +{
> > +	int ret;
> > +
> > +	ret = gpio_request(gpio, "mmc-slot-power");
> > +	if (ret) {
> > +		pr_err("Failed to request gpio mmc-slot-power: %d\n", ret);
> > +		return;
> > +	}
> > +
> > +	ret = gpio_direction_output(gpio, 0);
> > +	if (ret) {
> > +		pr_err("Failed to drive gpio mmc-slot-power: %d\n", ret);
> > +		return;
> > +	}
> > +}
> 
> Minor nit: You could use gpio_request_one(), and doing so maybe even get rid of
> this function and simply do it the init-function. The advantage would be, that
> you can name the two GPIOs independently.
> 
OK. Will take it.

Thanks,
Shawn


^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 7/7] ARM: mxs/mx28evk: add mmc device
@ 2011-02-15 23:11       ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-15 23:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Feb 14, 2011 at 11:26:46AM +0100, Wolfram Sang wrote:
> Shawn,
> 
> > +/* mmc */
> > +static void __init mx28evk_mmc_slot_poweron(int gpio)
> > +{
> > +	int ret;
> > +
> > +	ret = gpio_request(gpio, "mmc-slot-power");
> > +	if (ret) {
> > +		pr_err("Failed to request gpio mmc-slot-power: %d\n", ret);
> > +		return;
> > +	}
> > +
> > +	ret = gpio_direction_output(gpio, 0);
> > +	if (ret) {
> > +		pr_err("Failed to drive gpio mmc-slot-power: %d\n", ret);
> > +		return;
> > +	}
> > +}
> 
> Minor nit: You could use gpio_request_one(), and doing so maybe even get rid of
> this function and simply do it the init-function. The advantage would be, that
> you can name the two GPIOs independently.
> 
OK. Will take it.

Thanks,
Shawn

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-16 20:28               ` Shawn Guo
@ 2011-02-16 15:33                 ` Wolfram Sang
  -1 siblings, 0 replies; 64+ messages in thread
From: Wolfram Sang @ 2011-02-16 15:33 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Russell King - ARM Linux, arnd, s.hauer, linux-mmc, cjb,
	linux-arm-kernel, LW

Hi Shawn,

[CRC failures on MMC]
> I guess you will also get the unknown partition table message if you
> test this card on mx35 right now.

No, I didn't see that message on MX35. (Doesn't matter much now).

> I just tested 7 mmc cards in total.  6 cards work fine, and 1 card
> (Transcend MMC plus 1GB) has the exactly same problem as yours. And
> if I remove the 8 bit cap, this card also works fine.  So I would
> agree with Russell that it's unrelated to the driver.

Ah, the 8_BIT_CAP was the right pointer. It works now and I can see the
partitions \o/ But IMHO it is related to the driver because it cannot set that
8_BIT_DATA_CAP unconditionally? Probably something like 'flags' should be added
to platform_data? One flag could then be 8_BIT_CAPABLE_SLOT or something.

> I tested the SDIO, but probably in different way from yours.  I had
> two card slots on my board, rootfs on mmc0 and SDIO card on mmc1.
> It seems working fine in this way.  However, when I use nfs and test
> SDIO on mmc0, my systems hangs too.  I will look into it.

The latter scenario is the only one I can test, because I don't have an
(active) second slot.

Thanks for keeping up with the driver!

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-16 15:33                 ` Wolfram Sang
  0 siblings, 0 replies; 64+ messages in thread
From: Wolfram Sang @ 2011-02-16 15:33 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Shawn,

[CRC failures on MMC]
> I guess you will also get the unknown partition table message if you
> test this card on mx35 right now.

No, I didn't see that message on MX35. (Doesn't matter much now).

> I just tested 7 mmc cards in total.  6 cards work fine, and 1 card
> (Transcend MMC plus 1GB) has the exactly same problem as yours. And
> if I remove the 8 bit cap, this card also works fine.  So I would
> agree with Russell that it's unrelated to the driver.

Ah, the 8_BIT_CAP was the right pointer. It works now and I can see the
partitions \o/ But IMHO it is related to the driver because it cannot set that
8_BIT_DATA_CAP unconditionally? Probably something like 'flags' should be added
to platform_data? One flag could then be 8_BIT_CAPABLE_SLOT or something.

> I tested the SDIO, but probably in different way from yours.  I had
> two card slots on my board, rootfs on mmc0 and SDIO card on mmc1.
> It seems working fine in this way.  However, when I use nfs and test
> SDIO on mmc0, my systems hangs too.  I will look into it.

The latter scenario is the only one I can test, because I don't have an
(active) second slot.

Thanks for keeping up with the driver!

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-16 20:28               ` Shawn Guo
@ 2011-02-16 15:59                 ` Arnd Bergmann
  -1 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2011-02-16 15:59 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Wolfram Sang, Russell King - ARM Linux, s.hauer, linux-mmc, cjb,
	linux-arm-kernel, LW

On Wednesday 16 February 2011, Shawn Guo wrote:
> It's caused by spinlock recursion introduced by mxs-dma functions
> mxs_dma_tx_submit and mxs_dma_tasklet.  We have mmc_request_done
> invoked in the dma callback tasklet.  At the meantime,
> mmc_request_done will issue retries in some case, which will call in
> mxs_dma_tx_submit.
> 
> I added the lock by referring to other dma driver implementation, but
> now I'm considering to remove the lock completely, as I do not see
> any global data needs to be protected there.  Comments?

You need to be sure that the data accessed in the tasklet does not
need to be locked against mxs_dma_tx_submit.

I haven't looked at the dmaengine code for this, but it's quite likely
that you actually need it, because you need to serialize adding an
element to the DMA device with removing it again.

Also, since the lock is taken in a tasklet, every thread that takes
it outside of a tasklet must do spin_lock_bh(), not spin_lock(), to
prevent the tasklet from running.

	Arnd

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-16 15:59                 ` Arnd Bergmann
  0 siblings, 0 replies; 64+ messages in thread
From: Arnd Bergmann @ 2011-02-16 15:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 16 February 2011, Shawn Guo wrote:
> It's caused by spinlock recursion introduced by mxs-dma functions
> mxs_dma_tx_submit and mxs_dma_tasklet.  We have mmc_request_done
> invoked in the dma callback tasklet.  At the meantime,
> mmc_request_done will issue retries in some case, which will call in
> mxs_dma_tx_submit.
> 
> I added the lock by referring to other dma driver implementation, but
> now I'm considering to remove the lock completely, as I do not see
> any global data needs to be protected there.  Comments?

You need to be sure that the data accessed in the tasklet does not
need to be locked against mxs_dma_tx_submit.

I haven't looked at the dmaengine code for this, but it's quite likely
that you actually need it, because you need to serialize adding an
element to the DMA device with removing it again.

Also, since the lock is taken in a tasklet, every thread that takes
it outside of a tasklet must do spin_lock_bh(), not spin_lock(), to
prevent the tasklet from running.

	Arnd

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-15 17:29             ` Wolfram Sang
@ 2011-02-16 20:28               ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-16 20:28 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Russell King - ARM Linux, arnd, s.hauer, linux-mmc, cjb,
	linux-arm-kernel, LW

Hi Wolfram,

Thanks for testing.

On Tue, Feb 15, 2011 at 06:29:48PM +0100, Wolfram Sang wrote:
> On Tue, Feb 15, 2011 at 05:19:17PM +0000, Russell King - ARM Linux wrote:
> > On Tue, Feb 15, 2011 at 06:13:41PM +0100, Wolfram Sang wrote:
> > > 
> > > > Ah, yes.  I can also see the problem here after turning on
> > > > DEBUG_SPINLOCK.
> > > 
> > > Ah, okay. After turning it off, it works a lot better :)
> > 
> > That doesn't mean the problem is fixed. [...]
> 
> Yes, I know that. I should have put the 'works' above in quotes, sorry.
> 
It's caused by spinlock recursion introduced by mxs-dma functions
mxs_dma_tx_submit and mxs_dma_tasklet.  We have mmc_request_done
invoked in the dma callback tasklet.  At the meantime,
mmc_request_done will issue retries in some case, which will call in
mxs_dma_tx_submit.

I added the lock by referring to other dma driver implementation, but
now I'm considering to remove the lock completely, as I do not see
any global data needs to be protected there.  Comments?

> > > MMC fails for me (note: the card works fine with an mx35-based board)
> > > 
> > > 	mmc0: new high speed MMC card at address 0001
> > > 	mmcblk0: mmc0:0001 AF HMP 247 MiB 
> > > 	mmcblk0: retrying using single block read
> > > 	mmcblk0: error -84 transferring data, sector 0, nr 8, card status 0x900
> > > 	end_request: I/O error, dev mmcblk0, sector 0
> > 
> > EILSEQ means CRC failure.  Probably unrelated.
> 
> Even if it works in another setup? As a result of the above, I can't read the
> partition table of that MMC. The mx35 can do so.
> 
First of all, it's not a problem that partition table of the card
can not be read.  For example, I have every card giving unknown
partition table message after performing mmc host driver test on the
cards, but they are working good.

I guess you will also get the unknown partition table message if you
test this card on mx35 right now.

I just tested 7 mmc cards in total.  6 cards work fine, and 1 card
(Transcend MMC plus 1GB) has the exactly same problem as yours. And
if I remove the 8 bit cap, this card also works fine.  So I would
agree with Russell that it's unrelated to the driver.

mmc1: new high speed MMC card at address 0001
mmcblk1: mmc1:0001 MMC    3.75 GiB
 mmcblk1: unknown partition table
mmc1: card 0001 removed

mmc1: new MMC card at address 0001
mmcblk1: mmc1:0001 SMIMMC 122 MiB
 mmcblk1: unknown partition table
mmc1: card 0001 removed

mmc1: new high speed MMC card at address 0001
mmcblk1: mmc1:0001 NCard  967 MiB
 mmcblk1: p1
mmc1: card 0001 removed

mmc1: new high speed MMC card at address 0001
mmcblk1: mmc1:0001 MMC512 483 MiB
 mmcblk1: p1 < p5 >
mmc1: card 0001 removed

mmc1: new high speed MMC card at address 0001
mmcblk1: mmc1:0001 000000 980 MiB
 mmcblk1: unknown partition table
mmc1: card 0001 removed

mmc1: new high speed MMC card at address 0001
mmcblk1: mmc1:0001 AF HMP 490 MiB
 mmcblk1: p1 < p5 >
mmc1: card 0001 removed

mmc1: new high speed MMC card at address 0001
mmcblk1: mmc1:0001 MMC    967 MiB
mmcblk1: retrying using single block read
mmcblk1: error -84 transferring data, sector 0, nr 8, card status 0x900
end_request: I/O error, dev mmcblk1, sector 0
mmcblk1: error -84 transferring data, sector 1, nr 7, card status 0x900
end_request: I/O error, dev mmcblk1, sector 1
mmcblk1: error -84 transferring data, sector 2, nr 6, card status 0x900
end_request: I/O error, dev mmcblk1, sector 2
...

> > > SDIO card locks the machine. Is it supposed to work already?
> > 
> > Guess it's the spinlock causing that problem.
> 
> Yeah, that could be. In addition, I was just generally interested if SDIO has
> been tested by Shawn.
> 
I tested the SDIO, but probably in different way from yours.  I had
two card slots on my board, rootfs on mmc0 and SDIO card on mmc1.
It seems working fine in this way.  However, when I use nfs and test
SDIO on mmc0, my systems hangs too.  I will look into it.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-16 20:28               ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-16 20:28 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Wolfram,

Thanks for testing.

On Tue, Feb 15, 2011 at 06:29:48PM +0100, Wolfram Sang wrote:
> On Tue, Feb 15, 2011 at 05:19:17PM +0000, Russell King - ARM Linux wrote:
> > On Tue, Feb 15, 2011 at 06:13:41PM +0100, Wolfram Sang wrote:
> > > 
> > > > Ah, yes.  I can also see the problem here after turning on
> > > > DEBUG_SPINLOCK.
> > > 
> > > Ah, okay. After turning it off, it works a lot better :)
> > 
> > That doesn't mean the problem is fixed. [...]
> 
> Yes, I know that. I should have put the 'works' above in quotes, sorry.
> 
It's caused by spinlock recursion introduced by mxs-dma functions
mxs_dma_tx_submit and mxs_dma_tasklet.  We have mmc_request_done
invoked in the dma callback tasklet.  At the meantime,
mmc_request_done will issue retries in some case, which will call in
mxs_dma_tx_submit.

I added the lock by referring to other dma driver implementation, but
now I'm considering to remove the lock completely, as I do not see
any global data needs to be protected there.  Comments?

> > > MMC fails for me (note: the card works fine with an mx35-based board)
> > > 
> > > 	mmc0: new high speed MMC card at address 0001
> > > 	mmcblk0: mmc0:0001 AF HMP 247 MiB 
> > > 	mmcblk0: retrying using single block read
> > > 	mmcblk0: error -84 transferring data, sector 0, nr 8, card status 0x900
> > > 	end_request: I/O error, dev mmcblk0, sector 0
> > 
> > EILSEQ means CRC failure.  Probably unrelated.
> 
> Even if it works in another setup? As a result of the above, I can't read the
> partition table of that MMC. The mx35 can do so.
> 
First of all, it's not a problem that partition table of the card
can not be read.  For example, I have every card giving unknown
partition table message after performing mmc host driver test on the
cards, but they are working good.

I guess you will also get the unknown partition table message if you
test this card on mx35 right now.

I just tested 7 mmc cards in total.  6 cards work fine, and 1 card
(Transcend MMC plus 1GB) has the exactly same problem as yours. And
if I remove the 8 bit cap, this card also works fine.  So I would
agree with Russell that it's unrelated to the driver.

mmc1: new high speed MMC card at address 0001
mmcblk1: mmc1:0001 MMC    3.75 GiB
 mmcblk1: unknown partition table
mmc1: card 0001 removed

mmc1: new MMC card at address 0001
mmcblk1: mmc1:0001 SMIMMC 122 MiB
 mmcblk1: unknown partition table
mmc1: card 0001 removed

mmc1: new high speed MMC card at address 0001
mmcblk1: mmc1:0001 NCard  967 MiB
 mmcblk1: p1
mmc1: card 0001 removed

mmc1: new high speed MMC card at address 0001
mmcblk1: mmc1:0001 MMC512 483 MiB
 mmcblk1: p1 < p5 >
mmc1: card 0001 removed

mmc1: new high speed MMC card at address 0001
mmcblk1: mmc1:0001 000000 980 MiB
 mmcblk1: unknown partition table
mmc1: card 0001 removed

mmc1: new high speed MMC card at address 0001
mmcblk1: mmc1:0001 AF HMP 490 MiB
 mmcblk1: p1 < p5 >
mmc1: card 0001 removed

mmc1: new high speed MMC card at address 0001
mmcblk1: mmc1:0001 MMC    967 MiB
mmcblk1: retrying using single block read
mmcblk1: error -84 transferring data, sector 0, nr 8, card status 0x900
end_request: I/O error, dev mmcblk1, sector 0
mmcblk1: error -84 transferring data, sector 1, nr 7, card status 0x900
end_request: I/O error, dev mmcblk1, sector 1
mmcblk1: error -84 transferring data, sector 2, nr 6, card status 0x900
end_request: I/O error, dev mmcblk1, sector 2
...

> > > SDIO card locks the machine. Is it supposed to work already?
> > 
> > Guess it's the spinlock causing that problem.
> 
> Yeah, that could be. In addition, I was just generally interested if SDIO has
> been tested by Shawn.
> 
I tested the SDIO, but probably in different way from yours.  I had
two card slots on my board, rootfs on mmc0 and SDIO card on mmc1.
It seems working fine in this way.  However, when I use nfs and test
SDIO on mmc0, my systems hangs too.  I will look into it.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-16 15:59                 ` Arnd Bergmann
@ 2011-02-17  2:44                   ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-17  2:44 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Wolfram Sang, Russell King - ARM Linux, s.hauer, linux-mmc, cjb,
	linux-arm-kernel, LW

Hi Arnd,

On Wed, Feb 16, 2011 at 04:59:18PM +0100, Arnd Bergmann wrote:
> On Wednesday 16 February 2011, Shawn Guo wrote:
> > It's caused by spinlock recursion introduced by mxs-dma functions
> > mxs_dma_tx_submit and mxs_dma_tasklet.  We have mmc_request_done
> > invoked in the dma callback tasklet.  At the meantime,
> > mmc_request_done will issue retries in some case, which will call in
> > mxs_dma_tx_submit.
> > 
> > I added the lock by referring to other dma driver implementation, but
> > now I'm considering to remove the lock completely, as I do not see
> > any global data needs to be protected there.  Comments?
> 
> You need to be sure that the data accessed in the tasklet does not
> need to be locked against mxs_dma_tx_submit.
> 
The only thing we actually put in tasklet is just the callback
registered by client device driver, which should not have anything
that mxs_dma_tx_submit would concern.

> I haven't looked at the dmaengine code for this, but it's quite likely
> that you actually need it, because you need to serialize adding an
> element to the DMA device with removing it again.
> 
I'm not sure that I understand your comment. If the adding/removing
an element means what mxs_dma_alloc_chan_resources and 
mxs_dma_free_chan_resources do, I do not think it's a problem, as
client driver is calling them in probe/remove for once.

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-17  2:44                   ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-17  2:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,

On Wed, Feb 16, 2011 at 04:59:18PM +0100, Arnd Bergmann wrote:
> On Wednesday 16 February 2011, Shawn Guo wrote:
> > It's caused by spinlock recursion introduced by mxs-dma functions
> > mxs_dma_tx_submit and mxs_dma_tasklet.  We have mmc_request_done
> > invoked in the dma callback tasklet.  At the meantime,
> > mmc_request_done will issue retries in some case, which will call in
> > mxs_dma_tx_submit.
> > 
> > I added the lock by referring to other dma driver implementation, but
> > now I'm considering to remove the lock completely, as I do not see
> > any global data needs to be protected there.  Comments?
> 
> You need to be sure that the data accessed in the tasklet does not
> need to be locked against mxs_dma_tx_submit.
> 
The only thing we actually put in tasklet is just the callback
registered by client device driver, which should not have anything
that mxs_dma_tx_submit would concern.

> I haven't looked at the dmaengine code for this, but it's quite likely
> that you actually need it, because you need to serialize adding an
> element to the DMA device with removing it again.
> 
I'm not sure that I understand your comment. If the adding/removing
an element means what mxs_dma_alloc_chan_resources and 
mxs_dma_free_chan_resources do, I do not think it's a problem, as
client driver is calling them in probe/remove for once.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-16 15:33                 ` Wolfram Sang
@ 2011-02-17  4:17                   ` Shawn Guo
  -1 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-17  4:17 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Russell King - ARM Linux, arnd, s.hauer, linux-mmc, cjb,
	linux-arm-kernel, LW

Hi Wolfram,

On Wed, Feb 16, 2011 at 04:33:32PM +0100, Wolfram Sang wrote:
> Hi Shawn,
> 
> [CRC failures on MMC]
> > I guess you will also get the unknown partition table message if you
> > test this card on mx35 right now.
> 
> No, I didn't see that message on MX35. (Doesn't matter much now).
> 
> > I just tested 7 mmc cards in total.  6 cards work fine, and 1 card
> > (Transcend MMC plus 1GB) has the exactly same problem as yours. And
> > if I remove the 8 bit cap, this card also works fine.  So I would
> > agree with Russell that it's unrelated to the driver.
> 
> Ah, the 8_BIT_CAP was the right pointer. It works now and I can see the
> partitions \o/ But IMHO it is related to the driver because it cannot set that
> 8_BIT_DATA_CAP unconditionally? Probably something like 'flags' should be added
> to platform_data? One flag could then be 8_BIT_CAPABLE_SLOT or something.
> 
If a platform is designed to support 8-bit mode (e.g. all 8 data
lines are routed), I do not think the 8-bit cap will be removed from
this platform just because one particular card has problem to work
in 8-bit mode.

But I would anyway let platform_data tell the 4 BIT_CAP and 8_BIT_CAP
just like what Freescale BSP is doing, as some platforms may design
this cap differently.

> > I tested the SDIO, but probably in different way from yours.  I had
> > two card slots on my board, rootfs on mmc0 and SDIO card on mmc1.
> > It seems working fine in this way.  However, when I use nfs and test
> > SDIO on mmc0, my systems hangs too.  I will look into it.
> 
> The latter scenario is the only one I can test, because I don't have an
> (active) second slot.
> 
It's a board thing.  I just rechecked the schematics of mx28evk
board, and found that the power supply of the two slots are
different.  The mmc1 uses the external regulator REG_3V3 which can
supply up to 1.5 A current, while mmc0 uses mx28 internal regulator
VDDIO_3V3 which has very limited current capability.  That's why my
SDIO WiFi card works on mmc1 slot while hangs system on mmc0.  When
I reworked the board to supply mmc0 with REG_3V3, the card works on
mmc0 too.

So your board supplies mmc0 slot with VDDIO_3V3 as well?

-- 
Regards,
Shawn


^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-17  4:17                   ` Shawn Guo
  0 siblings, 0 replies; 64+ messages in thread
From: Shawn Guo @ 2011-02-17  4:17 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Wolfram,

On Wed, Feb 16, 2011 at 04:33:32PM +0100, Wolfram Sang wrote:
> Hi Shawn,
> 
> [CRC failures on MMC]
> > I guess you will also get the unknown partition table message if you
> > test this card on mx35 right now.
> 
> No, I didn't see that message on MX35. (Doesn't matter much now).
> 
> > I just tested 7 mmc cards in total.  6 cards work fine, and 1 card
> > (Transcend MMC plus 1GB) has the exactly same problem as yours. And
> > if I remove the 8 bit cap, this card also works fine.  So I would
> > agree with Russell that it's unrelated to the driver.
> 
> Ah, the 8_BIT_CAP was the right pointer. It works now and I can see the
> partitions \o/ But IMHO it is related to the driver because it cannot set that
> 8_BIT_DATA_CAP unconditionally? Probably something like 'flags' should be added
> to platform_data? One flag could then be 8_BIT_CAPABLE_SLOT or something.
> 
If a platform is designed to support 8-bit mode (e.g. all 8 data
lines are routed), I do not think the 8-bit cap will be removed from
this platform just because one particular card has problem to work
in 8-bit mode.

But I would anyway let platform_data tell the 4 BIT_CAP and 8_BIT_CAP
just like what Freescale BSP is doing, as some platforms may design
this cap differently.

> > I tested the SDIO, but probably in different way from yours.  I had
> > two card slots on my board, rootfs on mmc0 and SDIO card on mmc1.
> > It seems working fine in this way.  However, when I use nfs and test
> > SDIO on mmc0, my systems hangs too.  I will look into it.
> 
> The latter scenario is the only one I can test, because I don't have an
> (active) second slot.
> 
It's a board thing.  I just rechecked the schematics of mx28evk
board, and found that the power supply of the two slots are
different.  The mmc1 uses the external regulator REG_3V3 which can
supply up to 1.5 A current, while mmc0 uses mx28 internal regulator
VDDIO_3V3 which has very limited current capability.  That's why my
SDIO WiFi card works on mmc1 slot while hangs system on mmc0.  When
I reworked the board to supply mmc0 with REG_3V3, the card works on
mmc0 too.

So your board supplies mmc0 slot with VDDIO_3V3 as well?

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
  2011-02-17  4:17                   ` Shawn Guo
@ 2011-02-17 12:06                     ` Wolfram Sang
  -1 siblings, 0 replies; 64+ messages in thread
From: Wolfram Sang @ 2011-02-17 12:06 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Russell King - ARM Linux, arnd, s.hauer, linux-mmc, cjb,
	linux-arm-kernel, LW

Hi Shawn,

> > Ah, the 8_BIT_CAP was the right pointer. It works now and I can see the
> > partitions \o/ But IMHO it is related to the driver because it cannot set that
> > 8_BIT_DATA_CAP unconditionally? Probably something like 'flags' should be added
> > to platform_data? One flag could then be 8_BIT_CAPABLE_SLOT or something.
> > 
> If a platform is designed to support 8-bit mode (e.g. all 8 data
> lines are routed), I do not think the 8-bit cap will be removed from
> this platform just because one particular card has problem to work
> in 8-bit mode.

Right, surely not beacuse of a card, this was a misunderstanding. The issue is
not related to cards but slots. By naming the flag 8_BIT_CAPABLE_SLOT I wanted
to indicate this.

> But I would anyway let platform_data tell the 4 BIT_CAP and 8_BIT_CAP
> just like what Freescale BSP is doing, as some platforms may design
> this cap differently.

Yep, that's what I meant, too :) Adding the slot capabilities in platform_data.

> So your board supplies mmc0 slot with VDDIO_3V3 as well?

Hmm, the schematics say no, but I will assume it is a board issue and check
with the manufacturer.

Thanks again!

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v2 1/7] mmc: mxs-mmc: add mmc host driver for i.MX23/28
@ 2011-02-17 12:06                     ` Wolfram Sang
  0 siblings, 0 replies; 64+ messages in thread
From: Wolfram Sang @ 2011-02-17 12:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Shawn,

> > Ah, the 8_BIT_CAP was the right pointer. It works now and I can see the
> > partitions \o/ But IMHO it is related to the driver because it cannot set that
> > 8_BIT_DATA_CAP unconditionally? Probably something like 'flags' should be added
> > to platform_data? One flag could then be 8_BIT_CAPABLE_SLOT or something.
> > 
> If a platform is designed to support 8-bit mode (e.g. all 8 data
> lines are routed), I do not think the 8-bit cap will be removed from
> this platform just because one particular card has problem to work
> in 8-bit mode.

Right, surely not beacuse of a card, this was a misunderstanding. The issue is
not related to cards but slots. By naming the flag 8_BIT_CAPABLE_SLOT I wanted
to indicate this.

> But I would anyway let platform_data tell the 4 BIT_CAP and 8_BIT_CAP
> just like what Freescale BSP is doing, as some platforms may design
> this cap differently.

Yep, that's what I meant, too :) Adding the slot capabilities in platform_data.

> So your board supplies mmc0 slot with VDDIO_3V3 as well?

Hmm, the schematics say no, but I will assume it is a board issue and check
with the manufacturer.

Thanks again!

   Wolfram

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 64+ messages in thread

end of thread, other threads:[~2011-02-17 12:06 UTC | newest]

Thread overview: 64+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-14  2:32 [PATCH v2 0/7] Add mmc driver for i.MX23/28 Shawn Guo
2011-02-14  2:32 ` Shawn Guo
2011-02-14  2:32 ` [PATCH v2 1/7] mmc: mxs-mmc: add mmc host " Shawn Guo
2011-02-14  2:32   ` Shawn Guo
2011-02-13 19:26   ` Chris Ball
2011-02-13 19:26     ` Chris Ball
2011-02-13 22:35     ` Arnd Bergmann
2011-02-13 22:35       ` Arnd Bergmann
2011-02-14  0:25       ` Chris Ball
2011-02-14  0:25         ` Chris Ball
2011-02-15 21:27       ` Shawn Guo
2011-02-15 21:27         ` Shawn Guo
2011-02-15 21:26     ` Shawn Guo
2011-02-15 21:26       ` Shawn Guo
2011-02-14 15:39   ` Wolfram Sang
2011-02-14 15:39     ` Wolfram Sang
2011-02-15 21:28     ` Shawn Guo
2011-02-15 21:28       ` Shawn Guo
2011-02-14 16:59   ` Wolfram Sang
2011-02-14 16:59     ` Wolfram Sang
2011-02-15 22:39     ` Shawn Guo
2011-02-15 22:39       ` Shawn Guo
2011-02-15 17:13       ` Wolfram Sang
2011-02-15 17:13         ` Wolfram Sang
2011-02-15 17:19         ` Russell King - ARM Linux
2011-02-15 17:19           ` Russell King - ARM Linux
2011-02-15 17:29           ` Wolfram Sang
2011-02-15 17:29             ` Wolfram Sang
2011-02-15 17:32             ` Russell King - ARM Linux
2011-02-15 17:32               ` Russell King - ARM Linux
2011-02-16 20:28             ` Shawn Guo
2011-02-16 20:28               ` Shawn Guo
2011-02-16 15:33               ` Wolfram Sang
2011-02-16 15:33                 ` Wolfram Sang
2011-02-17  4:17                 ` Shawn Guo
2011-02-17  4:17                   ` Shawn Guo
2011-02-17 12:06                   ` Wolfram Sang
2011-02-17 12:06                     ` Wolfram Sang
2011-02-16 15:59               ` Arnd Bergmann
2011-02-16 15:59                 ` Arnd Bergmann
2011-02-17  2:44                 ` Shawn Guo
2011-02-17  2:44                   ` Shawn Guo
2011-02-14 16:59   ` Russell King - ARM Linux
2011-02-14 16:59     ` Russell King - ARM Linux
2011-02-15 22:03     ` Shawn Guo
2011-02-15 22:03       ` Shawn Guo
2011-02-15 14:13       ` Russell King - ARM Linux
2011-02-15 14:13         ` Russell King - ARM Linux
2011-02-14  2:32 ` [PATCH v2 2/7] ARM: mxs/clock: fix base address missing in name##_set_parent Shawn Guo
2011-02-14  2:32   ` Shawn Guo
2011-02-14  2:32 ` [PATCH v2 3/7] ARM: mxs: make ssp error irq definition consistent Shawn Guo
2011-02-14  2:32   ` Shawn Guo
2011-02-14  2:32 ` [PATCH v2 4/7] ARM: mxs: dynamically allocate mmc device Shawn Guo
2011-02-14  2:32   ` Shawn Guo
2011-02-14  2:32 ` [PATCH v2 5/7] ARM: mxs: fix typo "GPO" in iomux-mx23.h Shawn Guo
2011-02-14  2:32   ` Shawn Guo
2011-02-14  2:32 ` [PATCH v2 6/7] ARM: mxs/mx23evk: add mmc device Shawn Guo
2011-02-14  2:32   ` Shawn Guo
2011-02-14  2:32 ` [PATCH v2 7/7] ARM: mxs/mx28evk: " Shawn Guo
2011-02-14  2:32   ` Shawn Guo
2011-02-14 10:26   ` Wolfram Sang
2011-02-14 10:26     ` Wolfram Sang
2011-02-15 23:11     ` Shawn Guo
2011-02-15 23:11       ` Shawn Guo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.