mxcmmc.c 29.6 KB
Newer Older
1 2 3 4 5 6
/*
 *  linux/drivers/mmc/host/mxcmmc.c - Freescale i.MX MMCI driver
 *
 *  This is a driver for the SDHC controller found in Freescale MX2/MX3
 *  SoCs. It is basically the same hardware as found on MX1 (imxmmc.c).
 *  Unlike the hardware found on MX1, this hardware just works and does
D
Daniel Mack 已提交
7
 *  not need all the quirks found in imxmmc.c, hence the separate driver.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
 *
 *  Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
 *  Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
 *
 *  derived from pxamci.c by Russell King
 *
 * 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/module.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/blkdev.h>
#include <linux/dma-mapping.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/gpio.h>
34
#include <linux/regulator/consumer.h>
S
Sascha Hauer 已提交
35
#include <linux/dmaengine.h>
36
#include <linux/types.h>
M
Markus Pargmann 已提交
37 38 39 40
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_dma.h>
#include <linux/of_gpio.h>
41
#include <linux/mmc/slot-gpio.h>
42 43 44

#include <asm/dma.h>
#include <asm/irq.h>
45
#include <linux/platform_data/mmc-mxcmmc.h>
46

47
#include <linux/platform_data/dma-imx.h>
48

49
#define DRIVER_NAME "mxc-mmc"
50
#define MXCMCI_TIMEOUT_MS 10000
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118

#define MMC_REG_STR_STP_CLK		0x00
#define MMC_REG_STATUS			0x04
#define MMC_REG_CLK_RATE		0x08
#define MMC_REG_CMD_DAT_CONT		0x0C
#define MMC_REG_RES_TO			0x10
#define MMC_REG_READ_TO			0x14
#define MMC_REG_BLK_LEN			0x18
#define MMC_REG_NOB			0x1C
#define MMC_REG_REV_NO			0x20
#define MMC_REG_INT_CNTR		0x24
#define MMC_REG_CMD			0x28
#define MMC_REG_ARG			0x2C
#define MMC_REG_RES_FIFO		0x34
#define MMC_REG_BUFFER_ACCESS		0x38

#define STR_STP_CLK_RESET               (1 << 3)
#define STR_STP_CLK_START_CLK           (1 << 1)
#define STR_STP_CLK_STOP_CLK            (1 << 0)

#define STATUS_CARD_INSERTION		(1 << 31)
#define STATUS_CARD_REMOVAL		(1 << 30)
#define STATUS_YBUF_EMPTY		(1 << 29)
#define STATUS_XBUF_EMPTY		(1 << 28)
#define STATUS_YBUF_FULL		(1 << 27)
#define STATUS_XBUF_FULL		(1 << 26)
#define STATUS_BUF_UND_RUN		(1 << 25)
#define STATUS_BUF_OVFL			(1 << 24)
#define STATUS_SDIO_INT_ACTIVE		(1 << 14)
#define STATUS_END_CMD_RESP		(1 << 13)
#define STATUS_WRITE_OP_DONE		(1 << 12)
#define STATUS_DATA_TRANS_DONE		(1 << 11)
#define STATUS_READ_OP_DONE		(1 << 11)
#define STATUS_WR_CRC_ERROR_CODE_MASK	(3 << 10)
#define STATUS_CARD_BUS_CLK_RUN		(1 << 8)
#define STATUS_BUF_READ_RDY		(1 << 7)
#define STATUS_BUF_WRITE_RDY		(1 << 6)
#define STATUS_RESP_CRC_ERR		(1 << 5)
#define STATUS_CRC_READ_ERR		(1 << 3)
#define STATUS_CRC_WRITE_ERR		(1 << 2)
#define STATUS_TIME_OUT_RESP		(1 << 1)
#define STATUS_TIME_OUT_READ		(1 << 0)
#define STATUS_ERR_MASK			0x2f

#define CMD_DAT_CONT_CMD_RESP_LONG_OFF	(1 << 12)
#define CMD_DAT_CONT_STOP_READWAIT	(1 << 11)
#define CMD_DAT_CONT_START_READWAIT	(1 << 10)
#define CMD_DAT_CONT_BUS_WIDTH_4	(2 << 8)
#define CMD_DAT_CONT_INIT		(1 << 7)
#define CMD_DAT_CONT_WRITE		(1 << 4)
#define CMD_DAT_CONT_DATA_ENABLE	(1 << 3)
#define CMD_DAT_CONT_RESPONSE_48BIT_CRC	(1 << 0)
#define CMD_DAT_CONT_RESPONSE_136BIT	(2 << 0)
#define CMD_DAT_CONT_RESPONSE_48BIT	(3 << 0)

#define INT_SDIO_INT_WKP_EN		(1 << 18)
#define INT_CARD_INSERTION_WKP_EN	(1 << 17)
#define INT_CARD_REMOVAL_WKP_EN		(1 << 16)
#define INT_CARD_INSERTION_EN		(1 << 15)
#define INT_CARD_REMOVAL_EN		(1 << 14)
#define INT_SDIO_IRQ_EN			(1 << 13)
#define INT_DAT0_EN			(1 << 12)
#define INT_BUF_READ_EN			(1 << 4)
#define INT_BUF_WRITE_EN		(1 << 3)
#define INT_END_CMD_RES_EN		(1 << 2)
#define INT_WRITE_OP_DONE_EN		(1 << 1)
#define INT_READ_OP_EN			(1 << 0)

119 120 121
enum mxcmci_type {
	IMX21_MMC,
	IMX31_MMC,
122
	MPC512X_MMC,
123 124
};

125 126 127
struct mxcmci_host {
	struct mmc_host		*mmc;
	void __iomem		*base;
128
	dma_addr_t		phys_base;
129
	int			detect_irq;
S
Sascha Hauer 已提交
130 131
	struct dma_chan		*dma;
	struct dma_async_tx_descriptor *desc;
132
	int			do_dma;
133
	int			default_irq_mask;
134
	int			use_sdio;
135 136 137 138 139 140 141 142 143 144 145 146 147
	unsigned int		power_mode;
	struct imxmmc_platform_data *pdata;

	struct mmc_request	*req;
	struct mmc_command	*cmd;
	struct mmc_data		*data;

	unsigned int		datasize;
	unsigned int		dma_dir;

	u16			rev_no;
	unsigned int		cmdat;

148 149
	struct clk		*clk_ipg;
	struct clk		*clk_per;
150 151 152 153

	int			clock;

	struct work_struct	datawork;
154
	spinlock_t		lock;
155

S
Sascha Hauer 已提交
156 157 158 159
	int			burstlen;
	int			dmareq;
	struct dma_slave_config dma_slave_config;
	struct imx_dma_data	dma_data;
160 161

	struct timer_list	watchdog;
162 163 164
	enum mxcmci_type	devtype;
};

165
static const struct platform_device_id mxcmci_devtype[] = {
166 167 168 169 170 171
	{
		.name = "imx21-mmc",
		.driver_data = IMX21_MMC,
	}, {
		.name = "imx31-mmc",
		.driver_data = IMX31_MMC,
172 173 174
	}, {
		.name = "mpc512x-sdhc",
		.driver_data = MPC512X_MMC,
175 176 177
	}, {
		/* sentinel */
	}
178
};
179 180
MODULE_DEVICE_TABLE(platform, mxcmci_devtype);

M
Markus Pargmann 已提交
181 182 183 184 185 186 187
static const struct of_device_id mxcmci_of_match[] = {
	{
		.compatible = "fsl,imx21-mmc",
		.data = &mxcmci_devtype[IMX21_MMC],
	}, {
		.compatible = "fsl,imx31-mmc",
		.data = &mxcmci_devtype[IMX31_MMC],
188 189 190
	}, {
		.compatible = "fsl,mpc5121-sdhc",
		.data = &mxcmci_devtype[MPC512X_MMC],
M
Markus Pargmann 已提交
191 192 193 194 195 196
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(of, mxcmci_of_match);

197 198 199 200
static inline int is_imx31_mmc(struct mxcmci_host *host)
{
	return host->devtype == IMX31_MMC;
}
201

202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
static inline int is_mpc512x_mmc(struct mxcmci_host *host)
{
	return host->devtype == MPC512X_MMC;
}

static inline u32 mxcmci_readl(struct mxcmci_host *host, int reg)
{
	if (IS_ENABLED(CONFIG_PPC_MPC512x))
		return ioread32be(host->base + reg);
	else
		return readl(host->base + reg);
}

static inline void mxcmci_writel(struct mxcmci_host *host, u32 val, int reg)
{
	if (IS_ENABLED(CONFIG_PPC_MPC512x))
		iowrite32be(val, host->base + reg);
	else
		writel(val, host->base + reg);
}

static inline u16 mxcmci_readw(struct mxcmci_host *host, int reg)
{
	if (IS_ENABLED(CONFIG_PPC_MPC512x))
		return ioread32be(host->base + reg);
	else
		return readw(host->base + reg);
}

static inline void mxcmci_writew(struct mxcmci_host *host, u16 val, int reg)
{
	if (IS_ENABLED(CONFIG_PPC_MPC512x))
		iowrite32be(val, host->base + reg);
	else
		writew(val, host->base + reg);
}

239 240
static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);

241
static void mxcmci_set_power(struct mxcmci_host *host, unsigned int vdd)
242
{
243 244 245 246 247 248 249
	if (!IS_ERR(host->mmc->supply.vmmc)) {
		if (host->power_mode == MMC_POWER_UP)
			mmc_regulator_set_ocr(host->mmc,
					      host->mmc->supply.vmmc, vdd);
		else if (host->power_mode == MMC_POWER_OFF)
			mmc_regulator_set_ocr(host->mmc,
					      host->mmc->supply.vmmc, 0);
250 251
	}

252 253 254 255
	if (host->pdata && host->pdata->setpower)
		host->pdata->setpower(mmc_dev(host->mmc), vdd);
}

256 257 258 259 260 261 262 263 264
static inline int mxcmci_use_dma(struct mxcmci_host *host)
{
	return host->do_dma;
}

static void mxcmci_softreset(struct mxcmci_host *host)
{
	int i;

D
Daniel Mack 已提交
265 266
	dev_dbg(mmc_dev(host->mmc), "mxcmci_softreset\n");

267
	/* reset sequence */
268 269 270
	mxcmci_writew(host, STR_STP_CLK_RESET, MMC_REG_STR_STP_CLK);
	mxcmci_writew(host, STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
			MMC_REG_STR_STP_CLK);
271 272

	for (i = 0; i < 8; i++)
273
		mxcmci_writew(host, STR_STP_CLK_START_CLK, MMC_REG_STR_STP_CLK);
274

275
	mxcmci_writew(host, 0xff, MMC_REG_RES_TO);
276 277
}

278 279 280 281 282 283
#if IS_ENABLED(CONFIG_PPC_MPC512x)
static inline void buffer_swap32(u32 *buf, int len)
{
	int i;

	for (i = 0; i < ((len + 3) / 4); i++) {
284
		*buf = swab32(*buf);
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
		buf++;
	}
}

static void mxcmci_swap_buffers(struct mmc_data *data)
{
	struct scatterlist *sg;
	int i;

	for_each_sg(data->sg, sg, data->sg_len, i)
		buffer_swap32(sg_virt(sg), sg->length);
}
#else
static inline void mxcmci_swap_buffers(struct mmc_data *data) {}
#endif

301
static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
302 303 304 305 306
{
	unsigned int nob = data->blocks;
	unsigned int blksz = data->blksz;
	unsigned int datasize = nob * blksz;
	struct scatterlist *sg;
307
	enum dma_transfer_direction slave_dirn;
S
Sascha Hauer 已提交
308 309
	int i, nents;

310 311 312
	host->data = data;
	data->bytes_xfered = 0;

313 314
	mxcmci_writew(host, nob, MMC_REG_NOB);
	mxcmci_writew(host, blksz, MMC_REG_BLK_LEN);
315 316
	host->datasize = datasize;

S
Sascha Hauer 已提交
317 318 319
	if (!mxcmci_use_dma(host))
		return 0;

320
	for_each_sg(data->sg, sg, data->sg_len, i) {
321
		if (sg->offset & 3 || sg->length & 3 || sg->length < 512) {
322
			host->do_dma = 0;
323
			return 0;
324 325 326
		}
	}

327
	if (data->flags & MMC_DATA_READ) {
328
		host->dma_dir = DMA_FROM_DEVICE;
329 330
		slave_dirn = DMA_DEV_TO_MEM;
	} else {
331
		host->dma_dir = DMA_TO_DEVICE;
332
		slave_dirn = DMA_MEM_TO_DEV;
333 334

		mxcmci_swap_buffers(data);
335
	}
336

S
Sascha Hauer 已提交
337 338 339 340 341
	nents = dma_map_sg(host->dma->device->dev, data->sg,
				     data->sg_len,  host->dma_dir);
	if (nents != data->sg_len)
		return -EINVAL;

342
	host->desc = dmaengine_prep_slave_sg(host->dma,
343
		data->sg, data->sg_len, slave_dirn,
S
Sascha Hauer 已提交
344
		DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
345

S
Sascha Hauer 已提交
346 347 348 349 350
	if (!host->desc) {
		dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len,
				host->dma_dir);
		host->do_dma = 0;
		return 0; /* Fall back to PIO */
351
	}
352 353
	wmb();

S
Sascha Hauer 已提交
354
	dmaengine_submit(host->desc);
355
	dma_async_issue_pending(host->dma);
S
Sascha Hauer 已提交
356

357 358
	mod_timer(&host->watchdog, jiffies + msecs_to_jiffies(MXCMCI_TIMEOUT_MS));

359
	return 0;
360 361
}

362 363 364 365 366 367 368 369 370 371
static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat);
static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat);

