summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/omap_hsmmc.c
diff options
context:
space:
mode:
authorPantelis Antoniou <panto@antoniou-consulting.com>2014-03-11 19:34:20 +0200
committerPantelis Antoniou <panto@antoniou-consulting.com>2014-03-24 12:58:56 +0200
commit93bfd6167713a5cc1a78bcf60fa63f990fd3f4b3 (patch)
tree9450ca369c296374e9a376f6950c521c2a89cab8 /drivers/mmc/omap_hsmmc.c
parent22cb7d334e296288e53057467dfee26858275516 (diff)
downloadtalos-obmc-uboot-93bfd6167713a5cc1a78bcf60fa63f990fd3f4b3.tar.gz
talos-obmc-uboot-93bfd6167713a5cc1a78bcf60fa63f990fd3f4b3.zip
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/omap_hsmmc.c')
-rw-r--r--drivers/mmc/omap_hsmmc.c55
1 files changed, 32 insertions, 23 deletions
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index fecac5698b..17cbb0983d 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;
}
OpenPOWER on IntegriCloud