]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - drivers/mmc/omap_hsmmc.c
mmc: use pr_* log functions
[people/ms/u-boot.git] / drivers / mmc / omap_hsmmc.c
index d151fe726622e4d075bb7ebb29a2ed8fcc3c384e..b12d6d9102ed57e7aac5b9616d2c45143c94757b 100644 (file)
 #include <config.h>
 #include <common.h>
 #include <malloc.h>
+#include <memalign.h>
 #include <mmc.h>
 #include <part.h>
 #include <i2c.h>
-#include <twl4030.h>
-#include <twl6030.h>
+#if defined(CONFIG_OMAP54XX) || defined(CONFIG_OMAP44XX)
 #include <palmas.h>
+#endif
 #include <asm/io.h>
 #include <asm/arch/mmc_host_def.h>
 #if !defined(CONFIG_SOC_KEYSTONE)
@@ -56,22 +57,13 @@ DECLARE_GLOBAL_DATA_PTR;
 #define SYSCTL_SRC     (1 << 25)
 #define SYSCTL_SRD     (1 << 26)
 
-struct omap_hsmmc_plat {
-       struct mmc_config cfg;
-       struct mmc mmc;
-};
-
-struct omap2_mmc_platform_config {
-       u32 reg_offset;
-};
-
 struct omap_hsmmc_data {
        struct hsmmc *base_addr;
-#ifndef CONFIG_DM_MMC
+#if !CONFIG_IS_ENABLED(DM_MMC)
        struct mmc_config cfg;
 #endif
 #ifdef OMAP_HSMMC_USE_GPIO
-#ifdef CONFIG_DM_MMC
+#if CONFIG_IS_ENABLED(DM_MMC)
        struct gpio_desc cd_gpio;       /* Change Detect GPIO */
        struct gpio_desc wp_gpio;       /* Write Protect GPIO */
        bool cd_inverted;
@@ -79,19 +71,53 @@ struct omap_hsmmc_data {
        int cd_gpio;
        int wp_gpio;
 #endif
+#endif
+       u8 controller_flags;
+#ifndef CONFIG_OMAP34XX
+       struct omap_hsmmc_adma_desc *adma_desc_table;
+       uint desc_slot;
 #endif
 };
 
+#ifndef CONFIG_OMAP34XX
+struct omap_hsmmc_adma_desc {
+       u8 attr;
+       u8 reserved;
+       u16 len;
+       u32 addr;
+};
+
+#define ADMA_MAX_LEN   63488
+
+/* Decriptor table defines */
+#define ADMA_DESC_ATTR_VALID           BIT(0)
+#define ADMA_DESC_ATTR_END             BIT(1)
+#define ADMA_DESC_ATTR_INT             BIT(2)
+#define ADMA_DESC_ATTR_ACT1            BIT(4)
+#define ADMA_DESC_ATTR_ACT2            BIT(5)
+
+#define ADMA_DESC_TRANSFER_DATA                ADMA_DESC_ATTR_ACT2
+#define ADMA_DESC_LINK_DESC    (ADMA_DESC_ATTR_ACT1 | ADMA_DESC_ATTR_ACT2)
+#endif
+
 /* If we fail after 1 second wait, something is really bad */
 #define MAX_RETRY_MS   1000
 
+/* DMA transfers can take a long time if a lot a data is transferred.
+ * The timeout must take in account the amount of data. Let's assume
+ * that the time will never exceed 333 ms per MB (in other word we assume
+ * that the bandwidth is always above 3MB/s).
+ */
+#define DMA_TIMEOUT_PER_MB     333
+#define OMAP_HSMMC_USE_ADMA                    BIT(2)
+
 static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size);
 static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
                        unsigned int siz);
 
 static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc)
 {
-#ifdef CONFIG_DM_MMC
+#if CONFIG_IS_ENABLED(DM_MMC)
        return dev_get_priv(mmc->dev);
 #else
        return (struct omap_hsmmc_data *)mmc->priv;
@@ -99,7 +125,7 @@ static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc)
 }
 static inline struct mmc_config *omap_hsmmc_get_cfg(struct mmc *mmc)
 {
-#ifdef CONFIG_DM_MMC
+#if CONFIG_IS_ENABLED(DM_MMC)
        struct omap_hsmmc_plat *plat = dev_get_platdata(mmc->dev);
        return &plat->cfg;
 #else
@@ -107,7 +133,7 @@ static inline struct mmc_config *omap_hsmmc_get_cfg(struct mmc *mmc)
 #endif
 }
 
