File Index
Files and directories
Sign in
FILE

loongson2-mmc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/mmc/host/loongson2-mmc.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Loongson-2K MMC/SDIO controller driver
   4 *
   5 * Copyright (C) 2018-2025 Loongson Technology Corporation Limited.
   6 *
   7 */
   8
   9#include <linux/bitfield.h>
  10#include <linux/bitrev.h>
  11#include <linux/clk.h>
  12#include <linux/delay.h>
  13#include <linux/dmaengine.h>
  14#include <linux/dma-mapping.h>
  15#include <linux/interrupt.h>
  16#include <linux/io.h>
  17#include <linux/mmc/core.h>
  18#include <linux/mmc/host.h>
  19#include <linux/mmc/mmc.h>
  20#include <linux/mmc/sd.h>
  21#include <linux/mmc/sdio.h>
  22#include <linux/mmc/slot-gpio.h>
  23#include <linux/module.h>
  24#include <linux/of.h>
  25#include <linux/platform_device.h>
  26#include <linux/regmap.h>
  27
  28#define LOONGSON2_MMC_REG_CTL		0x00 /* Control Register */
  29#define LOONGSON2_MMC_REG_PRE		0x04 /* Prescaler Register */
  30#define LOONGSON2_MMC_REG_CARG		0x08 /* Command Register */
  31#define LOONGSON2_MMC_REG_CCTL		0x0c /* Command Control Register */
  32#define LOONGSON2_MMC_REG_CSTS		0x10 /* Command Status Register */
  33#define LOONGSON2_MMC_REG_RSP0		0x14 /* Command Response Register 0 */
  34#define LOONGSON2_MMC_REG_RSP1		0x18 /* Command Response Register 1 */
  35#define LOONGSON2_MMC_REG_RSP2		0x1c /* Command Response Register 2 */
  36#define LOONGSON2_MMC_REG_RSP3		0x20 /* Command Response Register 3 */
  37#define LOONGSON2_MMC_REG_TIMER		0x24 /* Data Timeout Register */
  38#define LOONGSON2_MMC_REG_BSIZE		0x28 /* Block Size Register */
  39#define LOONGSON2_MMC_REG_DCTL		0x2c /* Data Control Register */
  40#define LOONGSON2_MMC_REG_DCNT		0x30 /* Data Counter Register */
  41#define LOONGSON2_MMC_REG_DSTS		0x34 /* Data Status Register */
  42#define LOONGSON2_MMC_REG_FSTS		0x38 /* FIFO Status Register */
  43#define LOONGSON2_MMC_REG_INT		0x3c /* Interrupt Register */
  44#define LOONGSON2_MMC_REG_DATA		0x40 /* Data Register */
  45#define LOONGSON2_MMC_REG_IEN		0x64 /* Interrupt Enable Register */
  46
  47/* EMMC DLL Mode Registers */
  48#define LOONGSON2_MMC_REG_DLLVAL	0xf0 /* DLL Master Lock-value Register */
  49#define LOONGSON2_MMC_REG_DLLCTL	0xf4 /* DLL Control Register */
  50#define LOONGSON2_MMC_REG_DELAY		0xf8 /* DLL Delayed Parameter Register */
  51#define LOONGSON2_MMC_REG_SEL		0xfc /* Bus Mode Selection Register */
  52
  53/* Exclusive DMA R/W Registers */
  54#define LOONGSON2_MMC_REG_WDMA_LO	0x400
  55#define LOONGSON2_MMC_REG_WDMA_HI	0x404
  56#define LOONGSON2_MMC_REG_RDMA_LO	0x800
  57#define LOONGSON2_MMC_REG_RDMA_HI	0x804
  58
  59/* Bitfields of control register */
  60#define LOONGSON2_MMC_CTL_ENCLK		BIT(0)
  61#define LOONGSON2_MMC_CTL_EXTCLK	BIT(1)
  62#define LOONGSON2_MMC_CTL_RESET		BIT(8)
  63
  64/* Bitfields of prescaler register */
  65#define LOONGSON2_MMC_PRE		GENMASK(9, 0)
  66#define LOONGSON2_MMC_PRE_EN		BIT(31)
  67
  68/* Bitfields of command control register */
  69#define LOONGSON2_MMC_CCTL_INDEX	GENMASK(5, 0)
  70#define LOONGSON2_MMC_CCTL_HOST		BIT(6)
  71#define LOONGSON2_MMC_CCTL_START	BIT(8)
  72#define LOONGSON2_MMC_CCTL_WAIT_RSP	BIT(9)
  73#define LOONGSON2_MMC_CCTL_LONG_RSP	BIT(10)
  74#define LOONGSON2_MMC_CCTL_ABORT	BIT(12)
  75#define LOONGSON2_MMC_CCTL_CHECK	BIT(13)
  76#define LOONGSON2_MMC_CCTL_SDIO		BIT(14)
  77#define LOONGSON2_MMC_CCTL_CMD6		BIT(18)
  78
  79/* Bitfields of command status register */
  80#define LOONGSON2_MMC_CSTS_INDEX	GENMASK(7, 0)
  81#define LOONGSON2_MMC_CSTS_ON		BIT(8)
  82#define LOONGSON2_MMC_CSTS_RSP		BIT(9)
  83#define LOONGSON2_MMC_CSTS_TIMEOUT	BIT(10)
  84#define LOONGSON2_MMC_CSTS_END		BIT(11)
  85#define LOONGSON2_MMC_CSTS_CRC_ERR	BIT(12)
  86#define LOONGSON2_MMC_CSTS_AUTO_STOP	BIT(13)
  87#define LOONGSON2_MMC_CSTS_FIN		BIT(14)
  88
  89/* Bitfields of data timeout register */
  90#define LOONGSON2_MMC_DTIMR		GENMASK(23, 0)
  91
  92/* Bitfields of block size register */
  93#define LOONGSON2_MMC_BSIZE		GENMASK(11, 0)
  94
  95/* Bitfields of data control register */
  96#define LOONGSON2_MMC_DCTL_BNUM		GENMASK(11, 0)
  97#define LOONGSON2_MMC_DCTL_START	BIT(14)
  98#define LOONGSON2_MMC_DCTL_ENDMA	BIT(15)
  99#define LOONGSON2_MMC_DCTL_WIDE		BIT(16)
 100#define LOONGSON2_MMC_DCTL_RWAIT	BIT(17)
 101#define LOONGSON2_MMC_DCTL_IO_SUSPEND	BIT(18)
 102#define LOONGSON2_MMC_DCTL_IO_RESUME	BIT(19)
 103#define LOONGSON2_MMC_DCTL_RW_RESUME	BIT(20)
 104#define LOONGSON2_MMC_DCTL_8BIT_BUS	BIT(26)
 105
 106/* Bitfields of sata counter register */
 107#define LOONGSON2_MMC_DCNT_BNUM		GENMASK(11, 0)
 108#define LOONGSON2_MMC_DCNT_BYTE		GENMASK(23, 12)
 109
 110/* Bitfields of command status register */
 111#define LOONGSON2_MMC_DSTS_RXON		BIT(0)
 112#define LOONGSON2_MMC_DSTS_TXON		BIT(1)
 113#define LOONGSON2_MMC_DSTS_SBITERR	BIT(2)
 114#define LOONGSON2_MMC_DSTS_BUSYFIN	BIT(3)
 115#define LOONGSON2_MMC_DSTS_XFERFIN	BIT(4)
 116#define LOONGSON2_MMC_DSTS_DTIMEOUT	BIT(5)
 117#define LOONGSON2_MMC_DSTS_RXCRC	BIT(6)
 118#define LOONGSON2_MMC_DSTS_TXCRC	BIT(7)
 119#define LOONGSON2_MMC_DSTS_IRQ		BIT(8)
 120#define LOONGSON2_MMC_DSTS_START	BIT(13)
 121#define LOONGSON2_MMC_DSTS_RESUME	BIT(15)
 122#define LOONGSON2_MMC_DSTS_SUSPEND	BIT(16)
 123
 124/* Bitfields of FIFO Status Register */
 125#define LOONGSON2_MMC_FSTS_TXFULL	BIT(11)
 126
 127/* Bitfields of interrupt register */
 128#define LOONGSON2_MMC_INT_DFIN		BIT(0)
 129#define LOONGSON2_MMC_INT_DTIMEOUT	BIT(1)
 130#define LOONGSON2_MMC_INT_RXCRC		BIT(2)
 131#define LOONGSON2_MMC_INT_TXCRC		BIT(3)
 132#define LOONGSON2_MMC_INT_PROGERR	BIT(4)
 133#define LOONGSON2_MMC_INT_SDIOIRQ	BIT(5)
 134#define LOONGSON2_MMC_INT_CSENT		BIT(6)
 135#define LOONGSON2_MMC_INT_CTIMEOUT	BIT(7)
 136#define LOONGSON2_MMC_INT_RESPCRC	BIT(8)
 137#define LOONGSON2_MMC_INT_BUSYEND	BIT(9)
 138
 139/* Bitfields of interrupt enable register */
 140#define LOONGSON2_MMC_IEN_DFIN		BIT(0)
 141#define LOONGSON2_MMC_IEN_DTIMEOUT	BIT(1)
 142#define LOONGSON2_MMC_IEN_RXCRC		BIT(2)
 143#define LOONGSON2_MMC_IEN_TXCRC		BIT(3)
 144#define LOONGSON2_MMC_IEN_PROGERR	BIT(4)
 145#define LOONGSON2_MMC_IEN_SDIOIRQ	BIT(5)
 146#define LOONGSON2_MMC_IEN_CSENT		BIT(6)
 147#define LOONGSON2_MMC_IEN_CTIMEOUT	BIT(7)
 148#define LOONGSON2_MMC_IEN_RESPCRC	BIT(8)
 149#define LOONGSON2_MMC_IEN_BUSYEND	BIT(9)
 150
 151#define LOONGSON2_MMC_IEN_ALL		GENMASK(9, 0)
 152#define LOONGSON2_MMC_INT_CLEAR		GENMASK(9, 0)
 153
 154/* Bitfields of DLL master lock-value register */
 155#define LOONGSON2_MMC_DLLVAL_DONE	BIT(8)
 156
 157/* Bitfields of DLL control register */
 158#define LOONGSON2_MMC_DLLCTL_TIME	GENMASK(7, 0)
 159#define LOONGSON2_MMC_DLLCTL_INCRE	GENMASK(15, 8)
 160#define LOONGSON2_MMC_DLLCTL_START	GENMASK(23, 16)
 161#define LOONGSON2_MMC_DLLCTL_CLK_MODE	BIT(24)
 162#define LOONGSON2_MMC_DLLCTL_START_BIT	BIT(25)
 163#define LOONGSON2_MMC_DLLCTL_TIME_BPASS	GENMASK(29, 26)
 164
 165#define LOONGSON2_MMC_DELAY_PAD		GENMASK(7, 0)
 166#define LOONGSON2_MMC_DELAY_RD		GENMASK(15, 8)
 167
 168#define LOONGSON2_MMC_SEL_DATA		BIT(0)	/* 0: SDR, 1: DDR */
 169#define LOONGSON2_MMC_SEL_BUS		BIT(0)	/* 0: EMMC, 1: SDIO */
 170
 171/* Internal dma controller registers */
 172
 173/* Bitfields of Global Configuration Register */
 174#define LOONGSON2_MMC_DMA_64BIT_EN	BIT(0) /* 1: 64 bit support */
 175#define LOONGSON2_MMC_DMA_UNCOHERENT_EN	BIT(1) /* 0: cache, 1: uncache */
 176#define LOONGSON2_MMC_DMA_ASK_VALID	BIT(2)
 177#define LOONGSON2_MMC_DMA_START		BIT(3) /* DMA start operation */
 178#define LOONGSON2_MMC_DMA_STOP		BIT(4) /* DMA stop operation */
 179#define LOONGSON2_MMC_DMA_CONFIG_MASK	GENMASK_ULL(4, 0) /* DMA controller config bits mask */
 180
 181/* Bitfields of ndesc_addr field of HW descriptor */
 182#define LOONGSON2_MMC_DMA_DESC_EN	BIT(0) /*1: The next descriptor is valid */
 183#define LOONGSON2_MMC_DMA_DESC_ADDR_LOW	GENMASK(31, 1)
 184
 185/* Bitfields of cmd field of HW descriptor */
 186#define LOONGSON2_MMC_DMA_INT		BIT(1)	/* Enable DMA interrupts */
 187#define LOONGSON2_MMC_DMA_DATA_DIR	BIT(12) /* 1: write to device, 0: read from device */
 188
 189#define LOONGSON2_MMC_DLLVAL_TIMEOUT_US		4000
 190#define LOONGSON2_MMC_TXFULL_TIMEOUT_US		500
 191
 192/* Loongson-2K1000 SDIO2 DMA routing register */
 193#define LS2K1000_SDIO_DMA_MASK		GENMASK(17, 15)
 194#define LS2K1000_DMA0_CONF		0x0
 195#define LS2K1000_DMA1_CONF		0x1
 196#define LS2K1000_DMA2_CONF		0x2
 197#define LS2K1000_DMA3_CONF		0x3
 198#define LS2K1000_DMA4_CONF		0x4
 199
 200/* Loongson-2K0500 SDIO2 DMA routing register */
 201#define LS2K0500_SDIO_DMA_MASK		GENMASK(15, 14)
 202#define LS2K0500_DMA0_CONF		0x1
 203#define LS2K0500_DMA1_CONF		0x2
 204#define LS2K0500_DMA2_CONF		0x3
 205
 206enum loongson2_mmc_state {
 207	STATE_NONE,
 208	STATE_FINALIZE,
 209	STATE_CMDSENT,
 210	STATE_RSPFIN,
 211	STATE_XFERFINISH,
 212	STATE_XFERFINISH_RSPFIN,
 213};
 214
 215struct loongson2_dma_desc {
 216	u32 ndesc_addr;
 217	u32 mem_addr;
 218	u32 apb_addr;
 219	u32 len;
 220	u32 step_len;
 221	u32 step_times;
 222	u32 cmd;
 223	u32 stats;
 224	u32 high_ndesc_addr;
 225	u32 high_mem_addr;
 226	u32 reserved[2];
 227} __packed;
 228
 229struct loongson2_mmc_host {
 230	struct device *dev;
 231	struct mmc_request *mrq;
 232	struct regmap *regmap;
 233	struct resource *res;
 234	struct clk *clk;
 235	u32 current_clk;
 236	void *sg_cpu;
 237	dma_addr_t sg_dma;
 238	int dma_complete;
 239	struct dma_chan *chan;
 240	int cmd_is_stop;
 241	int bus_width;
 242	spinlock_t lock; /* Prevent races with irq handler */
 243	enum loongson2_mmc_state state;
 244	const struct loongson2_mmc_pdata *pdata;
 245};
 246
 247struct loongson2_mmc_pdata {
 248	const struct regmap_config *regmap_config;
 249	void (*reorder_cmd_data)(struct loongson2_mmc_host *host, struct mmc_command *cmd);
 250	void (*fix_data_timeout)(struct loongson2_mmc_host *host, struct mmc_command *cmd);
 251	int (*setting_dma)(struct loongson2_mmc_host *host, struct platform_device *pdev);
 252	int (*prepare_dma)(struct loongson2_mmc_host *host, struct mmc_data *data);
 253	void (*release_dma)(struct loongson2_mmc_host *host, struct device *dev);
 254};
 255
 256static void loongson2_mmc_send_command(struct loongson2_mmc_host *host,
 257				       struct mmc_command *cmd)
 258{
 259	u32 cctrl;
 260
 261	if (cmd->data)
 262		host->state = STATE_XFERFINISH_RSPFIN;
 263	else if (cmd->flags & MMC_RSP_PRESENT)
 264		host->state = STATE_RSPFIN;
 265	else
 266		host->state = STATE_CMDSENT;
 267
 268	regmap_write(host->regmap, LOONGSON2_MMC_REG_CARG, cmd->arg);
 269
 270	cctrl = FIELD_PREP(LOONGSON2_MMC_CCTL_INDEX, cmd->opcode);
 271	cctrl |= LOONGSON2_MMC_CCTL_HOST | LOONGSON2_MMC_CCTL_START;
 272
 273	if (cmd->opcode == SD_SWITCH && cmd->data)
 274		cctrl |= LOONGSON2_MMC_CCTL_CMD6;
 275
 276	if (cmd->flags & MMC_RSP_PRESENT)
 277		cctrl |= LOONGSON2_MMC_CCTL_WAIT_RSP;
 278
 279	if (cmd->flags & MMC_RSP_136)
 280		cctrl |= LOONGSON2_MMC_CCTL_LONG_RSP;
 281
 282	regmap_write(host->regmap, LOONGSON2_MMC_REG_CCTL, cctrl);
 283}
 284
 285static int loongson2_mmc_setup_data(struct loongson2_mmc_host *host,
 286				    struct mmc_data *data)
 287{
 288	u32 dctrl;
 289
 290	if ((data->blksz & 3) != 0)
 291		return -EINVAL;
 292
 293	dctrl = FIELD_PREP(LOONGSON2_MMC_DCTL_BNUM, data->blocks);
 294	dctrl |= LOONGSON2_MMC_DCTL_START | LOONGSON2_MMC_DCTL_ENDMA;
 295
 296	if (host->bus_width == MMC_BUS_WIDTH_4)
 297		dctrl |= LOONGSON2_MMC_DCTL_WIDE;
 298	else if (host->bus_width == MMC_BUS_WIDTH_8)
 299		dctrl |= LOONGSON2_MMC_DCTL_8BIT_BUS;
 300
 301	regmap_write(host->regmap, LOONGSON2_MMC_REG_DCTL, dctrl);
 302	regmap_write(host->regmap, LOONGSON2_MMC_REG_BSIZE, data->blksz);
 303	regmap_write(host->regmap, LOONGSON2_MMC_REG_TIMER, U32_MAX);
 304
 305	return 0;
 306}
 307
 308static int loongson2_mmc_prepare_dma(struct loongson2_mmc_host *host,
 309				     struct mmc_data *data)
 310{
 311	int ret;
 312
 313	if (!data)
 314		return 0;
 315
 316	ret = loongson2_mmc_setup_data(host, data);
 317	if (ret)
 318		return ret;
 319
 320	host->dma_complete = 0;
 321
 322	return host->pdata->prepare_dma(host, data);
 323}
 324
 325static void loongson2_mmc_send_request(struct mmc_host *mmc)
 326{
 327	int ret;
 328	struct loongson2_mmc_host *host = mmc_priv(mmc);
 329	struct mmc_request *mrq = host->mrq;
 330	struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;
 331
 332	ret = loongson2_mmc_prepare_dma(host, cmd->data);
 333	if (ret) {
 334		dev_err(host->dev, "DMA data prepared failed with %d\n", ret);
 335		cmd->error = ret;
 336		cmd->data->error = ret;
 337		mmc_request_done(mmc, mrq);
 338		return;
 339	}
 340
 341	if (host->pdata->fix_data_timeout)
 342		host->pdata->fix_data_timeout(host, cmd);
 343
 344	loongson2_mmc_send_command(host, cmd);
 345
 346	/* Fix deselect card */
 347	if (cmd->opcode == MMC_SELECT_CARD && cmd->arg == 0) {
 348		cmd->error = 0;
 349		mmc_request_done(mmc, mrq);
 350	}
 351}
 352
 353static irqreturn_t loongson2_mmc_irq_worker(int irq, void *devid)
 354{
 355	struct loongson2_mmc_host *host = (struct loongson2_mmc_host *)devid;
 356	struct mmc_host *mmc = mmc_from_priv(host);
 357	struct mmc_request *mrq = host->mrq;
 358	struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;
 359
 360	if (cmd->data)
 361		dma_unmap_sg(mmc_dev(mmc), cmd->data->sg, cmd->data->sg_len,
 362			     mmc_get_dma_dir(cmd->data));
 363
 364	if (cmd->data && !cmd->error &&
 365	    !cmd->data->error && !host->dma_complete)
 366		return IRQ_HANDLED;
 367
 368	/* Read response from controller. */
 369	regmap_read(host->regmap, LOONGSON2_MMC_REG_RSP0, &cmd->resp[0]);
 370	regmap_read(host->regmap, LOONGSON2_MMC_REG_RSP1, &cmd->resp[1]);
 371	regmap_read(host->regmap, LOONGSON2_MMC_REG_RSP2, &cmd->resp[2]);
 372	regmap_read(host->regmap, LOONGSON2_MMC_REG_RSP3, &cmd->resp[3]);
 373
 374	/* Cleanup controller */
 375	regmap_write(host->regmap, LOONGSON2_MMC_REG_CARG, 0);
 376	regmap_write(host->regmap, LOONGSON2_MMC_REG_CCTL, 0);
 377
 378	if (cmd->data && cmd->error)
 379		cmd->data->error = cmd->error;
 380
 381	if (cmd->data && cmd->data->stop && !host->cmd_is_stop) {
 382		host->cmd_is_stop = 1;
 383		loongson2_mmc_send_request(mmc);
 384		return IRQ_HANDLED;
 385	}
 386
 387	/* If we have no data transfer we are finished here */
 388	if (!mrq->data)
 389		goto request_done;
 390
 391	/* Calculate the amount of bytes transfer if there was no error */
 392	if (mrq->data->error == 0) {
 393		mrq->data->bytes_xfered =
 394			(mrq->data->blocks * mrq->data->blksz);
 395	} else {
 396		mrq->data->bytes_xfered = 0;
 397	}
 398
 399request_done:
 400	host->state = STATE_NONE;
 401	host->mrq = NULL;
 402	mmc_request_done(mmc, mrq);
 403	return IRQ_HANDLED;
 404}
 405
 406static irqreturn_t loongson2_mmc_irq(int irq, void *devid)
 407{
 408	struct loongson2_mmc_host *host = (struct loongson2_mmc_host *)devid;
 409	struct mmc_host *mmc = mmc_from_priv(host);
 410	struct mmc_command *cmd;
 411	unsigned long iflags;
 412	u32 dsts, imsk;
 413
 414	regmap_read(host->regmap, LOONGSON2_MMC_REG_INT, &imsk);
 415	regmap_read(host->regmap, LOONGSON2_MMC_REG_DSTS, &dsts);
 416
 417	if ((dsts & LOONGSON2_MMC_DSTS_IRQ) &&
 418	    (imsk & LOONGSON2_MMC_INT_SDIOIRQ)) {
 419		regmap_update_bits(host->regmap, LOONGSON2_MMC_REG_INT,
 420				   LOONGSON2_MMC_INT_SDIOIRQ, LOONGSON2_MMC_INT_SDIOIRQ);
 421
 422		sdio_signal_irq(mmc);
 423		return IRQ_HANDLED;
 424	}
 425
 426	spin_lock_irqsave(&host->lock, iflags);
 427
 428	if (host->state == STATE_NONE || host->state == STATE_FINALIZE || !host->mrq)
 429		goto irq_out;
 430
 431	cmd = host->cmd_is_stop ? host->mrq->stop : host->mrq->cmd;
 432	if (!cmd)
 433		goto irq_out;
 434
 435	cmd->error = 0;
 436
 437	if (imsk & LOONGSON2_MMC_INT_CTIMEOUT) {
 438		cmd->error = -ETIMEDOUT;
 439		goto close_transfer;
 440	}
 441
 442	if (imsk & LOONGSON2_MMC_INT_CSENT) {
 443		if (host->state == STATE_RSPFIN || host->state == STATE_CMDSENT)
 444			goto close_transfer;
 445
 446		if (host->state == STATE_XFERFINISH_RSPFIN)
 447			host->state = STATE_XFERFINISH;
 448	}
 449
 450	if (!cmd->data)
 451		goto irq_out;
 452
 453	if (imsk & (LOONGSON2_MMC_INT_RXCRC | LOONGSON2_MMC_INT_TXCRC)) {
 454		cmd->data->error = -EILSEQ;
 455		goto close_transfer;
 456	}
 457
 458	if (imsk & LOONGSON2_MMC_INT_DTIMEOUT) {
 459		cmd->data->error = -ETIMEDOUT;
 460		goto close_transfer;
 461	}
 462
 463	if (imsk & LOONGSON2_MMC_INT_DFIN) {
 464		if (host->state == STATE_XFERFINISH) {
 465			host->dma_complete = 1;
 466			goto close_transfer;
 467		}
 468
 469		if (host->state == STATE_XFERFINISH_RSPFIN)
 470			host->state = STATE_RSPFIN;
 471	}
 472
 473irq_out:
 474	regmap_write(host->regmap, LOONGSON2_MMC_REG_INT, imsk);
 475	spin_unlock_irqrestore(&host->lock, iflags);
 476	return IRQ_HANDLED;
 477
 478close_transfer:
 479	host->state = STATE_FINALIZE;
 480	host->pdata->reorder_cmd_data(host, cmd);
 481	regmap_write(host->regmap, LOONGSON2_MMC_REG_INT, imsk);
 482	spin_unlock_irqrestore(&host->lock, iflags);
 483	return IRQ_WAKE_THREAD;
 484}
 485
 486static void loongson2_mmc_dll_mode_init(struct loongson2_mmc_host *host)
 487{
 488	u32 val, pad_delay, delay;
 489	int ret;
 490
 491	regmap_update_bits(host->regmap, LOONGSON2_MMC_REG_SEL,
 492			   LOONGSON2_MMC_SEL_DATA, LOONGSON2_MMC_SEL_DATA);
 493
 494	val = FIELD_PREP(LOONGSON2_MMC_DLLCTL_TIME, 0xc8)
 495	    | FIELD_PREP(LOONGSON2_MMC_DLLCTL_INCRE, 0x1)
 496	    | FIELD_PREP(LOONGSON2_MMC_DLLCTL_START, 0x1)
 497	    | FIELD_PREP(LOONGSON2_MMC_DLLCTL_CLK_MODE, 0x1)
 498	    | FIELD_PREP(LOONGSON2_MMC_DLLCTL_START_BIT, 0x1)
 499	    | FIELD_PREP(LOONGSON2_MMC_DLLCTL_TIME_BPASS, 0xf);
 500
 501	regmap_write(host->regmap, LOONGSON2_MMC_REG_DLLCTL, val);
 502
 503	ret = regmap_read_poll_timeout(host->regmap, LOONGSON2_MMC_REG_DLLVAL, val,
 504				       (val & LOONGSON2_MMC_DLLVAL_DONE), 0,
 505				       LOONGSON2_MMC_DLLVAL_TIMEOUT_US);
 506	if (ret < 0)
 507		return;
 508
 509	regmap_read(host->regmap, LOONGSON2_MMC_REG_DLLVAL, &val);
 510	pad_delay = FIELD_GET(GENMASK(7, 1), val);
 511
 512	delay = FIELD_PREP(LOONGSON2_MMC_DELAY_PAD, pad_delay)
 513	      | FIELD_PREP(LOONGSON2_MMC_DELAY_RD, pad_delay + 1);
 514
 515	regmap_write(host->regmap, LOONGSON2_MMC_REG_DELAY, delay);
 516}
 517
 518static void loongson2_mmc_set_clk(struct loongson2_mmc_host *host, struct mmc_ios *ios)
 519{
 520	u32 pre;
 521
 522	pre = DIV_ROUND_UP(host->current_clk, ios->clock);
 523	if (pre > 255)
 524		pre = 255;
 525
 526	regmap_write(host->regmap, LOONGSON2_MMC_REG_PRE, pre | LOONGSON2_MMC_PRE_EN);
 527
 528	regmap_update_bits(host->regmap, LOONGSON2_MMC_REG_CTL,
 529			   LOONGSON2_MMC_CTL_ENCLK, LOONGSON2_MMC_CTL_ENCLK);
 530
 531	/* EMMC DLL mode setting */
 532	if (ios->timing == MMC_TIMING_UHS_DDR50 || ios->timing == MMC_TIMING_MMC_DDR52)
 533		loongson2_mmc_dll_mode_init(host);
 534}
 535
 536static void loongson2_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 537{
 538	struct loongson2_mmc_host *host = mmc_priv(mmc);
 539	int ret;
 540
 541	if (ios->power_mode == MMC_POWER_UP) {
 542		if (!IS_ERR(mmc->supply.vmmc)) {
 543			ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);
 544			if (ret) {
 545				dev_err(host->dev, "failed to enable vmmc regulator\n");
 546				return; /* return, if failed turn on vmmc */
 547			}
 548		}
 549		regmap_write(host->regmap, LOONGSON2_MMC_REG_CTL, LOONGSON2_MMC_CTL_RESET);
 550		mdelay(10);
 551		regmap_write(host->regmap, LOONGSON2_MMC_REG_CTL, LOONGSON2_MMC_CTL_EXTCLK);
 552		regmap_write(host->regmap, LOONGSON2_MMC_REG_INT, LOONGSON2_MMC_IEN_ALL);
 553		regmap_write(host->regmap, LOONGSON2_MMC_REG_IEN, LOONGSON2_MMC_INT_CLEAR);
 554	} else if (ios->power_mode == MMC_POWER_OFF) {
 555		regmap_update_bits(host->regmap, LOONGSON2_MMC_REG_CTL,
 556				   LOONGSON2_MMC_CTL_RESET, LOONGSON2_MMC_CTL_RESET);
 557		if (!IS_ERR(mmc->supply.vmmc))
 558			mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
 559		return;
 560	}
 561
 562	loongson2_mmc_set_clk(host, ios);
 563
 564	host->bus_width = ios->bus_width;
 565}
 566
 567static void loongson2_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 568{
 569	struct loongson2_mmc_host *host = mmc_priv(mmc);
 570
 571	host->cmd_is_stop = 0;
 572	host->mrq = mrq;
 573	loongson2_mmc_send_request(mmc);
 574}
 575
 576static void loongson2_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
 577{
 578	struct loongson2_mmc_host *host = mmc_priv(mmc);
 579
 580	regmap_update_bits(host->regmap, LOONGSON2_MMC_REG_IEN, LOONGSON2_MMC_INT_SDIOIRQ, enable);
 581}
 582
 583static void loongson2_mmc_ack_sdio_irq(struct mmc_host *mmc)
 584{
 585	loongson2_mmc_enable_sdio_irq(mmc, 1);
 586}
 587
 588static struct mmc_host_ops loongson2_mmc_ops = {
 589	.request	= loongson2_mmc_request,
 590	.set_ios	= loongson2_mmc_set_ios,
 591	.get_ro		= mmc_gpio_get_ro,
 592	.get_cd		= mmc_gpio_get_cd,
 593	.enable_sdio_irq = loongson2_mmc_enable_sdio_irq,
 594	.ack_sdio_irq	= loongson2_mmc_ack_sdio_irq,
 595};
 596
 597static const struct regmap_config ls2k0500_mmc_regmap_config = {
 598	.reg_bits = 32,
 599	.val_bits = 32,
 600	.reg_stride = 4,
 601	.max_register = LOONGSON2_MMC_REG_IEN,
 602};
 603
 604static int loongson2_reorder_cmd_list[] = { SD_APP_SEND_SCR, SD_APP_SEND_NUM_WR_BLKS,
 605					    SD_APP_SD_STATUS, MMC_SEND_WRITE_PROT, SD_SWITCH };
 606
 607/*
 608 * According to SD spec, ACMD13, ACMD22, ACMD51 and CMD30
 609 * response datas has different byte order with usual data packets.
 610 * However sdio controller will send these datas in usual data format,
 611 * so we need to adjust these datas to a protocol consistent byte order.
 612 */
 613static void ls2k0500_mmc_reorder_cmd_data(struct loongson2_mmc_host *host,
 614					  struct mmc_command *cmd)
 615{
 616	struct scatterlist *sg;
 617	u32 *data;
 618	int i, j;
 619
 620	if (mmc_cmd_type(cmd) != MMC_CMD_ADTC)
 621		return;
 622
 623	for (i = 0; i < ARRAY_SIZE(loongson2_reorder_cmd_list); i++)
 624		if (cmd->opcode == loongson2_reorder_cmd_list[i])
 625			break;
 626
 627	if (i == ARRAY_SIZE(loongson2_reorder_cmd_list))
 628		return;
 629
 630	for_each_sg(cmd->data->sg, sg, cmd->data->sg_len, i) {
 631		data = sg_virt(&sg[i]);
 632		for (j = 0; j < (sg_dma_len(&sg[i]) / 4); j++)
 633			if (cmd->opcode == SD_SWITCH)
 634				data[j] = bitrev8x4(data[j]);
 635			else
 636				data[j] = (__force u32)cpu_to_be32(data[j]);
 637	}
 638}
 639
 640static int loongson2_mmc_prepare_external_dma(struct loongson2_mmc_host *host,
 641					      struct mmc_data *data)
 642{
 643	struct mmc_host *mmc = mmc_from_priv(host);
 644	struct dma_slave_config dma_conf = { };
 645	struct dma_async_tx_descriptor *desc;
 646	int ret;
 647
 648	ret = dma_map_sg(mmc_dev(mmc), data->sg, data->sg_len,
 649			 mmc_get_dma_dir(data));
 650	if (!ret)
 651		return -ENOMEM;
 652
 653	dma_conf.src_addr = host->res->start + LOONGSON2_MMC_REG_DATA,
 654	dma_conf.dst_addr = host->res->start + LOONGSON2_MMC_REG_DATA,
 655	dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
 656	dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
 657	dma_conf.direction = !(data->flags & MMC_DATA_WRITE) ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV;
 658
 659	dmaengine_slave_config(host->chan, &dma_conf);
 660	desc = dmaengine_prep_slave_sg(host->chan, data->sg, data->sg_len,
 661				       dma_conf.direction,
 662				       DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
 663	if (!desc)
 664		goto unmap_exit;
 665
 666	dmaengine_submit(desc);
 667	dma_async_issue_pending(host->chan);
 668
 669	return 0;
 670
 671unmap_exit:
 672	dma_unmap_sg(mmc_dev(mmc), data->sg, data->sg_len, mmc_get_dma_dir(data));
 673	return -ENOMEM;
 674}
 675
 676static void loongson2_mmc_release_external_dma(struct loongson2_mmc_host *host,
 677					       struct device *dev)
 678{
 679	dma_release_channel(host->chan);
 680}
 681
 682static int ls2k0500_mmc_set_external_dma(struct loongson2_mmc_host *host,
 683					 struct platform_device *pdev)
 684{
 685	int ret, val;
 686	void __iomem *regs;
 687
 688	regs = devm_platform_ioremap_resource(pdev, 1);
 689	if (IS_ERR(regs))
 690		return PTR_ERR(regs);
 691
 692	val = readl(regs);
 693	val |= FIELD_PREP(LS2K0500_SDIO_DMA_MASK, LS2K0500_DMA2_CONF);
 694	writel(val, regs);
 695
 696	host->chan = dma_request_chan(&pdev->dev, "rx-tx");
 697	ret = PTR_ERR_OR_ZERO(host->chan);
 698	if (ret) {
 699		dev_err(&pdev->dev, "Cannot get DMA channel.\n");
 700		return ret;
 701	}
 702
 703	return 0;
 704}
 705
 706static struct loongson2_mmc_pdata ls2k0500_mmc_pdata = {
 707	.regmap_config		= &ls2k0500_mmc_regmap_config,
 708	.reorder_cmd_data	= ls2k0500_mmc_reorder_cmd_data,
 709	.setting_dma		= ls2k0500_mmc_set_external_dma,
 710	.prepare_dma		= loongson2_mmc_prepare_external_dma,
 711	.release_dma		= loongson2_mmc_release_external_dma,
 712};
 713
 714static int ls2k1000_mmc_set_external_dma(struct loongson2_mmc_host *host,
 715					 struct platform_device *pdev)
 716{
 717	int ret, val;
 718	void __iomem *regs;
 719
 720	regs = devm_platform_ioremap_resource(pdev, 1);
 721	if (IS_ERR(regs))
 722		return PTR_ERR(regs);
 723
 724	val = readl(regs);
 725	val |= FIELD_PREP(LS2K1000_SDIO_DMA_MASK, LS2K1000_DMA1_CONF);
 726	writel(val, regs);
 727
 728	host->chan = dma_request_chan(&pdev->dev, "rx-tx");
 729	ret = PTR_ERR_OR_ZERO(host->chan);
 730	if (ret) {
 731		dev_err(&pdev->dev, "Cannot get DMA channel.\n");
 732		return ret;
 733	}
 734
 735	return 0;
 736}
 737
 738static struct loongson2_mmc_pdata ls2k1000_mmc_pdata = {
 739	.regmap_config		= &ls2k0500_mmc_regmap_config,
 740	.reorder_cmd_data	= ls2k0500_mmc_reorder_cmd_data,
 741	.setting_dma		= ls2k1000_mmc_set_external_dma,
 742	.prepare_dma		= loongson2_mmc_prepare_external_dma,
 743	.release_dma		= loongson2_mmc_release_external_dma,
 744};
 745
 746static const struct regmap_config ls2k2000_mmc_regmap_config = {
 747	.reg_bits = 32,
 748	.val_bits = 32,
 749	.reg_stride = 4,
 750	.max_register = LOONGSON2_MMC_REG_RDMA_HI,
 751};
 752
 753static void ls2k2000_mmc_reorder_cmd_data(struct loongson2_mmc_host *host,
 754					  struct mmc_command *cmd)
 755{
 756	struct scatterlist *sg;
 757	u32 *data;
 758	int i, j;
 759
 760	if (cmd->opcode != SD_SWITCH || mmc_cmd_type(cmd) != MMC_CMD_ADTC)
 761		return;
 762
 763	for_each_sg(cmd->data->sg, sg, cmd->data->sg_len, i) {
 764		data = sg_virt(&sg[i]);
 765		for (j = 0; j < (sg_dma_len(&sg[i]) / 4); j++)
 766			data[j] = bitrev8x4(data[j]);
 767	}
 768}
 769
 770/*
 771 * This is a controller hardware defect. Single/multiple block write commands
 772 * must be sent after the TX FULL flag is set, otherwise a data timeout interrupt
 773 * will occur.
 774 */
 775static void ls2k2000_mmc_fix_data_timeout(struct loongson2_mmc_host *host,
 776					  struct mmc_command *cmd)
 777{
 778	int val;
 779
 780	if (cmd->opcode != MMC_WRITE_BLOCK && cmd->opcode != MMC_WRITE_MULTIPLE_BLOCK)
 781		return;
 782
 783	regmap_read_poll_timeout(host->regmap, LOONGSON2_MMC_REG_FSTS, val,
 784				 (val & LOONGSON2_MMC_FSTS_TXFULL), 0,
 785				 LOONGSON2_MMC_TXFULL_TIMEOUT_US);
 786}
 787
 788static int loongson2_mmc_prepare_internal_dma(struct loongson2_mmc_host *host,
 789					      struct mmc_data *data)
 790{
 791	struct loongson2_dma_desc *pdes = (struct loongson2_dma_desc *)host->sg_cpu;
 792	struct mmc_host *mmc = mmc_from_priv(host);
 793	dma_addr_t next_desc = host->sg_dma;
 794	struct scatterlist *sg;
 795	int reg_lo, reg_hi;
 796	u64 dma_order;
 797	int i, ret;
 798
 799	ret = dma_map_sg(mmc_dev(mmc), data->sg, data->sg_len,
 800			 mmc_get_dma_dir(data));
 801	if (!ret)
 802		return -ENOMEM;
 803
 804	for_each_sg(data->sg, sg, data->sg_len, i) {
 805		pdes[i].len = sg_dma_len(&sg[i]) / 4;
 806		pdes[i].step_len = 0;
 807		pdes[i].step_times = 1;
 808		pdes[i].mem_addr = lower_32_bits(sg_dma_address(&sg[i]));
 809		pdes[i].high_mem_addr = upper_32_bits(sg_dma_address(&sg[i]));
 810		pdes[i].apb_addr = host->res->start + LOONGSON2_MMC_REG_DATA;
 811		pdes[i].cmd = LOONGSON2_MMC_DMA_INT;
 812
 813		if (data->flags & MMC_DATA_READ) {
 814			reg_lo = LOONGSON2_MMC_REG_RDMA_LO;
 815			reg_hi = LOONGSON2_MMC_REG_RDMA_HI;
 816		} else {
 817			pdes[i].cmd |= LOONGSON2_MMC_DMA_DATA_DIR;
 818			reg_lo = LOONGSON2_MMC_REG_WDMA_LO;
 819			reg_hi = LOONGSON2_MMC_REG_WDMA_HI;
 820		}
 821
 822		next_desc += sizeof(struct loongson2_dma_desc);
 823		pdes[i].ndesc_addr = lower_32_bits(next_desc) |
 824				     LOONGSON2_MMC_DMA_DESC_EN;
 825		pdes[i].high_ndesc_addr = upper_32_bits(next_desc);
 826	}
 827
 828	/* Setting the last descriptor enable bit */
 829	pdes[i - 1].ndesc_addr &= ~LOONGSON2_MMC_DMA_DESC_EN;
 830
 831	dma_order = (host->sg_dma & ~LOONGSON2_MMC_DMA_CONFIG_MASK) |
 832		    LOONGSON2_MMC_DMA_64BIT_EN |
 833		    LOONGSON2_MMC_DMA_START;
 834
 835	regmap_write(host->regmap, reg_hi, upper_32_bits(dma_order));
 836	regmap_write(host->regmap, reg_lo, lower_32_bits(dma_order));
 837
 838	return 0;
 839}
 840
 841static int ls2k2000_mmc_set_internal_dma(struct loongson2_mmc_host *host,
 842					 struct platform_device *pdev)
 843{
 844	host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE,
 845					  &host->sg_dma, GFP_KERNEL);
 846	if (!host->sg_cpu)
 847		return -ENOMEM;
 848
 849	memset(host->sg_cpu, 0, PAGE_SIZE);
 850	return 0;
 851}
 852
 853static void loongson2_mmc_release_internal_dma(struct loongson2_mmc_host *host,
 854					       struct device *dev)
 855{
 856	dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
 857}
 858
 859static struct loongson2_mmc_pdata ls2k2000_mmc_pdata = {
 860	.regmap_config		= &ls2k2000_mmc_regmap_config,
 861	.reorder_cmd_data	= ls2k2000_mmc_reorder_cmd_data,
 862	.fix_data_timeout	= ls2k2000_mmc_fix_data_timeout,
 863	.setting_dma		= ls2k2000_mmc_set_internal_dma,
 864	.prepare_dma		= loongson2_mmc_prepare_internal_dma,
 865	.release_dma		= loongson2_mmc_release_internal_dma,
 866};
 867
 868static int loongson2_mmc_resource_request(struct platform_device *pdev,
 869					  struct loongson2_mmc_host *host)
 870{
 871	struct device *dev = &pdev->dev;
 872	void __iomem *base;
 873	int ret, irq;
 874
 875	base = devm_platform_get_and_ioremap_resource(pdev, 0, &host->res);
 876	if (IS_ERR(base))
 877		return PTR_ERR(base);
 878
 879	host->regmap = devm_regmap_init_mmio(dev, base, host->pdata->regmap_config);
 880	if (IS_ERR(host->regmap))
 881		return PTR_ERR(host->regmap);
 882
 883	host->clk = devm_clk_get_optional_enabled(dev, NULL);
 884	if (IS_ERR(host->clk))
 885		return PTR_ERR(host->clk);
 886
 887	if (host->clk) {
 888		ret = devm_clk_rate_exclusive_get(dev, host->clk);
 889		if (ret)
 890			return ret;
 891
 892		host->current_clk = clk_get_rate(host->clk);
 893	} else {
 894		/* For ACPI, the clock is accessed via the clock-frequency attribute. */
 895		device_property_read_u32(dev, "clock-frequency", &host->current_clk);
 896	}
 897
 898	irq = platform_get_irq(pdev, 0);
 899	if (irq < 0)
 900		return irq;
 901
 902	ret = devm_request_threaded_irq(dev, irq, loongson2_mmc_irq,
 903					loongson2_mmc_irq_worker,
 904					IRQF_ONESHOT, "loongson2-mmc", host);
 905	if (ret)
 906		return ret;
 907
 908	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
 909	if (ret)
 910		return ret;
 911
 912	return host->pdata->setting_dma(host, pdev);
 913}
 914
 915static int loongson2_mmc_probe(struct platform_device *pdev)
 916{
 917	struct device *dev = &pdev->dev;
 918	struct loongson2_mmc_host *host;
 919	struct mmc_host	*mmc;
 920	int ret;
 921
 922	mmc = devm_mmc_alloc_host(dev, sizeof(*host));
 923	if (!mmc)
 924		return -ENOMEM;
 925
 926	platform_set_drvdata(pdev, mmc);
 927
 928	host = mmc_priv(mmc);
 929	host->state = STATE_NONE;
 930	spin_lock_init(&host->lock);
 931
 932	host->pdata = device_get_match_data(dev);
 933	if (!host->pdata)
 934		return dev_err_probe(dev, -EINVAL, "Failed to get match data\n");
 935
 936	ret = loongson2_mmc_resource_request(pdev, host);
 937	if (ret)
 938		return dev_err_probe(dev, ret, "Failed to request resource\n");
 939
 940	mmc->ops = &loongson2_mmc_ops;
 941	mmc->f_min = DIV_ROUND_UP(host->current_clk, 256);
 942	mmc->f_max = host->current_clk;
 943	mmc->max_blk_count = 4095;
 944	mmc->max_blk_size = 4095;
 945	mmc->max_req_size = mmc->max_blk_count * mmc->max_blk_size;
 946	mmc->max_segs = 1;
 947	mmc->max_seg_size = mmc->max_req_size;
 948
 949	/* Process SDIO IRQs through the sdio_irq_work. */
 950	if (mmc->caps & MMC_CAP_SDIO_IRQ)
 951		mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD;
 952
 953	ret = mmc_regulator_get_supply(mmc);
 954	if (ret || mmc->ocr_avail == 0) {
 955		dev_warn(dev, "Can't get voltage, defaulting to 3.3V\n");
 956		mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
 957	}
 958
 959	ret = mmc_of_parse(mmc);
 960	if (ret) {
 961		dev_err(dev, "Failed to parse device node\n");
 962		goto free_dma;
 963	}
 964
 965	ret = mmc_add_host(mmc);
 966	if (ret) {
 967		dev_err(dev, "Failed to add mmc host\n");
 968		goto free_dma;
 969	}
 970
 971	return 0;
 972
 973free_dma:
 974	host->pdata->release_dma(host, dev);
 975	return ret;
 976}
 977
 978static void loongson2_mmc_remove(struct platform_device *pdev)
 979{
 980	struct mmc_host *mmc  = platform_get_drvdata(pdev);
 981	struct loongson2_mmc_host *host = mmc_priv(mmc);
 982
 983	mmc_remove_host(mmc);
 984	host->pdata->release_dma(host, &pdev->dev);
 985}
 986
 987static const struct of_device_id loongson2_mmc_of_ids[] = {
 988	{ .compatible = "loongson,ls2k0500-mmc", .data = &ls2k0500_mmc_pdata },
 989	{ .compatible = "loongson,ls2k1000-mmc", .data = &ls2k1000_mmc_pdata },
 990	{ .compatible = "loongson,ls2k2000-mmc", .data = &ls2k2000_mmc_pdata },
 991	{ },
 992};
 993MODULE_DEVICE_TABLE(of, loongson2_mmc_of_ids);
 994
 995static int loongson2_mmc_suspend(struct device *dev)
 996{
 997	struct mmc_host *mmc = dev_get_drvdata(dev);
 998	struct loongson2_mmc_host *host = mmc_priv(mmc);
 999
1000	clk_disable_unprepare(host->clk);
1001
1002	return 0;
1003}
1004
1005static int loongson2_mmc_resume(struct device *dev)
1006{
1007	struct mmc_host *mmc = dev_get_drvdata(dev);
1008	struct loongson2_mmc_host *host = mmc_priv(mmc);
1009
1010	return clk_prepare_enable(host->clk);
1011}
1012
1013static DEFINE_SIMPLE_DEV_PM_OPS(loongson2_mmc_pm_ops, loongson2_mmc_suspend, loongson2_mmc_resume);
1014
1015static struct platform_driver loongson2_mmc_driver = {
1016	.driver	= {
1017		.name = "loongson2-mmc",
1018		.of_match_table = loongson2_mmc_of_ids,
1019		.pm = pm_ptr(&loongson2_mmc_pm_ops),
1020		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
1021	},
1022	.probe = loongson2_mmc_probe,
1023	.remove = loongson2_mmc_remove,
1024};
1025
1026module_platform_driver(loongson2_mmc_driver);
1027
1028MODULE_DESCRIPTION("Loongson-2K SD/SDIO/eMMC Interface driver");
1029MODULE_AUTHOR("Loongson Technology Corporation Limited");
1030MODULE_LICENSE("GPL");
~/ Read-only file preview.