mmc: Split mmc struct, rework mmc initialization (v2)
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>
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 @@
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 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 @@
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;
}