static void mxcmci_dma_callback(void *data)
{
	struct mxcmci_host *host = data;
	u32 stat;

	del_timer(&host->watchdog);

372
	stat = mxcmci_readl(host, MMC_REG_STATUS);
373 374 375 376 377 378

	dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);

	mxcmci_data_done(host, stat);
}

379 380 381
static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
		unsigned int cmdat)
{
382
	u32 int_cntr = host->default_irq_mask;
383 384
	unsigned long flags;

385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
	WARN_ON(host->cmd != NULL);
	host->cmd = cmd;

	switch (mmc_resp_type(cmd)) {
	case MMC_RSP_R1: /* short CRC, OPCODE */
	case MMC_RSP_R1B:/* short CRC, OPCODE, BUSY */
		cmdat |= CMD_DAT_CONT_RESPONSE_48BIT_CRC;
		break;
	case MMC_RSP_R2: /* long 136 bit + CRC */
		cmdat |= CMD_DAT_CONT_RESPONSE_136BIT;
		break;
	case MMC_RSP_R3: /* short */
		cmdat |= CMD_DAT_CONT_RESPONSE_48BIT;
		break;
	case MMC_RSP_NONE:
		break;
	default:
		dev_err(mmc_dev(host->mmc), "unhandled response type 0x%x\n",
				mmc_resp_type(cmd));
		cmd->error = -EINVAL;
		return -EINVAL;
	}

408 409
	int_cntr = INT_END_CMD_RES_EN;

410 411 412 413 414 415 416 417
	if (mxcmci_use_dma(host)) {
		if (host->dma_dir == DMA_FROM_DEVICE) {
			host->desc->callback = mxcmci_dma_callback;
			host->desc->callback_param = host;
		} else {
			int_cntr |= INT_WRITE_OP_DONE_EN;
		}
	}
418 419 420 421

	spin_lock_irqsave(&host->lock, flags);
	if (host->use_sdio)
		int_cntr |= INT_SDIO_IRQ_EN;
422
	mxcmci_writel(host, int_cntr, MMC_REG_INT_CNTR);
423
	spin_unlock_irqrestore(&host->lock, flags);
424

425 426 427
	mxcmci_writew(host, cmd->opcode, MMC_REG_CMD);
	mxcmci_writel(host, cmd->arg, MMC_REG_ARG);
	mxcmci_writew(host, cmdat, MMC_REG_CMD_DAT_CONT);
428 429 430 431 432 433 434

	return 0;
}

static void mxcmci_finish_request(struct mxcmci_host *host,
		struct mmc_request *req)
{
435
	u32 int_cntr = host->default_irq_mask;
436 437 438 439 440
	unsigned long flags;

	spin_lock_irqsave(&host->lock, flags);
	if (host->use_sdio)
		int_cntr |= INT_SDIO_IRQ_EN;
441
	mxcmci_writel(host, int_cntr, MMC_REG_INT_CNTR);
442
	spin_unlock_irqrestore(&host->lock, flags);
443 444 445 446 447 448 449 450 451 452 453 454 455

	host->req = NULL;
	host->cmd = NULL;
	host->data = NULL;

	mmc_request_done(host->mmc, req);
}

static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
{
	struct mmc_data *data = host->data;
	int data_error;

456
	if (mxcmci_use_dma(host)) {
S
Sascha Hauer 已提交
457
		dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len,
458
				host->dma_dir);
459 460
		mxcmci_swap_buffers(data);
	}
