[U-Boot] [PATCH 0/3] mmc: Cleanup time for mmc_struct

Struct mmc has picked up a lot of cruft over the years.
It is time for it to be split in 3 parts; the original mmc struct containing the state, the mmc_config struct containing the board setup configuration and the mmc_ops struct contains the method pointers.
Using the new config structures the mmc device creation now gets much more easier by using the new mmc_create() call
Pantelis Antoniou (3): mmc: Remove ops from struct mmc and put in mmc_ops mmc: Convert mmc struct's name array to a pointer mmc: Split mmc struct, rework mmc initialization
arch/arm/include/asm/arch-davinci/sdmmc_defs.h | 1 + arch/arm/include/asm/arch-tegra/tegra_mmc.h | 4 + common/cmd_mmc.c | 2 +- common/cmd_mmc_spi.c | 2 +- drivers/mmc/arm_pl180_mmci.c | 50 +++++---- drivers/mmc/arm_pl180_mmci.h | 4 + drivers/mmc/bfin_sdh.c | 40 +++---- drivers/mmc/davinci_mmc.c | 41 ++++--- drivers/mmc/dw_mmc.c | 58 +++++----- drivers/mmc/fsl_esdhc.c | 65 +++++------ drivers/mmc/ftsdc010_mci.c | 63 +++++------ drivers/mmc/gen_atmel_mci.c | 53 +++++---- drivers/mmc/mmc.c | 88 +++++++++------ drivers/mmc/mmc_spi.c | 50 +++++---- drivers/mmc/mmc_write.c | 3 +- drivers/mmc/mxcmmc.c | 45 ++++---- drivers/mmc/mxsmmc.c | 48 ++++----- drivers/mmc/omap_hsmmc.c | 142 +++++++++++++++---------- drivers/mmc/pxa_mmc_gen.c | 70 ++++++------ drivers/mmc/sdhci.c | 84 ++++++++------- drivers/mmc/sh_mmcif.c | 52 ++++----- drivers/mmc/tegra_mmc.c | 53 ++++----- include/dwmmc.h | 2 + include/fsl_esdhc.h | 4 + include/mmc.h | 48 ++++++--- include/sdhci.h | 2 + 26 files changed, 590 insertions(+), 484 deletions(-)

