> Subject: [PATCH v3 3/6] mmc: mmc_spi: Re-write driver using DM framework > > From: Bhargav Shah <bhargavshah1...@gmail.com> > > This patch rewrites MMC SPI driver using U-Boot DM framework and get it's > working on SiFive Unleashed board. > > Signed-off-by: Bhargav Shah <bhargavshah1...@gmail.com> > Signed-off-by: Anup Patel <anup.pa...@wdc.com> > Reviewed-by: Bin Meng <bmeng...@gmail.com> > Tested-by: Bin Meng <bmeng...@gmail.com> > --- > drivers/mmc/Kconfig | 18 ++ > drivers/mmc/mmc_spi.c | 469 > ++++++++++++++++++++++------------- > scripts/config_whitelist.txt | 6 - > 3 files changed, 320 insertions(+), 173 deletions(-) > > diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index > c23299ea96..f750dad00a 100644 > --- a/drivers/mmc/Kconfig > +++ b/drivers/mmc/Kconfig > @@ -46,6 +46,24 @@ config SPL_DM_MMC > > if MMC > > +config MMC_SPI > + bool "Support for SPI-based MMC controller" > + depends on DM_MMC && DM_SPI > + help > + This selects SPI-based MMC controllers. > + If you have an MMC controller on a SPI bus, say Y here. > + > + If unsure, say N. > + > +config MMC_SPI_CRC_ON > + bool "Support CRC for SPI-based MMC controller" > + depends on MMC_SPI > + default y > + help > + This enables CRC for SPI-based MMC controllers. > + > + If unsure, say N. > + > config ARM_PL180_MMCI > bool "ARM AMBA Multimedia Card Interface and compatible support" > depends on DM_MMC && OF_CONTROL > diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c index > 4f57990d9c..f3d687ae80 100644 > --- a/drivers/mmc/mmc_spi.c > +++ b/drivers/mmc/mmc_spi.c > @@ -2,6 +2,8 @@ > * generic mmc spi driver > * > * Copyright (C) 2010 Thomas Chou <tho...@wytron.com.tw> > + * Copyright 2019 Bhargav Shah <bhargavshah1...@gmail.com> > + * > * Licensed under the GPL-2 or later. > */ > #include <common.h> > @@ -9,21 +11,23 @@ > #include <malloc.h> > #include <part.h> > #include <mmc.h> > -#include <spi.h> > +#include <stdlib.h> > #include <u-boot/crc.h> > #include <linux/crc7.h> > #include <asm/byteorder.h> > +#include <dm.h> > +#include <spi.h> > > /* MMC/SD in SPI mode reports R1 status always */ > -#define R1_SPI_IDLE (1 << 0) > -#define R1_SPI_ERASE_RESET (1 << 1) > -#define R1_SPI_ILLEGAL_COMMAND (1 << 2) > -#define R1_SPI_COM_CRC (1 << 3) > -#define R1_SPI_ERASE_SEQ (1 << 4) > -#define R1_SPI_ADDRESS (1 << 5) > -#define R1_SPI_PARAMETER (1 << 6) > +#define R1_SPI_IDLE BIT(0) > +#define R1_SPI_ERASE_RESET BIT(1) > +#define R1_SPI_ILLEGAL_COMMAND BIT(2) > +#define R1_SPI_COM_CRC BIT(3) > +#define R1_SPI_ERASE_SEQ BIT(4) > +#define R1_SPI_ADDRESS BIT(5) > +#define R1_SPI_PARAMETER BIT(6) > /* R1 bit 7 is always zero, reuse this bit for error */ > -#define R1_SPI_ERROR (1 << 7) > +#define R1_SPI_ERROR BIT(7) > > /* Response tokens used to ack each block written: */ > #define SPI_MMC_RESPONSE_CODE(x) ((x) & 0x1f) > @@ -34,28 +38,45 @@ > /* Read and write blocks start with these tokens and end with crc; > * on error, read tokens act like a subset of R2_SPI_* values. > */ > -#define SPI_TOKEN_SINGLE 0xfe /* single block r/w, multiblock read */ > -#define SPI_TOKEN_MULTI_WRITE 0xfc /* multiblock write */ > -#define SPI_TOKEN_STOP_TRAN 0xfd /* terminate multiblock write */ > +/* single block write multiblock read */ > +#define SPI_TOKEN_SINGLE 0xfe > +/* multiblock write */ > +#define SPI_TOKEN_MULTI_WRITE 0xfc > +/* terminate multiblock write */ > +#define SPI_TOKEN_STOP_TRAN 0xfd > > /* MMC SPI commands start with a start bit "0" and a transmit bit "1" */ > -#define MMC_SPI_CMD(x) (0x40 | (x & 0x3f)) > +#define MMC_SPI_CMD(x) (0x40 | (x)) > > /* bus capability */ > -#define MMC_SPI_VOLTAGE (MMC_VDD_32_33 | MMC_VDD_33_34) > -#define MMC_SPI_MIN_CLOCK 400000 /* 400KHz to meet MMC spec */ > +#define MMC_SPI_VOLTAGE (MMC_VDD_32_33 | > MMC_VDD_33_34) > +#define MMC_SPI_MIN_CLOCK 400000 /* 400KHz to meet MMC > spec */ > +#define MMC_SPI_MAX_CLOCK 25000000 /* SD/MMC legacy speed */ > > /* timeout value */ > -#define CTOUT 8 > -#define RTOUT 3000000 /* 1 sec */ > -#define WTOUT 3000000 /* 1 sec */ > +#define CMD_TIMEOUT 8 > +#define READ_TIMEOUT 3000000 /* 1 sec */ > +#define WRITE_TIMEOUT 3000000 /* 1 sec */ > > -static uint mmc_spi_sendcmd(struct mmc *mmc, ushort cmdidx, u32 > cmdarg) > +struct mmc_spi_priv { > + struct spi_slave *spi; > + struct mmc_config cfg; > + struct mmc mmc; > +}; > + > +static int mmc_spi_sendcmd(struct udevice *dev, > + ushort cmdidx, u32 cmdarg, u32 resp_type, > + u8 *resp, u32 resp_size, > + bool resp_match, u8 resp_match_value) > { > - struct spi_slave *spi = mmc->priv; > - u8 cmdo[7]; > - u8 r1; > - int i; > + int i, rpos = 0, ret = 0; > + u8 cmdo[7], r; > + > + debug("%s: cmd%d cmdarg=0x%x resp_type=0x%x " > + "resp_size=%d resp_match=%d resp_match_value=0x%x\n", > + __func__, cmdidx, cmdarg, resp_type, > + resp_size, resp_match, resp_match_value); > + > cmdo[0] = 0xff; > cmdo[1] = MMC_SPI_CMD(cmdidx); > cmdo[2] = cmdarg >> 24; > @@ -63,37 +84,79 @@ static uint mmc_spi_sendcmd(struct mmc *mmc, > ushort cmdidx, u32 cmdarg) > cmdo[4] = cmdarg >> 8; > cmdo[5] = cmdarg; > cmdo[6] = (crc7(0, &cmdo[1], 5) << 1) | 0x01; > - spi_xfer(spi, sizeof(cmdo) * 8, cmdo, NULL, 0); > - for (i = 0; i < CTOUT; i++) { > - spi_xfer(spi, 1 * 8, NULL, &r1, 0); > - if (i && (r1 & 0x80) == 0) /* r1 response */ > - break; > + ret = dm_spi_xfer(dev, sizeof(cmdo) * 8, cmdo, NULL, 0); > + if (ret) > + return ret; > + > + ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0); > + if (ret) > + return ret; > + > + if (!resp || !resp_size) > + return 0; > + > + debug("%s: cmd%d", __func__, cmdidx); > + > + if (resp_match) { > + r = ~resp_match_value; > + i = CMD_TIMEOUT; > + while (i--) { > + ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0); > + if (ret) > + return ret; > + debug(" resp%d=0x%x", rpos, r); > + rpos++; > + if (r == resp_match_value) > + break; > + } > + if (!i && (r != resp_match_value)) > + return -ETIMEDOUT; > + } > + > + for (i = 0; i < resp_size; i++) { > + if (i == 0 && resp_match) { > + resp[i] = resp_match_value; > + continue; > + } > + ret = dm_spi_xfer(dev, 1 * 8, NULL, &r, 0); > + if (ret) > + return ret; > + debug(" resp%d=0x%x", rpos, r); > + rpos++; > + resp[i] = r; > } > - debug("%s:cmd%d resp%d %x\n", __func__, cmdidx, i, r1); > - return r1; > + > + debug("\n"); > + > + return 0; > } > > -static uint mmc_spi_readdata(struct mmc *mmc, void *xbuf, > - u32 bcnt, u32 bsize) > +static int mmc_spi_readdata(struct udevice *dev, > + void *xbuf, u32 bcnt, u32 bsize) > { > - struct spi_slave *spi = mmc->priv; > - u8 *buf = xbuf; > - u8 r1; > u16 crc; > - int i; > + u8 *buf = xbuf, r1; > + int i, ret = 0; > + > while (bcnt--) { > - for (i = 0; i < RTOUT; i++) { > - spi_xfer(spi, 1 * 8, NULL, &r1, 0); > - if (r1 != 0xff) /* data token */ > + for (i = 0; i < READ_TIMEOUT; i++) { > + ret = dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0); > + if (ret) > + return ret; > + if (r1 == SPI_TOKEN_SINGLE) > break; > } > - debug("%s:tok%d %x\n", __func__, i, r1); > + debug("%s: data tok%d 0x%x\n", __func__, i, r1); > if (r1 == SPI_TOKEN_SINGLE) { > - spi_xfer(spi, bsize * 8, NULL, buf, 0); > - spi_xfer(spi, 2 * 8, NULL, &crc, 0); > + ret = dm_spi_xfer(dev, bsize * 8, NULL, buf, 0); > + if (ret) > + return ret; > + ret = dm_spi_xfer(dev, 2 * 8, NULL, &crc, 0); > + if (ret) > + return ret; > #ifdef CONFIG_MMC_SPI_CRC_ON > - if (be_to_cpu16(crc16_ccitt(0, buf, bsize)) != crc) { > - debug("%s: CRC error\n", mmc->cfg->name); > + if (be16_to_cpu(crc16_ccitt(0, buf, bsize)) != crc) { > + debug("%s: data crc error\n", __func__); > r1 = R1_SPI_COM_CRC; > break; > } > @@ -105,48 +168,56 @@ static uint mmc_spi_readdata(struct mmc *mmc, > void *xbuf, > } > buf += bsize; > } > - return r1; > + > + if (r1 & R1_SPI_COM_CRC) > + ret = -ECOMM; > + else if (r1) /* other errors */ > + ret = -ETIMEDOUT; > + > + return ret; > } > > -static uint mmc_spi_writedata(struct mmc *mmc, const void *xbuf, > - u32 bcnt, u32 bsize, int multi) > +static int mmc_spi_writedata(struct udevice *dev, const void *xbuf, > + u32 bcnt, u32 bsize, int multi) > { > - struct spi_slave *spi = mmc->priv; > const u8 *buf = xbuf; > - u8 r1; > + u8 r1, tok[2]; > u16 crc; > - u8 tok[2]; > - int i; > + int i, ret = 0; > + > tok[0] = 0xff; > tok[1] = multi ? SPI_TOKEN_MULTI_WRITE : SPI_TOKEN_SINGLE; > + > while (bcnt--) { > #ifdef CONFIG_MMC_SPI_CRC_ON > crc = cpu_to_be16(crc16_ccitt(0, (u8 *)buf, bsize)); #endif > - spi_xfer(spi, 2 * 8, tok, NULL, 0); > - spi_xfer(spi, bsize * 8, buf, NULL, 0); > - spi_xfer(spi, 2 * 8, &crc, NULL, 0); > - for (i = 0; i < CTOUT; i++) { > - spi_xfer(spi, 1 * 8, NULL, &r1, 0); > + dm_spi_xfer(dev, 2 * 8, tok, NULL, 0); > + dm_spi_xfer(dev, bsize * 8, buf, NULL, 0); > + dm_spi_xfer(dev, 2 * 8, &crc, NULL, 0); > + for (i = 0; i < CMD_TIMEOUT; i++) { > + dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0); > if ((r1 & 0x10) == 0) /* response token */ > break; > } > - debug("%s:tok%d %x\n", __func__, i, r1); > + debug("%s: data tok%d 0x%x\n", __func__, i, r1); > if (SPI_MMC_RESPONSE_CODE(r1) == SPI_RESPONSE_ACCEPTED) { > - for (i = 0; i < WTOUT; i++) { /* wait busy */ > - spi_xfer(spi, 1 * 8, NULL, &r1, 0); > + debug("%s: data accepted\n", __func__); > + for (i = 0; i < WRITE_TIMEOUT; i++) { /* wait busy */ > + dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0); > if (i && r1 == 0xff) { > r1 = 0; > break; > } > } > - if (i == WTOUT) { > - debug("%s:wtout %x\n", __func__, r1); > + if (i == WRITE_TIMEOUT) { > + debug("%s: data write timeout 0x%x\n", > + __func__, r1); > r1 = R1_SPI_ERROR; > break; > } > } else { > - debug("%s: err %x\n", __func__, r1); > + debug("%s: data error 0x%x\n", __func__, r1); > r1 = R1_SPI_COM_CRC; > break; > } > @@ -154,140 +225,204 @@ static uint mmc_spi_writedata(struct mmc > *mmc, const void *xbuf, > } > if (multi && bcnt == -1) { /* stop multi write */ > tok[1] = SPI_TOKEN_STOP_TRAN; > - spi_xfer(spi, 2 * 8, tok, NULL, 0); > - for (i = 0; i < WTOUT; i++) { /* wait busy */ > - spi_xfer(spi, 1 * 8, NULL, &r1, 0); > + dm_spi_xfer(dev, 2 * 8, tok, NULL, 0); > + for (i = 0; i < WRITE_TIMEOUT; i++) { /* wait busy */ > + dm_spi_xfer(dev, 1 * 8, NULL, &r1, 0); > if (i && r1 == 0xff) { > r1 = 0; > break; > } > } > - if (i == WTOUT) { > - debug("%s:wstop %x\n", __func__, r1); > + if (i == WRITE_TIMEOUT) { > + debug("%s: data write timeout 0x%x\n", __func__, r1); > r1 = R1_SPI_ERROR; > } > } > - return r1; > -} > > -static int mmc_spi_request(struct mmc *mmc, struct mmc_cmd *cmd, > - struct mmc_data *data) > -{ > - struct spi_slave *spi = mmc->priv; > - u8 r1; > - int i; > - int ret = 0; > - debug("%s:cmd%d %x %x\n", __func__, > - cmd->cmdidx, cmd->resp_type, cmd->cmdarg); > - spi_claim_bus(spi); > - spi_cs_activate(spi); > - r1 = mmc_spi_sendcmd(mmc, cmd->cmdidx, cmd->cmdarg); > - if (r1 == 0xff) { /* no response */ > - ret = -ENOMEDIUM; > - goto done; > - } else if (r1 & R1_SPI_COM_CRC) { > + if (r1 & R1_SPI_COM_CRC) > ret = -ECOMM; > - goto done; > - } else if (r1 & ~R1_SPI_IDLE) { /* other errors */ > + else if (r1) /* other errors */ > ret = -ETIMEDOUT; > + > + return ret; > +} > + > +static int dm_mmc_spi_set_ios(struct udevice *dev) { > + return 0; > +} > + > +static int dm_mmc_spi_request(struct udevice *dev, struct mmc_cmd *cmd, > + struct mmc_data *data) > +{ > + int i, multi, ret = 0; > + u8 *resp = NULL; > + u32 resp_size = 0; > + bool resp_match = false; > + u8 resp8 = 0, resp40[5] = { 0 }, resp_match_value = 0; > + > + dm_spi_claim_bus(dev); > + > + for (i = 0; i < 4; i++) > + cmd->response[i] = 0; > + > + switch (cmd->cmdidx) { > + case SD_CMD_APP_SEND_OP_COND: > + case MMC_CMD_SEND_OP_COND: > + resp = &resp8; > + resp_size = sizeof(resp8); > + cmd->cmdarg = 0x40000000; > + break; > + case SD_CMD_SEND_IF_COND: > + resp = (u8 *)&resp40[0]; > + resp_size = sizeof(resp40); > + resp_match = true; > + resp_match_value = R1_SPI_IDLE; > + break; > + case MMC_CMD_SPI_READ_OCR: > + resp = (u8 *)&resp40[0]; > + resp_size = sizeof(resp40); > + break; > + case MMC_CMD_SEND_STATUS: > + case MMC_CMD_SET_BLOCKLEN: > + case MMC_CMD_SPI_CRC_ON_OFF: > + case MMC_CMD_STOP_TRANSMISSION: > + resp = &resp8; > + resp_size = sizeof(resp8); > + resp_match = true; > + resp_match_value = 0x0; > + break; > + case MMC_CMD_SEND_CSD: > + case MMC_CMD_SEND_CID: > + case MMC_CMD_READ_SINGLE_BLOCK: > + case MMC_CMD_READ_MULTIPLE_BLOCK: > + case MMC_CMD_WRITE_SINGLE_BLOCK: > + case MMC_CMD_WRITE_MULTIPLE_BLOCK: > + break; > + default: > + resp = &resp8; > + resp_size = sizeof(resp8); > + resp_match = true; > + resp_match_value = R1_SPI_IDLE; > + break; > + }; > + > + ret = mmc_spi_sendcmd(dev, cmd->cmdidx, cmd->cmdarg, > cmd->resp_type, > + resp, resp_size, resp_match, resp_match_value); > + if (ret) > goto done; > - } else if (cmd->resp_type == MMC_RSP_R2) { > - r1 = mmc_spi_readdata(mmc, cmd->response, 1, 16); > + > + switch (cmd->cmdidx) { > + case SD_CMD_APP_SEND_OP_COND: > + case MMC_CMD_SEND_OP_COND: > + cmd->response[0] = (resp8 & R1_SPI_IDLE) ? 0 : OCR_BUSY; > + break; > + case SD_CMD_SEND_IF_COND: > + case MMC_CMD_SPI_READ_OCR: > + cmd->response[0] = resp40[4]; > + cmd->response[0] |= (uint)resp40[3] << 8; > + cmd->response[0] |= (uint)resp40[2] << 16; > + cmd->response[0] |= (uint)resp40[1] << 24; > + break; > + case MMC_CMD_SEND_STATUS: > + cmd->response[0] = (resp8 & 0xff) ? > + MMC_STATUS_ERROR : MMC_STATUS_RDY_FOR_DATA; > + break; > + case MMC_CMD_SEND_CID: > + case MMC_CMD_SEND_CSD: > + ret = mmc_spi_readdata(dev, cmd->response, 1, 16); > + if (ret) > + return ret; > for (i = 0; i < 4; i++) > - cmd->response[i] = be32_to_cpu(cmd->response[i]); > - debug("r128 %x %x %x %x\n", cmd->response[0], > cmd->response[1], > - cmd->response[2], cmd->response[3]); > - } else if (!data) { > - switch (cmd->cmdidx) { > - case SD_CMD_APP_SEND_OP_COND: > - case MMC_CMD_SEND_OP_COND: > - cmd->response[0] = (r1 & R1_SPI_IDLE) ? 0 : OCR_BUSY; > - break; > - case SD_CMD_SEND_IF_COND: > - case MMC_CMD_SPI_READ_OCR: > - spi_xfer(spi, 4 * 8, NULL, cmd->response, 0); > - cmd->response[0] = be32_to_cpu(cmd->response[0]); > - debug("r32 %x\n", cmd->response[0]); > - break; > - case MMC_CMD_SEND_STATUS: > - spi_xfer(spi, 1 * 8, NULL, cmd->response, 0); > - cmd->response[0] = (cmd->response[0] & 0xff) ? > - MMC_STATUS_ERROR : MMC_STATUS_RDY_FOR_DATA; > - break; > - } > - } else { > - debug("%s:data %x %x %x\n", __func__, > - data->flags, data->blocks, data->blocksize); > + cmd->response[i] = > + cpu_to_be32(cmd->response[i]); > + break; > + default: > + cmd->response[0] = resp8; > + break; > + } > + > + debug("%s: cmd%d resp0=0x%x resp1=0x%x resp2=0x%x > resp3=0x%x\n", > + __func__, cmd->cmdidx, cmd->response[0], cmd->response[1], > + cmd->response[2], cmd->response[3]); > + > + if (data) { > + debug("%s: data flags=0x%x blocks=%d block_size=%d\n", > + __func__, data->flags, data->blocks, data->blocksize); > + multi = (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK); > if (data->flags == MMC_DATA_READ) > - r1 = mmc_spi_readdata(mmc, data->dest, > - data->blocks, data->blocksize); > + ret = mmc_spi_readdata(dev, data->dest, > + data->blocks, data->blocksize); > else if (data->flags == MMC_DATA_WRITE) > - r1 = mmc_spi_writedata(mmc, data->src, > - data->blocks, data->blocksize, > - (cmd->cmdidx == > MMC_CMD_WRITE_MULTIPLE_BLOCK)); > - if (r1 & R1_SPI_COM_CRC) > - ret = -ECOMM; > - else if (r1) /* other errors */ > - ret = -ETIMEDOUT; > + ret = mmc_spi_writedata(dev, data->src, > + data->blocks, data->blocksize, > + multi); > } > + > done: > - spi_cs_deactivate(spi); > - spi_release_bus(spi); > + dm_spi_release_bus(dev); > + > return ret; > } > > -static int mmc_spi_set_ios(struct mmc *mmc) > +static int mmc_spi_probe(struct udevice *dev) > { > - struct spi_slave *spi = mmc->priv; > + struct mmc_spi_priv *priv = dev_get_priv(dev); > + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); > + char *name; > + > + priv->spi = dev_get_parent_priv(dev); > + if (!priv->spi->max_hz) > + priv->spi->max_hz = MMC_SPI_MAX_CLOCK; > + priv->spi->speed = 0; > + priv->spi->mode = SPI_MODE_0; > + priv->spi->wordlen = 8; > + > + name = malloc(strlen(dev->parent->name) + strlen(dev->name) + 4); > + if (!name) > + return -ENOMEM; > + sprintf(name, "%s:%s", dev->parent->name, dev->name); > + > + priv->cfg.name = name; > + priv->cfg.host_caps = MMC_MODE_SPI; > + priv->cfg.voltages = MMC_SPI_VOLTAGE; > + priv->cfg.f_min = MMC_SPI_MIN_CLOCK; > + priv->cfg.f_max = priv->spi->max_hz; > + priv->cfg.part_type = PART_TYPE_DOS; > + priv->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; > + > + priv->mmc.cfg = &priv->cfg; > + priv->mmc.priv = priv; > + priv->mmc.dev = dev; > + > + upriv->mmc = &priv->mmc; > > - debug("%s: clock %u\n", __func__, mmc->clock); > - if (mmc->clock) > - spi_set_speed(spi, mmc->clock); > return 0; > } > > -static int mmc_spi_init_p(struct mmc *mmc) > +static int mmc_spi_bind(struct udevice *dev) > { > - struct spi_slave *spi = mmc->priv; > - spi_set_speed(spi, MMC_SPI_MIN_CLOCK); > - spi_claim_bus(spi); > - /* cs deactivated for 100+ clock */ > - spi_xfer(spi, 18 * 8, NULL, NULL, 0); > - spi_release_bus(spi); > - return 0; > + struct mmc_spi_priv *priv = dev_get_priv(dev); > + > + return mmc_bind(dev, &priv->mmc, &priv->cfg); > } > > -static const struct mmc_ops mmc_spi_ops = { > - .send_cmd = mmc_spi_request, > - .set_ios = mmc_spi_set_ios, > - .init = mmc_spi_init_p, > +static const struct dm_mmc_ops mmc_spi_ops = { > + .send_cmd = dm_mmc_spi_request, > + .set_ios = dm_mmc_spi_set_ios, > }; > > -static struct mmc_config mmc_spi_cfg = { > - .name = "MMC_SPI", > - .ops = &mmc_spi_ops, > - .host_caps = MMC_MODE_SPI, > - .voltages = MMC_SPI_VOLTAGE, > - .f_min = MMC_SPI_MIN_CLOCK, > - .part_type = PART_TYPE_DOS, > - .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, > +static const struct udevice_id dm_mmc_spi_match[] = { > + { .compatible = "mmc-spi-slot" }, > + { /* sentinel */ } > }; > > -struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode) -{ > - struct mmc *mmc; > - struct spi_slave *spi; > - > - spi = spi_setup_slave(bus, cs, speed, mode); > - if (spi == NULL) > - return NULL; > - > - mmc_spi_cfg.f_max = speed; > - > - mmc = mmc_create(&mmc_spi_cfg, spi); > - if (mmc == NULL) { > - spi_free_slave(spi); > - return NULL; > - } > - return mmc; > -} > +U_BOOT_DRIVER(mmc_spi) = { > + .name = "mmc_spi", > + .id = UCLASS_MMC, > + .of_match = dm_mmc_spi_match, > + .ops = &mmc_spi_ops, > + .probe = mmc_spi_probe, > + .bind = mmc_spi_bind, > + .priv_auto_alloc_size = sizeof(struct mmc_spi_priv), }; > diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index > 8651d569c5..0ce7016e84 100644 > --- a/scripts/config_whitelist.txt > +++ b/scripts/config_whitelist.txt > @@ -1182,12 +1182,6 @@ CONFIG_MMCBOOTCOMMAND > CONFIG_MMCROOT CONFIG_MMC_DEFAULT_DEV > CONFIG_MMC_RPMB_TRACE -CONFIG_MMC_SPI -CONFIG_MMC_SPI_BUS > -CONFIG_MMC_SPI_CRC_ON -CONFIG_MMC_SPI_CS > -CONFIG_MMC_SPI_MODE -CONFIG_MMC_SPI_SPEED > CONFIG_MMC_SUNXI_SLOT CONFIG_MMU > CONFIG_MONITOR_IS_IN_RAM
Applied to mmc/master. Thanks, Peng. > -- > 2.17.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot