aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2012-05-13 01:33:24 -0400
committerOlof Johansson <olof@lixom.net>2012-05-13 01:33:24 -0400
commite29402edf848359d619ce06af86d61e62c292c87 (patch)
tree94451c1d400d478654e0d0e78564e882081b806c /drivers/mmc
parentbf98a6eaa9964fef49f186834713bfc57d16ede1 (diff)
parent530f1d416091212243b341e0022b2967886b30e4 (diff)
Merge branch 'mxs/dt/for-3.5' of git://git.linaro.org/people/shawnguo/linux-2.6 into next/dt2
* 'mxs/dt/for-3.5' of git://git.linaro.org/people/shawnguo/linux-2.6: (51 commits) ARM: dts: enable audio support for imx28-evk ARM: dts: enable i2c device for imx28-evk i2c: mxs: add device tree probe support ARM: dts: enable mmc for imx28-evk ARM: dts: enable mmc for imx23-evk mmc: mxs-mmc: add device tree support mmc: mxs-mmc: copy wp_gpio in struct mxs_mmc_host mmc: mxs-mmc: have dma_channel than dma_res in mxs_mmc_host mmc: mxs-mmc: use devm_* helper to make cleanup simpler mmc: mxs-mmc: move header from mach into linux folder mmc: mxs-mmc: get rid of the use of cpu_is_xxx mmc: mxs-mmc: let ssp_is_old take host as parameter mmc: mxs-mmc: use global stmp_device functionality ARM: mxs: add gpio support for device tree boot gpio/mxs: add device tree probe gpio/mxs: get rid of the use of cpu_is_xxx gpio/mxs: use devm_* helpers to make error handling simple ARM: mxs: add mxs-dma dt support ARM: mxs: do not add dma device by default dma: mxs-dma: add device tree probe support ...
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/mxs-mmc.c203
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c9
2 files changed, 127 insertions, 85 deletions
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index e3f5af96ab87..34a90266ab11 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -23,6 +23,9 @@
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/ioport.h> 25#include <linux/ioport.h>
26#include <linux/of.h>
27#include <linux/of_device.h>
28#include <linux/of_gpio.h>
26#include <linux/platform_device.h> 29#include <linux/platform_device.h>
27#include <linux/delay.h> 30#include <linux/delay.h>
28#include <linux/interrupt.h> 31#include <linux/interrupt.h>
@@ -39,18 +42,16 @@
39#include <linux/regulator/consumer.h> 42#include <linux/regulator/consumer.h>
40#include <linux/module.h> 43#include <linux/module.h>
41#include <linux/fsl/mxs-dma.h> 44#include <linux/fsl/mxs-dma.h>
42 45#include <linux/pinctrl/consumer.h>
43#include <mach/mxs.h> 46#include <linux/stmp_device.h>
44#include <mach/common.h> 47#include <linux/mmc/mxs-mmc.h>
45#include <mach/mmc.h>
46 48
47#define DRIVER_NAME "mxs-mmc" 49#define DRIVER_NAME "mxs-mmc"
48 50
49/* card detect polling timeout */ 51/* card detect polling timeout */
50#define MXS_MMC_DETECT_TIMEOUT (HZ/2) 52#define MXS_MMC_DETECT_TIMEOUT (HZ/2)
51 53
52#define SSP_VERSION_LATEST 4 54#define ssp_is_old(host) ((host)->devid == IMX23_MMC)
53#define ssp_is_old() (host->version < SSP_VERSION_LATEST)
54 55
55/* SSP registers */ 56/* SSP registers */
56#define HW_SSP_CTRL0 0x000 57#define HW_SSP_CTRL0 0x000
@@ -85,14 +86,14 @@
85#define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4) 86#define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4)
86#define BP_SSP_BLOCK_SIZE_BLOCK_SIZE (0) 87#define BP_SSP_BLOCK_SIZE_BLOCK_SIZE (0)
87#define BM_SSP_BLOCK_SIZE_BLOCK_SIZE (0xf) 88#define BM_SSP_BLOCK_SIZE_BLOCK_SIZE (0xf)
88#define HW_SSP_TIMING (ssp_is_old() ? 0x050 : 0x070) 89#define HW_SSP_TIMING(h) (ssp_is_old(h) ? 0x050 : 0x070)
89#define BP_SSP_TIMING_TIMEOUT (16) 90#define BP_SSP_TIMING_TIMEOUT (16)
90#define BM_SSP_TIMING_TIMEOUT (0xffff << 16) 91#define BM_SSP_TIMING_TIMEOUT (0xffff << 16)
91#define BP_SSP_TIMING_CLOCK_DIVIDE (8) 92#define BP_SSP_TIMING_CLOCK_DIVIDE (8)
92#define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8) 93#define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8)
93#define BP_SSP_TIMING_CLOCK_RATE (0) 94#define BP_SSP_TIMING_CLOCK_RATE (0)
94#define BM_SSP_TIMING_CLOCK_RATE (0xff) 95#define BM_SSP_TIMING_CLOCK_RATE (0xff)
95#define HW_SSP_CTRL1 (ssp_is_old() ? 0x060 : 0x080) 96#define HW_SSP_CTRL1(h) (ssp_is_old(h) ? 0x060 : 0x080)
96#define BM_SSP_CTRL1_SDIO_IRQ (1 << 31) 97#define BM_SSP_CTRL1_SDIO_IRQ (1 << 31)
97#define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30) 98#define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30)
98#define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29) 99#define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29)
@@ -115,15 +116,13 @@
115#define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4) 116#define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4)
116#define BP_SSP_CTRL1_SSP_MODE (0) 117#define BP_SSP_CTRL1_SSP_MODE (0)
117#define BM_SSP_CTRL1_SSP_MODE (0xf) 118#define BM_SSP_CTRL1_SSP_MODE (0xf)
118#define HW_SSP_SDRESP0 (ssp_is_old() ? 0x080 : 0x0a0) 119#define HW_SSP_SDRESP0(h) (ssp_is_old(h) ? 0x080 : 0x0a0)
119#define HW_SSP_SDRESP1 (ssp_is_old() ? 0x090 : 0x0b0) 120#define HW_SSP_SDRESP1(h) (ssp_is_old(h) ? 0x090 : 0x0b0)
120#define HW_SSP_SDRESP2 (ssp_is_old() ? 0x0a0 : 0x0c0) 121#define HW_SSP_SDRESP2(h) (ssp_is_old(h) ? 0x0a0 : 0x0c0)
121#define HW_SSP_SDRESP3 (ssp_is_old() ? 0x0b0 : 0x0d0) 122#define HW_SSP_SDRESP3(h) (ssp_is_old(h) ? 0x0b0 : 0x0d0)
122#define HW_SSP_STATUS (ssp_is_old() ? 0x0c0 : 0x100) 123#define HW_SSP_STATUS(h) (ssp_is_old(h) ? 0x0c0 : 0x100)
123#define BM_SSP_STATUS_CARD_DETECT (1 << 28) 124#define BM_SSP_STATUS_CARD_DETECT (1 << 28)
124#define BM_SSP_STATUS_SDIO_IRQ (1 << 17) 125#define BM_SSP_STATUS_SDIO_IRQ (1 << 17)
125#define HW_SSP_VERSION (cpu_is_mx23() ? 0x110 : 0x130)
126#define BP_SSP_VERSION_MAJOR (24)
127 126
128#define BF_SSP(value, field) (((value) << BP_SSP_##field) & BM_SSP_##field) 127#define BF_SSP(value, field) (((value) << BP_SSP_##field) & BM_SSP_##field)
129 128
@@ -138,6 +137,11 @@
138 137
139#define SSP_PIO_NUM 3 138#define SSP_PIO_NUM 3
140 139
140enum mxs_mmc_id {
141 IMX23_MMC,
142 IMX28_MMC,
143};
144
141struct mxs_mmc_host { 145struct mxs_mmc_host {
142 struct mmc_host *mmc; 146 struct mmc_host *mmc;
143 struct mmc_request *mrq; 147 struct mmc_request *mrq;
@@ -145,9 +149,7 @@ struct mxs_mmc_host {
145 struct mmc_data *data; 149 struct mmc_data *data;
146 150
147 void __iomem *base; 151 void __iomem *base;
148 int irq; 152 int dma_channel;
149 struct resource *res;
150 struct resource *dma_res;
151 struct clk *clk; 153 struct clk *clk;
152 unsigned int clk_rate; 154 unsigned int clk_rate;
153 155
@@ -157,32 +159,28 @@ struct mxs_mmc_host {
157 enum dma_transfer_direction slave_dirn; 159 enum dma_transfer_direction slave_dirn;
158 u32 ssp_pio_words[SSP_PIO_NUM]; 160 u32 ssp_pio_words[SSP_PIO_NUM];
159 161
160 unsigned int version; 162 enum mxs_mmc_id devid;
161 unsigned char bus_width; 163 unsigned char bus_width;
162 spinlock_t lock; 164 spinlock_t lock;
163 int sdio_irq_en; 165 int sdio_irq_en;
166 int wp_gpio;
164}; 167};
165 168
166static int mxs_mmc_get_ro(struct mmc_host *mmc) 169static int mxs_mmc_get_ro(struct mmc_host *mmc)
167{ 170{
168 struct mxs_mmc_host *host = mmc_priv(mmc); 171 struct mxs_mmc_host *host = mmc_priv(mmc);
169 struct mxs_mmc_platform_data *pdata =
170 mmc_dev(host->mmc)->platform_data;
171
172 if (!pdata)
173 return -EFAULT;
174 172
175 if (!gpio_is_valid(pdata->wp_gpio)) 173 if (!gpio_is_valid(host->wp_gpio))
176 return -EINVAL; 174 return -EINVAL;
177 175
178 return gpio_get_value(pdata->wp_gpio); 176 return gpio_get_value(host->wp_gpio);
179} 177}
180 178
181static int mxs_mmc_get_cd(struct mmc_host *mmc) 179static int mxs_mmc_get_cd(struct mmc_host *mmc)
182{ 180{
183 struct mxs_mmc_host *host = mmc_priv(mmc); 181 struct mxs_mmc_host *host = mmc_priv(mmc);
184 182
185 return !(readl(host->base + HW_SSP_STATUS) & 183 return !(readl(host->base + HW_SSP_STATUS(host)) &
186 BM_SSP_STATUS_CARD_DETECT); 184 BM_SSP_STATUS_CARD_DETECT);
187} 185}
188 186
@@ -190,7 +188,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
190{ 188{
191 u32 ctrl0, ctrl1; 189 u32 ctrl0, ctrl1;
192 190
193 mxs_reset_block(host->base); 191 stmp_reset_block(host->base);
194 192
195 ctrl0 = BM_SSP_CTRL0_IGNORE_CRC; 193 ctrl0 = BM_SSP_CTRL0_IGNORE_CRC;
196 ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) | 194 ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) |
@@ -206,7 +204,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
206 writel(BF_SSP(0xffff, TIMING_TIMEOUT) | 204 writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
207 BF_SSP(2, TIMING_CLOCK_DIVIDE) | 205 BF_SSP(2, TIMING_CLOCK_DIVIDE) |
208 BF_SSP(0, TIMING_CLOCK_RATE), 206 BF_SSP(0, TIMING_CLOCK_RATE),
209 host->base + HW_SSP_TIMING); 207 host->base + HW_SSP_TIMING(host));
210 208
211 if (host->sdio_irq_en) { 209 if (host->sdio_irq_en) {
212 ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK; 210 ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
@@ -214,7 +212,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
214 } 212 }
215 213
216 writel(ctrl0, host->base + HW_SSP_CTRL0); 214 writel(ctrl0, host->base + HW_SSP_CTRL0);
217 writel(ctrl1, host->base + HW_SSP_CTRL1); 215 writel(ctrl1, host->base + HW_SSP_CTRL1(host));
218} 216}
219 217
220static void mxs_mmc_start_cmd(struct mxs_mmc_host *host, 218static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
@@ -228,12 +226,12 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
228 226
229 if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) { 227 if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) {
230 if (mmc_resp_type(cmd) & MMC_RSP_136) { 228 if (mmc_resp_type(cmd) & MMC_RSP_136) {
231 cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0); 229 cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0(host));
232 cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1); 230 cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1(host));
233 cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2); 231 cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2(host));
234 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3); 232 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3(host));
235 } else { 233 } else {
236 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0); 234 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0(host));
237 } 235 }
238 } 236 }
239 237
@@ -276,9 +274,9 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
276 274
277 spin_lock(&host->lock); 275 spin_lock(&host->lock);
278 276
279 stat = readl(host->base + HW_SSP_CTRL1); 277 stat = readl(host->base + HW_SSP_CTRL1(host));
280 writel(stat & MXS_MMC_IRQ_BITS, 278 writel(stat & MXS_MMC_IRQ_BITS,
281 host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR); 279 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
282 280
283 if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN)) 281 if ((stat & BM_SSP_CTRL1_SDIO_IRQ) && (stat & BM_SSP_CTRL1_SDIO_IRQ_EN))
284 mmc_signal_sdio_irq(host->mmc); 282 mmc_signal_sdio_irq(host->mmc);
@@ -484,7 +482,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
484 blocks = 1; 482 blocks = 1;
485 483
486 /* xfer count, block size and count need to be set differently */ 484 /* xfer count, block size and count need to be set differently */
487 if (ssp_is_old()) { 485 if (ssp_is_old(host)) {
488 ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT); 486 ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT);
489 cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) | 487 cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) |
490 BF_SSP(blocks - 1, CMD0_BLOCK_COUNT); 488 BF_SSP(blocks - 1, CMD0_BLOCK_COUNT);
@@ -508,10 +506,10 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
508 506
509 /* set the timeout count */ 507 /* set the timeout count */
510 timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns); 508 timeout = mxs_ns_to_ssp_ticks(host->clk_rate, data->timeout_ns);
511 val = readl(host->base + HW_SSP_TIMING); 509 val = readl(host->base + HW_SSP_TIMING(host));
512 val &= ~(BM_SSP_TIMING_TIMEOUT); 510 val &= ~(BM_SSP_TIMING_TIMEOUT);
513 val |= BF_SSP(timeout, TIMING_TIMEOUT); 511 val |= BF_SSP(timeout, TIMING_TIMEOUT);
514 writel(val, host->base + HW_SSP_TIMING); 512 writel(val, host->base + HW_SSP_TIMING(host));
515 513
516 /* pio */ 514 /* pio */
517 host->ssp_pio_words[0] = ctrl0; 515 host->ssp_pio_words[0] = ctrl0;
@@ -597,11 +595,11 @@ static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
597 595
598 ssp_sck = ssp_clk / clock_divide / (1 + clock_rate); 596 ssp_sck = ssp_clk / clock_divide / (1 + clock_rate);
599 597
600 val = readl(host->base + HW_SSP_TIMING); 598 val = readl(host->base + HW_SSP_TIMING(host));
601 val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE); 599 val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
602 val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE); 600 val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE);
603 val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE); 601 val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE);
604 writel(val, host->base + HW_SSP_TIMING); 602 writel(val, host->base + HW_SSP_TIMING(host));
605 603
606 host->clk_rate = ssp_sck; 604 host->clk_rate = ssp_sck;
607 605
@@ -636,18 +634,19 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
636 634
637 if (enable) { 635 if (enable) {
638 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, 636 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
639 host->base + HW_SSP_CTRL0 + MXS_SET_ADDR); 637 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
640 writel(BM_SSP_CTRL1_SDIO_IRQ_EN, 638 writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
641 host->base + HW_SSP_CTRL1 + MXS_SET_ADDR); 639 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET);
642 640
643 if (readl(host->base + HW_SSP_STATUS) & BM_SSP_STATUS_SDIO_IRQ) 641 if (readl(host->base + HW_SSP_STATUS(host)) &
642 BM_SSP_STATUS_SDIO_IRQ)
644 mmc_signal_sdio_irq(host->mmc); 643 mmc_signal_sdio_irq(host->mmc);
645 644
646 } else { 645 } else {
647 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, 646 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
648 host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR); 647 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
649 writel(BM_SSP_CTRL1_SDIO_IRQ_EN, 648 writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
650 host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR); 649 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
651 } 650 }
652 651
653 spin_unlock_irqrestore(&host->lock, flags); 652 spin_unlock_irqrestore(&host->lock, flags);
@@ -668,7 +667,7 @@ static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
668 if (!mxs_dma_is_apbh(chan)) 667 if (!mxs_dma_is_apbh(chan))
669 return false; 668 return false;
670 669
671 if (chan->chan_id != host->dma_res->start) 670 if (chan->chan_id != host->dma_channel)
672 return false; 671 return false;
673 672
674 chan->private = &host->dma_data; 673 chan->private = &host->dma_data;
@@ -676,12 +675,36 @@ static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
676 return true; 675 return true;
677} 676}
678 677
678static struct platform_device_id mxs_mmc_ids[] = {
679 {
680 .name = "imx23-mmc",
681 .driver_data = IMX23_MMC,
682 }, {
683 .name = "imx28-mmc",
684 .driver_data = IMX28_MMC,
685 }, {
686 /* sentinel */
687 }
688};
689MODULE_DEVICE_TABLE(platform, mxs_mmc_ids);
690
691static const struct of_device_id mxs_mmc_dt_ids[] = {
692 { .compatible = "fsl,imx23-mmc", .data = (void *) IMX23_MMC, },
693 { .compatible = "fsl,imx28-mmc", .data = (void *) IMX28_MMC, },
694 { /* sentinel */ }
695};
696MODULE_DEVICE_TABLE(of, mxs_mmc_dt_ids);
697
679static int mxs_mmc_probe(struct platform_device *pdev) 698static int mxs_mmc_probe(struct platform_device *pdev)
680{ 699{
700 const struct of_device_id *of_id =
701 of_match_device(mxs_mmc_dt_ids, &pdev->dev);
702 struct device_node *np = pdev->dev.of_node;
681 struct mxs_mmc_host *host; 703 struct mxs_mmc_host *host;
682 struct mmc_host *mmc; 704 struct mmc_host *mmc;
683 struct resource *iores, *dmares, *r; 705 struct resource *iores, *dmares;
684 struct mxs_mmc_platform_data *pdata; 706 struct mxs_mmc_platform_data *pdata;
707 struct pinctrl *pinctrl;
685 int ret = 0, irq_err, irq_dma; 708 int ret = 0, irq_err, irq_dma;
686 dma_cap_mask_t mask; 709 dma_cap_mask_t mask;
687 710
@@ -689,40 +712,51 @@ static int mxs_mmc_probe(struct platform_device *pdev)
689 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); 712 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
690 irq_err = platform_get_irq(pdev, 0); 713 irq_err = platform_get_irq(pdev, 0);
691 irq_dma = platform_get_irq(pdev, 1); 714 irq_dma = platform_get_irq(pdev, 1);
692 if (!iores || !dmares || irq_err < 0 || irq_dma < 0) 715 if (!iores || irq_err < 0 || irq_dma < 0)
693 return -EINVAL; 716 return -EINVAL;
694 717
695 r = request_mem_region(iores->start, resource_size(iores), pdev->name);
696 if (!r)
697 return -EBUSY;
698
699 mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev); 718 mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev);
700 if (!mmc) { 719 if (!mmc)
701 ret = -ENOMEM; 720 return -ENOMEM;
702 goto out_release_mem;
703 }
704 721
705 host = mmc_priv(mmc); 722 host = mmc_priv(mmc);
706 host->base = ioremap(r->start, resource_size(r)); 723 host->base = devm_request_and_ioremap(&pdev->dev, iores);
707 if (!host->base) { 724 if (!host->base) {
708 ret = -ENOMEM; 725 ret = -EADDRNOTAVAIL;
709 goto out_mmc_free; 726 goto out_mmc_free;
710 } 727 }
711 728
712 /* only major verion does matter */ 729 if (np) {
713 host->version = readl(host->base + HW_SSP_VERSION) >> 730 host->devid = (enum mxs_mmc_id) of_id->data;
714 BP_SSP_VERSION_MAJOR; 731 /*
732 * TODO: This is a temporary solution and should be changed
733 * to use generic DMA binding later when the helpers get in.
734 */
735 ret = of_property_read_u32(np, "fsl,ssp-dma-channel",
736 &host->dma_channel);
737 if (ret) {
738 dev_err(mmc_dev(host->mmc),
739 "failed to get dma channel\n");
740 goto out_mmc_free;
741 }
742 } else {
743 host->devid = pdev->id_entry->driver_data;
744 host->dma_channel = dmares->start;
745 }
715 746
716 host->mmc = mmc; 747 host->mmc = mmc;
717 host->res = r;
718 host->dma_res = dmares;
719 host->irq = irq_err;
720 host->sdio_irq_en = 0; 748 host->sdio_irq_en = 0;
721 749
750 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
751 if (IS_ERR(pinctrl)) {
752 ret = PTR_ERR(pinctrl);
753 goto out_mmc_free;
754 }
755
722 host->clk = clk_get(&pdev->dev, NULL); 756 host->clk = clk_get(&pdev->dev, NULL);
723 if (IS_ERR(host->clk)) { 757 if (IS_ERR(host->clk)) {
724 ret = PTR_ERR(host->clk); 758 ret = PTR_ERR(host->clk);
725 goto out_iounmap; 759 goto out_mmc_free;
726 } 760 }
727 clk_prepare_enable(host->clk); 761 clk_prepare_enable(host->clk);
728 762
@@ -744,11 +778,20 @@ static int mxs_mmc_probe(struct platform_device *pdev)
744 MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL; 778 MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL;
745 779
746 pdata = mmc_dev(host->mmc)->platform_data; 780 pdata = mmc_dev(host->mmc)->platform_data;
747 if (pdata) { 781 if (!pdata) {
782 u32 bus_width = 0;
783 of_property_read_u32(np, "bus-width", &bus_width);
784 if (bus_width == 4)
785 mmc->caps |= MMC_CAP_4_BIT_DATA;
786 else if (bus_width == 8)
787 mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
788 host->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
789 } else {
748 if (pdata->flags & SLOTF_8_BIT_CAPABLE) 790 if (pdata->flags & SLOTF_8_BIT_CAPABLE)
749 mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; 791 mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
750 if (pdata->flags & SLOTF_4_BIT_CAPABLE) 792 if (pdata->flags & SLOTF_4_BIT_CAPABLE)
751 mmc->caps |= MMC_CAP_4_BIT_DATA; 793 mmc->caps |= MMC_CAP_4_BIT_DATA;
794 host->wp_gpio = pdata->wp_gpio;
752 } 795 }
753 796
754 mmc->f_min = 400000; 797 mmc->f_min = 400000;
@@ -757,13 +800,14 @@ static int mxs_mmc_probe(struct platform_device *pdev)
757 800
758 mmc->max_segs = 52; 801 mmc->max_segs = 52;
759 mmc->max_blk_size = 1 << 0xf; 802 mmc->max_blk_size = 1 << 0xf;
760 mmc->max_blk_count = (ssp_is_old()) ? 0xff : 0xffffff; 803 mmc->max_blk_count = (ssp_is_old(host)) ? 0xff : 0xffffff;
761 mmc->max_req_size = (ssp_is_old()) ? 0xffff : 0xffffffff; 804 mmc->max_req_size = (ssp_is_old(host)) ? 0xffff : 0xffffffff;
762 mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev); 805 mmc->max_seg_size = dma_get_max_seg_size(host->dmach->device->dev);
763 806
764 platform_set_drvdata(pdev, mmc); 807 platform_set_drvdata(pdev, mmc);
765 808
766 ret = request_irq(host->irq, mxs_mmc_irq_handler, 0, DRIVER_NAME, host); 809 ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0,
810 DRIVER_NAME, host);
767 if (ret) 811 if (ret)
768 goto out_free_dma; 812 goto out_free_dma;
769 813
@@ -771,26 +815,20 @@ static int mxs_mmc_probe(struct platform_device *pdev)
771 815
772 ret = mmc_add_host(mmc); 816 ret = mmc_add_host(mmc);
773 if (ret) 817 if (ret)
774 goto out_free_irq; 818 goto out_free_dma;
775 819
776 dev_info(mmc_dev(host->mmc), "initialized\n"); 820 dev_info(mmc_dev(host->mmc), "initialized\n");
777 821
778 return 0; 822 return 0;
779 823
780out_free_irq:
781 free_irq(host->irq, host);
782out_free_dma: 824out_free_dma:
783 if (host->dmach) 825 if (host->dmach)
784 dma_release_channel(host->dmach); 826 dma_release_channel(host->dmach);
785out_clk_put: 827out_clk_put:
786 clk_disable_unprepare(host->clk); 828 clk_disable_unprepare(host->clk);
787 clk_put(host->clk); 829 clk_put(host->clk);
788out_iounmap:
789 iounmap(host->base);
790out_mmc_free: 830out_mmc_free:
791 mmc_free_host(mmc); 831 mmc_free_host(mmc);
792out_release_mem:
793 release_mem_region(iores->start, resource_size(iores));
794 return ret; 832 return ret;
795} 833}
796 834
@@ -798,12 +836,9 @@ static int mxs_mmc_remove(struct platform_device *pdev)
798{ 836{
799 struct mmc_host *mmc = platform_get_drvdata(pdev); 837 struct mmc_host *mmc = platform_get_drvdata(pdev);
800 struct mxs_mmc_host *host = mmc_priv(mmc); 838 struct mxs_mmc_host *host = mmc_priv(mmc);
801 struct resource *res = host->res;
802 839
803 mmc_remove_host(mmc); 840 mmc_remove_host(mmc);
804 841
805 free_irq(host->irq, host);
806
807 platform_set_drvdata(pdev, NULL); 842 platform_set_drvdata(pdev, NULL);
808 843
809 if (host->dmach) 844 if (host->dmach)
@@ -812,12 +847,8 @@ static int mxs_mmc_remove(struct platform_device *pdev)
812 clk_disable_unprepare(host->clk); 847 clk_disable_unprepare(host->clk);
813 clk_put(host->clk); 848 clk_put(host->clk);
814 849
815 iounmap(host->base);
816
817 mmc_free_host(mmc); 850 mmc_free_host(mmc);
818 851
819 release_mem_region(res->start, resource_size(res));
820
821 return 0; 852 return 0;
822} 853}
823 854
@@ -857,11 +888,13 @@ static const struct dev_pm_ops mxs_mmc_pm_ops = {
857static struct platform_driver mxs_mmc_driver = { 888static struct platform_driver mxs_mmc_driver = {
858 .probe = mxs_mmc_probe, 889 .probe = mxs_mmc_probe,
859 .remove = mxs_mmc_remove, 890 .remove = mxs_mmc_remove,
891 .id_table = mxs_mmc_ids,
860 .driver = { 892 .driver = {
861 .name = DRIVER_NAME, 893 .name = DRIVER_NAME,
862 .owner = THIS_MODULE, 894 .owner = THIS_MODULE,
863#ifdef CONFIG_PM 895#ifdef CONFIG_PM
864 .pm = &mxs_mmc_pm_ops, 896 .pm = &mxs_mmc_pm_ops,
897 .of_match_table = mxs_mmc_dt_ids,
865#endif 898#endif
866 }, 899 },
867}; 900};
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 8abdaf6697a8..d190d04636a7 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -24,6 +24,7 @@
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/of_device.h> 25#include <linux/of_device.h>
26#include <linux/of_gpio.h> 26#include <linux/of_gpio.h>
27#include <linux/pinctrl/consumer.h>
27#include <mach/esdhc.h> 28#include <mach/esdhc.h>
28#include "sdhci-pltfm.h" 29#include "sdhci-pltfm.h"
29#include "sdhci-esdhc.h" 30#include "sdhci-esdhc.h"
@@ -68,6 +69,7 @@ struct pltfm_imx_data {
68 int flags; 69 int flags;
69 u32 scratchpad; 70 u32 scratchpad;
70 enum imx_esdhc_type devtype; 71 enum imx_esdhc_type devtype;
72 struct pinctrl *pinctrl;
71 struct esdhc_platform_data boarddata; 73 struct esdhc_platform_data boarddata;
72}; 74};
73 75
@@ -467,6 +469,12 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
467 clk_prepare_enable(clk); 469 clk_prepare_enable(clk);
468 pltfm_host->clk = clk; 470 pltfm_host->clk = clk;
469 471
472 imx_data->pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
473 if (IS_ERR(imx_data->pinctrl)) {
474 err = PTR_ERR(imx_data->pinctrl);
475 goto pin_err;
476 }
477
470 host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; 478 host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
471 479
472 if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data)) 480 if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))
@@ -558,6 +566,7 @@ no_card_detect_irq:
558 gpio_free(boarddata->wp_gpio); 566 gpio_free(boarddata->wp_gpio);
559no_card_detect_pin: 567no_card_detect_pin:
560no_board_data: 568no_board_data:
569pin_err:
561 clk_disable_unprepare(pltfm_host->clk); 570 clk_disable_unprepare(pltfm_host->clk);
562 clk_put(pltfm_host->clk); 571 clk_put(pltfm_host->clk);
563err_clk_get: 572err_clk_get: