Thanks for the feedback! I forgot to disable e-mail formatting for that specific mail. I have a new patch series ready but I'm getting SMTP authentication errors through git send-email, I'll debug that with my IT department. -----Original Message----- From: Stefan Roese <s...@denx.de> To: Harm Berntsen <harm.bernt...@nedap.com>, u-boot@lists.denx.de <u-boot@lists.denx.de> Cc: pa...@antoniou-consulting.com <pa...@antoniou-consulting.com>, s...@chromium.org <s...@chromium.org>, drea...@doukki.net <drea...@doukki.net> Subject: Re: [PATCH 7/8] mmc: mvebu: convert to driver model Date: Fri, 26 Mar 2021 07:05:11 +0100
On 25.03.21 14:48, Harm Berntsen wrote: > This is a straightforward conversion of the old, non-dm driver. It > was > done in-place as the deadline for non-dm MMC has passed. Previous > commits ensured that no board depends on the old, non-dm variant. > Tested > on a Kirkwood based board with eMMC. > > Signed-off-by: Harm Berntsen <harm.bernt...@nedap.com> > Tested-by: Harm Berntsen <harm.bernt...@nedap.com> > CC: Pantelis Antoniou <pa...@antoniou-consulting.com> > CC: Stefan Roese <s...@denx.de> > CC: Gerald Kerma <drea...@doukki.net> > CC: Simon Glass <s...@chromium.org> Other than the comment from Jaehoon, that the patch is malformed (please use git send-email for sending): Reviewed-by: Stefan Roese <s...@denx.de> Thanks, Stefan > --- > > drivers/mmc/Kconfig | 9 ++ > drivers/mmc/mvebu_mmc.c | 309 +++++++++++++++++++++++-------------- > --- > include/mvebu_mmc.h | 13 +- > 3 files changed, 194 insertions(+), 137 deletions(-) > > diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig > index f8ca52efb6..de9ab8a387 100644 > --- a/drivers/mmc/Kconfig > +++ b/drivers/mmc/Kconfig > @@ -326,6 +326,15 @@ config MMC_OCTEONTX > > If unsure, say N. > > +config MVEBU_MMC > + bool "Kirkwood MMC controller support" > + depends on DM_MMC && BLK && ARCH_KIRKWOOD > + help > + Support for MMC host controller on Kirkwood SoCs. > + If you are on a Kirkwood architecture, say Y here. > + > + If unsure, say N. > + > config PXA_MMC_GENERIC > bool "Support for MMC controllers on PXA" > help > diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c > index 8ec1f57a1b..fea55c61ed 100644 > --- a/drivers/mmc/mvebu_mmc.c > +++ b/drivers/mmc/mvebu_mmc.c > @@ -11,60 +11,67 @@ > #include <errno.h> > #include <log.h> > #include <malloc.h> > +#include <dm.h> > +#include <fdtdec.h> > #include <part.h> > #include <mmc.h> > -#include <asm/global_data.h> > #include <asm/io.h> > #include <asm/arch/cpu.h> > #include <asm/arch/soc.h> > #include <mvebu_mmc.h> > - > -DECLARE_GLOBAL_DATA_PTR; > - > -#define DRIVER_NAME "MVEBU_MMC" > +#include <dm/device_compat.h> > > #define MVEBU_TARGET_DRAM 0 > > #define TIMEOUT_DELAY 5*CONFIG_SYS_HZ /* wait 5 seconds */ > > -static void mvebu_mmc_write(u32 offs, u32 val) > +static inline void *get_regbase(const struct mmc *mmc) > { > - writel(val, CONFIG_SYS_MMC_BASE + (offs)); > + struct mvebu_mmc_plat *pdata = mmc->priv; > + > + return pdata->iobase; > } > > -static u32 mvebu_mmc_read(u32 offs) > +static void mvebu_mmc_write(const struct mmc *mmc, u32 offs, u32 > val) > { > - return readl(CONFIG_SYS_MMC_BASE + (offs)); > + writel(val, get_regbase(mmc) + (offs)); > } > > -static int mvebu_mmc_setup_data(struct mmc_data *data) > +static u32 mvebu_mmc_read(const struct mmc *mmc, u32 offs) > { > + return readl(get_regbase(mmc) + (offs)); > +} > + > +static int mvebu_mmc_setup_data(struct udevice *dev, struct mmc_data > *data) > +{ > + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); > + struct mmc *mmc = &pdata->mmc; > u32 ctrl_reg; > > - debug("%s, data %s : blocks=%d blksz=%d\n", DRIVER_NAME, > - (data->flags & MMC_DATA_READ) ? "read" : "write", > - data->blocks, data->blocksize); > + dev_dbg(dev, "data %s : blocks=%d blksz=%d\n", > + (data->flags & MMC_DATA_READ) ? "read" : "write", > + data->blocks, data->blocksize); > > /* default to maximum timeout */ > - ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL); > + ctrl_reg = mvebu_mmc_read(mmc, SDIO_HOST_CTRL); > ctrl_reg |= SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MAX); > - mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg); > + mvebu_mmc_write(mmc, SDIO_HOST_CTRL, ctrl_reg); > > if (data->flags & MMC_DATA_READ) { > - mvebu_mmc_write(SDIO_SYS_ADDR_LOW, (u32)data->dest & > 0xffff); > - mvebu_mmc_write(SDIO_SYS_ADDR_HI, (u32)data->dest >> > 16); > + mvebu_mmc_write(mmc, SDIO_SYS_ADDR_LOW, (u32)data- > >dest > & 0xffff); > + mvebu_mmc_write(mmc, SDIO_SYS_ADDR_HI, (u32)data- > >dest > > > 16); > } else { > - mvebu_mmc_write(SDIO_SYS_ADDR_LOW, (u32)data->src & > 0xffff); > - mvebu_mmc_write(SDIO_SYS_ADDR_HI, (u32)data->src >> > 16); > + mvebu_mmc_write(mmc, SDIO_SYS_ADDR_LOW, (u32)data- > >src > & 0xffff); > + mvebu_mmc_write(mmc, SDIO_SYS_ADDR_HI, (u32)data->src > > > 16); > } > > - mvebu_mmc_write(SDIO_BLK_COUNT, data->blocks); > - mvebu_mmc_write(SDIO_BLK_SIZE, data->blocksize); > + mvebu_mmc_write(mmc, SDIO_BLK_COUNT, data->blocks); > + mvebu_mmc_write(mmc, SDIO_BLK_SIZE, data->blocksize); > > return 0; > } > > -static int mvebu_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, > +static int mvebu_mmc_send_cmd(struct udevice *dev, struct mmc_cmd > *cmd, > struct mmc_data *data) > { > ulong start; > @@ -72,12 +79,14 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, > struct mmc_cmd *cmd, > ushort resptype = 0; > ushort xfertype = 0; > ushort resp_indx = 0; > + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); > + struct mmc *mmc = &pdata->mmc; > > - debug("%s: cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n", > - DRIVER_NAME, cmd->cmdidx, cmd->resp_type, cmd->cmdarg); > + dev_dbg(dev, "cmdidx [0x%x] resp_type[0x%x] cmdarg[0x%x]\n", > + cmd->cmdidx, cmd->resp_type, cmd->cmdarg); > > - debug("%s: cmd %d (hw state 0x%04x)\n", DRIVER_NAME, > - cmd->cmdidx, mvebu_mmc_read(SDIO_HW_STATE)); > + dev_dbg(dev, "cmd %d (hw state 0x%04x)\n", > + cmd->cmdidx, mvebu_mmc_read(mmc, SDIO_HW_STATE)); > > /* > * Hardware weirdness. The FIFO_EMPTY bit of the HW_STATE > @@ -88,26 +97,26 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, > struct mmc_cmd *cmd, > * this bit comes to good sense (which eventually happens by > * itself) then the new transfer simply fails with a > timeout. > */ > - if (!(mvebu_mmc_read(SDIO_HW_STATE) & CMD_FIFO_EMPTY)) { > + if (!(mvebu_mmc_read(mmc, SDIO_HW_STATE) & CMD_FIFO_EMPTY)) { > ushort hw_state, count = 0; > > start = get_timer(0); > do { > - hw_state = mvebu_mmc_read(SDIO_HW_STATE); > + hw_state = mvebu_mmc_read(mmc, > SDIO_HW_STATE); > if ((get_timer(0) - start) > TIMEOUT_DELAY) > { > printf("%s : FIFO_EMPTY bit > missing\n", > - DRIVER_NAME); > + dev->name); > break; > } > count++; > } while (!(hw_state & CMD_FIFO_EMPTY)); > - debug("%s *** wait for FIFO_EMPTY bit (hw=0x%04x, > count=%d, jiffies=%ld)\n", > - DRIVER_NAME, hw_state, count, (get_timer(0) - > (start))); > + dev_dbg(dev, "*** wait for FIFO_EMPTY bit (hw=0x%04x, > count=%d, jiffies=%ld)\n", > + hw_state, count, (get_timer(0) - (start))); > } > > /* Clear status */ > - mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK); > - mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK); > + mvebu_mmc_write(mmc, SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK); > + mvebu_mmc_write(mmc, SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK); > > resptype = SDIO_CMD_INDEX(cmd->cmdidx); > > @@ -133,11 +142,10 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, > struct mmc_cmd *cmd, > } > > if (data) { > - int err = mvebu_mmc_setup_data(data); > + int err = mvebu_mmc_setup_data(dev, data); > > if (err) { > - debug("%s: command DATA error :%x\n", > - DRIVER_NAME, err); > + dev_dbg(dev, "command DATA error :%x\n", > err); > return err; > } > > @@ -154,34 +162,33 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, > struct mmc_cmd *cmd, > } > > /* Setting cmd arguments */ > - mvebu_mmc_write(SDIO_ARG_LOW, cmd->cmdarg & 0xffff); > - mvebu_mmc_write(SDIO_ARG_HI, cmd->cmdarg >> 16); > + mvebu_mmc_write(mmc, SDIO_ARG_LOW, cmd->cmdarg & 0xffff); > + mvebu_mmc_write(mmc, SDIO_ARG_HI, cmd->cmdarg >> 16); > > /* Setting Xfer mode */ > - mvebu_mmc_write(SDIO_XFER_MODE, xfertype); > + mvebu_mmc_write(mmc, SDIO_XFER_MODE, xfertype); > > /* Sending command */ > - mvebu_mmc_write(SDIO_CMD, resptype); > + mvebu_mmc_write(mmc, SDIO_CMD, resptype); > > start = get_timer(0); > > - while (!((mvebu_mmc_read(SDIO_NOR_INTR_STATUS)) & waittype)) > { > - if (mvebu_mmc_read(SDIO_NOR_INTR_STATUS) & > SDIO_NOR_ERROR) { > - debug("%s: error! cmdidx : %d, err reg: > %04x\n", > - DRIVER_NAME, cmd->cmdidx, > - mvebu_mmc_read(SDIO_ERR_INTR_STATUS)); > - if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) & > + while (!((mvebu_mmc_read(mmc, SDIO_NOR_INTR_STATUS)) & > waittype)) { > + if (mvebu_mmc_read(mmc, SDIO_NOR_INTR_STATUS) & > SDIO_NOR_ERROR) { > + dev_dbg(dev, "error! cmdidx : %d, err reg: > %04x\n", > + cmd->cmdidx, > + mvebu_mmc_read(mmc, > SDIO_ERR_INTR_STATUS)); > + if (mvebu_mmc_read(mmc, SDIO_ERR_INTR_STATUS) > & > (SDIO_ERR_CMD_TIMEOUT | > SDIO_ERR_DATA_TIMEOUT)) { > - debug("%s: command READ timed out\n", > - DRIVER_NAME); > + dev_dbg(dev, "command READ timed > out\n"); > return -ETIMEDOUT; > } > - debug("%s: command READ error\n", > DRIVER_NAME); > + dev_dbg(dev, "command READ error\n"); > return -ECOMM; > } > > if ((get_timer(0) - start) > TIMEOUT_DELAY) { > - debug("%s: command timed out\n", > DRIVER_NAME); > + dev_dbg(dev, "command timed out\n"); > return -ETIMEDOUT; > } > } > @@ -191,8 +198,7 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, > struct mmc_cmd *cmd, > uint response[8]; > > for (resp_indx = 0; resp_indx < 8; resp_indx++) > - response[resp_indx] > - = > mvebu_mmc_read(SDIO_RSP(resp_indx)); > + response[resp_indx] = mvebu_mmc_read(mmc, > SDIO_RSP(resp_indx)); > > cmd->response[0] = ((response[0] & 0x03ff) << > 22) > > > ((response[1] & 0xffff) << > 6) | > @@ -209,8 +215,7 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, > struct mmc_cmd *cmd, > uint response[3]; > > for (resp_indx = 0; resp_indx < 3; resp_indx++) > - response[resp_indx] > - = > mvebu_mmc_read(SDIO_RSP(resp_indx)); > + response[resp_indx] = mvebu_mmc_read(mmc, > SDIO_RSP(resp_indx)); > > cmd->response[0] = ((response[2] & 0x003f) << > (8 - > 8)) | > ((response[1] & 0xffff) << > (14 > - 8)) | > @@ -225,64 +230,71 @@ static int mvebu_mmc_send_cmd(struct mmc *mmc, > struct mmc_cmd *cmd, > cmd->response[3] = 0; > } > > - debug("%s: resp[0x%x] ", DRIVER_NAME, cmd->resp_type); > + dev_dbg(dev, "resp[0x%x] ", cmd->resp_type); > debug("[0x%x] ", cmd->response[0]); > debug("[0x%x] ", cmd->response[1]); > debug("[0x%x] ", cmd->response[2]); > debug("[0x%x] ", cmd->response[3]); > debug("\n"); > > - if (mvebu_mmc_read(SDIO_ERR_INTR_STATUS) & > + if (mvebu_mmc_read(mmc, SDIO_ERR_INTR_STATUS) & > (SDIO_ERR_CMD_TIMEOUT | SDIO_ERR_DATA_TIMEOUT)) > return -ETIMEDOUT; > > return 0; > } > > -static void mvebu_mmc_power_up(void) > +static void mvebu_mmc_power_up(struct udevice *dev) > { > - debug("%s: power up\n", DRIVER_NAME); > + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); > + struct mmc *mmc = &pdata->mmc; > + > + dev_dbg(dev, "power up\n"); > > /* disable interrupts */ > - mvebu_mmc_write(SDIO_NOR_INTR_EN, 0); > - mvebu_mmc_write(SDIO_ERR_INTR_EN, 0); > + mvebu_mmc_write(mmc, SDIO_NOR_INTR_EN, 0); > + mvebu_mmc_write(mmc, SDIO_ERR_INTR_EN, 0); > > /* SW reset */ > - mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW); > + mvebu_mmc_write(mmc, SDIO_SW_RESET, SDIO_SW_RESET_NOW); > > - mvebu_mmc_write(SDIO_XFER_MODE, 0); > + mvebu_mmc_write(mmc, SDIO_XFER_MODE, 0); > > /* enable status */ > - mvebu_mmc_write(SDIO_NOR_STATUS_EN, SDIO_POLL_MASK); > - mvebu_mmc_write(SDIO_ERR_STATUS_EN, SDIO_POLL_MASK); > + mvebu_mmc_write(mmc, SDIO_NOR_STATUS_EN, SDIO_POLL_MASK); > + mvebu_mmc_write(mmc, SDIO_ERR_STATUS_EN, SDIO_POLL_MASK); > > /* enable interrupts status */ > - mvebu_mmc_write(SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK); > - mvebu_mmc_write(SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK); > + mvebu_mmc_write(mmc, SDIO_NOR_INTR_STATUS, SDIO_POLL_MASK); > + mvebu_mmc_write(mmc, SDIO_ERR_INTR_STATUS, SDIO_POLL_MASK); > } > > -static void mvebu_mmc_set_clk(unsigned int clock) > +static void mvebu_mmc_set_clk(struct udevice *dev, unsigned int > clock) > { > unsigned int m; > + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); > + struct mmc *mmc = &pdata->mmc; > > if (clock == 0) { > - debug("%s: clock off\n", DRIVER_NAME); > - mvebu_mmc_write(SDIO_XFER_MODE, > SDIO_XFER_MODE_STOP_CLK); > - mvebu_mmc_write(SDIO_CLK_DIV, > MVEBU_MMC_BASE_DIV_MAX); > + dev_dbg(dev, "clock off\n"); > + mvebu_mmc_write(mmc, SDIO_XFER_MODE, > SDIO_XFER_MODE_STOP_CLK); > + mvebu_mmc_write(mmc, SDIO_CLK_DIV, > MVEBU_MMC_BASE_DIV_MAX); > } else { > m = MVEBU_MMC_BASE_FAST_CLOCK/(2*clock) - 1; > if (m > MVEBU_MMC_BASE_DIV_MAX) > m = MVEBU_MMC_BASE_DIV_MAX; > - mvebu_mmc_write(SDIO_CLK_DIV, m & > MVEBU_MMC_BASE_DIV_MAX); > - debug("%s: clock (%d) div : %d\n", DRIVER_NAME, > clock, > m); > + mvebu_mmc_write(mmc, SDIO_CLK_DIV, m & > MVEBU_MMC_BASE_DIV_MAX); > + dev_dbg(dev, "clock (%d) div : %d\n", clock, m); > } > } > > -static void mvebu_mmc_set_bus(unsigned int bus) > +static void mvebu_mmc_set_bus(struct udevice *dev, unsigned int bus) > { > + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); > + struct mmc *mmc = &pdata->mmc; > u32 ctrl_reg = 0; > > - ctrl_reg = mvebu_mmc_read(SDIO_HOST_CTRL); > + ctrl_reg = mvebu_mmc_read(mmc, SDIO_HOST_CTRL); > ctrl_reg &= ~SDIO_HOST_CTRL_DATA_WIDTH_4_BITS; > > switch (bus) { > @@ -306,23 +318,26 @@ static void mvebu_mmc_set_bus(unsigned int bus) > > ctrl_reg |= SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY; > > - debug("%s: ctrl 0x%04x: %s %s %s\n", DRIVER_NAME, ctrl_reg, > - (ctrl_reg & SDIO_HOST_CTRL_PUSH_PULL_EN) ? > - "push-pull" : "open-drain", > - (ctrl_reg & SDIO_HOST_CTRL_DATA_WIDTH_4_BITS) ? > - "4bit-width" : "1bit-width", > - (ctrl_reg & SDIO_HOST_CTRL_HI_SPEED_EN) ? > - "high-speed" : ""); > + dev_dbg(dev, "ctrl 0x%04x: %s %s %s\n", ctrl_reg, > + (ctrl_reg & SDIO_HOST_CTRL_PUSH_PULL_EN) ? > + "push-pull" : "open-drain", > + (ctrl_reg & SDIO_HOST_CTRL_DATA_WIDTH_4_BITS) ? > + "4bit-width" : "1bit-width", > + (ctrl_reg & SDIO_HOST_CTRL_HI_SPEED_EN) ? > + "high-speed" : ""); > > - mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg); > + mvebu_mmc_write(mmc, SDIO_HOST_CTRL, ctrl_reg); > } > > -static int mvebu_mmc_set_ios(struct mmc *mmc) > +static int mvebu_mmc_set_ios(struct udevice *dev) > { > - debug("%s: bus[%d] clock[%d]\n", DRIVER_NAME, > - mmc->bus_width, mmc->clock); > - mvebu_mmc_set_bus(mmc->bus_width); > - mvebu_mmc_set_clk(mmc->clock); > + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); > + struct mmc *mmc = &pdata->mmc; > + > + dev_dbg(dev, "bus[%d] clock[%d]\n", > + mmc->bus_width, mmc->clock); > + mvebu_mmc_set_bus(dev, mmc->bus_width); > + mvebu_mmc_set_clk(dev, mmc->clock); > > return 0; > } > @@ -330,13 +345,13 @@ static int mvebu_mmc_set_ios(struct mmc *mmc) > /* > * Set window register. > */ > -static void mvebu_window_setup(void) > +static void mvebu_window_setup(const struct mmc *mmc) > { > int i; > > for (i = 0; i < 4; i++) { > - mvebu_mmc_write(WINDOW_CTRL(i), 0); > - mvebu_mmc_write(WINDOW_BASE(i), 0); > + mvebu_mmc_write(mmc, WINDOW_CTRL(i), 0); > + mvebu_mmc_write(mmc, WINDOW_BASE(i), 0); > } > for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { > u32 size, base, attrib; > @@ -364,79 +379,119 @@ static void mvebu_window_setup(void) > size = gd->bd->bi_dram[i].size; > base = gd->bd->bi_dram[i].start; > if (size && attrib) { > - mvebu_mmc_write(WINDOW_CTRL(i), > + mvebu_mmc_write(mmc, WINDOW_CTRL(i), > MVCPU_WIN_CTRL_DATA(size, > > MVEBU_TARGET_DRAM, > attrib, > > MVCPU_WIN_ENABLE)); > } else { > - mvebu_mmc_write(WINDOW_CTRL(i), > MVCPU_WIN_DISABLE); > + mvebu_mmc_write(mmc, WINDOW_CTRL(i), > MVCPU_WIN_DISABLE); > } > - mvebu_mmc_write(WINDOW_BASE(i), base); > + mvebu_mmc_write(mmc, WINDOW_BASE(i), base); > } > } > > -static int mvebu_mmc_initialize(struct mmc *mmc) > +static int mvebu_mmc_initialize(struct udevice *dev) > { > - debug("%s: mvebu_mmc_initialize\n", DRIVER_NAME); > + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); > + struct mmc *mmc = &pdata->mmc; > + > + dev_dbg(dev, "%s\n", __func__); > > /* > * Setting host parameters > * Initial Host Ctrl : Timeout : max , Normal Speed mode, > * 4-bit data mode, Big Endian, SD memory Card, Push_pull > CMD > Line > */ > - mvebu_mmc_write(SDIO_HOST_CTRL, > + mvebu_mmc_write(mmc, SDIO_HOST_CTRL, > SDIO_HOST_CTRL_TMOUT(SDIO_HOST_CTRL_TMOUT_MA > X) > > > SDIO_HOST_CTRL_DATA_WIDTH_4_BITS | > SDIO_HOST_CTRL_BIG_ENDIAN | > SDIO_HOST_CTRL_PUSH_PULL_EN | > SDIO_HOST_CTRL_CARD_TYPE_MEM_ONLY); > > - mvebu_mmc_write(SDIO_CLK_CTRL, 0); > + mvebu_mmc_write(mmc, SDIO_CLK_CTRL, 0); > > /* enable status */ > - mvebu_mmc_write(SDIO_NOR_STATUS_EN, SDIO_POLL_MASK); > - mvebu_mmc_write(SDIO_ERR_STATUS_EN, SDIO_POLL_MASK); > + mvebu_mmc_write(mmc, SDIO_NOR_STATUS_EN, SDIO_POLL_MASK); > + mvebu_mmc_write(mmc, SDIO_ERR_STATUS_EN, SDIO_POLL_MASK); > > /* disable interrupts */ > - mvebu_mmc_write(SDIO_NOR_INTR_EN, 0); > - mvebu_mmc_write(SDIO_ERR_INTR_EN, 0); > + mvebu_mmc_write(mmc, SDIO_NOR_INTR_EN, 0); > + mvebu_mmc_write(mmc, SDIO_ERR_INTR_EN, 0); > > - mvebu_window_setup(); > + mvebu_window_setup(mmc); > > /* SW reset */ > - mvebu_mmc_write(SDIO_SW_RESET, SDIO_SW_RESET_NOW); > + mvebu_mmc_write(mmc, SDIO_SW_RESET, SDIO_SW_RESET_NOW); > > return 0; > } > > -static const struct mmc_ops mvebu_mmc_ops = { > - .send_cmd = mvebu_mmc_send_cmd, > - .set_ios = mvebu_mmc_set_ios, > - .init = mvebu_mmc_initialize, > -}; > - > -static struct mmc_config mvebu_mmc_cfg = { > - .name = DRIVER_NAME, > - .ops = &mvebu_mmc_ops, > - .f_min = MVEBU_MMC_BASE_FAST_CLOCK / > MVEBU_MMC_BASE_DIV_MAX, > - .f_max = MVEBU_MMC_CLOCKRATE_MAX, > - .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, > - .host_caps = MMC_MODE_4BIT | MMC_MODE_HS | > - MMC_MODE_HS_52MHz, > - .part_type = PART_TYPE_DOS, > - .b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT, > -}; > - > -int mvebu_mmc_init(struct bd_info *bis) > +static int mvebu_mmc_of_to_plat(struct udevice *dev) > { > - struct mmc *mmc; > + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); > + fdt_addr_t addr; > > - mvebu_mmc_power_up(); > + addr = dev_read_addr(dev); > + if (addr == FDT_ADDR_T_NONE) > + return -EINVAL; > > - mmc = mmc_create(&mvebu_mmc_cfg, bis); > - if (mmc == NULL) > - return -1; > + pdata->iobase = (void *)addr; > > return 0; > } > + > +static int mvebu_mmc_probe(struct udevice *dev) > +{ > + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); > + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); > + struct mmc *mmc = &pdata->mmc; > + struct mmc_config *cfg = &pdata->cfg; > + > + cfg->name = dev->name; > + cfg->f_min = MVEBU_MMC_BASE_FAST_CLOCK / > MVEBU_MMC_BASE_DIV_MAX; > + cfg->f_max = MVEBU_MMC_CLOCKRATE_MAX; > + cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; > + cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_HS | > MMC_MODE_HS_52MHz; > + cfg->part_type = PART_TYPE_DOS; > + cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; > + > + mmc->cfg = cfg; > + mmc->priv = pdata; > + mmc->dev = dev; > + upriv->mmc = mmc; > + > + mvebu_mmc_power_up(dev); > + mvebu_mmc_initialize(dev); > + > + return 0; > +} > + > +static const struct dm_mmc_ops mvebu_dm_mmc_ops = { > + .send_cmd = mvebu_mmc_send_cmd, > + .set_ios = mvebu_mmc_set_ios, > +}; > + > +static int mvebu_mmc_bind(struct udevice *dev) > +{ > + struct mvebu_mmc_plat *pdata = dev_get_plat(dev); > + > + return mmc_bind(dev, &pdata->mmc, &pdata->cfg); > +} > + > +static const struct udevice_id mvebu_mmc_match[] = { > + { .compatible = "marvell,orion-sdio" }, > + { /* sentinel */ } > +}; > + > +U_BOOT_DRIVER(mvebu_mmc) = { > + .name = "mvebu_mmc", > + .id = UCLASS_MMC, > + .of_match = mvebu_mmc_match, > + .ops = &mvebu_dm_mmc_ops, > + .probe = mvebu_mmc_probe, > + .bind = mvebu_mmc_bind, > + .of_to_plat = mvebu_mmc_of_to_plat, > + .plat_auto = sizeof(struct mvebu_mmc_plat), > +}; > diff --git a/include/mvebu_mmc.h b/include/mvebu_mmc.h > index a35e5a12ce..e75c3fa328 100644 > --- a/include/mvebu_mmc.h > +++ b/include/mvebu_mmc.h > @@ -258,17 +258,10 @@ > /* Hardware reset */ > #define MMC_CAP_HW_RESET (1 << 31) > > -struct mvebu_mmc_cfg { > - u32 mvebu_mmc_base; > - u32 mvebu_mmc_clk; > - u8 max_bus_width; > +struct mvebu_mmc_plat { > + void *iobase; > struct mmc_config cfg; > + struct mmc mmc; > }; > > -/* > - * Functions prototypes > - */ > - > -int mvebu_mmc_init(struct bd_info *bis); > - > #endif /* __MVEBU_MMC_H__ */ > Viele Grüße, Stefan