- #if defined(OMAP_HSMMC_USE_GPIO) && !defined(CONFIG_DM_MMC)
+#if defined(OMAP_HSMMC_USE_GPIO) && !CONFIG_IS_ENABLED(DM_MMC)
 static int omap_mmc_setup_gpio_in(int gpio, const char *label)
 {
        int ret;
@@ -251,6 +277,11 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
                        return -ETIMEDOUT;
                }
        }
+#ifndef CONFIG_OMAP34XX
+       reg_val = readl(&mmc_base->hl_hwinfo);
+       if (reg_val & MADMA_EN)
+               priv->controller_flags |= OMAP_HSMMC_USE_ADMA;
+#endif
        writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl);
        writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,
                &mmc_base->capa);
@@ -263,7 +294,7 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
 
        dsor = 240;
        mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK),
-               (ICE_STOP | DTO_15THDTO | CEN_DISABLE));
+               (ICE_STOP | DTO_15THDTO));
        mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK,
                (dsor << CLKD_OFFSET) | ICE_OSCILLATE);
        start = get_timer(0);
@@ -278,8 +309,8 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
        writel(readl(&mmc_base->hctl) | SDBP_PWRON, &mmc_base->hctl);
 
        writel(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO | IE_CIE |
-               IE_CEB | IE_CCRC | IE_CTO | IE_BRR | IE_BWR | IE_TC | IE_CC,
-               &mmc_base->ie);
+               IE_CEB | IE_CCRC | IE_ADMAE | IE_CTO | IE_BRR | IE_BWR | IE_TC |
+               IE_CC, &mmc_base->ie);
 
        mmc_init_stream(mmc_base);
 
@@ -332,15 +363,141 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit)
        }
 }
 
+#ifndef CONFIG_OMAP34XX
+static void omap_hsmmc_adma_desc(struct mmc *mmc, char *buf, u16 len, bool end)
+{
+       struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+       struct omap_hsmmc_adma_desc *desc;
+       u8 attr;
+
+       desc = &priv->adma_desc_table[priv->desc_slot];
+
+       attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA;
+       if (!end)
+               priv->desc_slot++;
+       else
+               attr |= ADMA_DESC_ATTR_END;
+
+       desc->len = len;
+       desc->addr = (u32)buf;
+       desc->reserved = 0;
+       desc->attr = attr;
+}
+
+static void omap_hsmmc_prepare_adma_table(struct mmc *mmc,
+                                         struct mmc_data *data)
+{
+       uint total_len = data->blocksize * data->blocks;
+       uint desc_count = DIV_ROUND_UP(total_len, ADMA_MAX_LEN);
+       struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+       int i = desc_count;
+       char *buf;
+
+       priv->desc_slot = 0;
+       priv->adma_desc_table = (struct omap_hsmmc_adma_desc *)
+                               memalign(ARCH_DMA_MINALIGN, desc_count *
+                               sizeof(struct omap_hsmmc_adma_desc));
+
+       if (data->flags & MMC_DATA_READ)
+               buf = data->dest;
+       else
+               buf = (char *)data->src;
+
+       while (--i) {
+               omap_hsmmc_adma_desc(mmc, buf, ADMA_MAX_LEN, false);
+               buf += ADMA_MAX_LEN;
+               total_len -= ADMA_MAX_LEN;
+       }
+
+       omap_hsmmc_adma_desc(mmc, buf, total_len, true);
+
+       flush_dcache_range((long)priv->adma_desc_table,
+                          (long)priv->adma_desc_table +
+                          ROUND(desc_count *
+                          sizeof(struct omap_hsmmc_adma_desc),
+                          ARCH_DMA_MINALIGN));
+}
+
+static void omap_hsmmc_prepare_data(struct mmc *mmc, struct mmc_data *data)
+{
+       struct hsmmc *mmc_base;
+       struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+       u32 val;
+       char *buf;
+
+       mmc_base = priv->base_addr;
+       omap_hsmmc_prepare_adma_table(mmc, data);
+
+       if (data->flags & MMC_DATA_READ)
+               buf = data->dest;
+       else
+               buf = (char *)data->src;
+
+       val = readl(&mmc_base->hctl);
+       val |= DMA_SELECT;
+       writel(val, &mmc_base->hctl);
+
+       val = readl(&mmc_base->con);
+       val |= DMA_MASTER;
+       writel(val, &mmc_base->con);
+
+       writel((u32)priv->adma_desc_table, &mmc_base->admasal);
+
+       flush_dcache_range((u32)buf,
+                          (u32)buf +
+                          ROUND(data->blocksize * data->blocks,
+                                ARCH_DMA_MINALIGN));
+}
+
+static void omap_hsmmc_dma_cleanup(struct mmc *mmc)
+{
+       struct hsmmc *mmc_base;
+       struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+       u32 val;
+
+       mmc_base = priv->base_addr;
+
+       val = readl(&mmc_base->con);
+       val &= ~DMA_MASTER;
+       writel(val, &mmc_base->con);
+
+       val = readl(&mmc_base->hctl);
+       val &= ~DMA_SELECT;
+       writel(val, &mmc_base->hctl);
+
+       kfree(priv->adma_desc_table);
+}
+#else
+#define omap_hsmmc_adma_desc
+#define omap_hsmmc_prepare_adma_table
+#define omap_hsmmc_prepare_data
+#define omap_hsmmc_dma_cleanup
+#endif
+
+#if !CONFIG_IS_ENABLED(DM_MMC)
 static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                        struct mmc_data *data)
 {
        struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+#else
+static int omap_hsmmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+                       struct mmc_data *data)
+{
+       struct omap_hsmmc_data *priv = dev_get_priv(dev);
+#ifndef CONFIG_OMAP34XX
+       struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+       struct mmc *mmc = upriv->mmc;
+#endif
+#endif
        struct hsmmc *mmc_base;
        unsigned int flags, mmc_stat;
        ulong start;
 
        mmc_base = priv->base_addr;
+
+       if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
+               return 0;
+
        start = get_timer(0);
        while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {
                if (get_timer(0) - start > MAX_RETRY_MS) {
@@ -387,7 +544,8 @@ static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 
        /* enable default flags */
        flags = flags | (CMD_TYPE_NORMAL | CICE_NOCHECK | CCCE_NOCHECK |
-                       MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE | DE_DISABLE);
+                       MSBS_SGLEBLK);
+       flags &= ~(ACEN_ENABLE | BCE_ENABLE | DE_ENABLE);
 
        if (cmd->resp_type & MMC_RSP_CRC)
                flags |= CCCE_CHECK;
@@ -397,7 +555,7 @@ static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
        if (data) {
                if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) ||
                         (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK)) {
-                       flags |= (MSBS_MULTIBLK | BCE_ENABLE);
+                       flags |= (MSBS_MULTIBLK | BCE_ENABLE | ACEN_ENABLE);
                        data->blocksize = 512;
                        writel(data->blocksize | (data->blocks << 16),
                                                        &mmc_base->blk);
@@ -408,6 +566,14 @@ static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                        flags |= (DP_DATA | DDIR_READ);
                else
                        flags |= (DP_DATA | DDIR_WRITE);
+
+#ifndef CONFIG_OMAP34XX
+               if ((priv->controller_flags & OMAP_HSMMC_USE_ADMA) &&
+                   !mmc_is_tuning_cmd(cmd->cmdidx)) {
+                       omap_hsmmc_prepare_data(mmc, data);
+                       flags |= DE_ENABLE;
+               }
+#endif
        }
 
        writel(cmd->cmdarg, &mmc_base->arg);
@@ -417,7 +583,7 @@ static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
        start = get_timer(0);
        do {
                mmc_stat = readl(&mmc_base->stat);
-               if (get_timer(0) - start > MAX_RETRY_MS) {
+               if (get_timer(start) > MAX_RETRY_MS) {
                        printf("%s : timeout: No status update\n", __func__);
                        return -ETIMEDOUT;
                }
@@ -444,6 +610,41 @@ static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                }
        }
 
+#ifndef CONFIG_OMAP34XX
+       if ((priv->controller_flags & OMAP_HSMMC_USE_ADMA) && data &&
+           !mmc_is_tuning_cmd(cmd->cmdidx)) {
+               u32 sz_mb, timeout;
+
+               if (mmc_stat & IE_ADMAE) {
+                       omap_hsmmc_dma_cleanup(mmc);
+                       return -EIO;
+               }
+
+               sz_mb = DIV_ROUND_UP(data->blocksize *  data->blocks, 1 << 20);
+               timeout = sz_mb * DMA_TIMEOUT_PER_MB;
+               if (timeout < MAX_RETRY_MS)
+                       timeout = MAX_RETRY_MS;
+
+               start = get_timer(0);
+               do {
+                       mmc_stat = readl(&mmc_base->stat);
+                       if (mmc_stat & TC_MASK) {
+                               writel(readl(&mmc_base->stat) | TC_MASK,
+                                      &mmc_base->stat);
+                               break;
+                       }
+                       if (get_timer(start) > timeout) {
+                               printf("%s : DMA timeout: No status update\n",
+                                      __func__);
+                               return -ETIMEDOUT;
+                       }
+               } while (1);
+
+               omap_hsmmc_dma_cleanup(mmc);
+               return 0;
+       }
+#endif
+
        if (data && (data->flags & MMC_DATA_READ)) {
                mmc_read_data(mmc_base, data->dest,
                                data->blocksize * data->blocks);
@@ -563,9 +764,17 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
        return 0;
 }
 
+#if !CONFIG_IS_ENABLED(DM_MMC)
 static int omap_hsmmc_set_ios(struct mmc *mmc)
 {
        struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+#else
+static int omap_hsmmc_set_ios(struct udevice *dev)
+{
+       struct omap_hsmmc_data *priv = dev_get_priv(dev);
+       struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+       struct mmc *mmc = upriv->mmc;
+#endif
        struct hsmmc *mmc_base;
        unsigned int dsor = 0;
        ulong start;
@@ -603,7 +812,7 @@ static int omap_hsmmc_set_ios(struct mmc *mmc)
        }
 
        mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK),
-                               (ICE_STOP | DTO_15THDTO | CEN_DISABLE));
+                               (ICE_STOP | DTO_15THDTO));
 
        mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK,
                                (dsor << CLKD_OFFSET) | ICE_OSCILLATE);