461 462 463 464 465

	if (stat & STATUS_ERR_MASK) {
		dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",
				stat);
		if (stat & STATUS_CRC_READ_ERR) {
D
Daniel Mack 已提交
466
			dev_err(mmc_dev(host->mmc), "%s: -EILSEQ\n", __func__);
467 468 469
			data->error = -EILSEQ;
		} else if (stat & STATUS_CRC_WRITE_ERR) {
			u32 err_code = (stat >> 9) & 0x3;
D
Daniel Mack 已提交
470 471 472
			if (err_code == 2) { /* No CRC response */
				dev_err(mmc_dev(host->mmc),
					"%s: No CRC -ETIMEDOUT\n", __func__);
473
				data->error = -ETIMEDOUT;
D
Daniel Mack 已提交
474 475 476
			} else {
				dev_err(mmc_dev(host->mmc),
					"%s: -EILSEQ\n", __func__);
477
				data->error = -EILSEQ;
D
Daniel Mack 已提交
478
			}
479
		} else if (stat & STATUS_TIME_OUT_READ) {
D
Daniel Mack 已提交
480 481
			dev_err(mmc_dev(host->mmc),
				"%s: read -ETIMEDOUT\n", __func__);
482 483
			data->error = -ETIMEDOUT;
		} else {
D
Daniel Mack 已提交
484
			dev_err(mmc_dev(host->mmc), "%s: -EIO\n", __func__);
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517
			data->error = -EIO;
		}
	} else {
		data->bytes_xfered = host->datasize;
	}

	data_error = data->error;

	host->data = NULL;

	return data_error;
}

static void mxcmci_read_response(struct mxcmci_host *host, unsigned int stat)
{
	struct mmc_command *cmd = host->cmd;
	int i;
	u32 a, b, c;

	if (!cmd)
		return;

	if (stat & STATUS_TIME_OUT_RESP) {
		dev_dbg(mmc_dev(host->mmc), "CMD TIMEOUT\n");
		cmd->error = -ETIMEDOUT;
	} else if (stat & STATUS_RESP_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
		dev_dbg(mmc_dev(host->mmc), "cmd crc error\n");
		cmd->error = -EILSEQ;
	}

	if (cmd->flags & MMC_RSP_PRESENT) {
		if (cmd->flags & MMC_RSP_136) {
			for (i = 0; i < 4; i++) {
518 519
				a = mxcmci_readw(host, MMC_REG_RES_FIFO);
				b = mxcmci_readw(host, MMC_REG_RES_FIFO);
520 521 522
				cmd->resp[i] = a << 16 | b;
			}
		} else {
523 524 525
			a = mxcmci_readw(host, MMC_REG_RES_FIFO);
			b = mxcmci_readw(host, MMC_REG_RES_FIFO);
			c = mxcmci_readw(host, MMC_REG_RES_FIFO);
526 527 528 529 530 531 532 533 534 535 536
			cmd->resp[0] = a << 24 | b << 8 | c >> 8;
		}
	}
}

static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask)
{
	u32 stat;
	unsigned long timeout = jiffies + HZ;

	do {
537
		stat = mxcmci_readl(host, MMC_REG_STATUS);
538 539
		if (stat & STATUS_ERR_MASK)
			return stat;
540 541 542
		if (time_after(jiffies, timeout)) {
			mxcmci_softreset(host);
			mxcmci_set_clk_rate(host, host->clock);
543
			return STATUS_TIME_OUT_READ;
544
		}
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
		if (stat & mask)
			return 0;
		cpu_relax();
	} while (1);
}

static int mxcmci_pull(struct mxcmci_host *host, void *_buf, int bytes)
{
	unsigned int stat;
	u32 *buf = _buf;

	while (bytes > 3) {
		stat = mxcmci_poll_status(host,
				STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
		if (stat)
			return stat;
561
		*buf++ = cpu_to_le32(mxcmci_readl(host, MMC_REG_BUFFER_ACCESS));
562 563 564 565 566 567 568 569 570 571 572
		bytes -= 4;
	}

	if (bytes) {
		u8 *b = (u8 *)buf;
		u32 tmp;

		stat = mxcmci_poll_status(host,
				STATUS_BUF_READ_RDY | STATUS_READ_OP_DONE);
		if (stat)
			return stat;
573
		tmp = cpu_to_le32(mxcmci_readl(host, MMC_REG_BUFFER_ACCESS));
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588
		memcpy(b, &tmp, bytes);
	}

	return 0;
}

static int mxcmci_push(struct mxcmci_host *host, void *_buf, int bytes)
{
	unsigned int stat;
	u32 *buf = _buf;

	while (bytes > 3) {
		stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
		if (stat)
			return stat;
589
		mxcmci_writel(host, cpu_to_le32(*buf++), MMC_REG_BUFFER_ACCESS);
590 591 592 593 594 595 596 597 598 599 600 601
		bytes -= 4;
	}

	if (bytes) {
		u8 *b = (u8 *)buf;
		u32 tmp;

		stat = mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
		if (stat)
			return stat;

		memcpy(&tmp, b, bytes);
602
		mxcmci_writel(host, cpu_to_le32(tmp), MMC_REG_BUFFER_ACCESS);
603 604
	}

605
	return mxcmci_poll_status(host, STATUS_BUF_WRITE_RDY);
606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
}

static int mxcmci_transfer_data(struct mxcmci_host *host)
{
	struct mmc_data *data = host->req->data;
	struct scatterlist *sg;
	int stat, i;

	host->data = data;
	host->datasize = 0;

	if (data->flags & MMC_DATA_READ) {
		for_each_sg(data->sg, sg, data->sg_len, i) {
			stat = mxcmci_pull(host, sg_virt(sg), sg->length);
			if (stat)
				return stat;
			host->datasize += sg->length;
		}
	} else {
		for_each_sg(data->sg, sg, data->sg_len, i) {
			stat = mxcmci_push(host, sg_virt(sg), sg->length);
			if (stat)
				return stat;
			host->datasize += sg->length;
		}
		stat = mxcmci_poll_status(host, STATUS_WRITE_OP_DONE);
		if (stat)
			return stat;
	}
	return 0;
}

static void mxcmci_datawork(struct work_struct *work)
{
	struct mxcmci_host *host = container_of(work, struct mxcmci_host,
						  datawork);
	int datastat = mxcmci_transfer_data(host);
643

644 645
	mxcmci_writel(host, STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE,
		MMC_REG_STATUS);
646 647 648 649 650 651 652 653 654 655 656 657 658 659
	mxcmci_finish_data(host, datastat);

	if (host->req->stop) {
		if (mxcmci_start_cmd(host, host->req->stop, 0)) {
			mxcmci_finish_request(host, host->req);
			return;
		}
	} else {
		mxcmci_finish_request(host, host->req);
	}
}

static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat)
{
660
	struct mmc_request *req;
661
	int data_error;
662 663 664
	unsigned long flags;

	spin_lock_irqsave(&host->lock, flags);
665

666 667
	if (!host->data) {
		spin_unlock_irqrestore(&host->lock, flags);
668
		return;
669 670 671 672 673 674 675 676 677 678
	}

	if (!host->req) {
		spin_unlock_irqrestore(&host->lock, flags);
		return;
	}

	req = host->req;
	if (!req->stop)
		host->req = NULL; /* we will handle finish req below */
679 680 681

	data_error = mxcmci_finish_data(host, stat);

682 683
	spin_unlock_irqrestore(&host->lock, flags);

684 685 686
	if (data_error)
		return;

687 688 689
	mxcmci_read_response(host, stat);
	host->cmd = NULL;

690 691 692
	if (req->stop) {
		if (mxcmci_start_cmd(host, req->stop, 0)) {
			mxcmci_finish_request(host, req);
693 694 695
			return;
		}
	} else {
696
		mxcmci_finish_request(host, req);
697 698 699 700 701 702 703 704 705 706 707 708 709 710
	}
}