Remove the in-structure ops and put them in mmc_ops with a constant pointer to it.
This makes the mmc structure smaller as well as conserving code space (in theory).
All in-tree drivers are converted as well; this is done in a single patch in order to not break git bisect.
Changes since V1: Fix compilation b0rked issue on omap platforms where OMAP_GPIO was not set.
Signed-off-by: Pantelis Antoniou panto@antoniou-consulting.com --- drivers/mmc/arm_pl180_mmci.c | 12 +++--- drivers/mmc/bfin_sdh.c | 11 +++--- drivers/mmc/davinci_mmc.c | 13 ++++--- drivers/mmc/dw_mmc.c | 10 +++-- drivers/mmc/fsl_esdhc.c | 14 ++++--- drivers/mmc/ftsdc010_mci.c | 11 ++++-- drivers/mmc/gen_atmel_mci.c | 12 +++--- drivers/mmc/mmc.c | 21 ++++++----- drivers/mmc/mmc_spi.c | 12 +++--- drivers/mmc/mxcmmc.c | 12 +++--- drivers/mmc/mxsmmc.c | 12 +++--- drivers/mmc/omap_hsmmc.c | 89 ++++++++++++++++++++++++++++---------------- drivers/mmc/pxa_mmc_gen.c | 11 ++++-- drivers/mmc/sdhci.c | 13 ++++--- drivers/mmc/sh_mmcif.c | 12 +++--- drivers/mmc/tegra_mmc.c | 19 ++++++---- include/mmc.h | 19 +++++++--- 17 files changed, 184 insertions(+), 119 deletions(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 5a55fe7..4490e97 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -335,6 +335,12 @@ static void host_set_ios(struct mmc *dev) udelay(CLK_CHANGE_DELAY); }
+static const struct mmc_ops arm_pl180_mmci_ops = { + .send_cmd = host_request, + .set_ios = host_set_ios, + .init = mmc_host_reset, +}; + /* * mmc_host_init - initialize the mmc controller. * Set initial clock and power for mmc slot. @@ -360,11 +366,7 @@ int arm_pl180_mmci_init(struct pl180_mmc_host *host) sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK; writel(sdi_u32, &host->base->mask0); strncpy(dev->name, host->name, sizeof(dev->name)); - dev->send_cmd = host_request; - dev->set_ios = host_set_ios; - dev->init = mmc_host_reset; - dev->getcd = NULL; - dev->getwp = NULL; + dev->ops = &arm_pl180_mmci_ops; dev->host_caps = host->caps; dev->voltages = host->voltages; dev->f_min = host->clock_min; diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c index bd9b641..f0871ec 100644 --- a/drivers/mmc/bfin_sdh.c +++ b/drivers/mmc/bfin_sdh.c @@ -274,6 +274,11 @@ static int bfin_sdh_init(struct mmc *mmc) return 0; }
+static const struct mmc_ops bfin_mmc_ops = { + .send_cmd = bfin_sdh_request, + .set_ios = bfin_sdh_set_ios, + .init = bfin_sdh_init, +};
int bfin_mmc_init(bd_t *bis) { @@ -284,11 +289,7 @@ int bfin_mmc_init(bd_t *bis) if (!mmc) return -ENOMEM; sprintf(mmc->name, "Blackfin SDH"); - mmc->send_cmd = bfin_sdh_request; - mmc->set_ios = bfin_sdh_set_ios; - mmc->init = bfin_sdh_init; - mmc->getcd = NULL; - mmc->getwp = NULL; + mmc->ops = &bfin_mmc_ops; mmc->host_caps = MMC_MODE_4BIT;
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index b380961..29ca4a6 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -363,6 +363,12 @@ static void dmmc_set_ios(struct mmc *mmc) dmmc_set_clock(mmc, mmc->clock); }
+static const struct mmc_ops dmmc_ops = { + .send_cmd = dmmc_send_cmd, + .set_ios = dmmc_set_ios, + .init = dmmc_init, +}; + /* Called from board_mmc_init during startup. Can be called multiple times * depending on the number of slots available on board and controller */ @@ -375,12 +381,7 @@ int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host)
sprintf(mmc->name, "davinci"); mmc->priv = host; - mmc->send_cmd = dmmc_send_cmd; - mmc->set_ios = dmmc_set_ios; - mmc->init = dmmc_init; - mmc->getcd = NULL; - mmc->getwp = NULL; - + mmc->ops = &dmmc_ops; mmc->f_min = 200000; mmc->f_max = 25000000; mmc->voltages = host->voltages; diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index d45c15c..2e6576e 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -343,6 +343,12 @@ static int dwmci_init(struct mmc *mmc) return 0; }
+static const struct mmc_ops dwmci_ops = { + .send_cmd = dwmci_send_cmd, + .set_ios = dwmci_set_ios, + .init = dwmci_init, +}; + int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk) { struct mmc *mmc; @@ -358,9 +364,7 @@ int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk) host->mmc = mmc;
sprintf(mmc->name, "%s", host->name); - mmc->send_cmd = dwmci_send_cmd; - mmc->set_ios = dwmci_set_ios; - mmc->init = dwmci_init; + mmc->ops = &dwmci_ops; mmc->f_min = min_clk; mmc->f_max = max_clk;
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 7b146a3..861f536 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -524,6 +524,13 @@ static void esdhc_reset(struct fsl_esdhc *regs) printf("MMC/SD: Reset never completed.\n"); }
+static const struct mmc_ops esdhc_ops = { + .send_cmd = esdhc_send_cmd, + .set_ios = esdhc_set_ios, + .init = esdhc_init, + .getcd = esdhc_getcd, +}; + int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) { struct fsl_esdhc *regs; @@ -548,12 +555,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) | SYSCTL_IPGEN | SYSCTL_CKEN);
mmc->priv = cfg; - mmc->send_cmd = esdhc_send_cmd; - mmc->set_ios = esdhc_set_ios; - mmc->init = esdhc_init; - mmc->getcd = esdhc_getcd; - mmc->getwp = NULL; - + mmc->ops = &esdhc_ops; voltage_caps = 0; caps = regs->hostcapblt;
diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c index 7600d5c..ce43ae1 100644 --- a/drivers/mmc/ftsdc010_mci.c +++ b/drivers/mmc/ftsdc010_mci.c @@ -316,6 +316,12 @@ static int ftsdc010_init(struct mmc *mmc) return 0; }
+static const struct mmc_ops ftsdc010_ops = { + .send_cmd = ftsdc010_request, + .set_ios = ftsdc010_set_ios, + .init = ftsdc010_init, +}; + int ftsdc010_mmc_init(int devid) { struct mmc *mmc; @@ -347,10 +353,7 @@ int ftsdc010_mmc_init(int devid) mmc->priv = chip;
sprintf(mmc->name, "ftsdc010"); - mmc->send_cmd = ftsdc010_request; - mmc->set_ios = ftsdc010_set_ios; - mmc->init = ftsdc010_init; - + mmc->ops = &ftsdc010_ops; mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz; switch (readl(®s->bwr) & FTSDC010_BWR_CAPS_MASK) { case FTSDC010_BWR_CAPS_4BIT: diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index c11dcd0..456f8bf 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -344,6 +344,12 @@ static int mci_init(struct mmc *mmc) return 0; }
+static const struct mmc_ops atmel_mci_ops = { + .send_cmd = mci_send_cmd, + .set_ios = mci_set_ios, + .init = mci_init, +}; + /* * This is the only exported function * @@ -360,11 +366,7 @@ int atmel_mci_init(void *regs)
strcpy(mmc->name, "mci"); mmc->priv = regs; - mmc->send_cmd = mci_send_cmd; - mmc->set_ios = mci_set_ios; - mmc->init = mci_init; - mmc->getcd = NULL; - mmc->getwp = NULL; + mmc->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; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 8ab0bc9..ac07bb9 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -37,8 +37,8 @@ int mmc_getwp(struct mmc *mmc) wp = board_mmc_getwp(mmc);
if (wp < 0) { - if (mmc->getwp) - wp = mmc->getwp(mmc); + if (mmc->ops->getwp) + wp = mmc->ops->getwp(mmc); else wp = 0; } @@ -63,7 +63,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->send_cmd(mmc, cmd, data); + ret = mmc->ops->send_cmd(mmc, cmd, data); switch (cmd->resp_type) { case MMC_RSP_NONE: printf("\t\tMMC_RSP_NONE\n"); @@ -106,7 +106,7 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) break; } #else - ret = mmc->send_cmd(mmc, cmd, data); + ret = mmc->ops->send_cmd(mmc, cmd, data); #endif return ret; } @@ -578,8 +578,8 @@ int mmc_getcd(struct mmc *mmc) cd = board_mmc_getcd(mmc);
if (cd < 0) { - if (mmc->getcd) - cd = mmc->getcd(mmc); + if (mmc->ops->getcd) + cd = mmc->ops->getcd(mmc); else cd = 1; } @@ -751,7 +751,8 @@ static const int multipliers[] = {
static void mmc_set_ios(struct mmc *mmc) { - mmc->set_ios(mmc); + if (mmc->ops->set_ios) + mmc->ops->set_ios(mmc); }
void mmc_set_clock(struct mmc *mmc, uint clock) @@ -1207,7 +1208,8 @@ int mmc_start_init(struct mmc *mmc) { int err;
- if (mmc_getcd(mmc) == 0) { + /* we pretend there's no card when init is NULL */ + if (mmc_getcd(mmc) == 0 || mmc->ops->init == NULL) { mmc->has_init = 0; #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) printf("MMC: no card present\n"); @@ -1218,7 +1220,8 @@ int mmc_start_init(struct mmc *mmc) if (mmc->has_init) return 0;
- err = mmc->init(mmc); + /* made sure it's not NULL earlier */ + err = mmc->ops->init(mmc);
if (err) return err; diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c index fe6a5a1..0a0f894 100644 --- a/drivers/mmc/mmc_spi.c +++ b/drivers/mmc/mmc_spi.c @@ -255,6 +255,12 @@ static int mmc_spi_init_p(struct mmc *mmc) return 0; }
+static const struct mmc_ops mmc_spi_ops = { + .send_cmd = mmc_spi_request, + .set_ios = mmc_spi_set_ios, + .init = mmc_spi_init_p, +}; + struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode) { struct mmc *mmc; @@ -269,11 +275,7 @@ struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode) return NULL; } sprintf(mmc->name, "MMC_SPI"); - mmc->send_cmd = mmc_spi_request; - mmc->set_ios = mmc_spi_set_ios; - mmc->init = mmc_spi_init_p; - mmc->getcd = NULL; - mmc->getwp = NULL; + mmc->ops = &mmc_spi_ops; mmc->host_caps = MMC_MODE_SPI;
mmc->voltages = MMC_SPI_VOLTAGE; diff --git a/drivers/mmc/mxcmmc.c b/drivers/mmc/mxcmmc.c index 4f99617..f3e1eed 100644 --- a/drivers/mmc/mxcmmc.c +++ b/drivers/mmc/mxcmmc.c @@ -485,6 +485,12 @@ static int mxcmci_init(struct mmc *mmc) return 0; }
+static const struct mmc_ops mxcmci_ops = { + .send_cmd = mxcmci_request, + .set_ios = mxcmci_set_ios, + .init = mxcmci_init, +}; + static int mxcmci_initialize(bd_t *bis) { struct mmc *mmc = NULL; @@ -495,11 +501,7 @@ static int mxcmci_initialize(bd_t *bis) return -ENOMEM;
sprintf(mmc->name, "MXC MCI"); - mmc->send_cmd = mxcmci_request; - mmc->set_ios = mxcmci_set_ios; - mmc->init = mxcmci_init; - mmc->getcd = NULL; - mmc->getwp = NULL; + mmc->ops = &mxcmci_ops; mmc->host_caps = MMC_MODE_4BIT;
host->base = (struct mxcmci_regs *)CONFIG_MXC_MCI_REGS_BASE; diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c index 245f9d0..97c9ee8 100644 --- a/drivers/mmc/mxsmmc.c +++ b/drivers/mmc/mxsmmc.c @@ -363,6 +363,12 @@ static int mxsmmc_init(struct mmc *mmc) return 0; }
+static const struct mmc_ops mxsmmc_ops = { + .send_cmd = mxsmmc_send_cmd, + .set_ios = mxsmmc_set_ios, + .init = mxsmmc_init, +}; + int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int)) { struct mmc *mmc = NULL; @@ -400,11 +406,7 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int)) priv->regs = mxs_ssp_regs_by_bus(id);
sprintf(mmc->name, "MXS MMC"); - mmc->send_cmd = mxsmmc_send_cmd; - mmc->set_ios = mxsmmc_set_ios; - mmc->init = mxsmmc_init; - mmc->getcd = NULL; - mmc->getwp = NULL; + mmc->ops = &mxsmmc_ops; mmc->priv = priv;
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index d3a8b53..6bf602f 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -35,14 +35,24 @@ #include <asm/arch/mmc_host_def.h> #include <asm/arch/sys_proto.h>
+/* simplify defines to OMAP_HSMMC_USE_GPIO */ +#if (defined(CONFIG_OMAP_GPIO) && !defined(CONFIG_SPL_BUILD)) || \ + (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO_SUPPORT)) +#define OMAP_HSMMC_USE_GPIO +#else +#undef OMAP_HSMMC_USE_GPIO +#endif + /* common definitions for all OMAPs */ #define SYSCTL_SRC (1 << 25) #define SYSCTL_SRD (1 << 26)
struct omap_hsmmc_data { struct hsmmc *base_addr; +#ifdef OMAP_HSMMC_USE_GPIO int cd_gpio; int wp_gpio; +#endif };
/* If we fail after 1 second wait, something is really bad */ @@ -54,8 +64,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf, static struct mmc hsmmc_dev[3]; static struct omap_hsmmc_data hsmmc_dev_data[3];
-#if (defined(CONFIG_OMAP_GPIO) && !defined(CONFIG_SPL_BUILD)) || \ - (defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_GPIO_SUPPORT)) +#ifdef OMAP_HSMMC_USE_GPIO static int omap_mmc_setup_gpio_in(int gpio, const char *label) { if (!gpio_is_valid(gpio)) @@ -69,26 +78,6 @@ static int omap_mmc_setup_gpio_in(int gpio, const char *label)
return gpio; } - -static int omap_mmc_getcd(struct mmc *mmc) -{ - int cd_gpio = ((struct omap_hsmmc_data *)mmc->priv)->cd_gpio; - return gpio_get_value(cd_gpio); -} - -static int omap_mmc_getwp(struct mmc *mmc) -{ - int wp_gpio = ((struct omap_hsmmc_data *)mmc->priv)->wp_gpio; - return gpio_get_value(wp_gpio); -} -#else -static inline int omap_mmc_setup_gpio_in(int gpio, const char *label) -{ - return -1; -} - -#define omap_mmc_getcd NULL -#define omap_mmc_getwp NULL #endif
#if defined(CONFIG_OMAP44XX) && defined(CONFIG_TWL6030_POWER) @@ -213,7 +202,7 @@ void mmc_init_stream(struct hsmmc *mmc_base) }
-static int mmc_init_setup(struct mmc *mmc) +static int omap_hsmmc_init_setup(struct mmc *mmc) { struct hsmmc *mmc_base; unsigned int reg_val; @@ -322,7 +311,7 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit) } }
-static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, +static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { struct hsmmc *mmc_base; @@ -552,7 +541,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf, return 0; }
-static void mmc_set_ios(struct mmc *mmc) +static void omap_hsmmc_set_ios(struct mmc *mmc) { struct hsmmc *mmc_base; unsigned int dsor = 0; @@ -606,6 +595,44 @@ static void mmc_set_ios(struct mmc *mmc) writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl); }
+#ifdef OMAP_HSMMC_USE_GPIO +static int omap_hsmmc_getcd(struct mmc *mmc) +{ + struct omap_hsmmc_data *priv_data = mmc->priv; + int cd_gpio; + + /* if no CD return as 1 */ + cd_gpio = priv_data->cd_gpio; + if (cd_gpio < 0) + return 1; + + return gpio_get_value(cd_gpio); +} + +static int omap_hsmmc_getwp(struct mmc *mmc) +{ + struct omap_hsmmc_data *priv_data = mmc->priv; + int wp_gpio; + + /* if no WP return as 0 */ + wp_gpio = priv_data->wp_gpio; + if (wp_gpio < 0) + return 0; + + return gpio_get_value(wp_gpio); +} +#endif + +static const struct mmc_ops omap_hsmmc_ops = { + .send_cmd = omap_hsmmc_send_cmd, + .set_ios = omap_hsmmc_set_ios, + .init = omap_hsmmc_init_setup, +#ifdef OMAP_HSMMC_USE_GPIO + .getcd = omap_hsmmc_getcd, + .getwp = omap_hsmmc_getwp, +#endif +}; + int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio, int wp_gpio) { @@ -615,9 +642,7 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio, MMC_MODE_HC;
sprintf(mmc->name, "OMAP SD/MMC"); - mmc->send_cmd = mmc_send_cmd; - mmc->set_ios = mmc_set_ios; - mmc->init = mmc_init_setup; + mmc->ops = &omap_hsmmc_ops; mmc->priv = priv_data;
switch (dev_index) { @@ -647,13 +672,11 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio, priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE; return 1; } +#ifdef OMAP_HSMMC_USE_GPIO + /* on error gpio values are set to -1, which is what we want */ priv_data->cd_gpio = omap_mmc_setup_gpio_in(cd_gpio, "mmc_cd"); - if (priv_data->cd_gpio != -1) - mmc->getcd = omap_mmc_getcd; - priv_data->wp_gpio = omap_mmc_setup_gpio_in(wp_gpio, "mmc_wp"); - if (priv_data->wp_gpio != -1) - mmc->getwp = omap_mmc_getwp; +#endif
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; mmc->host_caps = host_caps_val & ~host_caps_mask; diff --git a/drivers/mmc/pxa_mmc_gen.c b/drivers/mmc/pxa_mmc_gen.c index 29f3eaf..4694c8f 100644 --- a/drivers/mmc/pxa_mmc_gen.c +++ b/drivers/mmc/pxa_mmc_gen.c @@ -366,6 +366,12 @@ static int pxa_mmc_init(struct mmc *mmc) return 0; }
+static const struct mmc_ops pxa_mmc_ops = { + .send_cmd = pxa_mmc_request, + .set_ios = pxa_mmc_set_ios, + .init = pxa_mmc_init, +}; + int pxa_mmc_register(int card_index) { struct mmc *mmc; @@ -397,10 +403,7 @@ int pxa_mmc_register(int card_index) mmc->priv = priv;
sprintf(mmc->name, "PXA MMC"); - mmc->send_cmd = pxa_mmc_request; - mmc->set_ios = pxa_mmc_set_ios; - mmc->init = pxa_mmc_init; - mmc->getcd = NULL; + mmc->ops = &pxa_mmc_ops;
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; mmc->f_max = PXAMMC_MAX_SPEED; diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 1e86b92..c3425a6 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -430,6 +430,13 @@ int sdhci_init(struct mmc *mmc) return 0; }
+ +static const struct mmc_ops sdhci_ops = { + .send_cmd = sdhci_send_command, + .set_ios = sdhci_set_ios, + .init = sdhci_init, +}; + int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) { struct mmc *mmc; @@ -445,11 +452,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) host->mmc = mmc;
sprintf(mmc->name, "%s", host->name); - mmc->send_cmd = sdhci_send_command; - mmc->set_ios = sdhci_set_ios; - mmc->init = sdhci_init; - mmc->getcd = NULL; - mmc->getwp = NULL; + mmc->ops = &sdhci_ops;
caps = sdhci_readl(host, SDHCI_CAPABILITIES); #ifdef CONFIG_MMC_SDMA diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 011d4f3..6a4860b 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -574,6 +574,12 @@ static int sh_mmcif_init(struct mmc *mmc) return 0; }
+static const struct mmc_ops sh_mmcif_ops = { + .send_cmd = sh_mmcif_request, + .set_ios = sh_mmcif_set_ios, + .init = sh_mmcif_init, +}; + int mmcif_mmc_init(void) { int ret = 0; @@ -595,11 +601,7 @@ int mmcif_mmc_init(void) mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC; memcpy(mmc->name, DRIVER_NAME, sizeof(DRIVER_NAME)); - mmc->send_cmd = sh_mmcif_request; - mmc->set_ios = sh_mmcif_set_ios; - mmc->init = sh_mmcif_init; - mmc->getcd = NULL; - mmc->getwp = NULL; + mmc->ops = &sh_mmcif_ops; host->regs = (struct sh_mmcif_regs *)CONFIG_SH_MMCIF_ADDR; host->clk = CONFIG_SH_MMCIF_CLK; mmc->priv = host; diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index 3d1ce12..5f7b590 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -314,7 +314,7 @@ static int mmc_send_cmd_bounced(struct mmc *mmc, struct mmc_cmd *cmd, return 0; }
-static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, +static int tegra_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { void *buf; @@ -396,7 +396,7 @@ out: host->clock = clock; }
-static void mmc_set_ios(struct mmc *mmc) +static void tegra_mmc_set_ios(struct mmc *mmc) { struct mmc_host *host = mmc->priv; unsigned char ctrl; @@ -464,7 +464,7 @@ static void mmc_reset(struct mmc_host *host, struct mmc *mmc) pad_init_mmc(host); }
-static int mmc_core_init(struct mmc *mmc) +static int tegra_mmc_core_init(struct mmc *mmc) { struct mmc_host *host = (struct mmc_host *)mmc->priv; unsigned int mask; @@ -521,6 +521,13 @@ int tegra_mmc_getcd(struct mmc *mmc) return 1; }
+static const struct mmc_ops tegra_mmc_ops = { + .send_cmd = tegra_mmc_send_cmd, + .set_ios = tegra_mmc_set_ios, + .init = tegra_mmc_core_init, + .getcd = tegra_mmc_getcd, +}; + static int do_mmc_init(int dev_index) { struct mmc_host *host; @@ -558,11 +565,7 @@ static int do_mmc_init(int dev_index)
sprintf(mmc->name, "Tegra SD/MMC"); mmc->priv = host; - mmc->send_cmd = mmc_send_cmd; - mmc->set_ios = mmc_set_ios; - mmc->init = mmc_core_init; - mmc->getcd = tegra_mmc_getcd; - mmc->getwp = NULL; + mmc->ops = &tegra_mmc_ops;
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; mmc->host_caps = 0; diff --git a/include/mmc.h b/include/mmc.h index e95a237..3d53ce1 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -250,6 +250,18 @@ struct mmc_data { uint blocksize; };
+/* forward decl. */ +struct mmc; + +struct mmc_ops { + int (*send_cmd)(struct mmc *mmc, + struct mmc_cmd *cmd, struct mmc_data *data); + void (*set_ios)(struct mmc *mmc); + int (*init)(struct mmc *mmc); + int (*getcd)(struct mmc *mmc); + int (*getwp)(struct mmc *mmc); +}; + struct mmc { struct list_head link; char name[32]; @@ -283,12 +295,7 @@ struct mmc { u64 capacity_rpmb; u64 capacity_gp[4]; block_dev_desc_t block_dev; - int (*send_cmd)(struct mmc *mmc, - struct mmc_cmd *cmd, struct mmc_data *data); - void (*set_ios)(struct mmc *mmc); - int (*init)(struct mmc *mmc); - int (*getcd)(struct mmc *mmc); - int (*getwp)(struct mmc *mmc); + 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() */

Hi,
On 12 March 2014 04:24, Pantelis Antoniou panto@antoniou-consulting.com wrote:
Remove the in-structure ops and put them in mmc_ops with a constant pointer to it.
This makes the mmc structure smaller as well as conserving code space (in theory).
You might be able to run buildman (and use -S) to check this.
These changes look good to me, and will make it easier to move to driver model I suspect.
Regards, Simon
All in-tree drivers are converted as well; this is done in a single patch in order to not break git bisect.
Changes since V1: Fix compilation b0rked issue on omap platforms where OMAP_GPIO was not set.
Signed-off-by: Pantelis Antoniou panto@antoniou-consulting.com

On Friday, March 14, 2014 at 09:53:51 PM, Simon Glass wrote:
Hi,
On 12 March 2014 04:24, Pantelis Antoniou panto@antoniou-consulting.com
wrote:
Remove the in-structure ops and put them in mmc_ops with a constant pointer to it.
This makes the mmc structure smaller as well as conserving code space (in theory).
You might be able to run buildman (and use -S) to check this.
These changes look good to me, and will make it easier to move to driver model I suspect.
Full ack on the driver model part.
Best regards, Marek Vasut

Using an array is pointless; even more pointless (and scary) is using sprintf to fill it without a format string.
Signed-off-by: Pantelis Antoniou panto@antoniou-consulting.com --- drivers/mmc/arm_pl180_mmci.c | 2 +- drivers/mmc/bfin_sdh.c | 2 +- drivers/mmc/davinci_mmc.c | 2 +- drivers/mmc/dw_mmc.c | 2 +- drivers/mmc/fsl_esdhc.c | 2 +- drivers/mmc/ftsdc010_mci.c | 2 +- drivers/mmc/gen_atmel_mci.c | 2 +- drivers/mmc/mmc_spi.c | 2 +- drivers/mmc/mxcmmc.c | 2 +- drivers/mmc/mxsmmc.c | 2 +- drivers/mmc/omap_hsmmc.c | 2 +- drivers/mmc/pxa_mmc_gen.c | 2 +- drivers/mmc/sdhci.c | 2 +- drivers/mmc/sh_mmcif.c | 2 +- drivers/mmc/tegra_mmc.c | 2 +- include/mmc.h | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 4490e97..5a30590 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -365,7 +365,7 @@ 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); - strncpy(dev->name, host->name, sizeof(dev->name)); + dev->name = host->name; dev->ops = &arm_pl180_mmci_ops; dev->host_caps = host->caps; dev->voltages = host->voltages; diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c index f0871ec..5f6145b 100644 --- a/drivers/mmc/bfin_sdh.c +++ b/drivers/mmc/bfin_sdh.c @@ -288,7 +288,7 @@ int bfin_mmc_init(bd_t *bis)
if (!mmc) return -ENOMEM; - sprintf(mmc->name, "Blackfin SDH"); + mmc->name = "Blackfin SDH"; mmc->ops = &bfin_mmc_ops; mmc->host_caps = MMC_MODE_4BIT;
diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index 29ca4a6..cae972a 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -379,7 +379,7 @@ int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host) mmc = malloc(sizeof(struct mmc)); memset(mmc, 0, sizeof(struct mmc));
- sprintf(mmc->name, "davinci"); + mmc->name = "davinci"; mmc->priv = host; mmc->ops = &dmmc_ops; mmc->f_min = 200000; diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 2e6576e..011efb1 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -363,7 +363,7 @@ int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk) mmc->priv = host; host->mmc = mmc;
- sprintf(mmc->name, "%s", host->name); + mmc->name = host->name; mmc->ops = &dwmci_ops; mmc->f_min = min_clk; mmc->f_max = max_clk; diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 861f536..f66513e 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -545,7 +545,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) return -ENOMEM;
memset(mmc, 0, sizeof(struct mmc)); - sprintf(mmc->name, "FSL_SDHC"); + mmc->name = "FSL_SDHC"; regs = (struct fsl_esdhc *)cfg->esdhc_base;
/* First reset the eSDHC controller */ diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c index ce43ae1..b1673fc 100644 --- a/drivers/mmc/ftsdc010_mci.c +++ b/drivers/mmc/ftsdc010_mci.c @@ -352,7 +352,7 @@ int ftsdc010_mmc_init(int devid) chip->regs = regs; mmc->priv = chip;
- sprintf(mmc->name, "ftsdc010"); + mmc->name = "ftsdc010"; mmc->ops = &ftsdc010_ops; mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz; switch (readl(®s->bwr) & FTSDC010_BWR_CAPS_MASK) { diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index 456f8bf..ce799f3 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -364,7 +364,7 @@ int atmel_mci_init(void *regs) if (!mmc) return -1;
- strcpy(mmc->name, "mci"); + mmc->name = "mci"; mmc->priv = regs; mmc->ops = &atmel_mci_ops;
diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c index 0a0f894..e94de37 100644 --- a/drivers/mmc/mmc_spi.c +++ b/drivers/mmc/mmc_spi.c @@ -274,7 +274,7 @@ struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode) free(mmc); return NULL; } - sprintf(mmc->name, "MMC_SPI"); + mmc->name = "MMC_SPI"; mmc->ops = &mmc_spi_ops; mmc->host_caps = MMC_MODE_SPI;
diff --git a/drivers/mmc/mxcmmc.c b/drivers/mmc/mxcmmc.c index f3e1eed..3357559 100644 --- a/drivers/mmc/mxcmmc.c +++ b/drivers/mmc/mxcmmc.c @@ -500,7 +500,7 @@ static int mxcmci_initialize(bd_t *bis) if (!mmc) return -ENOMEM;
- sprintf(mmc->name, "MXC MCI"); + mmc->name = "MXC MCI"; mmc->ops = &mxcmci_ops; mmc->host_caps = MMC_MODE_4BIT;
diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c index 97c9ee8..3512a99 100644 --- a/drivers/mmc/mxsmmc.c +++ b/drivers/mmc/mxsmmc.c @@ -405,7 +405,7 @@ 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);
- sprintf(mmc->name, "MXS MMC"); + mmc->name = "MXS MMC"; mmc->ops = &mxsmmc_ops; mmc->priv = priv;
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 6bf602f..fecac56 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -641,7 +641,7 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio, uint host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS | MMC_MODE_HC;
- sprintf(mmc->name, "OMAP SD/MMC"); + mmc->name = "OMAP SD/MMC"; mmc->ops = &omap_hsmmc_ops; mmc->priv = priv_data;
diff --git a/drivers/mmc/pxa_mmc_gen.c b/drivers/mmc/pxa_mmc_gen.c index 4694c8f..188e1d4 100644 --- a/drivers/mmc/pxa_mmc_gen.c +++ b/drivers/mmc/pxa_mmc_gen.c @@ -402,7 +402,7 @@ int pxa_mmc_register(int card_index)
mmc->priv = priv;
- sprintf(mmc->name, "PXA MMC"); + mmc->name = "PXA MMC"; mmc->ops = &pxa_mmc_ops;
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index c3425a6..dc6f4e4 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -451,7 +451,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) mmc->priv = host; host->mmc = mmc;
- sprintf(mmc->name, "%s", host->name); + mmc->name = host->name; mmc->ops = &sdhci_ops;
caps = sdhci_readl(host, SDHCI_CAPABILITIES); diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 6a4860b..008617d 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -600,7 +600,7 @@ int mmcif_mmc_init(void) 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; - memcpy(mmc->name, DRIVER_NAME, sizeof(DRIVER_NAME)); + 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; diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index 5f7b590..e8fbb63 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -563,7 +563,7 @@ static int do_mmc_init(int dev_index)
mmc = &mmc_dev[dev_index];
- sprintf(mmc->name, "Tegra SD/MMC"); + mmc->name = "Tegra SD/MMC"; mmc->priv = host; mmc->ops = &tegra_mmc_ops;
diff --git a/include/mmc.h b/include/mmc.h index 3d53ce1..6b08c62 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -264,7 +264,7 @@ struct mmc_ops {
struct mmc { struct list_head link; - char name[32]; + const char *name; /* no need for this to be an array */ void *priv; uint voltages; uint version;

Hi,
On 12 March 2014 04:24, Pantelis Antoniou panto@antoniou-consulting.com wrote:
Using an array is pointless; even more pointless (and scary) is using sprintf to fill it without a format string.
This is certainly better, but how about an mmc structure init function which sets this up?
Regards, Simon

On Friday, March 14, 2014 at 09:55:08 PM, Simon Glass wrote:
Hi,
On 12 March 2014 04:24, Pantelis Antoniou panto@antoniou-consulting.com
wrote:
Using an array is pointless; even more pointless (and scary) is using sprintf to fill it without a format string.
This is certainly better, but how about an mmc structure init function which sets this up?
You mean DM's .probe() ? :-)
Best regards, Marek Vasut

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.
Signed-off-by: Pantelis Antoniou panto@antoniou-consulting.com --- arch/arm/include/asm/arch-davinci/sdmmc_defs.h | 1 + arch/arm/include/asm/arch-tegra/tegra_mmc.h | 4 ++ common/cmd_mmc.c | 2 +- common/cmd_mmc_spi.c | 2 +- drivers/mmc/arm_pl180_mmci.c | 40 ++++++------ drivers/mmc/arm_pl180_mmci.h | 4 ++ drivers/mmc/bfin_sdh.c | 31 +++++---- drivers/mmc/davinci_mmc.c | 30 ++++----- drivers/mmc/dw_mmc.c | 50 +++++++-------- drivers/mmc/fsl_esdhc.c | 55 ++++++++-------- drivers/mmc/ftsdc010_mci.c | 54 +++++++--------- drivers/mmc/gen_atmel_mci.c | 43 ++++++++----- drivers/mmc/mmc.c | 87 +++++++++++++++++--------- drivers/mmc/mmc_spi.c | 40 ++++++------ drivers/mmc/mmc_write.c | 3 +- drivers/mmc/mxcmmc.c | 35 +++++------ drivers/mmc/mxsmmc.c | 38 ++++++----- drivers/mmc/omap_hsmmc.c | 55 +++++++++------- drivers/mmc/pxa_mmc_gen.c | 61 +++++++++--------- drivers/mmc/sdhci.c | 73 +++++++++++---------- drivers/mmc/sh_mmcif.c | 42 ++++++------- drivers/mmc/tegra_mmc.c | 36 ++++++----- include/dwmmc.h | 2 + include/fsl_esdhc.h | 4 ++ include/mmc.h | 31 ++++++--- include/sdhci.h | 2 + 26 files changed, 433 insertions(+), 392 deletions(-)
diff --git a/arch/arm/include/asm/arch-davinci/sdmmc_defs.h b/arch/arm/include/asm/arch-davinci/sdmmc_defs.h index 3e9e606..9aa3f4a 100644 --- a/arch/arm/include/asm/arch-davinci/sdmmc_defs.h +++ b/arch/arm/include/asm/arch-davinci/sdmmc_defs.h @@ -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 { diff --git a/arch/arm/include/asm/arch-tegra/tegra_mmc.h b/arch/arm/include/asm/arch-tegra/tegra_mmc.h index b6896af..310bbd7 100644 --- a/arch/arm/include/asm/arch-tegra/tegra_mmc.h +++ b/arch/arm/include/asm/arch-tegra/tegra_mmc.h @@ -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); diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 2d51927..bd1edc8 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -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, diff --git a/common/cmd_mmc_spi.c b/common/cmd_mmc_spi.c index 98cd788..a2138b8 100644 --- a/common/cmd_mmc_spi.c +++ b/common/cmd_mmc_spi.c @@ -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; diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 5a30590..5ef7ff7 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -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; } diff --git a/drivers/mmc/arm_pl180_mmci.h b/drivers/mmc/arm_pl180_mmci.h index 7234449..f23bd39 100644 --- a/drivers/mmc/arm_pl180_mmci.h +++ b/drivers/mmc/arm_pl180_mmci.h @@ -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 *); diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c index 5f6145b..7b35d8e 100644 --- a/drivers/mmc/bfin_sdh.c +++ b/drivers/mmc/bfin_sdh.c @@ -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; } diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index cae972a..aae00e9 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -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(®s->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; } diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 011efb1..eb4e2be 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -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; } diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index f66513e..d649626 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -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(®s->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; } diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c index b1673fc..a620678 100644 --- a/drivers/mmc/ftsdc010_mci.c +++ b/drivers/mmc/ftsdc010_mci.c @@ -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(®s->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; } diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index ce799f3..acca026 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -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; } diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index ac07bb9..4adb886 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -17,11 +17,6 @@ #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); @@ -1183,8 +1179,9 @@ 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; + + /* setup initial part type */ + mmc->block_dev.part_type = mmc->cfg->part_type;
INIT_LIST_HEAD (&mmc->link);
@@ -1193,6 +1190,34 @@ int mmc_register(struct mmc *mmc) return 0; }
+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 = malloc(sizeof(*mmc)); + if (mmc == NULL) + return NULL; + memset(mmc, 0, sizeof(*mmc)); + + mmc->cfg = cfg; + mmc->priv = priv; + + mmc_register(mmc); + + return mmc; +} + +void mmc_destroy(struct mmc *mmc) +{ + /* only freeing memory for now */ + free(mmc); +} + #ifdef CONFIG_PARTITIONS block_dev_desc_t *mmc_get_dev(int dev) { @@ -1209,7 +1234,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 +1246,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 +1348,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); diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c index e94de37..5b5b33a 100644 --- a/drivers/mmc/mmc_spi.c +++ b/drivers/mmc/mmc_spi.c @@ -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; } diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c index aa2fdef..3db9669 100644 --- a/drivers/mmc/mmc_write.c +++ b/drivers/mmc/mmc_write.c @@ -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; diff --git a/drivers/mmc/mxcmmc.c b/drivers/mmc/mxcmmc.c index 3357559..561b204 100644 --- a/drivers/mmc/mxcmmc.c +++ b/drivers/mmc/mxcmmc.c @@ -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; } diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c index 3512a99..2fa4eee 100644 --- a/drivers/mmc/mxsmmc.c +++ b/drivers/mmc/mxsmmc.c @@ -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; } diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index fecac56..17cbb09 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -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; } diff --git a/drivers/mmc/pxa_mmc_gen.c b/drivers/mmc/pxa_mmc_gen.c index 188e1d4..1f29757 100644 --- a/drivers/mmc/pxa_mmc_gen.c +++ b/drivers/mmc/pxa_mmc_gen.c @@ -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; } diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index dc6f4e4..3125d13 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -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; } diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 008617d..64b5b47 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -20,11 +20,6 @@
#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; } diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index e8fbb63..ed67eec 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -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; } diff --git a/include/dwmmc.h b/include/dwmmc.h index b641558..c9bdf51 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -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 { diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h index 89bcbd1..a6e3a5d 100644 --- a/include/fsl_esdhc.h +++ b/include/fsl_esdhc.h @@ -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 */ diff --git a/include/mmc.h b/include/mmc.h index 6b08c62..0172979 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -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_ */ diff --git a/include/sdhci.h b/include/sdhci.h index 74d06ae..2c480d0 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -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

On 12 March 2014 04:24, Pantelis Antoniou panto@antoniou-consulting.com wrote:
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.
Looks like a big improvement!
Signed-off-by: Pantelis Antoniou panto@antoniou-consulting.com

On Wednesday, March 12, 2014 at 11:24:24 AM, Pantelis Antoniou wrote:
Struct mmc has picked up a lot of cruft over the years.
It is time for it to be split in 3 parts; the original mmc struct containing the state, the mmc_config struct containing the board setup configuration and the mmc_ops struct contains the method pointers.
Using the new config structures the mmc device creation now gets much more easier by using the new mmc_create() call
Is this a V2? I don't see a changelog or anything ...
Best regards, Marek Vasut
participants (3)
-
Marek Vasut
-
Pantelis Antoniou
-
Simon Glass