@@ -621,10 +830,10 @@ static int omap_hsmmc_set_ios(struct mmc *mmc)
 }
 
 #ifdef OMAP_HSMMC_USE_GPIO
-#ifdef CONFIG_DM_MMC
-static int omap_hsmmc_getcd(struct mmc *mmc)
+#if CONFIG_IS_ENABLED(DM_MMC)
+static int omap_hsmmc_getcd(struct udevice *dev)
 {
-       struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+       struct omap_hsmmc_data *priv = dev_get_priv(dev);
        int value;
 
        value = dm_gpio_get_value(&priv->cd_gpio);
@@ -637,9 +846,9 @@ static int omap_hsmmc_getcd(struct mmc *mmc)
        return value;
 }
 
-static int omap_hsmmc_getwp(struct mmc *mmc)
+static int omap_hsmmc_getwp(struct udevice *dev)
 {
-       struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+       struct omap_hsmmc_data *priv = dev_get_priv(dev);
        int value;
 
        value = dm_gpio_get_value(&priv->wp_gpio);
@@ -679,6 +888,16 @@ static int omap_hsmmc_getwp(struct mmc *mmc)
 #endif
 #endif
 
+#if CONFIG_IS_ENABLED(DM_MMC)
+static const struct dm_mmc_ops omap_hsmmc_ops = {
+       .send_cmd       = omap_hsmmc_send_cmd,
+       .set_ios        = omap_hsmmc_set_ios,
+#ifdef OMAP_HSMMC_USE_GPIO
+       .get_cd         = omap_hsmmc_getcd,
+       .get_wp         = omap_hsmmc_getwp,
+#endif
+};
+#else
 static const struct mmc_ops omap_hsmmc_ops = {
        .send_cmd       = omap_hsmmc_send_cmd,
        .set_ios        = omap_hsmmc_set_ios,
@@ -688,8 +907,9 @@ static const struct mmc_ops omap_hsmmc_ops = {
        .getwp          = omap_hsmmc_getwp,
 #endif
 };
+#endif
 
-#ifndef CONFIG_DM_MMC
+#if !CONFIG_IS_ENABLED(DM_MMC)
 int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
                int wp_gpio)
 {
@@ -777,19 +997,18 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
        return 0;
 }
 #else
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 static int omap_hsmmc_ofdata_to_platdata(struct udevice *dev)
 {
-       struct omap_hsmmc_data *priv = dev_get_priv(dev);
        struct omap_hsmmc_plat *plat = dev_get_platdata(dev);
        struct mmc_config *cfg = &plat->cfg;
-       struct omap2_mmc_platform_config *data =
-               (struct omap2_mmc_platform_config *)dev_get_driver_data(dev);
        const void *fdt = gd->fdt_blob;
        int node = dev_of_offset(dev);
        int val;
 
-       priv->base_addr = map_physmem(dev_get_addr(dev), sizeof(struct hsmmc *),
-                                     MAP_NOCACHE) + data->reg_offset;
+       plat->base_addr = map_physmem(devfdt_get_addr(dev),
+                                     sizeof(struct hsmmc *),
+                                     MAP_NOCACHE);
 
        cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS;
        val = fdtdec_get_int(fdt, node, "bus-width", -1);
@@ -815,11 +1034,12 @@ static int omap_hsmmc_ofdata_to_platdata(struct udevice *dev)
        cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
 #ifdef OMAP_HSMMC_USE_GPIO
-       priv->cd_inverted = fdtdec_get_bool(fdt, node, "cd-inverted");
+       plat->cd_inverted = fdtdec_get_bool(fdt, node, "cd-inverted");
 #endif
 
        return 0;
 }
+#endif
 
 #ifdef CONFIG_BLK
 
@@ -839,7 +1059,10 @@ static int omap_hsmmc_probe(struct udevice *dev)
        struct mmc *mmc;
 
        cfg->name = "OMAP SD/MMC";
-       cfg->ops = &omap_hsmmc_ops;
+       priv->base_addr = plat->base_addr;
+#ifdef OMAP_HSMMC_USE_GPIO
+       priv->cd_inverted = plat->cd_inverted;
+#endif
 
 #ifdef CONFIG_BLK
        mmc = &plat->mmc;
@@ -849,7 +1072,7 @@ static int omap_hsmmc_probe(struct udevice *dev)
                return -1;
 #endif
 
-#ifdef OMAP_HSMMC_USE_GPIO
+#if defined(OMAP_HSMMC_USE_GPIO) && CONFIG_IS_ENABLED(OF_CONTROL)
        gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN);
        gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN);
 #endif