static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat)
{
	mxcmci_read_response(host, stat);
	host->cmd = NULL;

	if (!host->data && host->req) {
		mxcmci_finish_request(host, host->req);
		return;
	}

	/* For the DMA case the DMA engine handles the data transfer
711
	 * automatically. For non DMA we have to do it ourselves.
712 713 714 715 716 717 718 719 720 721
	 * Don't do it in interrupt context though.
	 */
	if (!mxcmci_use_dma(host) && host->data)
		schedule_work(&host->datawork);

}

static irqreturn_t mxcmci_irq(int irq, void *devid)
{
	struct mxcmci_host *host = devid;
722 723
	unsigned long flags;
	bool sdio_irq;
724 725
	u32 stat;

726 727 728 729 730
	stat = mxcmci_readl(host, MMC_REG_STATUS);
	mxcmci_writel(host,
		stat & ~(STATUS_SDIO_INT_ACTIVE | STATUS_DATA_TRANS_DONE |
			 STATUS_WRITE_OP_DONE),
		MMC_REG_STATUS);
731 732 733

	dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);

734 735 736 737
	spin_lock_irqsave(&host->lock, flags);
	sdio_irq = (stat & STATUS_SDIO_INT_ACTIVE) && host->use_sdio;
	spin_unlock_irqrestore(&host->lock, flags);

738 739
	if (mxcmci_use_dma(host) && (stat & (STATUS_WRITE_OP_DONE)))
		mxcmci_writel(host, STATUS_WRITE_OP_DONE, MMC_REG_STATUS);
740

741
	if (sdio_irq) {
742
		mxcmci_writel(host, STATUS_SDIO_INT_ACTIVE, MMC_REG_STATUS);
743 744 745
		mmc_signal_sdio_irq(host->mmc);
	}

746 747
	if (stat & STATUS_END_CMD_RESP)
		mxcmci_cmd_done(host, stat);
748

749
	if (mxcmci_use_dma(host) && (stat & STATUS_WRITE_OP_DONE)) {
750
		del_timer(&host->watchdog);
751
		mxcmci_data_done(host, stat);
752
	}
S
Sascha Hauer 已提交
753

754 755 756
	if (host->default_irq_mask &&
		  (stat & (STATUS_CARD_INSERTION | STATUS_CARD_REMOVAL)))
		mmc_detect_change(host->mmc, msecs_to_jiffies(200));
S
Sascha Hauer 已提交
757

758 759 760 761 762 763 764
	return IRQ_HANDLED;
}

static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req)
{
	struct mxcmci_host *host = mmc_priv(mmc);
	unsigned int cmdat = host->cmdat;
765
	int error;
766 767 768 769 770

	WARN_ON(host->req != NULL);

	host->req = req;
	host->cmdat &= ~CMD_DAT_CONT_INIT;
S
Sascha Hauer 已提交
771 772 773 774

	if (host->dma)
		host->do_dma = 1;

775
	if (req->data) {
776 777 778 779 780 781
		error = mxcmci_setup_data(host, req->data);
		if (error) {
			req->cmd->error = error;
			goto out;
		}

782 783 784 785 786 787 788

		cmdat |= CMD_DAT_CONT_DATA_ENABLE;

		if (req->data->flags & MMC_DATA_WRITE)
			cmdat |= CMD_DAT_CONT_WRITE;
	}

789
	error = mxcmci_start_cmd(host, req->cmd, cmdat);
S
Sascha Hauer 已提交
790

791 792
out:
	if (error)
793 794 795 796 797 798 799
		mxcmci_finish_request(host, req);
}

