diff options
author | Pantelis Antoniou <panto@antoniou-consulting.com> | 2014-03-11 19:34:20 +0200 |
---|---|---|
committer | Pantelis Antoniou <panto@antoniou-consulting.com> | 2014-03-24 12:58:56 +0200 |
commit | 93bfd6167713a5cc1a78bcf60fa63f990fd3f4b3 (patch) | |
tree | 9450ca369c296374e9a376f6950c521c2a89cab8 /drivers/mmc/sdhci.c | |
parent | 22cb7d334e296288e53057467dfee26858275516 (diff) | |
download | u-boot-imx-93bfd6167713a5cc1a78bcf60fa63f990fd3f4b3.zip u-boot-imx-93bfd6167713a5cc1a78bcf60fa63f990fd3f4b3.tar.gz u-boot-imx-93bfd6167713a5cc1a78bcf60fa63f990fd3f4b3.tar.bz2 |
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>
Diffstat (limited to 'drivers/mmc/sdhci.c')
-rw-r--r-- | drivers/mmc/sdhci.c | 73 |
1 files changed, 36 insertions, 37 deletions
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; } |