static int tegra_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { void *buf; unsigned int bbflags; size_t len; struct bounce_buffer bbstate; int ret; if (data) { if (data->flags & MMC_DATA_READ) { buf = data->dest; bbflags = GEN_BB_WRITE; } else { buf = (void *)data->src; bbflags = GEN_BB_READ; } len = data->blocks * data->blocksize; bounce_buffer_start(&bbstate, buf, len, bbflags); } ret = mmc_send_cmd_bounced(mmc, cmd, data, &bbstate); if (data) bounce_buffer_stop(&bbstate); return ret; }
static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data) { uint32_t data_count = data->blocksize * data->blocks; int dmach; struct mxs_dma_desc *desc = priv->desc; void *addr; unsigned int flags; struct bounce_buffer bbstate; memset(desc, 0, sizeof(struct mxs_dma_desc)); desc->address = (dma_addr_t)desc; if (data->flags & MMC_DATA_READ) { priv->desc->cmd.data = MXS_DMA_DESC_COMMAND_DMA_WRITE; addr = data->dest; flags = GEN_BB_WRITE; } else { priv->desc->cmd.data = MXS_DMA_DESC_COMMAND_DMA_READ; addr = (void *)data->src; flags = GEN_BB_READ; } bounce_buffer_start(&bbstate, addr, data_count, flags); priv->desc->cmd.address = (dma_addr_t)bbstate.bounce_buffer; priv->desc->cmd.data |= MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM | (data_count << MXS_DMA_DESC_BYTES_OFFSET); dmach = MXS_DMA_CHANNEL_AHB_APBH_SSP0 + priv->id + mxsmmc_id_offset; mxs_dma_desc_append(dmach, priv->desc); if (mxs_dma_go(dmach)) { bounce_buffer_stop(&bbstate); return COMM_ERR; } bounce_buffer_stop(&bbstate); return 0; }