static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios)
{
	unsigned int divider;
	int prescaler = 0;
800
	unsigned int clk_in = clk_get_rate(host->clk_per);
801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822

	while (prescaler <= 0x800) {
		for (divider = 1; divider <= 0xF; divider++) {
			int x;

			x = (clk_in / (divider + 1));

			if (prescaler)
				x /= (prescaler * 2);

			if (x <= clk_ios)
				break;
		}
		if (divider < 0x10)
			break;

		if (prescaler == 0)
			prescaler = 1;
		else
			prescaler <<= 1;
	}

823
	mxcmci_writew(host, (prescaler << 4) | divider, MMC_REG_CLK_RATE);
824 825 826 827 828

	dev_dbg(mmc_dev(host->mmc), "scaler: %d divider: %d in: %d out: %d\n",
			prescaler, divider, clk_in, clk_ios);
}

S
Sascha Hauer 已提交
829 830 831 832 833
static int mxcmci_setup_dma(struct mmc_host *mmc)
{
	struct mxcmci_host *host = mmc_priv(mmc);
	struct dma_slave_config *config = &host->dma_slave_config;

834 835
	config->dst_addr = host->phys_base + MMC_REG_BUFFER_ACCESS;
	config->src_addr = host->phys_base + MMC_REG_BUFFER_ACCESS;
S
Sascha Hauer 已提交
836 837 838 839
	config->dst_addr_width = 4;
	config->src_addr_width = 4;
	config->dst_maxburst = host->burstlen;
	config->src_maxburst = host->burstlen;
840
	config->device_fc = false;
S
Sascha Hauer 已提交
841 842 843 844

	return dmaengine_slave_config(host->dma, config);
}

845 846 847
static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct mxcmci_host *host = mmc_priv(mmc);
S
Sascha Hauer 已提交
848 849
	int burstlen, ret;

850
	/*
851 852
	 * use burstlen of 64 (16 words) in 4 bit mode (--> reg value  0)
	 * use burstlen of 16 (4 words) in 1 bit mode (--> reg value 16)
853 854
	 */
	if (ios->bus_width == MMC_BUS_WIDTH_4)
S
Sascha Hauer 已提交
855
		burstlen = 16;
856 857
	else
		burstlen = 4;
S
Sascha Hauer 已提交
858 859 860 861 862 863 864 865 866

	if (mxcmci_use_dma(host) && burstlen != host->burstlen) {
		host->burstlen = burstlen;
		ret = mxcmci_setup_dma(mmc);
		if (ret) {
			dev_err(mmc_dev(host->mmc),
				"failed to config DMA channel. Falling back to PIO\n");
			dma_release_channel(host->dma);
			host->do_dma = 0;
867
			host->dma = NULL;
S
Sascha Hauer 已提交
868 869
		}
	}
870 871 872 873 874 875 876 877

	if (ios->bus_width == MMC_BUS_WIDTH_4)
		host->cmdat |= CMD_DAT_CONT_BUS_WIDTH_4;
	else
		host->cmdat &= ~CMD_DAT_CONT_BUS_WIDTH_4;

	if (host->power_mode != ios->power_mode) {
		host->power_mode = ios->power_mode;
878
		mxcmci_set_power(host, ios->vdd);
879

880 881 882 883 884 885
		if (ios->power_mode == MMC_POWER_ON)
			host->cmdat |= CMD_DAT_CONT_INIT;
	}

	if (ios->clock) {
		mxcmci_set_clk_rate(host, ios->clock);
886
		mxcmci_writew(host, STR_STP_CLK_START_CLK, MMC_REG_STR_STP_CLK);
887
	} else {
888
		mxcmci_writew(host, STR_STP_CLK_STOP_CLK, MMC_REG_STR_STP_CLK);
889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910
	}

	host->clock = ios->clock;
}

static irqreturn_t mxcmci_detect_irq(int irq, void *data)
{
	struct mmc_host *mmc = data;

	dev_dbg(mmc_dev(mmc), "%s\n", __func__);

	mmc_detect_change(mmc, msecs_to_jiffies(250));
	return IRQ_HANDLED;
}

static int mxcmci_get_ro(struct mmc_host *mmc)
{
	struct mxcmci_host *host = mmc_priv(mmc);

	if (host->pdata && host->pdata->get_ro)
		return !!host->pdata->get_ro(mmc_dev(mmc));
	/*
911 912 913
	 * If board doesn't support read only detection (no mmc_gpio
	 * context or gpio is invalid), then let the mmc core decide
	 * what to do.
914
	 */
915
	return mmc_gpio_get_ro(mmc);
916 917
}

918 919 920 921 922 923 924 925
static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
	struct mxcmci_host *host = mmc_priv(mmc);
	unsigned long flags;
	u32 int_cntr;

	spin_lock_irqsave(&host->lock, flags);
	host->use_sdio = enable;
926
	int_cntr = mxcmci_readl(host, MMC_REG_INT_CNTR);
927 928 929 930 931 932

	if (enable)
		int_cntr |= INT_SDIO_IRQ_EN;
	else
		int_cntr &= ~INT_SDIO_IRQ_EN;

933
	mxcmci_writel(host, int_cntr, MMC_REG_INT_CNTR);
934 935
	spin_unlock_irqrestore(&host->lock, flags);
}
936

937 938
static void mxcmci_init_card(struct mmc_host *host, struct mmc_card *card)
{
939 940
	struct mxcmci_host *mxcmci = mmc_priv(host);

941 942 943 944 945 946 947
	/*
	 * MX3 SoCs have a silicon bug which corrupts CRC calculation of
	 * multi-block transfers when connected SDIO peripheral doesn't
	 * drive the BUSY line as required by the specs.
	 * One way to prevent this is to only allow 1-bit transfers.
	 */

948
	if (is_imx31_mmc(mxcmci) && card->type == MMC_TYPE_SDIO)
949 950 951 952 953
		host->caps &= ~MMC_CAP_4_BIT_DATA;
	else
		host->caps |= MMC_CAP_4_BIT_DATA;
}

S
Sascha Hauer 已提交
954 955 956 957 958 959 960 961 962 963 964 965
static bool filter(struct dma_chan *chan, void *param)
{
	struct mxcmci_host *host = param;

	if (!imx_dma_is_general_purpose(chan))
		return false;

	chan->private = &host->dma_data;

	return true;
}

