cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

moxart-mmc.c (17874B)


      1/*
      2 * MOXA ART MMC host driver.
      3 *
      4 * Copyright (C) 2014 Jonas Jensen
      5 *
      6 * Jonas Jensen <jonas.jensen@gmail.com>
      7 *
      8 * Based on code from
      9 * Moxa Technologies Co., Ltd. <www.moxa.com>
     10 *
     11 * This file is licensed under the terms of the GNU General Public
     12 * License version 2.  This program is licensed "as is" without any
     13 * warranty of any kind, whether express or implied.
     14 */
     15
     16#include <linux/module.h>
     17#include <linux/init.h>
     18#include <linux/platform_device.h>
     19#include <linux/delay.h>
     20#include <linux/errno.h>
     21#include <linux/interrupt.h>
     22#include <linux/blkdev.h>
     23#include <linux/dma-mapping.h>
     24#include <linux/dmaengine.h>
     25#include <linux/mmc/host.h>
     26#include <linux/mmc/sd.h>
     27#include <linux/sched.h>
     28#include <linux/io.h>
     29#include <linux/of_address.h>
     30#include <linux/of_irq.h>
     31#include <linux/clk.h>
     32#include <linux/bitops.h>
     33#include <linux/of_dma.h>
     34#include <linux/spinlock.h>
     35
     36#define REG_COMMAND		0
     37#define REG_ARGUMENT		4
     38#define REG_RESPONSE0		8
     39#define REG_RESPONSE1		12
     40#define REG_RESPONSE2		16
     41#define REG_RESPONSE3		20
     42#define REG_RESPONSE_COMMAND	24
     43#define REG_DATA_CONTROL	28
     44#define REG_DATA_TIMER		32
     45#define REG_DATA_LENGTH		36
     46#define REG_STATUS		40
     47#define REG_CLEAR		44
     48#define REG_INTERRUPT_MASK	48
     49#define REG_POWER_CONTROL	52
     50#define REG_CLOCK_CONTROL	56
     51#define REG_BUS_WIDTH		60
     52#define REG_DATA_WINDOW		64
     53#define REG_FEATURE		68
     54#define REG_REVISION		72
     55
     56/* REG_COMMAND */
     57#define CMD_SDC_RESET		BIT(10)
     58#define CMD_EN			BIT(9)
     59#define CMD_APP_CMD		BIT(8)
     60#define CMD_LONG_RSP		BIT(7)
     61#define CMD_NEED_RSP		BIT(6)
     62#define CMD_IDX_MASK		0x3f
     63
     64/* REG_RESPONSE_COMMAND */
     65#define RSP_CMD_APP		BIT(6)
     66#define RSP_CMD_IDX_MASK	0x3f
     67
     68/* REG_DATA_CONTROL */
     69#define DCR_DATA_FIFO_RESET     BIT(8)
     70#define DCR_DATA_THRES          BIT(7)
     71#define DCR_DATA_EN		BIT(6)
     72#define DCR_DMA_EN		BIT(5)
     73#define DCR_DATA_WRITE		BIT(4)
     74#define DCR_BLK_SIZE		0x0f
     75
     76/* REG_DATA_LENGTH */
     77#define DATA_LEN_MASK		0xffffff
     78
     79/* REG_STATUS */
     80#define WRITE_PROT		BIT(12)
     81#define CARD_DETECT		BIT(11)
     82/* 1-10 below can be sent to either registers, interrupt or clear. */
     83#define CARD_CHANGE		BIT(10)
     84#define FIFO_ORUN		BIT(9)
     85#define FIFO_URUN		BIT(8)
     86#define DATA_END		BIT(7)
     87#define CMD_SENT		BIT(6)
     88#define DATA_CRC_OK		BIT(5)
     89#define RSP_CRC_OK		BIT(4)
     90#define DATA_TIMEOUT		BIT(3)
     91#define RSP_TIMEOUT		BIT(2)
     92#define DATA_CRC_FAIL		BIT(1)
     93#define RSP_CRC_FAIL		BIT(0)
     94
     95#define MASK_RSP		(RSP_TIMEOUT | RSP_CRC_FAIL | \
     96				 RSP_CRC_OK  | CARD_DETECT  | CMD_SENT)
     97
     98#define MASK_DATA		(DATA_CRC_OK   | DATA_END | \
     99				 DATA_CRC_FAIL | DATA_TIMEOUT)
    100
    101#define MASK_INTR_PIO		(FIFO_URUN | FIFO_ORUN | CARD_CHANGE)
    102
    103/* REG_POWER_CONTROL */
    104#define SD_POWER_ON		BIT(4)
    105#define SD_POWER_MASK		0x0f
    106
    107/* REG_CLOCK_CONTROL */
    108#define CLK_HISPD		BIT(9)
    109#define CLK_OFF			BIT(8)
    110#define CLK_SD			BIT(7)
    111#define CLK_DIV_MASK		0x7f
    112
    113/* REG_BUS_WIDTH */
    114#define BUS_WIDTH_8		BIT(2)
    115#define BUS_WIDTH_4		BIT(1)
    116#define BUS_WIDTH_1		BIT(0)
    117
    118#define MMC_VDD_360		23
    119#define MIN_POWER		(MMC_VDD_360 - SD_POWER_MASK)
    120#define MAX_RETRIES		500000
    121
    122struct moxart_host {
    123	spinlock_t			lock;
    124
    125	void __iomem			*base;
    126
    127	phys_addr_t			reg_phys;
    128
    129	struct dma_chan			*dma_chan_tx;
    130	struct dma_chan                 *dma_chan_rx;
    131	struct dma_async_tx_descriptor	*tx_desc;
    132	struct mmc_host			*mmc;
    133	struct mmc_request		*mrq;
    134	struct scatterlist		*cur_sg;
    135	struct completion		dma_complete;
    136	struct completion		pio_complete;
    137
    138	u32				num_sg;
    139	u32				data_remain;
    140	u32				data_len;
    141	u32				fifo_width;
    142	u32				timeout;
    143	u32				rate;
    144
    145	long				sysclk;
    146
    147	bool				have_dma;
    148	bool				is_removed;
    149};
    150
    151static inline void moxart_init_sg(struct moxart_host *host,
    152				  struct mmc_data *data)
    153{
    154	host->cur_sg = data->sg;
    155	host->num_sg = data->sg_len;
    156	host->data_remain = host->cur_sg->length;
    157
    158	if (host->data_remain > host->data_len)
    159		host->data_remain = host->data_len;
    160}
    161
    162static inline int moxart_next_sg(struct moxart_host *host)
    163{
    164	int remain;
    165	struct mmc_data *data = host->mrq->cmd->data;
    166
    167	host->cur_sg++;
    168	host->num_sg--;
    169
    170	if (host->num_sg > 0) {
    171		host->data_remain = host->cur_sg->length;
    172		remain = host->data_len - data->bytes_xfered;
    173		if (remain > 0 && remain < host->data_remain)
    174			host->data_remain = remain;
    175	}
    176
    177	return host->num_sg;
    178}
    179
    180static int moxart_wait_for_status(struct moxart_host *host,
    181				  u32 mask, u32 *status)
    182{
    183	int ret = -ETIMEDOUT;
    184	u32 i;
    185
    186	for (i = 0; i < MAX_RETRIES; i++) {
    187		*status = readl(host->base + REG_STATUS);
    188		if (!(*status & mask)) {
    189			udelay(5);
    190			continue;
    191		}
    192		writel(*status & mask, host->base + REG_CLEAR);
    193		ret = 0;
    194		break;
    195	}
    196
    197	if (ret)
    198		dev_err(mmc_dev(host->mmc), "timed out waiting for status\n");
    199
    200	return ret;
    201}
    202
    203
    204static void moxart_send_command(struct moxart_host *host,
    205	struct mmc_command *cmd)
    206{
    207	u32 status, cmdctrl;
    208
    209	writel(RSP_TIMEOUT  | RSP_CRC_OK |
    210	       RSP_CRC_FAIL | CMD_SENT, host->base + REG_CLEAR);
    211	writel(cmd->arg, host->base + REG_ARGUMENT);
    212
    213	cmdctrl = cmd->opcode & CMD_IDX_MASK;
    214	if (cmdctrl == SD_APP_SET_BUS_WIDTH    || cmdctrl == SD_APP_OP_COND   ||
    215	    cmdctrl == SD_APP_SEND_SCR         || cmdctrl == SD_APP_SD_STATUS ||
    216	    cmdctrl == SD_APP_SEND_NUM_WR_BLKS)
    217		cmdctrl |= CMD_APP_CMD;
    218
    219	if (cmd->flags & MMC_RSP_PRESENT)
    220		cmdctrl |= CMD_NEED_RSP;
    221
    222	if (cmd->flags & MMC_RSP_136)
    223		cmdctrl |= CMD_LONG_RSP;
    224
    225	writel(cmdctrl | CMD_EN, host->base + REG_COMMAND);
    226
    227	if (moxart_wait_for_status(host, MASK_RSP, &status) == -ETIMEDOUT)
    228		cmd->error = -ETIMEDOUT;
    229
    230	if (status & RSP_TIMEOUT) {
    231		cmd->error = -ETIMEDOUT;
    232		return;
    233	}
    234	if (status & RSP_CRC_FAIL) {
    235		cmd->error = -EIO;
    236		return;
    237	}
    238	if (status & RSP_CRC_OK) {
    239		if (cmd->flags & MMC_RSP_136) {
    240			cmd->resp[3] = readl(host->base + REG_RESPONSE0);
    241			cmd->resp[2] = readl(host->base + REG_RESPONSE1);
    242			cmd->resp[1] = readl(host->base + REG_RESPONSE2);
    243			cmd->resp[0] = readl(host->base + REG_RESPONSE3);
    244		} else {
    245			cmd->resp[0] = readl(host->base + REG_RESPONSE0);
    246		}
    247	}
    248}
    249
    250static void moxart_dma_complete(void *param)
    251{
    252	struct moxart_host *host = param;
    253
    254	complete(&host->dma_complete);
    255}
    256
    257static void moxart_transfer_dma(struct mmc_data *data, struct moxart_host *host)
    258{
    259	u32 len, dir_slave;
    260	struct dma_async_tx_descriptor *desc = NULL;
    261	struct dma_chan *dma_chan;
    262
    263	if (host->data_len == data->bytes_xfered)
    264		return;
    265
    266	if (data->flags & MMC_DATA_WRITE) {
    267		dma_chan = host->dma_chan_tx;
    268		dir_slave = DMA_MEM_TO_DEV;
    269	} else {
    270		dma_chan = host->dma_chan_rx;
    271		dir_slave = DMA_DEV_TO_MEM;
    272	}
    273
    274	len = dma_map_sg(dma_chan->device->dev, data->sg,
    275			 data->sg_len, mmc_get_dma_dir(data));
    276
    277	if (len > 0) {
    278		desc = dmaengine_prep_slave_sg(dma_chan, data->sg,
    279					       len, dir_slave,
    280					       DMA_PREP_INTERRUPT |
    281					       DMA_CTRL_ACK);
    282	} else {
    283		dev_err(mmc_dev(host->mmc), "dma_map_sg returned zero length\n");
    284	}
    285
    286	if (desc) {
    287		host->tx_desc = desc;
    288		desc->callback = moxart_dma_complete;
    289		desc->callback_param = host;
    290		dmaengine_submit(desc);
    291		dma_async_issue_pending(dma_chan);
    292	}
    293
    294	data->bytes_xfered += host->data_remain;
    295
    296	wait_for_completion_interruptible_timeout(&host->dma_complete,
    297						  host->timeout);
    298
    299	dma_unmap_sg(dma_chan->device->dev,
    300		     data->sg, data->sg_len,
    301		     mmc_get_dma_dir(data));
    302}
    303
    304
    305static void moxart_transfer_pio(struct moxart_host *host)
    306{
    307	struct mmc_data *data = host->mrq->cmd->data;
    308	u32 *sgp, len = 0, remain, status;
    309
    310	if (host->data_len == data->bytes_xfered)
    311		return;
    312
    313	sgp = sg_virt(host->cur_sg);
    314	remain = host->data_remain;
    315
    316	if (data->flags & MMC_DATA_WRITE) {
    317		while (remain > 0) {
    318			if (moxart_wait_for_status(host, FIFO_URUN, &status)
    319			     == -ETIMEDOUT) {
    320				data->error = -ETIMEDOUT;
    321				complete(&host->pio_complete);
    322				return;
    323			}
    324			for (len = 0; len < remain && len < host->fifo_width;) {
    325				iowrite32(*sgp, host->base + REG_DATA_WINDOW);
    326				sgp++;
    327				len += 4;
    328			}
    329			remain -= len;
    330		}
    331
    332	} else {
    333		while (remain > 0) {
    334			if (moxart_wait_for_status(host, FIFO_ORUN, &status)
    335			    == -ETIMEDOUT) {
    336				data->error = -ETIMEDOUT;
    337				complete(&host->pio_complete);
    338				return;
    339			}
    340			for (len = 0; len < remain && len < host->fifo_width;) {
    341				/* SCR data must be read in big endian. */
    342				if (data->mrq->cmd->opcode == SD_APP_SEND_SCR)
    343					*sgp = ioread32be(host->base +
    344							  REG_DATA_WINDOW);
    345				else
    346					*sgp = ioread32(host->base +
    347							REG_DATA_WINDOW);
    348				sgp++;
    349				len += 4;
    350			}
    351			remain -= len;
    352		}
    353	}
    354
    355	data->bytes_xfered += host->data_remain - remain;
    356	host->data_remain = remain;
    357
    358	if (host->data_len != data->bytes_xfered)
    359		moxart_next_sg(host);
    360	else
    361		complete(&host->pio_complete);
    362}
    363
    364static void moxart_prepare_data(struct moxart_host *host)
    365{
    366	struct mmc_data *data = host->mrq->cmd->data;
    367	u32 datactrl;
    368	int blksz_bits;
    369
    370	if (!data)
    371		return;
    372
    373	host->data_len = data->blocks * data->blksz;
    374	blksz_bits = ffs(data->blksz) - 1;
    375	BUG_ON(1 << blksz_bits != data->blksz);
    376
    377	moxart_init_sg(host, data);
    378
    379	datactrl = DCR_DATA_EN | (blksz_bits & DCR_BLK_SIZE);
    380
    381	if (data->flags & MMC_DATA_WRITE)
    382		datactrl |= DCR_DATA_WRITE;
    383
    384	if ((host->data_len > host->fifo_width) && host->have_dma)
    385		datactrl |= DCR_DMA_EN;
    386
    387	writel(DCR_DATA_FIFO_RESET, host->base + REG_DATA_CONTROL);
    388	writel(MASK_DATA | FIFO_URUN | FIFO_ORUN, host->base + REG_CLEAR);
    389	writel(host->rate, host->base + REG_DATA_TIMER);
    390	writel(host->data_len, host->base + REG_DATA_LENGTH);
    391	writel(datactrl, host->base + REG_DATA_CONTROL);
    392}
    393
    394static void moxart_request(struct mmc_host *mmc, struct mmc_request *mrq)
    395{
    396	struct moxart_host *host = mmc_priv(mmc);
    397	unsigned long flags;
    398	u32 status;
    399
    400	spin_lock_irqsave(&host->lock, flags);
    401
    402	init_completion(&host->dma_complete);
    403	init_completion(&host->pio_complete);
    404
    405	host->mrq = mrq;
    406
    407	if (readl(host->base + REG_STATUS) & CARD_DETECT) {
    408		mrq->cmd->error = -ETIMEDOUT;
    409		goto request_done;
    410	}
    411
    412	moxart_prepare_data(host);
    413	moxart_send_command(host, host->mrq->cmd);
    414
    415	if (mrq->cmd->data) {
    416		if ((host->data_len > host->fifo_width) && host->have_dma) {
    417
    418			writel(CARD_CHANGE, host->base + REG_INTERRUPT_MASK);
    419
    420			spin_unlock_irqrestore(&host->lock, flags);
    421
    422			moxart_transfer_dma(mrq->cmd->data, host);
    423
    424			spin_lock_irqsave(&host->lock, flags);
    425		} else {
    426
    427			writel(MASK_INTR_PIO, host->base + REG_INTERRUPT_MASK);
    428
    429			spin_unlock_irqrestore(&host->lock, flags);
    430
    431			/* PIO transfers start from interrupt. */
    432			wait_for_completion_interruptible_timeout(&host->pio_complete,
    433								  host->timeout);
    434
    435			spin_lock_irqsave(&host->lock, flags);
    436		}
    437
    438		if (host->is_removed) {
    439			dev_err(mmc_dev(host->mmc), "card removed\n");
    440			mrq->cmd->error = -ETIMEDOUT;
    441			goto request_done;
    442		}
    443
    444		if (moxart_wait_for_status(host, MASK_DATA, &status)
    445		    == -ETIMEDOUT) {
    446			mrq->cmd->data->error = -ETIMEDOUT;
    447			goto request_done;
    448		}
    449
    450		if (status & DATA_CRC_FAIL)
    451			mrq->cmd->data->error = -ETIMEDOUT;
    452
    453		if (mrq->cmd->data->stop)
    454			moxart_send_command(host, mrq->cmd->data->stop);
    455	}
    456
    457request_done:
    458	spin_unlock_irqrestore(&host->lock, flags);
    459	mmc_request_done(host->mmc, mrq);
    460}
    461
    462static irqreturn_t moxart_irq(int irq, void *devid)
    463{
    464	struct moxart_host *host = (struct moxart_host *)devid;
    465	u32 status;
    466
    467	spin_lock(&host->lock);
    468
    469	status = readl(host->base + REG_STATUS);
    470	if (status & CARD_CHANGE) {
    471		host->is_removed = status & CARD_DETECT;
    472		if (host->is_removed && host->have_dma) {
    473			dmaengine_terminate_all(host->dma_chan_tx);
    474			dmaengine_terminate_all(host->dma_chan_rx);
    475		}
    476		host->mrq = NULL;
    477		writel(MASK_INTR_PIO, host->base + REG_CLEAR);
    478		writel(CARD_CHANGE, host->base + REG_INTERRUPT_MASK);
    479		mmc_detect_change(host->mmc, 0);
    480	}
    481	if (status & (FIFO_ORUN | FIFO_URUN) && host->mrq)
    482		moxart_transfer_pio(host);
    483
    484	spin_unlock(&host->lock);
    485
    486	return IRQ_HANDLED;
    487}
    488
    489static void moxart_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
    490{
    491	struct moxart_host *host = mmc_priv(mmc);
    492	unsigned long flags;
    493	u8 power, div;
    494	u32 ctrl;
    495
    496	spin_lock_irqsave(&host->lock, flags);
    497
    498	if (ios->clock) {
    499		for (div = 0; div < CLK_DIV_MASK; ++div) {
    500			if (ios->clock >= host->sysclk / (2 * (div + 1)))
    501				break;
    502		}
    503		ctrl = CLK_SD | div;
    504		host->rate = host->sysclk / (2 * (div + 1));
    505		if (host->rate > host->sysclk)
    506			ctrl |= CLK_HISPD;
    507		writel(ctrl, host->base + REG_CLOCK_CONTROL);
    508	}
    509
    510	if (ios->power_mode == MMC_POWER_OFF) {
    511		writel(readl(host->base + REG_POWER_CONTROL) & ~SD_POWER_ON,
    512		       host->base + REG_POWER_CONTROL);
    513	} else {
    514		if (ios->vdd < MIN_POWER)
    515			power = 0;
    516		else
    517			power = ios->vdd - MIN_POWER;
    518
    519		writel(SD_POWER_ON | (u32) power,
    520		       host->base + REG_POWER_CONTROL);
    521	}
    522
    523	switch (ios->bus_width) {
    524	case MMC_BUS_WIDTH_4:
    525		writel(BUS_WIDTH_4, host->base + REG_BUS_WIDTH);
    526		break;
    527	case MMC_BUS_WIDTH_8:
    528		writel(BUS_WIDTH_8, host->base + REG_BUS_WIDTH);
    529		break;
    530	default:
    531		writel(BUS_WIDTH_1, host->base + REG_BUS_WIDTH);
    532		break;
    533	}
    534
    535	spin_unlock_irqrestore(&host->lock, flags);
    536}
    537
    538
    539static int moxart_get_ro(struct mmc_host *mmc)
    540{
    541	struct moxart_host *host = mmc_priv(mmc);
    542
    543	return !!(readl(host->base + REG_STATUS) & WRITE_PROT);
    544}
    545
    546static const struct mmc_host_ops moxart_ops = {
    547	.request = moxart_request,
    548	.set_ios = moxart_set_ios,
    549	.get_ro = moxart_get_ro,
    550};
    551
    552static int moxart_probe(struct platform_device *pdev)
    553{
    554	struct device *dev = &pdev->dev;
    555	struct device_node *node = dev->of_node;
    556	struct resource res_mmc;
    557	struct mmc_host *mmc;
    558	struct moxart_host *host = NULL;
    559	struct dma_slave_config cfg;
    560	struct clk *clk;
    561	void __iomem *reg_mmc;
    562	int irq, ret;
    563	u32 i;
    564
    565	mmc = mmc_alloc_host(sizeof(struct moxart_host), dev);
    566	if (!mmc) {
    567		dev_err(dev, "mmc_alloc_host failed\n");
    568		ret = -ENOMEM;
    569		goto out_mmc;
    570	}
    571
    572	ret = of_address_to_resource(node, 0, &res_mmc);
    573	if (ret) {
    574		dev_err(dev, "of_address_to_resource failed\n");
    575		goto out_mmc;
    576	}
    577
    578	irq = irq_of_parse_and_map(node, 0);
    579	if (irq <= 0) {
    580		dev_err(dev, "irq_of_parse_and_map failed\n");
    581		ret = -EINVAL;
    582		goto out_mmc;
    583	}
    584
    585	clk = devm_clk_get(dev, NULL);
    586	if (IS_ERR(clk)) {
    587		ret = PTR_ERR(clk);
    588		goto out_mmc;
    589	}
    590
    591	reg_mmc = devm_ioremap_resource(dev, &res_mmc);
    592	if (IS_ERR(reg_mmc)) {
    593		ret = PTR_ERR(reg_mmc);
    594		goto out_mmc;
    595	}
    596
    597	ret = mmc_of_parse(mmc);
    598	if (ret)
    599		goto out_mmc;
    600
    601	host = mmc_priv(mmc);
    602	host->mmc = mmc;
    603	host->base = reg_mmc;
    604	host->reg_phys = res_mmc.start;
    605	host->timeout = msecs_to_jiffies(1000);
    606	host->sysclk = clk_get_rate(clk);
    607	host->fifo_width = readl(host->base + REG_FEATURE) << 2;
    608	host->dma_chan_tx = dma_request_chan(dev, "tx");
    609	host->dma_chan_rx = dma_request_chan(dev, "rx");
    610
    611	spin_lock_init(&host->lock);
    612
    613	mmc->ops = &moxart_ops;
    614	mmc->f_max = DIV_ROUND_CLOSEST(host->sysclk, 2);
    615	mmc->f_min = DIV_ROUND_CLOSEST(host->sysclk, CLK_DIV_MASK * 2);
    616	mmc->ocr_avail = 0xffff00;	/* Support 2.0v - 3.6v power. */
    617
    618	if (IS_ERR(host->dma_chan_tx) || IS_ERR(host->dma_chan_rx)) {
    619		if (PTR_ERR(host->dma_chan_tx) == -EPROBE_DEFER ||
    620		    PTR_ERR(host->dma_chan_rx) == -EPROBE_DEFER) {
    621			ret = -EPROBE_DEFER;
    622			goto out;
    623		}
    624		if (!IS_ERR(host->dma_chan_tx)) {
    625			dma_release_channel(host->dma_chan_tx);
    626			host->dma_chan_tx = NULL;
    627		}
    628		if (!IS_ERR(host->dma_chan_rx)) {
    629			dma_release_channel(host->dma_chan_rx);
    630			host->dma_chan_rx = NULL;
    631		}
    632		dev_dbg(dev, "PIO mode transfer enabled\n");
    633		host->have_dma = false;
    634	} else {
    635		dev_dbg(dev, "DMA channels found (%p,%p)\n",
    636			 host->dma_chan_tx, host->dma_chan_rx);
    637		host->have_dma = true;
    638
    639		memset(&cfg, 0, sizeof(cfg));
    640		cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
    641		cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
    642
    643		cfg.direction = DMA_MEM_TO_DEV;
    644		cfg.src_addr = 0;
    645		cfg.dst_addr = host->reg_phys + REG_DATA_WINDOW;
    646		dmaengine_slave_config(host->dma_chan_tx, &cfg);
    647
    648		cfg.direction = DMA_DEV_TO_MEM;
    649		cfg.src_addr = host->reg_phys + REG_DATA_WINDOW;
    650		cfg.dst_addr = 0;
    651		dmaengine_slave_config(host->dma_chan_rx, &cfg);
    652	}
    653
    654	switch ((readl(host->base + REG_BUS_WIDTH) >> 3) & 3) {
    655	case 1:
    656		mmc->caps |= MMC_CAP_4_BIT_DATA;
    657		break;
    658	case 2:
    659		mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA;
    660		break;
    661	default:
    662		break;
    663	}
    664
    665	writel(0, host->base + REG_INTERRUPT_MASK);
    666
    667	writel(CMD_SDC_RESET, host->base + REG_COMMAND);
    668	for (i = 0; i < MAX_RETRIES; i++) {
    669		if (!(readl(host->base + REG_COMMAND) & CMD_SDC_RESET))
    670			break;
    671		udelay(5);
    672	}
    673
    674	ret = devm_request_irq(dev, irq, moxart_irq, 0, "moxart-mmc", host);
    675	if (ret)
    676		goto out;
    677
    678	dev_set_drvdata(dev, mmc);
    679	mmc_add_host(mmc);
    680
    681	dev_dbg(dev, "IRQ=%d, FIFO is %d bytes\n", irq, host->fifo_width);
    682
    683	return 0;
    684
    685out:
    686	if (!IS_ERR_OR_NULL(host->dma_chan_tx))
    687		dma_release_channel(host->dma_chan_tx);
    688	if (!IS_ERR_OR_NULL(host->dma_chan_rx))
    689		dma_release_channel(host->dma_chan_rx);
    690out_mmc:
    691	if (mmc)
    692		mmc_free_host(mmc);
    693	return ret;
    694}
    695
    696static int moxart_remove(struct platform_device *pdev)
    697{
    698	struct mmc_host *mmc = dev_get_drvdata(&pdev->dev);
    699	struct moxart_host *host = mmc_priv(mmc);
    700
    701	dev_set_drvdata(&pdev->dev, NULL);
    702
    703	if (!IS_ERR_OR_NULL(host->dma_chan_tx))
    704		dma_release_channel(host->dma_chan_tx);
    705	if (!IS_ERR_OR_NULL(host->dma_chan_rx))
    706		dma_release_channel(host->dma_chan_rx);
    707	mmc_remove_host(mmc);
    708
    709	writel(0, host->base + REG_INTERRUPT_MASK);
    710	writel(0, host->base + REG_POWER_CONTROL);
    711	writel(readl(host->base + REG_CLOCK_CONTROL) | CLK_OFF,
    712	       host->base + REG_CLOCK_CONTROL);
    713	mmc_free_host(mmc);
    714
    715	return 0;
    716}
    717
    718static const struct of_device_id moxart_mmc_match[] = {
    719	{ .compatible = "moxa,moxart-mmc" },
    720	{ .compatible = "faraday,ftsdc010" },
    721	{ }
    722};
    723MODULE_DEVICE_TABLE(of, moxart_mmc_match);
    724
    725static struct platform_driver moxart_mmc_driver = {
    726	.probe      = moxart_probe,
    727	.remove     = moxart_remove,
    728	.driver     = {
    729		.name		= "mmc-moxart",
    730		.probe_type	= PROBE_PREFER_ASYNCHRONOUS,
    731		.of_match_table	= moxart_mmc_match,
    732	},
    733};
    734module_platform_driver(moxart_mmc_driver);
    735
    736MODULE_ALIAS("platform:mmc-moxart");
    737MODULE_DESCRIPTION("MOXA ART MMC driver");
    738MODULE_LICENSE("GPL v2");
    739MODULE_AUTHOR("Jonas Jensen <jonas.jensen@gmail.com>");