diff options
Diffstat (limited to 'drivers/mmc/host/dw_mmc.c')
| -rw-r--r-- | drivers/mmc/host/dw_mmc.c | 62 | 
1 files changed, 34 insertions, 28 deletions
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index c2828f35c3b..c0667c8af2b 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -232,6 +232,7 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)  {  	struct mmc_data	*data;  	struct dw_mci_slot *slot = mmc_priv(mmc); +	struct dw_mci_drv_data *drv_data = slot->host->drv_data;  	u32 cmdr;  	cmd->error = -EINPROGRESS; @@ -261,8 +262,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)  			cmdr |= SDMMC_CMD_DAT_WR;  	} -	if (slot->host->drv_data->prepare_command) -		slot->host->drv_data->prepare_command(slot->host, &cmdr); +	if (drv_data && drv_data->prepare_command) +		drv_data->prepare_command(slot->host, &cmdr);  	return cmdr;  } @@ -434,7 +435,7 @@ static int dw_mci_idmac_init(struct dw_mci *host)  	return 0;  } -static struct dw_mci_dma_ops dw_mci_idmac_ops = { +static const struct dw_mci_dma_ops dw_mci_idmac_ops = {  	.init = dw_mci_idmac_init,  	.start = dw_mci_idmac_start_dma,  	.stop = dw_mci_idmac_stop_dma, @@ -772,6 +773,7 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)  static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)  {  	struct dw_mci_slot *slot = mmc_priv(mmc); +	struct dw_mci_drv_data *drv_data = slot->host->drv_data;  	u32 regs;  	/* set default 1 bit mode */ @@ -807,8 +809,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)  		slot->clock = ios->clock;  	} -	if (slot->host->drv_data->set_ios) -		slot->host->drv_data->set_ios(slot->host, ios); +	if (drv_data && drv_data->set_ios) +		drv_data->set_ios(slot->host, ios);  	switch (ios->power_mode) {  	case MMC_POWER_UP: @@ -1815,6 +1817,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)  {  	struct mmc_host *mmc;  	struct dw_mci_slot *slot; +	struct dw_mci_drv_data *drv_data = host->drv_data;  	int ctrl_id, ret;  	u8 bus_width; @@ -1854,8 +1857,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)  	} else {  		ctrl_id = to_platform_device(host->dev)->id;  	} -	if (host->drv_data && host->drv_data->caps) -		mmc->caps |= host->drv_data->caps[ctrl_id]; +	if (drv_data && drv_data->caps) +		mmc->caps |= drv_data->caps[ctrl_id];  	if (host->pdata->caps2)  		mmc->caps2 = host->pdata->caps2; @@ -1867,10 +1870,10 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)  	else  		bus_width = 1; -	if (host->drv_data->setup_bus) { +	if (drv_data && drv_data->setup_bus) {  		struct device_node *slot_np;  		slot_np = dw_mci_of_find_slot_node(host->dev, slot->id); -		ret = host->drv_data->setup_bus(host, slot_np, bus_width); +		ret = drv_data->setup_bus(host, slot_np, bus_width);  		if (ret)  			goto err_setup_bus;  	} @@ -1968,7 +1971,7 @@ static void dw_mci_init_dma(struct dw_mci *host)  	/* Determine which DMA interface to use */  #ifdef CONFIG_MMC_DW_IDMAC  	host->dma_ops = &dw_mci_idmac_ops; -	dev_info(&host->dev, "Using internal DMA controller.\n"); +	dev_info(host->dev, "Using internal DMA controller.\n");  #endif  	if (!host->dma_ops) @@ -2035,6 +2038,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)  	struct dw_mci_board *pdata;  	struct device *dev = host->dev;  	struct device_node *np = dev->of_node; +	struct dw_mci_drv_data *drv_data = host->drv_data;  	int idx, ret;  	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); @@ -2062,8 +2066,8 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)  	of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); -	if (host->drv_data->parse_dt) { -		ret = host->drv_data->parse_dt(host); +	if (drv_data && drv_data->parse_dt) { +		ret = drv_data->parse_dt(host);  		if (ret)  			return ERR_PTR(ret);  	} @@ -2080,6 +2084,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)  int dw_mci_probe(struct dw_mci *host)  { +	struct dw_mci_drv_data *drv_data = host->drv_data;  	int width, i, ret = 0;  	u32 fifo_size;  	int init_slots = 0; @@ -2127,8 +2132,8 @@ int dw_mci_probe(struct dw_mci *host)  	else  		host->bus_hz = clk_get_rate(host->ciu_clk); -	if (host->drv_data->setup_clock) { -		ret = host->drv_data->setup_clock(host); +	if (drv_data && drv_data->setup_clock) { +		ret = drv_data->setup_clock(host);  		if (ret) {  			dev_err(host->dev,  				"implementation specific clock setup failed\n"); @@ -2228,6 +2233,21 @@ int dw_mci_probe(struct dw_mci *host)  	else  		host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; +	/* +	 * Enable interrupts for command done, data over, data empty, card det, +	 * receive ready and error such as transmit, receive timeout, crc error +	 */ +	mci_writel(host, RINTSTS, 0xFFFFFFFF); +	mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | +		   SDMMC_INT_TXDR | SDMMC_INT_RXDR | +		   DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); +	mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ + +	dev_info(host->dev, "DW MMC controller at irq %d, " +		 "%d bit host data width, " +		 "%u deep fifo\n", +		 host->irq, width, fifo_size); +  	/* We need at least one slot to succeed */  	for (i = 0; i < host->num_slots; i++) {  		ret = dw_mci_init_slot(host, i); @@ -2257,20 +2277,6 @@ int dw_mci_probe(struct dw_mci *host)  	else  		host->data_offset = DATA_240A_OFFSET; -	/* -	 * Enable interrupts for command done, data over, data empty, card det, -	 * receive ready and error such as transmit, receive timeout, crc error -	 */ -	mci_writel(host, RINTSTS, 0xFFFFFFFF); -	mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | -		   SDMMC_INT_TXDR | SDMMC_INT_RXDR | -		   DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); -	mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ - -	dev_info(host->dev, "DW MMC controller at irq %d, " -		 "%d bit host data width, " -		 "%u deep fifo\n", -		 host->irq, width, fifo_size);  	if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO)  		dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n");  |