966 967 968 969 970
static void mxcmci_watchdog(unsigned long data)
{
	struct mmc_host *mmc = (struct mmc_host *)data;
	struct mxcmci_host *host = mmc_priv(mmc);
	struct mmc_request *req = host->req;
971
	unsigned int stat = mxcmci_readl(host, MMC_REG_STATUS);
972 973 974 975 976 977 978 979 980 981 982 983 984 985 986

	if (host->dma_dir == DMA_FROM_DEVICE) {
		dmaengine_terminate_all(host->dma);
		dev_err(mmc_dev(host->mmc),
			"%s: read time out (status = 0x%08x)\n",
			__func__, stat);
	} else {
		dev_err(mmc_dev(host->mmc),
			"%s: write time out (status = 0x%08x)\n",
			__func__, stat);
		mxcmci_softreset(host);
	}

	/* Mark transfer as erroneus and inform the upper layers */

987 988
	if (host->data)
		host->data->error = -ETIMEDOUT;
989 990 991 992 993 994
	host->req = NULL;
	host->cmd = NULL;
	host->data = NULL;
	mmc_request_done(host->mmc, req);
}

995
static const struct mmc_host_ops mxcmci_ops = {
996 997 998 999
	.request		= mxcmci_request,
	.set_ios		= mxcmci_set_ios,
	.get_ro			= mxcmci_get_ro,
	.enable_sdio_irq	= mxcmci_enable_sdio_irq,
1000
	.init_card		= mxcmci_init_card,
1001 1002 1003 1004 1005
};

static int mxcmci_probe(struct platform_device *pdev)
{
	struct mmc_host *mmc;
1006 1007
	struct mxcmci_host *host;
	struct resource *res;
1008
	int ret = 0, irq;
M
Markus Pargmann 已提交
1009
	bool dat3_card_detect = false;
S
Sascha Hauer 已提交
1010
	dma_cap_mask_t mask;
M
Markus Pargmann 已提交
1011 1012
	const struct of_device_id *of_id;
	struct imxmmc_platform_data *pdata = pdev->dev.platform_data;
1013

1014
	pr_info("i.MX/MPC512x SDHC driver\n");
1015

M
Markus Pargmann 已提交
1016 1017
	of_id = of_match_device(mxcmci_of_match, &pdev->dev);

1018
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1019
	irq = platform_get_irq(pdev, 0);
1020 1021 1022 1023
	if (irq < 0) {
		dev_err(&pdev->dev, "failed to get IRQ: %d\n", irq);
		return irq;
	}
1024

1025 1026 1027
	mmc = mmc_alloc_host(sizeof(*host), &pdev->dev);
	if (!mmc)
		return -ENOMEM;
1028

1029 1030 1031 1032 1033 1034
	host = mmc_priv(mmc);

	host->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(host->base)) {
		ret = PTR_ERR(host->base);
		goto out_free;
1035 1036
	}

1037 1038
	host->phys_base = res->start;

1039 1040 1041
	ret = mmc_of_parse(mmc);
	if (ret)
		goto out_free;
1042
	mmc->ops = &mxcmci_ops;
M
Markus Pargmann 已提交
1043 1044 1045 1046 1047 1048

	/* For devicetree parsing, the bus width is read from devicetree */
	if (pdata)
		mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
	else
		mmc->caps |= MMC_CAP_SDIO_IRQ;
1049 1050 1051 1052 1053

	/* MMC core transfer sizes tunable parameters */
	mmc->max_blk_size = 2048;
	mmc->max_blk_count = 65535;
	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
1054
	mmc->max_seg_size = mmc->max_req_size;
1055

M
Markus Pargmann 已提交
1056 1057 1058 1059 1060 1061
	if (of_id) {
		const struct platform_device_id *id_entry = of_id->data;
		host->devtype = id_entry->driver_data;
	} else {
		host->devtype = pdev->id_entry->driver_data;
	}
1062 1063 1064 1065 1066

	/* adjust max_segs after devtype detection */
	if (!is_mpc512x_mmc(host))
		mmc->max_segs = 64;

1067
	host->mmc = mmc;
M
Markus Pargmann 已提交
1068
	host->pdata = pdata;
1069
	spin_lock_init(&host->lock);
1070

M
Markus Pargmann 已提交
1071 1072
	if (pdata)
		dat3_card_detect = pdata->dat3_card_detect;
1073
	else if (mmc_card_is_removable(mmc)
M
Markus Pargmann 已提交
1074 1075 1076
			&& !of_property_read_bool(pdev->dev.of_node, "cd-gpios"))
		dat3_card_detect = true;

1077
	ret = mmc_regulator_get_supply(mmc);
1078 1079 1080 1081 1082 1083
	if (ret == -EPROBE_DEFER)
		goto out_free;

	if (!mmc->ocr_avail) {
		if (pdata && pdata->ocr_avail)
			mmc->ocr_avail = pdata->ocr_avail;
1084
		else
1085
			mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
1086
	}
1087

M
Markus Pargmann 已提交
1088
	if (dat3_card_detect)
1089 1090 1091 1092 1093
		host->default_irq_mask =
			INT_CARD_INSERTION_EN | INT_CARD_REMOVAL_EN;
	else
		host->default_irq_mask = 0;

1094 1095 1096
	host->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
	if (IS_ERR(host->clk_ipg)) {
		ret = PTR_ERR(host->clk_ipg);
1097
		goto out_free;
1098
	}
1099 1100 1101 1102

	host->clk_per = devm_clk_get(&pdev->dev, "per");
	if (IS_ERR(host->clk_per)) {
		ret = PTR_ERR(host->clk_per);
1103
		goto out_free;
1104 1105
	}

