]> git.sur5r.net Git - u-boot/commitdiff
mmc: Split mmc struct, rework mmc initialization (v2)
authorPantelis Antoniou <panto@antoniou-consulting.com>
Tue, 11 Mar 2014 17:34:20 +0000 (19:34 +0200)
committerPantelis Antoniou <panto@antoniou-consulting.com>
Mon, 24 Mar 2014 10:58:56 +0000 (12:58 +0200)
The way that struct mmc was implemented was a bit of a mess;
configuration and internal state all jumbled up in a single structure.

On top of that the way initialization is done with mmc_register leads
to a lot of duplicated code in drivers.

Typically the initialization got something like this in every driver.

struct mmc *mmc = malloc(sizeof(struct mmc));
memset(mmc, 0, sizeof(struct mmc);
/* fill in fields of mmc struct */
/* store private data pointer */
mmc_register(mmc);

By using the new mmc_create call one just passes an mmc config struct
and an optional private data pointer like this:

struct mmc = mmc_create(&cfg, priv);

All in tree drivers have been updated to the new form, and expect
mmc_register to go away before long.

Changes since v1:

* Use calloc instead of manually calling memset.
* Mark mmc_register as deprecated.

Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
26 files changed:
arch/arm/include/asm/arch-davinci/sdmmc_defs.h
arch/arm/include/asm/arch-tegra/tegra_mmc.h
common/cmd_mmc.c
common/cmd_mmc_spi.c
drivers/mmc/arm_pl180_mmci.c
drivers/mmc/arm_pl180_mmci.h
drivers/mmc/bfin_sdh.c
drivers/mmc/davinci_mmc.c
drivers/mmc/dw_mmc.c
drivers/mmc/fsl_esdhc.c
drivers/mmc/ftsdc010_mci.c
drivers/mmc/gen_atmel_mci.c
drivers/mmc/mmc.c
drivers/mmc/mmc_spi.c
drivers/mmc/mmc_write.c
drivers/mmc/mxcmmc.c
drivers/mmc/mxsmmc.c
drivers/mmc/omap_hsmmc.c
drivers/mmc/pxa_mmc_gen.c
drivers/mmc/sdhci.c
drivers/mmc/sh_mmcif.c
drivers/mmc/tegra_mmc.c
include/dwmmc.h
include/fsl_esdhc.h
include/mmc.h
include/sdhci.h

index 3e9e6065c770e70827516998e3cc912c6025e7c8..9aa3f4ab279111ae5aa2b3379bfa08747668be2d 100644 (file)
@@ -151,6 +151,7 @@ struct davinci_mmc {
        uint host_caps;         /* Host capabilities */
        uint voltages;          /* Host supported voltages */
        uint version;           /* MMC Controller version */
+       struct mmc_config cfg;
 };
 
 enum {
index b6896afd96d4ed305d1cc5c7fd2f7698844ad8a2..310bbd7df9fe0bb492dfeab549e16dac626419b4 100644 (file)
@@ -11,6 +11,9 @@
 
 #include <fdtdec.h>
 
+/* for mmc_config definition */
+#include <mmc.h>
+
 #define MAX_HOSTS              4       /* Max number of 'hosts'/controllers */
 
 #ifndef __ASSEMBLY__
@@ -138,6 +141,7 @@ struct mmc_host {
        struct fdt_gpio_state wp_gpio;          /* Write Protect GPIO */
        unsigned int version;   /* SDHCI spec. version */
        unsigned int clock;     /* Current clock (MHz) */
+       struct mmc_config cfg;  /* mmc configuration */
 };
 
 void pad_init_mmc(struct mmc_host *host);
index 2d51927060280bfc0289f00b5514131075829dd7..bd1edc8c844871e85be5b3e812436e082d66f40e 100644 (file)
@@ -79,7 +79,7 @@ enum mmc_state {
 };
 static void print_mmcinfo(struct mmc *mmc)
 {
-       printf("Device: %s\n", mmc->name);
+       printf("Device: %s\n", mmc->cfg->name);
        printf("Manufacturer ID: %x\n", mmc->cid[0] >> 24);
        printf("OEM: %x\n", (mmc->cid[0] >> 8) & 0xffff);
        printf("Name: %c%c%c%c%c \n", mmc->cid[0] & 0xff,
index 98cd788c76d6136dc0e3ab175a89b763a0ba885a..a2138b8650e90cc68a1c2dde5b808fe9caa7dc47 100644 (file)
@@ -72,7 +72,7 @@ static int do_mmc_spi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                printf("Failed to create MMC Device\n");
                return 1;
        }
-       printf("%s: %d at %u:%u hz %u mode %u\n", mmc->name, mmc->block_dev.dev,
+       printf("%s: %d at %u:%u hz %u mode %u\n", mmc->cfg->name, mmc->block_dev.dev,
               bus, cs, speed, mode);
        mmc_init(mmc);
        return 0;
index 5a30590673cde025ec635b31b20b837c22b019df..5ef7ff7ff2b7fa584c36d64e8f9f530f43cd7425 100644 (file)
@@ -287,9 +287,9 @@ static void host_set_ios(struct mmc *dev)
                u32 clkdiv = 0;
                u32 tmp_clock;
 
-               if (dev->clock >= dev->f_max) {
+               if (dev->clock >= dev->cfg->f_max) {
                        clkdiv = 0;
-                       dev->clock = dev->f_max;
+                       dev->clock = dev->cfg->f_max;
                } else {
                        clkdiv = (host->clock_in / dev->clock) - 2;
                }
@@ -348,16 +348,9 @@ static const struct mmc_ops arm_pl180_mmci_ops = {
  */
 int arm_pl180_mmci_init(struct pl180_mmc_host *host)
 {
-       struct mmc *dev;
+       struct mmc *mmc;
        u32 sdi_u32;
 
-       dev = malloc(sizeof(struct mmc));
-       if (!dev)
-               return -ENOMEM;
-
-       memset(dev, 0, sizeof(struct mmc));
-       dev->priv = host;
-
        writel(host->pwr_init, &host->base->power);
        writel(host->clkdiv_init, &host->base->clock);
        udelay(CLK_CHANGE_DELAY);
@@ -365,15 +358,24 @@ int arm_pl180_mmci_init(struct pl180_mmc_host *host)
        /* Disable mmc interrupts */
        sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK;
        writel(sdi_u32, &host->base->mask0);
-       dev->name = host->name;
-       dev->ops = &arm_pl180_mmci_ops;
-       dev->host_caps = host->caps;
-       dev->voltages = host->voltages;
-       dev->f_min = host->clock_min;
-       dev->f_max = host->clock_max;
-       dev->b_max = host->b_max;
-       mmc_register(dev);
-       debug("registered mmc interface number is:%d\n", dev->block_dev.dev);
+
+       host->cfg.name = host->name;
+       host->cfg.ops = &arm_pl180_mmci_ops;
+       /* TODO remove the duplicates */
+       host->cfg.host_caps = host->caps;
+       host->cfg.voltages = host->voltages;
+       host->cfg.f_min = host->clock_min;
+       host->cfg.f_max = host->clock_max;
+       if (host->b_max != 0)
+               host->cfg.b_max = host->b_max;
+       else
+               host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+
+       mmc = mmc_create(&host->cfg, host);
+       if (mmc == NULL)
+               return -1;
+
+       debug("registered mmc interface number is:%d\n", mmc->block_dev.dev);
 
        return 0;
 }
index 72344498d651b777759c0e60f41155f255c9ac35..f23bd391eed1c5ce91af4ee59a8c992c69ff65e9 100644 (file)
@@ -13,6 +13,9 @@
 #ifndef __ARM_PL180_MMCI_H__
 #define __ARM_PL180_MMCI_H__
 
+/* need definition of struct mmc_config */
+#include <mmc.h>
+
 #define COMMAND_REG_DELAY      300
 #define DATA_REG_DELAY         1000
 #define CLK_CHANGE_DELAY       2000
@@ -184,6 +187,7 @@ struct pl180_mmc_host {
        unsigned int clkdiv_init;
        unsigned int pwr_init;
        int version2;
+       struct mmc_config cfg;
 };
 
 int arm_pl180_mmci_init(struct pl180_mmc_host *);
index 5f6145b0c774e268564ec1adb3f41e8abc8a4907..7b35d8e7d932229b90a0287c5656ae4c404bf551 100644 (file)
@@ -238,7 +238,7 @@ static void bfin_sdh_set_ios(struct mmc *mmc)
        u16 cfg = 0;
        u16 clk_ctl = 0;
 
-       if (mmc->bus_width == 4) {
+       if (mmc_bus_width(mmc) == 4) {
                cfg = bfin_read_SDH_CFG();
 #ifndef RSI_BLKSZ
                cfg &= ~PD_SDDAT3;
@@ -280,25 +280,24 @@ static const struct mmc_ops bfin_mmc_ops = {
        .init           = bfin_sdh_init,
 };
 
+static struct mmc_config bfin_mmc_cfg = {
+       .name           = "Blackfin SDH",
+       .ops            = &bfin_mmc_ops,
+       .host_caps      = MMC_MODE_4BIT,
+       .voltages       = MMC_VDD_32_33 | MMC_VDD_33_34,
+       .b_max          = CONFIG_SYS_MMC_MAX_BLK_COUNT,
+};
+
 int bfin_mmc_init(bd_t *bis)
 {
-       struct mmc *mmc = NULL;
-
-       mmc = malloc(sizeof(struct mmc));
-
-       if (!mmc)
-               return -ENOMEM;
-       mmc->name = "Blackfin SDH";
-       mmc->ops = &bfin_mmc_ops;
-       mmc->host_caps = MMC_MODE_4BIT;
-
-       mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
-       mmc->f_max = get_sclk();
-       mmc->f_min = mmc->f_max >> 9;
+       struct mmc *mmc;
 
-       mmc->b_max = 0;
+       bfin_mmc_cfg.f_max = get_sclk();
+       bfin_mmc_cfg.f_min = bfin_mmc_cfg.f_max >> 9;
 
-       mmc_register(mmc);
+       mmc = mmc_create(&bfin_mmc_cfg, NULL);
+       if (mmc == NULL)
+               return -1;
 
        return 0;
 }
index cae972a20f8e7954e2274973bc486339014f9168..aae00e9dab3103d539482b7fdb8ab2ff6e27e0e1 100644 (file)
@@ -30,10 +30,10 @@ static void dmmc_set_clock(struct mmc *mmc, uint clock)
        struct davinci_mmc_regs *regs = host->reg_base;
        uint clkrt, sysclk2, act_clock;
 
-       if (clock < mmc->f_min)
-               clock = mmc->f_min;
-       if (clock > mmc->f_max)
-               clock = mmc->f_max;
+       if (clock < mmc->cfg->f_min)
+               clock = mmc->cfg->f_min;
+       if (clock > mmc->cfg->f_max)
+               clock = mmc->cfg->f_max;
 
        set_val(&regs->mmcclk, 0);
        sysclk2 = host->input_clk;
@@ -374,22 +374,16 @@ static const struct mmc_ops dmmc_ops = {
  */
 int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host)
 {
-       struct mmc *mmc;
+       host->cfg.name = "davinci";
+       host->cfg.ops = &dmmc_ops;
+       host->cfg.f_min = 200000;
+       host->cfg.f_max = 25000000;
+       host->cfg.voltages = host->voltages;
+       host->cfg.host_caps = host->host_caps;
 
-       mmc = malloc(sizeof(struct mmc));
-       memset(mmc, 0, sizeof(struct mmc));
+       host->cfg.b_max = DAVINCI_MAX_BLOCKS;
 
-       mmc->name = "davinci";
-       mmc->priv = host;
-       mmc->ops = &dmmc_ops;
-       mmc->f_min = 200000;
-       mmc->f_max = 25000000;
-       mmc->voltages = host->voltages;
-       mmc->host_caps = host->host_caps;
-
-       mmc->b_max = DAVINCI_MAX_BLOCKS;
-
-       mmc_register(mmc);
+       mmc_create(&host->cfg, host);
 
        return 0;
 }
index 011efb14a98585d7b2d5992f482f98c094f41c33..eb4e2be5143ea3db71005f3c0522bb0dce037288 100644 (file)
@@ -107,7 +107,7 @@ static int dwmci_set_transfer_mode(struct dwmci_host *host,
 static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                struct mmc_data *data)
 {
-       struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
+       struct dwmci_host *host = mmc->priv;
        ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac,
                                 data ? DIV_ROUND_UP(data->blocks, 8) : 0);
        int flags = 0, i;
@@ -284,7 +284,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
 
 static void dwmci_set_ios(struct mmc *mmc)
 {
-       struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
+       struct dwmci_host *host = mmc->priv;
        u32 ctype;
 
        debug("Buswidth = %d, clock: %d\n",mmc->bus_width, mmc->clock);
@@ -310,7 +310,7 @@ static void dwmci_set_ios(struct mmc *mmc)
 
 static int dwmci_init(struct mmc *mmc)
 {
-       struct dwmci_host *host = (struct dwmci_host *)mmc->priv;
+       struct dwmci_host *host = mmc->priv;
 
        if (host->board_init)
                host->board_init(host);
@@ -323,7 +323,7 @@ static int dwmci_init(struct mmc *mmc)
        }
 
        /* Enumerate at 400KHz */
-       dwmci_setup_bus(host, mmc->f_min);
+       dwmci_setup_bus(host, mmc->cfg->f_min);
 
        dwmci_writel(host, DWMCI_RINTSTS, 0xFFFFFFFF);
        dwmci_writel(host, DWMCI_INTMASK, 0);
@@ -351,37 +351,29 @@ static const struct mmc_ops dwmci_ops = {
 
 int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk)
 {
-       struct mmc *mmc;
-       int err = 0;
+       host->cfg.name = host->name;
+       host->cfg.ops = &dwmci_ops;
+       host->cfg.f_min = min_clk;
+       host->cfg.f_max = max_clk;
 
-       mmc = calloc(sizeof(struct mmc), 1);
-       if (!mmc) {
-               printf("mmc calloc fail!\n");
-               return -1;
-       }
-
-       mmc->priv = host;
-       host->mmc = mmc;
-
-       mmc->name = host->name;
-       mmc->ops = &dwmci_ops;
-       mmc->f_min = min_clk;
-       mmc->f_max = max_clk;
+       host->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
 
-       mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
-
-       mmc->host_caps = host->caps;
+       host->cfg.host_caps = host->caps;
 
        if (host->buswidth == 8) {
-               mmc->host_caps |= MMC_MODE_8BIT;
-               mmc->host_caps &= ~MMC_MODE_4BIT;
+               host->cfg.host_caps |= MMC_MODE_8BIT;
+               host->cfg.host_caps &= ~MMC_MODE_4BIT;
        } else {
-               mmc->host_caps |= MMC_MODE_4BIT;
-               mmc->host_caps &= ~MMC_MODE_8BIT;
+               host->cfg.host_caps |= MMC_MODE_4BIT;
+               host->cfg.host_caps &= ~MMC_MODE_8BIT;
        }
-       mmc->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_HC;
+       host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_HC;
+
+       host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
-       err = mmc_register(mmc);
+       host->mmc = mmc_create(&host->cfg, host);
+       if (host->mmc == NULL)
+               return -1;
 
-       return err;
+       return 0;
 }
index f66513ed1610d328b25c5d51bc284fe70d9f341b..d64962652c133a538f7cbc00c584bc6017aba244 100644 (file)
@@ -172,7 +172,7 @@ esdhc_pio_read_write(struct mmc *mmc, struct mmc_data *data)
 static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
 {
        int timeout;
-       struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+       struct fsl_esdhc_cfg *cfg = mmc->priv;
        struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
 #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
        uint wml_value;
@@ -267,7 +267,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 {
        uint    xfertyp;
        uint    irqstat;
-       struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+       struct fsl_esdhc_cfg *cfg = mmc->priv;
        volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
 
 #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
@@ -406,13 +406,13 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 static void set_sysctl(struct mmc *mmc, uint clock)
 {
        int div, pre_div;
-       struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+       struct fsl_esdhc_cfg *cfg = mmc->priv;
        volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
        int sdhc_clk = cfg->sdhc_clk;
        uint clk;
 
-       if (clock < mmc->f_min)
-               clock = mmc->f_min;
+       if (clock < mmc->cfg->f_min)
+               clock = mmc->cfg->f_min;
 
        if (sdhc_clk / 16 > clock) {
                for (pre_div = 2; pre_div < 256; pre_div *= 2)
@@ -443,7 +443,7 @@ static void set_sysctl(struct mmc *mmc, uint clock)
 
 static void esdhc_set_ios(struct mmc *mmc)
 {
-       struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+       struct fsl_esdhc_cfg *cfg = mmc->priv;
        struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
 
        /* Set the clock speed */
@@ -461,7 +461,7 @@ static void esdhc_set_ios(struct mmc *mmc)
 
 static int esdhc_init(struct mmc *mmc)
 {
-       struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+       struct fsl_esdhc_cfg *cfg = mmc->priv;
        struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
        int timeout = 1000;
 
@@ -496,7 +496,7 @@ static int esdhc_init(struct mmc *mmc)
 
 static int esdhc_getcd(struct mmc *mmc)
 {
-       struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+       struct fsl_esdhc_cfg *cfg = mmc->priv;
        struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
        int timeout = 1000;
 
@@ -540,12 +540,6 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
        if (!cfg)
                return -1;
 
-       mmc = malloc(sizeof(struct mmc));
-       if (!mmc)
-               return -ENOMEM;
-
-       memset(mmc, 0, sizeof(struct mmc));
-       mmc->name = "FSL_SDHC";
        regs = (struct fsl_esdhc *)cfg->esdhc_base;
 
        /* First reset the eSDHC controller */
@@ -554,8 +548,8 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
        esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN
                                | SYSCTL_IPGEN | SYSCTL_CKEN);
 
-       mmc->priv = cfg;
-       mmc->ops = &esdhc_ops;
+       memset(&cfg->cfg, 0, sizeof(cfg->cfg));
+
        voltage_caps = 0;
        caps = regs->hostcapblt;
 
@@ -576,38 +570,43 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
        if (caps & ESDHC_HOSTCAPBLT_VS33)
                voltage_caps |= MMC_VDD_32_33 | MMC_VDD_33_34;
 
+       cfg->cfg.name = "FSL_SDHC";
+       cfg->cfg.ops = &esdhc_ops;
 #ifdef CONFIG_SYS_SD_VOLTAGE
-       mmc->voltages = CONFIG_SYS_SD_VOLTAGE;
+       cfg->cfg.voltages = CONFIG_SYS_SD_VOLTAGE;
 #else
-       mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
+       cfg->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 #endif
-       if ((mmc->voltages & voltage_caps) == 0) {
+       if ((cfg->cfg.voltages & voltage_caps) == 0) {
                printf("voltage not supported by controller\n");
                return -1;
        }
 
-       mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC;
+       cfg->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC;
 
        if (cfg->max_bus_width > 0) {
                if (cfg->max_bus_width < 8)
-                       mmc->host_caps &= ~MMC_MODE_8BIT;
+                       cfg->cfg.host_caps &= ~MMC_MODE_8BIT;
                if (cfg->max_bus_width < 4)
-                       mmc->host_caps &= ~MMC_MODE_4BIT;
+                       cfg->cfg.host_caps &= ~MMC_MODE_4BIT;
        }
 
        if (caps & ESDHC_HOSTCAPBLT_HSS)
-               mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+               cfg->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
 
 #ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK
        if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK)
-               mmc->host_caps &= ~MMC_MODE_8BIT;
+               cfg->cfg.host_caps &= ~MMC_MODE_8BIT;
 #endif
 
-       mmc->f_min = 400000;
-       mmc->f_max = MIN(gd->arch.sdhc_clk, 52000000);
+       cfg->cfg.f_min = 400000;
+       cfg->cfg.f_max = MIN(gd->arch.sdhc_clk, 52000000);
 
-       mmc->b_max = 0;
-       mmc_register(mmc);
+       cfg->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+
+       mmc = mmc_create(&cfg->cfg, cfg);
+       if (mmc == NULL)
+               return -1;
 
        return 0;
 }
index b1673fc917aa374d8be198f47529dedd7d0c150b..a620678e5f9e24654bf9a2399fc2d8373145a419 100644 (file)
@@ -27,6 +27,7 @@ struct ftsdc010_chip {
        uint32_t sclk;    /* FTSDC010 source clock in Hz */
        uint32_t fifo;    /* fifo depth in bytes */
        uint32_t acmd;
+       struct mmc_config cfg;  /* mmc configuration */
 };
 
 static inline int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
@@ -123,14 +124,6 @@ static void ftsdc010_clkset(struct mmc *mmc, uint32_t rate)
        }
 }
 
-static inline int ftsdc010_is_ro(struct mmc *mmc)
-{
-       struct ftsdc010_chip *chip = mmc->priv;
-       const uint8_t *csd = (const uint8_t *)mmc->csd;
-
-       return chip->wprot || (csd[1] & 0x30);
-}
-
 static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
 {
        int ret = TIMEOUT;
@@ -337,47 +330,44 @@ int ftsdc010_mmc_init(int devid)
        regs = (void __iomem *)(CONFIG_FTSDC010_BASE + (devid << 20));
 #endif
 
-       mmc = malloc(sizeof(struct mmc));
-       if (!mmc)
-               return -ENOMEM;
-       memset(mmc, 0, sizeof(struct mmc));
-
        chip = malloc(sizeof(struct ftsdc010_chip));
-       if (!chip) {
-               free(mmc);
+       if (!chip)
                return -ENOMEM;
-       }
        memset(chip, 0, sizeof(struct ftsdc010_chip));
 
        chip->regs = regs;
-       mmc->priv  = chip;
+#ifdef CONFIG_SYS_CLK_FREQ
+       chip->sclk = CONFIG_SYS_CLK_FREQ;
+#else
+       chip->sclk = clk_get_rate("SDC");
+#endif
 
-       mmc->name = "ftsdc010";
-       mmc->ops = &ftsdc010_ops;
-       mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz;
+       chip->cfg.name = "ftsdc010";
+       chip->cfg.ops = &ftsdc010_ops;
+       chip->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz;
        switch (readl(&regs->bwr) & FTSDC010_BWR_CAPS_MASK) {
        case FTSDC010_BWR_CAPS_4BIT:
-               mmc->host_caps |= MMC_MODE_4BIT;
+               chip->cfg.host_caps |= MMC_MODE_4BIT;
                break;
        case FTSDC010_BWR_CAPS_8BIT:
-               mmc->host_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
+               chip->cfg.host_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
                break;
        default:
                break;
        }
 
-#ifdef CONFIG_SYS_CLK_FREQ
-       chip->sclk = CONFIG_SYS_CLK_FREQ;
-#else
-       chip->sclk = clk_get_rate("SDC");
-#endif
+       chip->cfg.voltages  = MMC_VDD_32_33 | MMC_VDD_33_34;
+       chip->cfg.f_max     = chip->sclk / 2;
+       chip->cfg.f_min     = chip->sclk / 0x100;
 
-       mmc->voltages  = MMC_VDD_32_33 | MMC_VDD_33_34;
-       mmc->f_max     = chip->sclk / 2;
-       mmc->f_min     = chip->sclk / 0x100;
-       mmc->block_dev.part_type = PART_TYPE_DOS;
+       chip->cfg.part_type = PART_TYPE_DOS;
+       chip->cfg.b_max     = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
-       mmc_register(mmc);
+       mmc = mmc_create(&chip->cfg, chip);
+       if (mmc == NULL) {
+               free(chip);
+               return -ENOMEM;
+       }
 
        return 0;
 }
index ce799f38eeeb9d227351fade3a46473190b116ea..acca0269e585a702fd9dfac5877a0bc449ab2b27 100644 (file)
@@ -55,7 +55,7 @@ static void dump_cmd(u32 cmdr, u32 arg, u32 status, const char* msg)
 /* Setup for MCI Clock and Block Size */
 static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen)
 {
-       atmel_mci_t *mci = (atmel_mci_t *)mmc->priv;
+       atmel_mci_t *mci = mmc->priv;
        u32 bus_hz = get_mci_clk_rate();
        u32 clkdiv = 255;
 
@@ -165,7 +165,7 @@ io_fail:
 static int
 mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 {
-       atmel_mci_t *mci = (atmel_mci_t *)mmc->priv;
+       atmel_mci_t *mci = mmc->priv;
        u32 cmdr;
        u32 error_flags = 0;
        u32 status;
@@ -289,7 +289,7 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 /* Entered into mmc structure during driver init */
 static void mci_set_ios(struct mmc *mmc)
 {
-       atmel_mci_t *mci = (atmel_mci_t *)mmc->priv;
+       atmel_mci_t *mci = mmc->priv;
        int bus_width = mmc->bus_width;
        unsigned int version = atmel_mci_get_version(mci);
        int busw;
@@ -325,7 +325,7 @@ static void mci_set_ios(struct mmc *mmc)
 /* Entered into mmc structure during driver init */
 static int mci_init(struct mmc *mmc)
 {
-       atmel_mci_t *mci = (atmel_mci_t *)mmc->priv;
+       atmel_mci_t *mci = mmc->priv;
 
        /* Initialize controller */
        writel(MMCI_BIT(SWRST), &mci->cr);      /* soft reset */
@@ -357,36 +357,45 @@ static const struct mmc_ops atmel_mci_ops = {
  */
 int atmel_mci_init(void *regs)
 {
-       struct mmc *mmc = malloc(sizeof(struct mmc));
+       struct mmc *mmc;
+       struct mmc_config *cfg;
        struct atmel_mci *mci;
        unsigned int version;
 
-       if (!mmc)
+       cfg = malloc(sizeof(*cfg));
+       if (cfg == NULL)
                return -1;
+       memset(cfg, 0, sizeof(*cfg));
 
-       mmc->name = "mci";
-       mmc->priv = regs;
-       mmc->ops = &atmel_mci_ops;
+       mci = (struct atmel_mci *)regs;
+
+       cfg->name = "mci";
+       cfg->ops = &atmel_mci_ops;
 
        /* need to be able to pass these in on a board by board basis */
-       mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
-       mci = (struct atmel_mci *)mmc->priv;
+       cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
        version = atmel_mci_get_version(mci);
        if ((version & 0xf00) >= 0x300)
-               mmc->host_caps = MMC_MODE_8BIT;
+               cfg->host_caps = MMC_MODE_8BIT;
 
-       mmc->host_caps |= MMC_MODE_4BIT;
+       cfg->host_caps |= MMC_MODE_4BIT;
 
        /*
         * min and max frequencies determined by
         * max and min of clock divider
         */
-       mmc->f_min = get_mci_clk_rate() / (2*256);
-       mmc->f_max = get_mci_clk_rate() / (2*1);
+       cfg->f_min = get_mci_clk_rate() / (2*256);
+       cfg->f_max = get_mci_clk_rate() / (2*1);
+
+       cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
-       mmc->b_max = 0;
+       mmc = mmc_create(cfg, regs);
 
-       mmc_register(mmc);
+       if (mmc == NULL) {
+               free(cfg);
+               return -1;
+       }
+       /* NOTE: possibly leaking the cfg structure */
 
        return 0;
 }
index ac07bb9a2a979390fb130f4ae164e2e5fd75663e..eccdbc4b617716fea2dad4916fa5e0b3e376a79a 100644 (file)
 #include <div64.h>
 #include "mmc_private.h"
 
-/* Set block count limit because of 16 bit register limit on some hardware*/
-#ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
-#define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535
-#endif
-
 static struct list_head mmc_devices;
 static int cur_dev_num = -1;
 
@@ -37,8 +32,8 @@ int mmc_getwp(struct mmc *mmc)
        wp = board_mmc_getwp(mmc);
 
        if (wp < 0) {
-               if (mmc->ops->getwp)
-                       wp = mmc->ops->getwp(mmc);
+               if (mmc->cfg->ops->getwp)
+                       wp = mmc->cfg->ops->getwp(mmc);
                else
                        wp = 0;
        }
@@ -63,7 +58,7 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 
        printf("CMD_SEND:%d\n", cmd->cmdidx);
        printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
-       ret = mmc->ops->send_cmd(mmc, cmd, data);
+       ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
        switch (cmd->resp_type) {
                case MMC_RSP_NONE:
                        printf("\t\tMMC_RSP_NONE\n");
@@ -106,7 +101,7 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
                        break;
        }
 #else
-       ret = mmc->ops->send_cmd(mmc, cmd, data);
+       ret = mmc->cfg->ops->send_cmd(mmc, cmd, data);
 #endif
        return ret;
 }
@@ -253,7 +248,8 @@ static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
                return 0;
 
        do {
-               cur = (blocks_todo > mmc->b_max) ?  mmc->b_max : blocks_todo;
+               cur = (blocks_todo > mmc->cfg->b_max) ?
+                       mmc->cfg->b_max : blocks_todo;
                if(mmc_read_blocks(mmc, dst, start, cur) != cur)
                        return 0;
                blocks_todo -= cur;
@@ -312,7 +308,7 @@ static int sd_send_op_cond(struct mmc *mmc)
                 * specified.
                 */
                cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
-                       (mmc->voltages & 0xff8000);
+                       (mmc->cfg->voltages & 0xff8000);
 
                if (mmc->version == SD_VERSION_2)
                        cmd.cmdarg |= OCR_HCS;
@@ -361,11 +357,11 @@ static int mmc_send_op_cond_iter(struct mmc *mmc, struct mmc_cmd *cmd,
        cmd->cmdarg = 0;
        if (use_arg && !mmc_host_is_spi(mmc)) {
                cmd->cmdarg =
-                       (mmc->voltages &
+                       (mmc->cfg->voltages &
                        (mmc->op_cond_response & OCR_VOLTAGE_MASK)) |
                        (mmc->op_cond_response & OCR_ACCESS_MODE);
 
-               if (mmc->host_caps & MMC_MODE_HC)
+               if (mmc->cfg->host_caps & MMC_MODE_HC)
                        cmd->cmdarg |= OCR_HCS;
        }
        err = mmc_send_cmd(mmc, cmd, NULL);
@@ -578,8 +574,8 @@ int mmc_getcd(struct mmc *mmc)
        cd = board_mmc_getcd(mmc);
 
        if (cd < 0) {
-               if (mmc->ops->getcd)
-                       cd = mmc->ops->getcd(mmc);
+               if (mmc->cfg->ops->getcd)
+                       cd = mmc->cfg->ops->getcd(mmc);
                else
                        cd = 1;
        }
@@ -703,8 +699,8 @@ retry_scr:
         * This can avoid furthur problem when the card runs in different
         * mode between the host.
         */
-       if (!((mmc->host_caps & MMC_MODE_HS_52MHz) &&
-               (mmc->host_caps & MMC_MODE_HS)))
+       if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) &&
+               (mmc->cfg->host_caps & MMC_MODE_HS)))
                return 0;
 
        err = sd_switch(mmc, SD_SWITCH_SWITCH, 0, 1, (u8 *)switch_status);
@@ -751,17 +747,17 @@ static const int multipliers[] = {
 
 static void mmc_set_ios(struct mmc *mmc)
 {
-       if (mmc->ops->set_ios)
-               mmc->ops->set_ios(mmc);
+       if (mmc->cfg->ops->set_ios)
+               mmc->cfg->ops->set_ios(mmc);
 }
 
 void mmc_set_clock(struct mmc *mmc, uint clock)
 {
-       if (clock > mmc->f_max)
-               clock = mmc->f_max;
+       if (clock > mmc->cfg->f_max)
+               clock = mmc->cfg->f_max;
 
-       if (clock < mmc->f_min)
-               clock = mmc->f_min;
+       if (clock < mmc->cfg->f_min)
+               clock = mmc->cfg->f_min;
 
        mmc->clock = clock;
 
@@ -1027,7 +1023,7 @@ static int mmc_startup(struct mmc *mmc)
                return err;
 
        /* Restrict card's capabilities by what the host can do */
-       mmc->card_caps &= mmc->host_caps;
+       mmc->card_caps &= mmc->cfg->host_caps;
 
        if (IS_SD(mmc)) {
                if (mmc->card_caps & MMC_MODE_4BIT) {
@@ -1082,7 +1078,7 @@ static int mmc_startup(struct mmc *mmc)
                         * this bus width, if it's more than 1
                         */
                        if (extw != EXT_CSD_BUS_WIDTH_1 &&
-                                       !(mmc->host_caps & ext_to_hostcaps[extw]))
+                                       !(mmc->cfg->host_caps & ext_to_hostcaps[extw]))
                                continue;
 
                        err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
@@ -1155,7 +1151,7 @@ static int mmc_send_if_cond(struct mmc *mmc)
 
        cmd.cmdidx = SD_CMD_SEND_IF_COND;
        /* We set the bit if the host supports voltages between 2.7 and 3.6 V */
-       cmd.cmdarg = ((mmc->voltages & 0xff8000) != 0) << 8 | 0xaa;
+       cmd.cmdarg = ((mmc->cfg->voltages & 0xff8000) != 0) << 8 | 0xaa;
        cmd.resp_type = MMC_RSP_R7;
 
        err = mmc_send_cmd(mmc, &cmd, NULL);
@@ -1171,8 +1167,33 @@ static int mmc_send_if_cond(struct mmc *mmc)
        return 0;
 }
 
-int mmc_register(struct mmc *mmc)
+/* not used any more */
+int __deprecated mmc_register(struct mmc *mmc)
+{
+#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
+       printf("%s is deprecated! use mmc_create() instead.\n", __func__);
+#endif
+       return -1;
+}
+
+struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
 {
+       struct mmc *mmc;
+
+       /* quick validation */
+       if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL ||
+                       cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0)
+               return NULL;
+
+       mmc = calloc(1, sizeof(*mmc));
+       if (mmc == NULL)
+               return NULL;
+
+       mmc->cfg = cfg;
+       mmc->priv = priv;
+
+       /* the following chunk was mmc_register() */
+
        /* Setup dsr related values */
        mmc->dsr_imp = 0;
        mmc->dsr = 0xffffffff;
@@ -1183,14 +1204,21 @@ int mmc_register(struct mmc *mmc)
        mmc->block_dev.block_read = mmc_bread;
        mmc->block_dev.block_write = mmc_bwrite;
        mmc->block_dev.block_erase = mmc_berase;
-       if (!mmc->b_max)
-               mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
-       INIT_LIST_HEAD (&mmc->link);
+       /* setup initial part type */
+       mmc->block_dev.part_type = mmc->cfg->part_type;
 
-       list_add_tail (&mmc->link, &mmc_devices);
+       INIT_LIST_HEAD(&mmc->link);
 
-       return 0;
+       list_add_tail(&mmc->link, &mmc_devices);
+
+       return mmc;
+}
+
+void mmc_destroy(struct mmc *mmc)
+{
+       /* only freeing memory for now */
+       free(mmc);
 }
 
 #ifdef CONFIG_PARTITIONS
@@ -1209,7 +1237,7 @@ int mmc_start_init(struct mmc *mmc)
        int err;
 
        /* we pretend there's no card when init is NULL */
-       if (mmc_getcd(mmc) == 0 || mmc->ops->init == NULL) {
+       if (mmc_getcd(mmc) == 0 || mmc->cfg->ops->init == NULL) {
                mmc->has_init = 0;
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
                printf("MMC: no card present\n");
@@ -1221,7 +1249,7 @@ int mmc_start_init(struct mmc *mmc)
                return 0;
 
        /* made sure it's not NULL earlier */
-       err = mmc->ops->init(mmc);
+       err = mmc->cfg->ops->init(mmc);
 
        if (err)
                return err;
@@ -1323,7 +1351,7 @@ void print_mmc_devices(char separator)
        list_for_each(entry, &mmc_devices) {
                m = list_entry(entry, struct mmc, link);
 
-               printf("%s: %d", m->name, m->block_dev.dev);
+               printf("%s: %d", m->cfg->name, m->block_dev.dev);
 
                if (entry->next != &mmc_devices)
                        printf("%c ", separator);
index e94de37c8b44b99864b77a5afca34b9553353a99..5b5b33a4b23d293a0afcf79345e98102fc8d1e7b 100644 (file)
@@ -92,7 +92,7 @@ static uint mmc_spi_readdata(struct mmc *mmc, void *xbuf,
                        spi_xfer(spi, 2 * 8, NULL, &crc, 0);
 #ifdef CONFIG_MMC_SPI_CRC_ON
                        if (swab16(cyg_crc16(buf, bsize)) != crc) {
-                               debug("%s: CRC error\n", mmc->name);
+                               debug("%s: CRC error\n", mmc->cfg->name);
                                r1 = R1_SPI_COM_CRC;
                                break;
                        }
@@ -238,6 +238,7 @@ done:
 static void mmc_spi_set_ios(struct mmc *mmc)
 {
        struct spi_slave *spi = mmc->priv;
+
        debug("%s: clock %u\n", __func__, mmc->clock);
        if (mmc->clock)
                spi_set_speed(spi, mmc->clock);
@@ -246,7 +247,6 @@ static void mmc_spi_set_ios(struct mmc *mmc)
 static int mmc_spi_init_p(struct mmc *mmc)
 {
        struct spi_slave *spi = mmc->priv;
-       mmc->clock = 0;
        spi_set_speed(spi, MMC_SPI_MIN_CLOCK);
        spi_claim_bus(spi);
        /* cs deactivated for 100+ clock */
@@ -261,29 +261,31 @@ static const struct mmc_ops mmc_spi_ops = {
        .init           = mmc_spi_init_p,
 };
 
+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,
+};
+
 struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode)
 {
        struct mmc *mmc;
+       struct spi_slave *spi;
 
-       mmc = malloc(sizeof(*mmc));
-       if (!mmc)
-               return NULL;
-       memset(mmc, 0, sizeof(*mmc));
-       mmc->priv = spi_setup_slave(bus, cs, speed, mode);
-       if (!mmc->priv) {
-               free(mmc);
+       spi = spi_setup_slave(bus, cs, speed, mode);
+       if (spi == NULL)
                return NULL;
-       }
-       mmc->name = "MMC_SPI";
-       mmc->ops = &mmc_spi_ops;
-       mmc->host_caps = MMC_MODE_SPI;
-
-       mmc->voltages = MMC_SPI_VOLTAGE;
-       mmc->f_max = speed;
-       mmc->f_min = MMC_SPI_MIN_CLOCK;
-       mmc->block_dev.part_type = PART_TYPE_DOS;
 
-       mmc_register(mmc);
+       mmc_spi_cfg.f_max = speed;
 
+       mmc = mmc_create(&mmc_spi_cfg, spi);
+       if (mmc == NULL) {
+               spi_free_slave(spi);
+               return NULL;
+       }
        return mmc;
 }
index aa2fdefa75edeb39540954ae40cf73a841f5870a..3db9669c82eee981ba861baf315fa95e144c9597 100644 (file)
@@ -167,7 +167,8 @@ ulong mmc_bwrite(int dev_num, lbaint_t start, lbaint_t blkcnt, const void *src)
                return 0;
 
        do {
-               cur = (blocks_todo > mmc->b_max) ?  mmc->b_max : blocks_todo;
+               cur = (blocks_todo > mmc->cfg->b_max) ?
+                       mmc->cfg->b_max : blocks_todo;
                if (mmc_write_blocks(mmc, start, cur, src) != cur)
                        return 0;
                blocks_todo -= cur;
index 335755998180b8fb2f052b33fcb141174c056a02..561b2045986f5858bcc1f90b0398831dfa32f079 100644 (file)
@@ -122,6 +122,8 @@ struct mxcmci_host {
 };
 
 static struct mxcmci_host mxcmci_host;
+
+/* maintainer note: do we really want to have a global host pointer? */
 static struct mxcmci_host *host = &mxcmci_host;
 
 static inline int mxcmci_use_dma(struct mxcmci_host *host)
@@ -491,31 +493,24 @@ static const struct mmc_ops mxcmci_ops = {
        .init           = mxcmci_init,
 };
 
+static struct mmc_config mxcmci_cfg = {
+       .name           = "MXC MCI",
+       .ops            = &mxcmci_ops,
+       .host_caps      = MMC_MODE_4BIT,
+       .voltages       = MMC_VDD_32_33 | MMC_VDD_33_34,
+       .b_max          = CONFIG_SYS_MMC_MAX_BLK_COUNT,
+};
+
 static int mxcmci_initialize(bd_t *bis)
 {
-       struct mmc *mmc = NULL;
-
-       mmc = malloc(sizeof(struct mmc));
-
-       if (!mmc)
-               return -ENOMEM;
-
-       mmc->name = "MXC MCI";
-       mmc->ops = &mxcmci_ops;
-       mmc->host_caps = MMC_MODE_4BIT;
-
        host->base = (struct mxcmci_regs *)CONFIG_MXC_MCI_REGS_BASE;
-       mmc->priv = host;
-       host->mmc = mmc;
-
-       mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
-
-       mmc->f_min = mxc_get_clock(MXC_ESDHC_CLK) >> 7;
-       mmc->f_max = mxc_get_clock(MXC_ESDHC_CLK) >> 1;
 
-       mmc->b_max = 0;
+       mxcmci_cfg.f_min = mxc_get_clock(MXC_ESDHC_CLK) >> 7;
+       mxcmci_cfg.f_max = mxc_get_clock(MXC_ESDHC_CLK) >> 1;
 
-       mmc_register(mmc);
+       host->mmc = mmc_create(&mxcmci_cfg, host);
+       if (host->mmc == NULL)
+               return -1;
 
        return 0;
 }
index 3512a99de9f55392f51a6a78f4946c6950a65d70..2fa4eeef441f16b552e0742571dd6c625cf85cd5 100644 (file)
@@ -35,6 +35,7 @@ struct mxsmmc_priv {
        int                     (*mmc_is_wp)(int);
        int                     (*mmc_cd)(int);
        struct mxs_dma_desc     *desc;
+       struct mmc_config       cfg;    /* mmc configuration */
 };
 
 #define        MXSMMC_MAX_TIMEOUT      10000
@@ -134,7 +135,7 @@ static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data)
 static int
 mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 {
-       struct mxsmmc_priv *priv = (struct mxsmmc_priv *)mmc->priv;
+       struct mxsmmc_priv *priv = mmc->priv;
        struct mxs_ssp_regs *ssp_regs = priv->regs;
        uint32_t reg;
        int timeout;
@@ -305,7 +306,7 @@ mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 
 static void mxsmmc_set_ios(struct mmc *mmc)
 {
-       struct mxsmmc_priv *priv = (struct mxsmmc_priv *)mmc->priv;
+       struct mxsmmc_priv *priv = mmc->priv;
        struct mxs_ssp_regs *ssp_regs = priv->regs;
 
        /* Set the clock speed */
@@ -334,7 +335,7 @@ static void mxsmmc_set_ios(struct mmc *mmc)
 
 static int mxsmmc_init(struct mmc *mmc)
 {
-       struct mxsmmc_priv *priv = (struct mxsmmc_priv *)mmc->priv;
+       struct mxsmmc_priv *priv = mmc->priv;
        struct mxs_ssp_regs *ssp_regs = priv->regs;
 
        /* Reset SSP */
@@ -379,20 +380,13 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int))
        if (!mxs_ssp_bus_id_valid(id))
                return -ENODEV;
 
-       mmc = malloc(sizeof(struct mmc));
-       if (!mmc)
-               return -ENOMEM;
-
        priv = malloc(sizeof(struct mxsmmc_priv));
-       if (!priv) {
-               free(mmc);
+       if (!priv)
                return -ENOMEM;
-       }
 
        priv->desc = mxs_dma_desc_alloc();
        if (!priv->desc) {
                free(priv);
-               free(mmc);
                return -ENOMEM;
        }
 
@@ -405,13 +399,12 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int))
        priv->id = id;
        priv->regs = mxs_ssp_regs_by_bus(id);
 
-       mmc->name = "MXS MMC";
-       mmc->ops = &mxsmmc_ops;
-       mmc->priv = priv;
+       priv->cfg.name = "MXS MMC";
+       priv->cfg.ops = &mxsmmc_ops;
 
-       mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
+       priv->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 
-       mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT |
+       priv->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT |
                         MMC_MODE_HS_52MHz | MMC_MODE_HS |
                         MMC_MODE_HC;
 
@@ -421,10 +414,15 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int))
         * CLOCK_DIVIDE has to be an even value from 2 to 254, and
         * CLOCK_RATE could be any integer from 0 to 255.
         */
-       mmc->f_min = 400000;
-       mmc->f_max = mxc_get_clock(MXC_SSP0_CLK + mxsmmc_clk_id) * 1000 / 2;
-       mmc->b_max = 0x20;
+       priv->cfg.f_min = 400000;
+       priv->cfg.f_max = mxc_get_clock(MXC_SSP0_CLK + mxsmmc_clk_id) * 1000 / 2;
+       priv->cfg.b_max = 0x20;
 
-       mmc_register(mmc);
+       mmc = mmc_create(&priv->cfg, priv);
+       if (mmc == NULL) {
+               mxs_dma_desc_free(priv->desc);
+               free(priv);
+               return -ENOMEM;
+       }
        return 0;
 }
index fecac5698bf017c1fcf2370d2970680999c80f34..17cbb0983db37f0e976b7fbd12bc208a70eabfbc 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <config.h>
 #include <common.h>
+#include <malloc.h>
 #include <mmc.h>
 #include <part.h>
 #include <i2c.h>
@@ -49,6 +50,7 @@
 
 struct omap_hsmmc_data {
        struct hsmmc *base_addr;
+       struct mmc_config cfg;
 #ifdef OMAP_HSMMC_USE_GPIO
        int cd_gpio;
        int wp_gpio;
@@ -61,8 +63,6 @@ struct omap_hsmmc_data {
 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 struct mmc hsmmc_dev[3];
-static struct omap_hsmmc_data hsmmc_dev_data[3];
 
 #ifdef OMAP_HSMMC_USE_GPIO
 static int omap_mmc_setup_gpio_in(int gpio, const char *label)
@@ -147,7 +147,7 @@ unsigned char mmc_board_init(struct mmc *mmc)
                &t2_base->devconf1);
 
        /* Change from default of 52MHz to 26MHz if necessary */
-       if (!(mmc->host_caps & MMC_MODE_HS_52MHz))
+       if (!(mmc->cfg->host_caps & MMC_MODE_HS_52MHz))
                writel(readl(&t2_base->ctl_prog_io1) & ~CTLPROGIO1SPEEDCTRL,
                        &t2_base->ctl_prog_io1);
 
@@ -636,14 +636,17 @@ static const struct mmc_ops omap_hsmmc_ops = {
 int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
                int wp_gpio)
 {
-       struct mmc *mmc = &hsmmc_dev[dev_index];
-       struct omap_hsmmc_data *priv_data = &hsmmc_dev_data[dev_index];
-       uint host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
-                            MMC_MODE_HC;
+       struct mmc *mmc;
+       struct omap_hsmmc_data *priv_data;
+       struct mmc_config *cfg;
+       uint host_caps_val;
+
+       priv_data = malloc(sizeof(*priv_data));
+       if (priv_data == NULL)
+               return -1;
 
-       mmc->name = "OMAP SD/MMC";
-       mmc->ops = &omap_hsmmc_ops;
-       mmc->priv = priv_data;
+       host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
+                            MMC_MODE_HC;
 
        switch (dev_index) {
        case 0:
@@ -678,34 +681,40 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
        priv_data->wp_gpio = omap_mmc_setup_gpio_in(wp_gpio, "mmc_wp");
 #endif
 
-       mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
-       mmc->host_caps = host_caps_val & ~host_caps_mask;
+       cfg = &priv_data->cfg;
 
-       mmc->f_min = 400000;
+       cfg->name = "OMAP SD/MMC";
+       cfg->ops = &omap_hsmmc_ops;
+
+       cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+       cfg->host_caps = host_caps_val & ~host_caps_mask;
+
+       cfg->f_min = 400000;
 
        if (f_max != 0)
-               mmc->f_max = f_max;
+               cfg->f_max = f_max;
        else {
-               if (mmc->host_caps & MMC_MODE_HS) {
-                       if (mmc->host_caps & MMC_MODE_HS_52MHz)
-                               mmc->f_max = 52000000;
+               if (cfg->host_caps & MMC_MODE_HS) {
+                       if (cfg->host_caps & MMC_MODE_HS_52MHz)
+                               cfg->f_max = 52000000;
                        else
-                               mmc->f_max = 26000000;
+                               cfg->f_max = 26000000;
                } else
-                       mmc->f_max = 20000000;
+                       cfg->f_max = 20000000;
        }
 
-       mmc->b_max = 0;
+       cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
 #if defined(CONFIG_OMAP34XX)
        /*
         * Silicon revs 2.1 and older do not support multiblock transfers.
         */
        if ((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() <= CPU_3XX_ES21))
-               mmc->b_max = 1;
+               cfg->b_max = 1;
 #endif
-
-       mmc_register(mmc);
+       mmc = mmc_create(cfg, priv_data);
+       if (mmc == NULL)
+               return -1;
 
        return 0;
 }
index 188e1d4c6b0163a84e8f50f5f278cc517318ce55..1f297571e563c7c69bf653f574c890ea916ac69b 100644 (file)
@@ -52,7 +52,7 @@ struct pxa_mmc_priv {
 /* Wait for bit to be set */
 static int pxa_mmc_wait(struct mmc *mmc, uint32_t mask)
 {
-       struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
+       struct pxa_mmc_priv *priv = mmc->priv;
        struct pxa_mmc_regs *regs = priv->regs;
        unsigned int timeout = PXA_MMC_TIMEOUT;
 
@@ -71,7 +71,7 @@ static int pxa_mmc_wait(struct mmc *mmc, uint32_t mask)
 
 static int pxa_mmc_stop_clock(struct mmc *mmc)
 {
-       struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
+       struct pxa_mmc_priv *priv = mmc->priv;
        struct pxa_mmc_regs *regs = priv->regs;
        unsigned int timeout = PXA_MMC_TIMEOUT;
 
@@ -100,7 +100,7 @@ static int pxa_mmc_stop_clock(struct mmc *mmc)
 static int pxa_mmc_start_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                                uint32_t cmdat)
 {
-       struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
+       struct pxa_mmc_priv *priv = mmc->priv;
        struct pxa_mmc_regs *regs = priv->regs;
        int ret;
 
@@ -143,7 +143,7 @@ static int pxa_mmc_start_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 
 static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd)
 {
-       struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
+       struct pxa_mmc_priv *priv = mmc->priv;
        struct pxa_mmc_regs *regs = priv->regs;
        uint32_t a, b, c;
        int i;
@@ -185,7 +185,7 @@ static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd)
 
 static int pxa_mmc_do_read_xfer(struct mmc *mmc, struct mmc_data *data)
 {
-       struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
+       struct pxa_mmc_priv *priv = mmc->priv;
        struct pxa_mmc_regs *regs = priv->regs;
        uint32_t len;
        uint32_t *buf = (uint32_t *)data->dest;
@@ -221,7 +221,7 @@ static int pxa_mmc_do_read_xfer(struct mmc *mmc, struct mmc_data *data)
 
 static int pxa_mmc_do_write_xfer(struct mmc *mmc, struct mmc_data *data)
 {
-       struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
+       struct pxa_mmc_priv *priv = mmc->priv;
        struct pxa_mmc_regs *regs = priv->regs;
        uint32_t len;
        uint32_t *buf = (uint32_t *)data->src;
@@ -264,7 +264,7 @@ static int pxa_mmc_do_write_xfer(struct mmc *mmc, struct mmc_data *data)
 static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd,
                                struct mmc_data *data)
 {
-       struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
+       struct pxa_mmc_priv *priv = mmc->priv;
        struct pxa_mmc_regs *regs = priv->regs;
        uint32_t cmdat = 0;
        int ret;
@@ -317,7 +317,7 @@ static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd,
 
 static void pxa_mmc_set_ios(struct mmc *mmc)
 {
-       struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
+       struct pxa_mmc_priv *priv = mmc->priv;
        struct pxa_mmc_regs *regs = priv->regs;
        uint32_t tmp;
        uint32_t pxa_mmc_clock;
@@ -335,7 +335,7 @@ static void pxa_mmc_set_ios(struct mmc *mmc)
 
        /* Set clock to the card the usual way. */
        pxa_mmc_clock = 0;
-       tmp = mmc->f_max / mmc->clock;
+       tmp = mmc->cfg->f_max / mmc->clock;
        tmp += tmp % 2;
 
        while (tmp > 1) {
@@ -348,7 +348,7 @@ static void pxa_mmc_set_ios(struct mmc *mmc)
 
 static int pxa_mmc_init(struct mmc *mmc)
 {
-       struct pxa_mmc_priv *priv = (struct pxa_mmc_priv *)mmc->priv;
+       struct pxa_mmc_priv *priv = mmc->priv;
        struct pxa_mmc_regs *regs = priv->regs;
 
        /* Make sure the clock are stopped */
@@ -372,6 +372,16 @@ static const struct mmc_ops pxa_mmc_ops = {
        .init           = pxa_mmc_init,
 };
 
+static struct mmc_config pxa_mmc_cfg = {
+       .name           = "PXA MMC",
+       .ops            = &pxa_mmc_ops,
+       .voltages       = MMC_VDD_32_33 | MMC_VDD_33_34,
+       .f_max          = PXAMMC_MAX_SPEED,
+       .f_min          = PXAMMC_MIN_SPEED,
+       .host_caps      = PXAMMC_HOST_CAPS,
+       .b_max          = CONFIG_SYS_MMC_MAX_BLK_COUNT,
+};
+
 int pxa_mmc_register(int card_index)
 {
        struct mmc *mmc;
@@ -379,13 +389,11 @@ int pxa_mmc_register(int card_index)
        uint32_t reg;
        int ret = -ENOMEM;
 
-       mmc = malloc(sizeof(struct mmc));
-       if (!mmc)
-               goto err0;
-
        priv = malloc(sizeof(struct pxa_mmc_priv));
        if (!priv)
-               goto err1;
+               goto err0;
+
+       memset(priv, 0, sizeof(*priv));
 
        switch (card_index) {
        case 0:
@@ -395,23 +403,12 @@ int pxa_mmc_register(int card_index)
                priv->regs = (struct pxa_mmc_regs *)MMC1_BASE;
                break;
        default:
+               ret = -EINVAL;
                printf("PXA MMC: Invalid MMC controller ID (card_index = %d)\n",
                        card_index);
-               goto err2;
+               goto err1;
        }
 
-       mmc->priv = priv;
-
-       mmc->name = "PXA MMC";
-       mmc->ops = &pxa_mmc_ops;
-
-       mmc->voltages   = MMC_VDD_32_33 | MMC_VDD_33_34;
-       mmc->f_max      = PXAMMC_MAX_SPEED;
-       mmc->f_min      = PXAMMC_MIN_SPEED;
-       mmc->host_caps  = PXAMMC_HOST_CAPS;
-
-       mmc->b_max = 0;
-
 #ifndef        CONFIG_CPU_MONAHANS     /* PXA2xx */
        reg = readl(CKEN);
        reg |= CKEN12_MMC;
@@ -422,14 +419,14 @@ int pxa_mmc_register(int card_index)
        writel(reg, CKENA);
 #endif
 
-       mmc_register(mmc);
+       mmc = mmc_create(&pxa_mmc_cfg, priv);
+       if (mmc == NULL)
+               goto err1;
 
        return 0;
 
-err2:
-       free(priv);
 err1:
-       free(mmc);
+       free(priv);
 err0:
        return ret;
 }
index dc6f4e4972b9bb74f8d30085fe0f2b42334a83cf..3125d13ba3ce8e8e2552248e41c059bd31e5fb3c 100644 (file)
@@ -127,7 +127,7 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
 int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
                       struct mmc_data *data)
 {
-       struct sdhci_host *host = (struct sdhci_host *)mmc->priv;
+       struct sdhci_host *host = mmc->priv;
        unsigned int stat = 0;
        int ret = 0;
        int trans_bytes = 0, is_aligned = 1;
@@ -268,7 +268,7 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
 
 static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
 {
-       struct sdhci_host *host = (struct sdhci_host *)mmc->priv;
+       struct sdhci_host *host = mmc->priv;
        unsigned int div, clk, timeout;
 
        sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
@@ -278,18 +278,18 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
 
        if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
                /* Version 3.00 divisors must be a multiple of 2. */
-               if (mmc->f_max <= clock)
+               if (mmc->cfg->f_max <= clock)
                        div = 1;
                else {
                        for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) {
-                               if ((mmc->f_max / div) <= clock)
+                               if ((mmc->cfg->f_max / div) <= clock)
                                        break;
                        }
                }
        } else {
                /* Version 2.00 divisors must be a power of 2. */
                for (div = 1; div < SDHCI_MAX_DIV_SPEC_200; div *= 2) {
-                       if ((mmc->f_max / div) <= clock)
+                       if ((mmc->cfg->f_max / div) <= clock)
                                break;
                }
        }
@@ -358,7 +358,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
 void sdhci_set_ios(struct mmc *mmc)
 {
        u32 ctrl;
-       struct sdhci_host *host = (struct sdhci_host *)mmc->priv;
+       struct sdhci_host *host = mmc->priv;
 
        if (host->set_control_reg)
                host->set_control_reg(host);
@@ -395,7 +395,7 @@ void sdhci_set_ios(struct mmc *mmc)
 
 int sdhci_init(struct mmc *mmc)
 {
-       struct sdhci_host *host = (struct sdhci_host *)mmc->priv;
+       struct sdhci_host *host = mmc->priv;
 
        if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && !aligned_buffer) {
                aligned_buffer = memalign(8, 512*1024);
@@ -406,7 +406,7 @@ int sdhci_init(struct mmc *mmc)
                }
        }
 
-       sdhci_set_power(host, fls(mmc->voltages) - 1);
+       sdhci_set_power(host, fls(mmc->cfg->voltages) - 1);
 
        if (host->quirks & SDHCI_QUIRK_NO_CD) {
                unsigned int status;
@@ -439,20 +439,10 @@ static const struct mmc_ops sdhci_ops = {
 
 int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
 {
-       struct mmc *mmc;
        unsigned int caps;
 
-       mmc = malloc(sizeof(struct mmc));
-       if (!mmc) {
-               printf("%s: mmc malloc fail!\n", __func__);
-               return -1;
-       }
-
-       mmc->priv = host;
-       host->mmc = mmc;
-
-       mmc->name = host->name;
-       mmc->ops = &sdhci_ops;
+       host->cfg.name = host->name;
+       host->cfg.ops = &sdhci_ops;
 
        caps = sdhci_readl(host, SDHCI_CAPABILITIES);
 #ifdef CONFIG_MMC_SDMA
@@ -464,51 +454,60 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
 #endif
 
        if (max_clk)
-               mmc->f_max = max_clk;
+               host->cfg.f_max = max_clk;
        else {
                if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
-                       mmc->f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK)
+                       host->cfg.f_max = (caps & SDHCI_CLOCK_V3_BASE_MASK)
                                >> SDHCI_CLOCK_BASE_SHIFT;
                else
-                       mmc->f_max = (caps & SDHCI_CLOCK_BASE_MASK)
+                       host->cfg.f_max = (caps & SDHCI_CLOCK_BASE_MASK)
                                >> SDHCI_CLOCK_BASE_SHIFT;
-               mmc->f_max *= 1000000;
+               host->cfg.f_max *= 1000000;
        }
-       if (mmc->f_max == 0) {
+       if (host->cfg.f_max == 0) {
                printf("%s: Hardware doesn't specify base clock frequency\n",
                       __func__);
                return -1;
        }
        if (min_clk)
-               mmc->f_min = min_clk;
+               host->cfg.f_min = min_clk;
        else {
                if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
-                       mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_300;
+                       host->cfg.f_min = host->cfg.f_max /
+                               SDHCI_MAX_DIV_SPEC_300;
                else
-                       mmc->f_min = mmc->f_max / SDHCI_MAX_DIV_SPEC_200;
+                       host->cfg.f_min = host->cfg.f_max /
+                               SDHCI_MAX_DIV_SPEC_200;
        }
 
-       mmc->voltages = 0;
+       host->cfg.voltages = 0;
        if (caps & SDHCI_CAN_VDD_330)
-               mmc->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;
+               host->cfg.voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;
        if (caps & SDHCI_CAN_VDD_300)
-               mmc->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
+               host->cfg.voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
        if (caps & SDHCI_CAN_VDD_180)
-               mmc->voltages |= MMC_VDD_165_195;
+               host->cfg.voltages |= MMC_VDD_165_195;
 
        if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE)
-               mmc->voltages |= host->voltages;
+               host->cfg.voltages |= host->voltages;
 
-       mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
+       host->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
        if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
                if (caps & SDHCI_CAN_DO_8BIT)
-                       mmc->host_caps |= MMC_MODE_8BIT;
+                       host->cfg.host_caps |= MMC_MODE_8BIT;
        }
        if (host->host_caps)
-               mmc->host_caps |= host->host_caps;
+               host->cfg.host_caps |= host->host_caps;
+
+       host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
        sdhci_reset(host, SDHCI_RESET_ALL);
-       mmc_register(mmc);
+
+       host->mmc = mmc_create(&host->cfg, host);
+       if (host->mmc == NULL) {
+               printf("%s: mmc create fail!\n", __func__);
+               return -1;
+       }
 
        return 0;
 }
index 008617d5e6931ce17c60a72918dfbeb3184a8282..64b5b472616b828ccf2d3743d42666337ec6585d 100644 (file)
 
 #define DRIVER_NAME    "sh_mmcif"
 
-static void *mmc_priv(struct mmc *mmc)
-{
-       return (void *)mmc->priv;
-}
-
 static int sh_mmcif_intr(void *dev_id)
 {
        struct sh_mmcif_host *host = dev_id;
@@ -522,7 +517,7 @@ static int sh_mmcif_start_cmd(struct sh_mmcif_host *host,
 static int sh_mmcif_request(struct mmc *mmc, struct mmc_cmd *cmd,
                            struct mmc_data *data)
 {
-       struct sh_mmcif_host *host = mmc_priv(mmc);
+       struct sh_mmcif_host *host = mmc->priv;
        int ret;
 
        WATCHDOG_RESET();
@@ -550,7 +545,7 @@ static int sh_mmcif_request(struct mmc *mmc, struct mmc_cmd *cmd,
 
 static void sh_mmcif_set_ios(struct mmc *mmc)
 {
-       struct sh_mmcif_host *host = mmc_priv(mmc);
+       struct sh_mmcif_host *host = mmc->priv;
 
        if (mmc->clock)
                sh_mmcif_clock_control(host, mmc->clock);
@@ -567,7 +562,7 @@ static void sh_mmcif_set_ios(struct mmc *mmc)
 
 static int sh_mmcif_init(struct mmc *mmc)
 {
-       struct sh_mmcif_host *host = mmc_priv(mmc);
+       struct sh_mmcif_host *host = mmc->priv;
 
        sh_mmcif_sync_reset(host);
        sh_mmcif_write(MASK_ALL, &host->regs->ce_int_mask);
@@ -580,33 +575,36 @@ static const struct mmc_ops sh_mmcif_ops = {
        .init           = sh_mmcif_init,
 };
 
+static struct mmc_config sh_mmcif_cfg = {
+       .name           = DRIVER_NAME,
+       .ops            = &sh_mmcif_ops,
+       .host_caps      = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT |
+                         MMC_MODE_8BIT | MMC_MODE_HC,
+       .voltages       = MMC_VDD_32_33 | MMC_VDD_33_34;
+       .f_min          = CLKDEV_MMC_INIT,
+       .f_max          = CLKDEV_EMMC_DATA,
+       .b_max          = CONFIG_SYS_MMC_MAX_BLK_COUNT,
+};
+
 int mmcif_mmc_init(void)
 {
        int ret = 0;
        struct mmc *mmc;
        struct sh_mmcif_host *host = NULL;
 
-       mmc = malloc(sizeof(struct mmc));
-       if (!mmc)
-               ret = -ENOMEM;
-       memset(mmc, 0, sizeof(*mmc));
        host = malloc(sizeof(struct sh_mmcif_host));
        if (!host)
                ret = -ENOMEM;
        memset(host, 0, sizeof(*host));
 
-       mmc->f_min = CLKDEV_MMC_INIT;
-       mmc->f_max = CLKDEV_EMMC_DATA;
-       mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
-       mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT |
-                        MMC_MODE_8BIT | MMC_MODE_HC;
-       mmc->name = DRIVER_NAME;
-       mmc->ops = &sh_mmcif_ops;
        host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR;
        host->clk = CONFIG_SH_MMCIF_CLK;
-       mmc->priv = host;
 
-       mmc_register(mmc);
+       mmc = mmc_create(&sh_mmcif_cfg, host);
+       if (mmc == NULL) {
+               free(host);
+               return -ENOMEM;
+       }
 
-       return ret;
+       return 0;
 }
index e8fbb63f2988f7c470ee8bc1403e6b34bddebbdc..ed67eec2527347740ea731153e368876e56e28f5 100644 (file)
@@ -18,7 +18,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-struct mmc mmc_dev[MAX_HOSTS];
 struct mmc_host mmc_host[MAX_HOSTS];
 
 #ifndef CONFIG_OF_CONTROL
@@ -145,7 +144,7 @@ static int mmc_wait_inhibit(struct mmc_host *host,
 static int mmc_send_cmd_bounced(struct mmc *mmc, struct mmc_cmd *cmd,
                        struct mmc_data *data, struct bounce_buffer *bbstate)
 {
-       struct mmc_host *host = (struct mmc_host *)mmc->priv;
+       struct mmc_host *host = mmc->priv;
        int flags, i;
        int result;
        unsigned int mask = 0;
@@ -456,7 +455,7 @@ static void mmc_reset(struct mmc_host *host, struct mmc *mmc)
        }
 
        /* Set SD bus voltage & enable bus power */
-       mmc_set_power(host, fls(mmc->voltages) - 1);
+       mmc_set_power(host, fls(mmc->cfg->voltages) - 1);
        debug("%s: power control = %02X, host control = %02X\n", __func__,
                readb(&host->reg->pwrcon), readb(&host->reg->hostctl));
 
@@ -466,7 +465,7 @@ static void mmc_reset(struct mmc_host *host, struct mmc *mmc)
 
 static int tegra_mmc_core_init(struct mmc *mmc)
 {
-       struct mmc_host *host = (struct mmc_host *)mmc->priv;
+       struct mmc_host *host = mmc->priv;
        unsigned int mask;
        debug(" mmc_core_init called\n");
 
@@ -511,7 +510,7 @@ static int tegra_mmc_core_init(struct mmc *mmc)
 
 int tegra_mmc_getcd(struct mmc *mmc)
 {
-       struct mmc_host *host = (struct mmc_host *)mmc->priv;
+       struct mmc_host *host = mmc->priv;
 
        debug("tegra_mmc_getcd called\n");
 
@@ -561,19 +560,18 @@ static int do_mmc_init(int dev_index)
                debug(" CD GPIO name = %s\n", host->cd_gpio.name);
        }
 
-       mmc = &mmc_dev[dev_index];
+       memset(&host->cfg, 0, sizeof(host->cfg));
 
-       mmc->name = "Tegra SD/MMC";
-       mmc->priv = host;
-       mmc->ops = &tegra_mmc_ops;
+       host->cfg.name = "Tegra SD/MMC";
+       host->cfg.ops = &tegra_mmc_ops;
 
-       mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
-       mmc->host_caps = 0;
+       host->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+       host->cfg.host_caps = 0;
        if (host->width == 8)
-               mmc->host_caps |= MMC_MODE_8BIT;
+               host->cfg.host_caps |= MMC_MODE_8BIT;
        if (host->width >= 4)
-               mmc->host_caps |= MMC_MODE_4BIT;
-       mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC;
+               host->cfg.host_caps |= MMC_MODE_4BIT;
+       host->cfg.host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC;
 
        /*
         * min freq is for card identification, and is the highest
@@ -581,10 +579,14 @@ static int do_mmc_init(int dev_index)
         * max freq is highest HS eMMC clock as per the SD/MMC spec
         *  (actually 52MHz)
         */
-       mmc->f_min = 375000;
-       mmc->f_max = 48000000;
+       host->cfg.f_min = 375000;
+       host->cfg.f_max = 48000000;
 
-       mmc_register(mmc);
+       host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+
+       mmc = mmc_create(&host->cfg, host);
+       if (mmc == NULL)
+               return -1;
 
        return 0;
 }
index b64155851d6491a5093068848c8fe5627d62e363..c9bdf51a6718fd7638f4168f324d6592bc63febb 100644 (file)
@@ -143,6 +143,8 @@ struct dwmci_host {
        void (*clksel)(struct dwmci_host *host);
        void (*board_init)(struct dwmci_host *host);
        unsigned int (*get_mmc_clk)(struct dwmci_host *host);
+
+       struct mmc_config cfg;
 };
 
 struct dwmci_idmac {
index 89bcbd1700ac7b62d4fcc06304177a176180aef3..a6e3a5dc9af395c364d95698315042d5bccd9d9a 100644 (file)
@@ -13,6 +13,9 @@
 #include <asm/errno.h>
 #include <asm/byteorder.h>
 
+/* needed for the mmc_cfg definition */
+#include <mmc.h>
+
 /* FSL eSDHC-specific constants */
 #define SYSCTL                 0x0002e02c
 #define SYSCTL_INITA           0x08000000
@@ -155,6 +158,7 @@ struct fsl_esdhc_cfg {
        u32     esdhc_base;
        u32     sdhc_clk;
        u8      max_bus_width;
+       struct mmc_config cfg;
 };
 
 /* Select the correct accessors depending on endianess */
index 6b08c62a51d2f684136ccf885ebec1870eda4aa7..0172979f1154c96ba3769a65f529a0df92e7807c 100644 (file)
@@ -262,20 +262,28 @@ struct mmc_ops {
        int (*getwp)(struct mmc *mmc);
 };
 
+struct mmc_config {
+       const char *name;
+       const struct mmc_ops *ops;
+       uint host_caps;
+       uint voltages;
+       uint f_min;
+       uint f_max;
+       uint b_max;
+       unsigned char part_type;
+};
+
+/* TODO struct mmc should be in mmc_private but it's hard to fix right now */
 struct mmc {
        struct list_head link;
-       const char *name;       /* no need for this to be an array */
-       void *priv;
-       uint voltages;
+       const struct mmc_config *cfg;   /* provided configuration */
        uint version;
+       void *priv;
        uint has_init;
-       uint f_min;
-       uint f_max;
        int high_capacity;
        uint bus_width;
        uint clock;
        uint card_caps;
-       uint host_caps;
        uint ocr;
        uint dsr;
        uint dsr_imp;
@@ -295,8 +303,6 @@ struct mmc {
        u64 capacity_rpmb;
        u64 capacity_gp[4];
        block_dev_desc_t block_dev;
-       const struct mmc_ops *ops;
-       uint b_max;
        char op_cond_pending;   /* 1 if we are waiting on an op_cond command */
        char init_in_progress;  /* 1 if we have done mmc_start_init() */
        char preinit;           /* start init as early as possible */
@@ -304,6 +310,8 @@ struct mmc {
 };
 
 int mmc_register(struct mmc *mmc);
+struct mmc *mmc_create(const struct mmc_config *cfg, void *priv);
+void mmc_destroy(struct mmc *mmc);
 int mmc_initialize(bd_t *bis);
 int mmc_init(struct mmc *mmc);
 int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
@@ -352,7 +360,7 @@ void mmc_set_preinit(struct mmc *mmc, int preinit);
 
 #ifdef CONFIG_GENERIC_MMC
 #ifdef CONFIG_MMC_SPI
-#define mmc_host_is_spi(mmc)   ((mmc)->host_caps & MMC_MODE_SPI)
+#define mmc_host_is_spi(mmc)   ((mmc)->cfg.host_caps & MMC_MODE_SPI)
 #else
 #define mmc_host_is_spi(mmc)   0
 #endif
@@ -361,4 +369,9 @@ struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
 int mmc_legacy_init(int verbose);
 #endif
 
+/* Set block count limit because of 16 bit register limit on some hardware*/
+#ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
+#define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535
+#endif
+
 #endif /* _MMC_H_ */
index 74d06ae18a229ff7182249815ba53ec17cdfb166..2c480d07bfe438f89de75703bd5b71393f6e43ee 100644 (file)
@@ -247,6 +247,8 @@ struct sdhci_host {
        void (*set_control_reg)(struct sdhci_host *host);
        void (*set_clock)(int dev_index, unsigned int div);
        uint    voltages;
+
+       struct mmc_config cfg;
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS