aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-26 15:57:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-26 15:57:47 -0400
commit84a442b9a16ee69243ce7fce5d6f6f9c3fbdee68 (patch)
tree332a0c901d8ab2ffb19b8ce14b4b094bf5b08657 /drivers/mmc
parent39b6cc668c5ecc66f6f9c9293ffab681cb6f7065 (diff)
parentdeb88cc3c69975cbd9875ed9fac259b351f6b64d (diff)
Merge tag 'dt2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull arm-soc device tree conversions (part 2) from Olof Johansson: "These continue the device tree work from part 1, this set is for the tegra, mxs and imx platforms, all of which have dependencies on clock or pinctrl changes submitted earlier." Fix up trivial conflicts due to nearby changes in drivers/{gpio/gpio,i2c/busses/i2c}-mxs.c * tag 'dt2' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (73 commits) ARM: dt: tegra: invert status=disable vs status=okay ARM: dt: tegra: consistent basic property ordering ARM: dt: tegra: sort nodes based on bus order ARM: dt: tegra: remove duplicate device_type property ARM: dt: tegra: consistenly use lower-case for hex constants ARM: dt: tegra: format regs properties consistently ARM: dt: tegra: gpio comment cleanup ARM: dt: tegra: remove unnecessary unit addresses ARM: dt: tegra: whitespace cleanup ARM: dt: tegra cardhu: fix typo in SDHCI node name ARM: dt: tegra: cardhu: register core regulator tps62361 ARM: dt: tegra30.dtsi: Add SMMU node ARM: dt: tegra20.dtsi: Add GART node ARM: dt: tegra30.dtsi: Add Memory Controller(MC) nodes ARM: dt: tegra20.dtsi: Add Memory Controller(MC) nodes ARM: dt: tegra: Add device tree support for AHB 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 ...
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/host/mxs-mmc.c197
1 files changed, 111 insertions, 86 deletions
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index bb03ddda481d..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>
@@ -40,18 +43,15 @@
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#include <linux/pinctrl/consumer.h> 45#include <linux/pinctrl/consumer.h>
43 46#include <linux/stmp_device.h>
44#include <mach/mxs.h> 47#include <linux/mmc/mxs-mmc.h>
45#include <mach/common.h>
46#include <mach/mmc.h>
47 48
48#define DRIVER_NAME "mxs-mmc" 49#define DRIVER_NAME "mxs-mmc"
49 50
50/* card detect polling timeout */ 51/* card detect polling timeout */
51#define MXS_MMC_DETECT_TIMEOUT (HZ/2) 52#define MXS_MMC_DETECT_TIMEOUT (HZ/2)
52 53
53#define SSP_VERSION_LATEST 4 54#define ssp_is_old(host) ((host)->devid == IMX23_MMC)
54#define ssp_is_old() (host->version < SSP_VERSION_LATEST)
55 55
56/* SSP registers */ 56/* SSP registers */
57#define HW_SSP_CTRL0 0x000 57#define HW_SSP_CTRL0 0x000
@@ -86,14 +86,14 @@
86#define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4) 86#define BM_SSP_BLOCK_SIZE_BLOCK_COUNT (0xffffff << 4)
87#define BP_SSP_BLOCK_SIZE_BLOCK_SIZE (0) 87#define BP_SSP_BLOCK_SIZE_BLOCK_SIZE (0)
88#define BM_SSP_BLOCK_SIZE_BLOCK_SIZE (0xf) 88#define BM_SSP_BLOCK_SIZE_BLOCK_SIZE (0xf)
89#define HW_SSP_TIMING (ssp_is_old() ? 0x050 : 0x070) 89#define HW_SSP_TIMING(h) (ssp_is_old(h) ? 0x050 : 0x070)
90#define BP_SSP_TIMING_TIMEOUT (16) 90#define BP_SSP_TIMING_TIMEOUT (16)
91#define BM_SSP_TIMING_TIMEOUT (0xffff << 16) 91#define BM_SSP_TIMING_TIMEOUT (0xffff << 16)
92#define BP_SSP_TIMING_CLOCK_DIVIDE (8) 92#define BP_SSP_TIMING_CLOCK_DIVIDE (8)
93#define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8) 93#define BM_SSP_TIMING_CLOCK_DIVIDE (0xff << 8)
94#define BP_SSP_TIMING_CLOCK_RATE (0) 94#define BP_SSP_TIMING_CLOCK_RATE (0)
95#define BM_SSP_TIMING_CLOCK_RATE (0xff) 95#define BM_SSP_TIMING_CLOCK_RATE (0xff)
96#define HW_SSP_CTRL1 (ssp_is_old() ? 0x060 : 0x080) 96#define HW_SSP_CTRL1(h) (ssp_is_old(h) ? 0x060 : 0x080)
97#define BM_SSP_CTRL1_SDIO_IRQ (1 << 31) 97#define BM_SSP_CTRL1_SDIO_IRQ (1 << 31)
98#define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30) 98#define BM_SSP_CTRL1_SDIO_IRQ_EN (1 << 30)
99#define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29) 99#define BM_SSP_CTRL1_RESP_ERR_IRQ (1 << 29)
@@ -116,15 +116,13 @@
116#define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4) 116#define BM_SSP_CTRL1_WORD_LENGTH (0xf << 4)
117#define BP_SSP_CTRL1_SSP_MODE (0) 117#define BP_SSP_CTRL1_SSP_MODE (0)
118#define BM_SSP_CTRL1_SSP_MODE (0xf) 118#define BM_SSP_CTRL1_SSP_MODE (0xf)
119#define HW_SSP_SDRESP0 (ssp_is_old() ? 0x080 : 0x0a0) 119#define HW_SSP_SDRESP0(h) (ssp_is_old(h) ? 0x080 : 0x0a0)
120#define HW_SSP_SDRESP1 (ssp_is_old() ? 0x090 : 0x0b0) 120#define HW_SSP_SDRESP1(h) (ssp_is_old(h) ? 0x090 : 0x0b0)
121#define HW_SSP_SDRESP2 (ssp_is_old() ? 0x0a0 : 0x0c0) 121#define HW_SSP_SDRESP2(h) (ssp_is_old(h) ? 0x0a0 : 0x0c0)
122#define HW_SSP_SDRESP3 (ssp_is_old() ? 0x0b0 : 0x0d0) 122#define HW_SSP_SDRESP3(h) (ssp_is_old(h) ? 0x0b0 : 0x0d0)
123#define HW_SSP_STATUS (ssp_is_old() ? 0x0c0 : 0x100) 123#define HW_SSP_STATUS(h) (ssp_is_old(h) ? 0x0c0 : 0x100)
124#define BM_SSP_STATUS_CARD_DETECT (1 << 28) 124#define BM_SSP_STATUS_CARD_DETECT (1 << 28)
125#define BM_SSP_STATUS_SDIO_IRQ (1 << 17) 125#define BM_SSP_STATUS_SDIO_IRQ (1 << 17)
126#define HW_SSP_VERSION (cpu_is_mx23() ? 0x110 : 0x130)
127#define BP_SSP_VERSION_MAJOR (24)
128 126
129#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)
130 128
@@ -139,6 +137,11 @@
139 137
140#define SSP_PIO_NUM 3 138#define SSP_PIO_NUM 3
141 139
140enum mxs_mmc_id {
141 IMX23_MMC,
142 IMX28_MMC,
143};
144
142struct mxs_mmc_host { 145struct mxs_mmc_host {
143 struct mmc_host *mmc; 146 struct mmc_host *mmc;
144 struct mmc_request *mrq; 147 struct mmc_request *mrq;
@@ -146,9 +149,7 @@ struct mxs_mmc_host {
146 struct mmc_data *data; 149 struct mmc_data *data;
147 150
148 void __iomem *base; 151 void __iomem *base;
149 int irq; 152 int dma_channel;
150 struct resource *res;
151 struct resource *dma_res;
152 struct clk *clk; 153 struct clk *clk;
153 unsigned int clk_rate; 154 unsigned int clk_rate;
154 155
@@ -158,32 +159,28 @@ struct mxs_mmc_host {
158 enum dma_transfer_direction slave_dirn; 159 enum dma_transfer_direction slave_dirn;
159 u32 ssp_pio_words[SSP_PIO_NUM]; 160 u32 ssp_pio_words[SSP_PIO_NUM];
160 161
161 unsigned int version; 162 enum mxs_mmc_id devid;
162 unsigned char bus_width; 163 unsigned char bus_width;
163 spinlock_t lock; 164 spinlock_t lock;
164 int sdio_irq_en; 165 int sdio_irq_en;
166 int wp_gpio;
165}; 167};
166 168
167static int mxs_mmc_get_ro(struct mmc_host *mmc) 169static int mxs_mmc_get_ro(struct mmc_host *mmc)
168{ 170{
169 struct mxs_mmc_host *host = mmc_priv(mmc); 171 struct mxs_mmc_host *host = mmc_priv(mmc);
170 struct mxs_mmc_platform_data *pdata =
171 mmc_dev(host->mmc)->platform_data;
172
173 if (!pdata)
174 return -EFAULT;
175 172
176 if (!gpio_is_valid(pdata->wp_gpio)) 173 if (!gpio_is_valid(host->wp_gpio))
177 return -EINVAL; 174 return -EINVAL;
178 175
179 return gpio_get_value(pdata->wp_gpio); 176 return gpio_get_value(host->wp_gpio);
180} 177}
181 178
182static int mxs_mmc_get_cd(struct mmc_host *mmc) 179static int mxs_mmc_get_cd(struct mmc_host *mmc)
183{ 180{
184 struct mxs_mmc_host *host = mmc_priv(mmc); 181 struct mxs_mmc_host *host = mmc_priv(mmc);
185 182
186 return !(readl(host->base + HW_SSP_STATUS) & 183 return !(readl(host->base + HW_SSP_STATUS(host)) &
187 BM_SSP_STATUS_CARD_DETECT); 184 BM_SSP_STATUS_CARD_DETECT);
188} 185}
189 186
@@ -191,7 +188,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
191{ 188{
192 u32 ctrl0, ctrl1; 189 u32 ctrl0, ctrl1;
193 190
194 mxs_reset_block(host->base); 191 stmp_reset_block(host->base);
195 192
196 ctrl0 = BM_SSP_CTRL0_IGNORE_CRC; 193 ctrl0 = BM_SSP_CTRL0_IGNORE_CRC;
197 ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) | 194 ctrl1 = BF_SSP(0x3, CTRL1_SSP_MODE) |
@@ -207,7 +204,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
207 writel(BF_SSP(0xffff, TIMING_TIMEOUT) | 204 writel(BF_SSP(0xffff, TIMING_TIMEOUT) |
208 BF_SSP(2, TIMING_CLOCK_DIVIDE) | 205 BF_SSP(2, TIMING_CLOCK_DIVIDE) |
209 BF_SSP(0, TIMING_CLOCK_RATE), 206 BF_SSP(0, TIMING_CLOCK_RATE),
210 host->base + HW_SSP_TIMING); 207 host->base + HW_SSP_TIMING(host));
211 208
212 if (host->sdio_irq_en) { 209 if (host->sdio_irq_en) {
213 ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK; 210 ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
@@ -215,7 +212,7 @@ static void mxs_mmc_reset(struct mxs_mmc_host *host)
215 } 212 }
216 213
217 writel(ctrl0, host->base + HW_SSP_CTRL0); 214 writel(ctrl0, host->base + HW_SSP_CTRL0);
218 writel(ctrl1, host->base + HW_SSP_CTRL1); 215 writel(ctrl1, host->base + HW_SSP_CTRL1(host));
219} 216}
220 217
221static void mxs_mmc_start_cmd(struct mxs_mmc_host *host, 218static void mxs_mmc_start_cmd(struct mxs_mmc_host *host,
@@ -229,12 +226,12 @@ static void mxs_mmc_request_done(struct mxs_mmc_host *host)
229 226
230 if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) { 227 if (mmc_resp_type(cmd) & MMC_RSP_PRESENT) {
231 if (mmc_resp_type(cmd) & MMC_RSP_136) { 228 if (mmc_resp_type(cmd) & MMC_RSP_136) {
232 cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0); 229 cmd->resp[3] = readl(host->base + HW_SSP_SDRESP0(host));
233 cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1); 230 cmd->resp[2] = readl(host->base + HW_SSP_SDRESP1(host));
234 cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2); 231 cmd->resp[1] = readl(host->base + HW_SSP_SDRESP2(host));
235 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3); 232 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP3(host));
236 } else { 233 } else {
237 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0); 234 cmd->resp[0] = readl(host->base + HW_SSP_SDRESP0(host));
238 } 235 }
239 } 236 }
240 237
@@ -277,9 +274,9 @@ static irqreturn_t mxs_mmc_irq_handler(int irq, void *dev_id)
277 274
278 spin_lock(&host->lock); 275 spin_lock(&host->lock);
279 276
280 stat = readl(host->base + HW_SSP_CTRL1); 277 stat = readl(host->base + HW_SSP_CTRL1(host));
281 writel(stat & MXS_MMC_IRQ_BITS, 278 writel(stat & MXS_MMC_IRQ_BITS,
282 host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR); 279 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
283 280
284 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))
285 mmc_signal_sdio_irq(host->mmc); 282 mmc_signal_sdio_irq(host->mmc);
@@ -485,7 +482,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
485 blocks = 1; 482 blocks = 1;
486 483
487 /* xfer count, block size and count need to be set differently */ 484 /* xfer count, block size and count need to be set differently */
488 if (ssp_is_old()) { 485 if (ssp_is_old(host)) {
489 ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT); 486 ctrl0 |= BF_SSP(data_size, CTRL0_XFER_COUNT);
490 cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) | 487 cmd0 |= BF_SSP(log2_blksz, CMD0_BLOCK_SIZE) |
491 BF_SSP(blocks - 1, CMD0_BLOCK_COUNT); 488 BF_SSP(blocks - 1, CMD0_BLOCK_COUNT);
@@ -509,10 +506,10 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
509 506
510 /* set the timeout count */ 507 /* set the timeout count */
511 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);
512 val = readl(host->base + HW_SSP_TIMING); 509 val = readl(host->base + HW_SSP_TIMING(host));
513 val &= ~(BM_SSP_TIMING_TIMEOUT); 510 val &= ~(BM_SSP_TIMING_TIMEOUT);
514 val |= BF_SSP(timeout, TIMING_TIMEOUT); 511 val |= BF_SSP(timeout, TIMING_TIMEOUT);
515 writel(val, host->base + HW_SSP_TIMING); 512 writel(val, host->base + HW_SSP_TIMING(host));
516 513
517 /* pio */ 514 /* pio */
518 host->ssp_pio_words[0] = ctrl0; 515 host->ssp_pio_words[0] = ctrl0;
@@ -598,11 +595,11 @@ static void mxs_mmc_set_clk_rate(struct mxs_mmc_host *host, unsigned int rate)
598 595
599 ssp_sck = ssp_clk / clock_divide / (1 + clock_rate); 596 ssp_sck = ssp_clk / clock_divide / (1 + clock_rate);
600 597
601 val = readl(host->base + HW_SSP_TIMING); 598 val = readl(host->base + HW_SSP_TIMING(host));
602 val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE); 599 val &= ~(BM_SSP_TIMING_CLOCK_DIVIDE | BM_SSP_TIMING_CLOCK_RATE);
603 val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE); 600 val |= BF_SSP(clock_divide, TIMING_CLOCK_DIVIDE);
604 val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE); 601 val |= BF_SSP(clock_rate, TIMING_CLOCK_RATE);
605 writel(val, host->base + HW_SSP_TIMING); 602 writel(val, host->base + HW_SSP_TIMING(host));
606 603
607 host->clk_rate = ssp_sck; 604 host->clk_rate = ssp_sck;
608 605
@@ -637,18 +634,19 @@ static void mxs_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
637 634
638 if (enable) { 635 if (enable) {
639 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, 636 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
640 host->base + HW_SSP_CTRL0 + MXS_SET_ADDR); 637 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
641 writel(BM_SSP_CTRL1_SDIO_IRQ_EN, 638 writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
642 host->base + HW_SSP_CTRL1 + MXS_SET_ADDR); 639 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_SET);
643 640
644 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)
645 mmc_signal_sdio_irq(host->mmc); 643 mmc_signal_sdio_irq(host->mmc);
646 644
647 } else { 645 } else {
648 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK, 646 writel(BM_SSP_CTRL0_SDIO_IRQ_CHECK,
649 host->base + HW_SSP_CTRL0 + MXS_CLR_ADDR); 647 host->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_CLR);
650 writel(BM_SSP_CTRL1_SDIO_IRQ_EN, 648 writel(BM_SSP_CTRL1_SDIO_IRQ_EN,
651 host->base + HW_SSP_CTRL1 + MXS_CLR_ADDR); 649 host->base + HW_SSP_CTRL1(host) + STMP_OFFSET_REG_CLR);
652 } 650 }
653 651
654 spin_unlock_irqrestore(&host->lock, flags); 652 spin_unlock_irqrestore(&host->lock, flags);
@@ -669,7 +667,7 @@ static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
669 if (!mxs_dma_is_apbh(chan)) 667 if (!mxs_dma_is_apbh(chan))
670 return false; 668 return false;
671 669
672 if (chan->chan_id != host->dma_res->start) 670 if (chan->chan_id != host->dma_channel)
673 return false; 671 return false;
674 672
675 chan->private = &host->dma_data; 673 chan->private = &host->dma_data;
@@ -677,11 +675,34 @@ static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
677 return true; 675 return true;
678} 676}
679 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
680static int mxs_mmc_probe(struct platform_device *pdev) 698static int mxs_mmc_probe(struct platform_device *pdev)
681{ 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;
682 struct mxs_mmc_host *host; 703 struct mxs_mmc_host *host;
683 struct mmc_host *mmc; 704 struct mmc_host *mmc;
684 struct resource *iores, *dmares, *r; 705 struct resource *iores, *dmares;
685 struct mxs_mmc_platform_data *pdata; 706 struct mxs_mmc_platform_data *pdata;
686 struct pinctrl *pinctrl; 707 struct pinctrl *pinctrl;
687 int ret = 0, irq_err, irq_dma; 708 int ret = 0, irq_err, irq_dma;
@@ -691,46 +712,51 @@ static int mxs_mmc_probe(struct platform_device *pdev)
691 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); 712 dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
692 irq_err = platform_get_irq(pdev, 0); 713 irq_err = platform_get_irq(pdev, 0);
693 irq_dma = platform_get_irq(pdev, 1); 714 irq_dma = platform_get_irq(pdev, 1);
694 if (!iores || !dmares || irq_err < 0 || irq_dma < 0) 715 if (!iores || irq_err < 0 || irq_dma < 0)
695 return -EINVAL; 716 return -EINVAL;
696 717
697 r = request_mem_region(iores->start, resource_size(iores), pdev->name);
698 if (!r)
699 return -EBUSY;
700
701 mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev); 718 mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev);
702 if (!mmc) { 719 if (!mmc)
703 ret = -ENOMEM; 720 return -ENOMEM;
704 goto out_release_mem;
705 }
706 721
707 host = mmc_priv(mmc); 722 host = mmc_priv(mmc);
708 host->base = ioremap(r->start, resource_size(r)); 723 host->base = devm_request_and_ioremap(&pdev->dev, iores);
709 if (!host->base) { 724 if (!host->base) {
710 ret = -ENOMEM; 725 ret = -EADDRNOTAVAIL;
711 goto out_mmc_free; 726 goto out_mmc_free;
712 } 727 }
713 728
714 /* only major verion does matter */ 729 if (np) {
715 host->version = readl(host->base + HW_SSP_VERSION) >> 730 host->devid = (enum mxs_mmc_id) of_id->data;
716 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 }
717 746
718 host->mmc = mmc; 747 host->mmc = mmc;
719 host->res = r;
720 host->dma_res = dmares;
721 host->irq = irq_err;
722 host->sdio_irq_en = 0; 748 host->sdio_irq_en = 0;
723 749
724 pinctrl = devm_pinctrl_get_select_default(&pdev->dev); 750 pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
725 if (IS_ERR(pinctrl)) { 751 if (IS_ERR(pinctrl)) {
726 ret = PTR_ERR(pinctrl); 752 ret = PTR_ERR(pinctrl);
727 goto out_iounmap; 753 goto out_mmc_free;
728 } 754 }
729 755
730 host->clk = clk_get(&pdev->dev, NULL); 756 host->clk = clk_get(&pdev->dev, NULL);
731 if (IS_ERR(host->clk)) { 757 if (IS_ERR(host->clk)) {
732 ret = PTR_ERR(host->clk); 758 ret = PTR_ERR(host->clk);
733 goto out_iounmap; 759 goto out_mmc_free;
734 } 760 }
735 clk_prepare_enable(host->clk); 761 clk_prepare_enable(host->clk);
736 762
@@ -752,11 +778,20 @@ static int mxs_mmc_probe(struct platform_device *pdev)
752 MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL; 778 MMC_CAP_SDIO_IRQ | MMC_CAP_NEEDS_POLL;
753 779
754 pdata = mmc_dev(host->mmc)->platform_data; 780 pdata = mmc_dev(host->mmc)->platform_data;
755 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 {
756 if (pdata->flags & SLOTF_8_BIT_CAPABLE) 790 if (pdata->flags & SLOTF_8_BIT_CAPABLE)
757 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;
758 if (pdata->flags & SLOTF_4_BIT_CAPABLE) 792 if (pdata->flags & SLOTF_4_BIT_CAPABLE)
759 mmc->caps |= MMC_CAP_4_BIT_DATA; 793 mmc->caps |= MMC_CAP_4_BIT_DATA;
794 host->wp_gpio = pdata->wp_gpio;
760 } 795 }
761 796
762 mmc->f_min = 400000; 797 mmc->f_min = 400000;
@@ -765,13 +800,14 @@ static int mxs_mmc_probe(struct platform_device *pdev)
765 800
766 mmc->max_segs = 52; 801 mmc->max_segs = 52;
767 mmc->max_blk_size = 1 << 0xf; 802 mmc->max_blk_size = 1 << 0xf;
768 mmc->max_blk_count = (ssp_is_old()) ? 0xff : 0xffffff; 803 mmc->max_blk_count = (ssp_is_old(host)) ? 0xff : 0xffffff;
769 mmc->max_req_size = (ssp_is_old()) ? 0xffff : 0xffffffff; 804 mmc->max_req_size = (ssp_is_old(host)) ? 0xffff : 0xffffffff;
770 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);
771 806
772 platform_set_drvdata(pdev, mmc); 807 platform_set_drvdata(pdev, mmc);
773 808
774 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);
775 if (ret) 811 if (ret)
776 goto out_free_dma; 812 goto out_free_dma;
777 813
@@ -779,26 +815,20 @@ static int mxs_mmc_probe(struct platform_device *pdev)
779 815
780 ret = mmc_add_host(mmc); 816 ret = mmc_add_host(mmc);
781 if (ret) 817 if (ret)
782 goto out_free_irq; 818 goto out_free_dma;
783 819
784 dev_info(mmc_dev(host->mmc), "initialized\n"); 820 dev_info(mmc_dev(host->mmc), "initialized\n");
785 821
786 return 0; 822 return 0;
787 823
788out_free_irq:
789 free_irq(host->irq, host);
790out_free_dma: 824out_free_dma:
791 if (host->dmach) 825 if (host->dmach)
792 dma_release_channel(host->dmach); 826 dma_release_channel(host->dmach);
793out_clk_put: 827out_clk_put:
794 clk_disable_unprepare(host->clk); 828 clk_disable_unprepare(host->clk);
795 clk_put(host->clk); 829 clk_put(host->clk);
796out_iounmap:
797 iounmap(host->base);
798out_mmc_free: 830out_mmc_free:
799 mmc_free_host(mmc); 831 mmc_free_host(mmc);
800out_release_mem:
801 release_mem_region(iores->start, resource_size(iores));
802 return ret; 832 return ret;
803} 833}
804 834
@@ -806,12 +836,9 @@ static int mxs_mmc_remove(struct platform_device *pdev)
806{ 836{
807 struct mmc_host *mmc = platform_get_drvdata(pdev); 837 struct mmc_host *mmc = platform_get_drvdata(pdev);
808 struct mxs_mmc_host *host = mmc_priv(mmc); 838 struct mxs_mmc_host *host = mmc_priv(mmc);
809 struct resource *res = host->res;
810 839
811 mmc_remove_host(mmc); 840 mmc_remove_host(mmc);
812 841
813 free_irq(host->irq, host);
814
815 platform_set_drvdata(pdev, NULL); 842 platform_set_drvdata(pdev, NULL);
816 843
817 if (host->dmach) 844 if (host->dmach)
@@ -820,12 +847,8 @@ static int mxs_mmc_remove(struct platform_device *pdev)
820 clk_disable_unprepare(host->clk); 847 clk_disable_unprepare(host->clk);
821 clk_put(host->clk); 848 clk_put(host->clk);
822 849
823 iounmap(host->base);
824
825 mmc_free_host(mmc); 850 mmc_free_host(mmc);
826 851
827 release_mem_region(res->start, resource_size(res));
828
829 return 0; 852 return 0;
830} 853}
831 854
@@ -865,11 +888,13 @@ static const struct dev_pm_ops mxs_mmc_pm_ops = {
865static struct platform_driver mxs_mmc_driver = { 888static struct platform_driver mxs_mmc_driver = {
866 .probe = mxs_mmc_probe, 889 .probe = mxs_mmc_probe,
867 .remove = mxs_mmc_remove, 890 .remove = mxs_mmc_remove,
891 .id_table = mxs_mmc_ids,
868 .driver = { 892 .driver = {
869 .name = DRIVER_NAME, 893 .name = DRIVER_NAME,
870 .owner = THIS_MODULE, 894 .owner = THIS_MODULE,
871#ifdef CONFIG_PM 895#ifdef CONFIG_PM
872 .pm = &mxs_mmc_pm_ops, 896 .pm = &mxs_mmc_pm_ops,
897 .of_match_table = mxs_mmc_dt_ids,
873#endif 898#endif
874 }, 899 },
875}; 900};