1106 1107 1108 1109 1110 1111 1112
	ret = clk_prepare_enable(host->clk_per);
	if (ret)
		goto out_free;

	ret = clk_prepare_enable(host->clk_ipg);
	if (ret)
		goto out_clk_per_put;
1113 1114 1115

	mxcmci_softreset(host);

1116
	host->rev_no = mxcmci_readw(host, MMC_REG_REV_NO);
1117 1118 1119 1120 1121 1122 1123
	if (host->rev_no != 0x400) {
		ret = -ENODEV;
		dev_err(mmc_dev(host->mmc), "wrong rev.no. 0x%08x. aborting.\n",
			host->rev_no);
		goto out_clk_put;
	}

1124 1125
	mmc->f_min = clk_get_rate(host->clk_per) >> 16;
	mmc->f_max = clk_get_rate(host->clk_per) >> 1;
1126 1127

	/* recommended in data sheet */
1128
	mxcmci_writew(host, 0x2db4, MMC_REG_READ_TO);
1129

1130
	mxcmci_writel(host, host->default_irq_mask, MMC_REG_INT_CNTR);
1131

M
Markus Pargmann 已提交
1132 1133 1134
	if (!host->pdata) {
		host->dma = dma_request_slave_channel(&pdev->dev, "rx-tx");
	} else {
1135 1136 1137
		res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
		if (res) {
			host->dmareq = res->start;
M
Markus Pargmann 已提交
1138 1139 1140 1141 1142 1143 1144
			host->dma_data.peripheral_type = IMX_DMATYPE_SDHC;
			host->dma_data.priority = DMA_PRIO_LOW;
			host->dma_data.dma_request = host->dmareq;
			dma_cap_zero(mask);
			dma_cap_set(DMA_SLAVE, mask);
			host->dma = dma_request_channel(mask, filter, host);
		}
S
Sascha Hauer 已提交
1145
	}
M
Markus Pargmann 已提交
1146 1147 1148 1149
	if (host->dma)
		mmc->max_seg_size = dma_get_max_seg_size(
				host->dma->device->dev);
	else
S
Sascha Hauer 已提交
1150
		dev_info(mmc_dev(host->mmc), "dma not available. Using PIO\n");
1151 1152 1153

	INIT_WORK(&host->datawork, mxcmci_datawork);

1154 1155
	ret = devm_request_irq(&pdev->dev, irq, mxcmci_irq, 0,
			       dev_name(&pdev->dev), host);
1156 1157 1158 1159 1160 1161 1162 1163 1164
	if (ret)
		goto out_free_dma;

	platform_set_drvdata(pdev, mmc);

	if (host->pdata && host->pdata->init) {
		ret = host->pdata->init(&pdev->dev, mxcmci_detect_irq,
				host->mmc);
		if (ret)
1165
			goto out_free_dma;
1166 1167
	}

1168
	setup_timer(&host->watchdog, &mxcmci_watchdog, (unsigned long)mmc);
1169

1170 1171
	mmc_add_host(mmc);

1172 1173 1174
	return 0;

out_free_dma:
S
Sascha Hauer 已提交
1175 1176
	if (host->dma)
		dma_release_channel(host->dma);
1177

1178
out_clk_put:
1179
	clk_disable_unprepare(host->clk_ipg);
1180 1181
out_clk_per_put:
	clk_disable_unprepare(host->clk_per);
1182

1183 1184
out_free:
	mmc_free_host(mmc);
1185

1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198
	return ret;
}

static int mxcmci_remove(struct platform_device *pdev)
{
	struct mmc_host *mmc = platform_get_drvdata(pdev);
	struct mxcmci_host *host = mmc_priv(mmc);

	mmc_remove_host(mmc);

	if (host->pdata && host->pdata->exit)
		host->pdata->exit(&pdev->dev, mmc);

S
Sascha Hauer 已提交
1199 1200 1201
	if (host->dma)
		dma_release_channel(host->dma);

1202 1203
	clk_disable_unprepare(host->clk_per);
	clk_disable_unprepare(host->clk_ipg);
1204 1205 1206 1207 1208 1209

	mmc_free_host(mmc);

	return 0;
}

1210
static int __maybe_unused mxcmci_suspend(struct device *dev)
1211
{
1212 1213
	struct mmc_host *mmc = dev_get_drvdata(dev);
	struct mxcmci_host *host = mmc_priv(mmc);
1214

1215 1216
	clk_disable_unprepare(host->clk_per);
	clk_disable_unprepare(host->clk_ipg);
1217
	return 0;
1218 1219
}

1220
static int __maybe_unused mxcmci_resume(struct device *dev)
1221
{
1222 1223
	struct mmc_host *mmc = dev_get_drvdata(dev);
	struct mxcmci_host *host = mmc_priv(mmc);
1224
	int ret;
1225

1226 1227 1228 1229 1230 1231 1232 1233 1234
	ret = clk_prepare_enable(host->clk_per);
	if (ret)
		return ret;

	ret = clk_prepare_enable(host->clk_ipg);
	if (ret)
		clk_disable_unprepare(host->clk_per);

	return ret;
1235
}
1236

1237
static SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume);
1238 1239 1240 1241

static struct platform_driver mxcmci_driver = {
	.probe		= mxcmci_probe,
	.remove		= mxcmci_remove,
1242
	.id_table	= mxcmci_devtype,
1243 1244
	.driver		= {
		.name		= DRIVER_NAME,
1245
		.pm	= &mxcmci_pm_ops,
M
Markus Pargmann 已提交
1246
		.of_match_table	= mxcmci_of_match,
1247 1248 1249
	}
};

1250
module_platform_driver(mxcmci_driver);
1251 1252 1253 1254

MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
MODULE_AUTHOR("Sascha Hauer, Pengutronix");
MODULE_LICENSE("GPL");
F
Fabio Estevam 已提交
1255
MODULE_ALIAS("platform:mxc-mmc");