@@ -857,47 +1080,32 @@ static int omap_hsmmc_probe(struct udevice *dev)
        mmc->dev = dev;
        upriv->mmc = mmc;
 
-       return 0;
+       return omap_hsmmc_init_setup(mmc);
 }
 
-static const struct omap2_mmc_platform_config omap3_mmc_pdata = {
-       .reg_offset = 0,
-};
-
-static const struct omap2_mmc_platform_config am33xx_mmc_pdata = {
-       .reg_offset = 0x100,
-};
-
-static const struct omap2_mmc_platform_config omap4_mmc_pdata = {
-       .reg_offset = 0x100,
-};
-
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 static const struct udevice_id omap_hsmmc_ids[] = {
-       {
-                       .compatible = "ti,omap3-hsmmc",
-                       .data = (ulong)&omap3_mmc_pdata
-       },
-       {
-                       .compatible = "ti,omap4-hsmmc",
-                       .data = (ulong)&omap4_mmc_pdata
-       },
-       {
-                       .compatible = "ti,am33xx-hsmmc",
-                       .data = (ulong)&am33xx_mmc_pdata
-       },
+       { .compatible = "ti,omap3-hsmmc" },
+       { .compatible = "ti,omap4-hsmmc" },
+       { .compatible = "ti,am33xx-hsmmc" },
        { }
 };
+#endif
 
 U_BOOT_DRIVER(omap_hsmmc) = {
        .name   = "omap_hsmmc",
        .id     = UCLASS_MMC,
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
        .of_match = omap_hsmmc_ids,
        .ofdata_to_platdata = omap_hsmmc_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct omap_hsmmc_plat),
+#endif
 #ifdef CONFIG_BLK
        .bind = omap_hsmmc_bind,
 #endif
+       .ops = &omap_hsmmc_ops,
        .probe  = omap_hsmmc_probe,
        .priv_auto_alloc_size = sizeof(struct omap_hsmmc_data),
-       .platdata_auto_alloc_size = sizeof(struct omap_hsmmc_plat),
+       .flags  = DM_FLAG_PRE_RELOC,
 };
 #endif