diff options
Diffstat (limited to 'drivers/mmc')
| -rw-r--r-- | drivers/mmc/arm_pl180_mmci.c | 50 | ||||
| -rw-r--r-- | drivers/mmc/arm_pl180_mmci.h | 4 | ||||
| -rw-r--r-- | drivers/mmc/bfin_sdh.c | 40 | ||||
| -rw-r--r-- | drivers/mmc/davinci_mmc.c | 41 | ||||
| -rw-r--r-- | drivers/mmc/dw_mmc.c | 58 | ||||
| -rw-r--r-- | drivers/mmc/fsl_esdhc.c | 65 | ||||
| -rw-r--r-- | drivers/mmc/ftsdc010_mci.c | 63 | ||||
| -rw-r--r-- | drivers/mmc/gen_atmel_mci.c | 53 | ||||
| -rw-r--r-- | drivers/mmc/mmc.c | 99 | ||||
| -rw-r--r-- | drivers/mmc/mmc_spi.c | 50 | ||||
| -rw-r--r-- | drivers/mmc/mmc_write.c | 3 | ||||
| -rw-r--r-- | drivers/mmc/mxcmmc.c | 45 | ||||
| -rw-r--r-- | drivers/mmc/mxsmmc.c | 48 | ||||
| -rw-r--r-- | drivers/mmc/omap_hsmmc.c | 142 | ||||
| -rw-r--r-- | drivers/mmc/pxa_mmc_gen.c | 70 | ||||
| -rw-r--r-- | drivers/mmc/sdhci.c | 84 | ||||
| -rw-r--r-- | drivers/mmc/sh_mmcif.c | 52 | ||||
| -rw-r--r-- | drivers/mmc/tegra_mmc.c | 53 | 
18 files changed, 548 insertions, 472 deletions
| diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 5a55fe73b..5ef7ff7ff 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;  		} @@ -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. @@ -342,16 +348,9 @@ static void host_set_ios(struct mmc *dev)   */  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); @@ -359,19 +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); -	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->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 72344498d..f23bd391e 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 bd9b64113..7b35d8e7d 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; @@ -274,30 +274,30 @@ 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, +}; + +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; -	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->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 b38096118..aae00e9da 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; @@ -363,32 +363,27 @@ 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   */  int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host)  { -	struct mmc *mmc; - -	mmc = malloc(sizeof(struct mmc)); -	memset(mmc, 0, sizeof(struct mmc)); - -	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->f_min = 200000; -	mmc->f_max = 25000000; -	mmc->voltages = host->voltages; -	mmc->host_caps = host->host_caps; +	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->b_max = DAVINCI_MAX_BLOCKS; +	host->cfg.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 d45c15cfa..eb4e2be51 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); @@ -343,41 +343,37 @@ 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; -	int err = 0; - -	mmc = calloc(sizeof(struct mmc), 1); -	if (!mmc) { -		printf("mmc calloc fail!\n"); -		return -1; -	} - -	mmc->priv = host; -	host->mmc = mmc; +	host->cfg.name = host->name; +	host->cfg.ops = &dwmci_ops; +	host->cfg.f_min = min_clk; +	host->cfg.f_max = max_clk; -	sprintf(mmc->name, "%s", host->name); -	mmc->send_cmd = dwmci_send_cmd; -	mmc->set_ios = dwmci_set_ios; -	mmc->init = dwmci_init; -	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 7b146a360..d64962652 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; @@ -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; @@ -533,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)); -	sprintf(mmc->name, "FSL_SDHC");  	regs = (struct fsl_esdhc *)cfg->esdhc_base;  	/* First reset the eSDHC controller */ @@ -547,12 +548,7 @@ 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->send_cmd = esdhc_send_cmd; -	mmc->set_ios = esdhc_set_ios; -	mmc->init = esdhc_init; -	mmc->getcd = esdhc_getcd; -	mmc->getwp = NULL; +	memset(&cfg->cfg, 0, sizeof(cfg->cfg));  	voltage_caps = 0;  	caps = regs->hostcapblt; @@ -574,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 7600d5ce5..a620678e5 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; @@ -316,6 +309,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; @@ -331,50 +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; - -	sprintf(mmc->name, "ftsdc010"); -	mmc->send_cmd  = ftsdc010_request; -	mmc->set_ios   = ftsdc010_set_ios; -	mmc->init      = ftsdc010_init; +#ifdef CONFIG_SYS_CLK_FREQ +	chip->sclk = CONFIG_SYS_CLK_FREQ; +#else +	chip->sclk = clk_get_rate("SDC"); +#endif -	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 c11dcd0f9..acca0269e 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 */ @@ -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   * @@ -351,40 +357,45 @@ static int mci_init(struct mmc *mmc)   */  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)); + +	mci = (struct atmel_mci *)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; +	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 8ab0bc948..eccdbc4b6 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->getwp) -			wp = mmc->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->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->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->getcd) -			cd = mmc->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,16 +747,17 @@ static const int multipliers[] = {  static void mmc_set_ios(struct mmc *mmc)  { -	mmc->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; @@ -1026,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) { @@ -1081,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, @@ -1154,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); @@ -1170,8 +1167,33 @@ static int mmc_send_if_cond(struct mmc *mmc)  	return 0;  } -int mmc_register(struct mmc *mmc) +/* not used any more */ +int __deprecated mmc_register(struct mmc *mmc) +{ +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) +	printf("%s is deprecated! use mmc_create() instead.\n", __func__); +#endif +	return -1; +} + +struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)  { +	struct mmc *mmc; + +	/* quick validation */ +	if (cfg == NULL || cfg->ops == NULL || cfg->ops->send_cmd == NULL || +			cfg->f_min == 0 || cfg->f_max == 0 || cfg->b_max == 0) +		return NULL; + +	mmc = calloc(1, sizeof(*mmc)); +	if (mmc == NULL) +		return NULL; + +	mmc->cfg = cfg; +	mmc->priv = priv; + +	/* the following chunk was mmc_register() */ +  	/* Setup dsr related values */  	mmc->dsr_imp = 0;  	mmc->dsr = 0xffffffff; @@ -1182,14 +1204,21 @@ int mmc_register(struct mmc *mmc)  	mmc->block_dev.block_read = mmc_bread;  	mmc->block_dev.block_write = mmc_bwrite;  	mmc->block_dev.block_erase = mmc_berase; -	if (!mmc->b_max) -		mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; -	INIT_LIST_HEAD (&mmc->link); +	/* setup initial part type */ +	mmc->block_dev.part_type = mmc->cfg->part_type; -	list_add_tail (&mmc->link, &mmc_devices); +	INIT_LIST_HEAD(&mmc->link); -	return 0; +	list_add_tail(&mmc->link, &mmc_devices); + +	return mmc; +} + +void mmc_destroy(struct mmc *mmc) +{ +	/* only freeing memory for now */ +	free(mmc);  }  #ifdef CONFIG_PARTITIONS @@ -1207,7 +1236,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->cfg->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 +1248,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->cfg->ops->init(mmc);  	if (err)  		return err; @@ -1320,7 +1351,7 @@ void print_mmc_devices(char separator)  	list_for_each(entry, &mmc_devices) {  		m = list_entry(entry, struct mmc, link); -		printf("%s: %d", m->name, m->block_dev.dev); +		printf("%s: %d", m->cfg->name, m->block_dev.dev);  		if (entry->next != &mmc_devices)  			printf("%c ", separator); diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c index fe6a5a166..5b5b33a4b 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 */ @@ -255,33 +255,37 @@ 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, +}; + +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; -	} -	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->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 aa2fdefa7..3db9669c8 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 4f99617b9..561b20459 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) @@ -485,35 +487,30 @@ static int mxcmci_init(struct mmc *mmc)  	return 0;  } -static int mxcmci_initialize(bd_t *bis) -{ -	struct mmc *mmc = NULL; - -	mmc = malloc(sizeof(struct mmc)); - -	if (!mmc) -		return -ENOMEM; +static const struct mmc_ops mxcmci_ops = { +	.send_cmd	= mxcmci_request, +	.set_ios	= mxcmci_set_ios, +	.init		= mxcmci_init, +}; -	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->host_caps = MMC_MODE_4BIT; +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) +{  	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 245f9d0c6..2fa4eeef4 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 */ @@ -363,6 +364,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; @@ -373,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;  	} @@ -399,17 +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); -	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->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; @@ -419,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 d3a8b5303..17cbb0983 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> @@ -35,14 +36,25 @@  #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; +	struct mmc_config cfg; +#ifdef OMAP_HSMMC_USE_GPIO  	int cd_gpio;  	int wp_gpio; +#endif  };  /* If we fail after 1 second wait, something is really bad */ @@ -51,11 +63,8 @@ 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]; -#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) @@ -158,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); @@ -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,19 +595,58 @@ 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)  { -	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; -	sprintf(mmc->name, "OMAP SD/MMC"); -	mmc->send_cmd = mmc_send_cmd; -	mmc->set_ios = mmc_set_ios; -	mmc->init = mmc_init_setup; -	mmc->priv = priv_data; +	priv_data = malloc(sizeof(*priv_data)); +	if (priv_data == NULL) +		return -1; + +	host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS | +			     MMC_MODE_HC;  	switch (dev_index) {  	case 0: @@ -647,42 +675,46 @@ 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 + +	cfg = &priv_data->cfg; -	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; -	mmc->host_caps = host_caps_val & ~host_caps_mask; +	cfg->name = "OMAP SD/MMC"; +	cfg->ops = &omap_hsmmc_ops; -	mmc->f_min = 400000; +	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 29f3eaf30..1f297571e 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 */ @@ -366,6 +366,22 @@ 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, +}; + +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; @@ -373,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: @@ -389,26 +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; - -	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->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; @@ -419,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 1e86b92be..3125d13ba 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; @@ -430,26 +430,19 @@ 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;  	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; - -	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; +	host->cfg.name = host->name; +	host->cfg.ops = &sdhci_ops;  	caps = sdhci_readl(host, SDHCI_CAPABILITIES);  #ifdef CONFIG_MMC_SDMA @@ -461,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 011d4f3e6..64b5b4726 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,44 +562,49 @@ 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);  	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, +}; + +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; -	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;  	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 3d1ce1263..ed67eec25 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; @@ -314,7 +313,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 +395,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; @@ -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)); @@ -464,9 +463,9 @@ 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; +	struct mmc_host *host = mmc->priv;  	unsigned int mask;  	debug(" mmc_core_init called\n"); @@ -511,7 +510,7 @@ static int 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"); @@ -521,6 +520,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; @@ -554,23 +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)); -	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; +	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 @@ -578,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; + +	host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; -	mmc_register(mmc); +	mmc = mmc_create(&host->cfg, host); +	if (mmc == NULL) +		return -1;  	return 0;  } |