Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a914ded2 authored by Juha Yrjola's avatar Juha Yrjola Committed by Pierre Ossman
Browse files

MMC: OMAP: New release dma and abort xfer functions



New functions to support MMC multislot:
mmc_omap_release_dma() and mmc_omap_abort_xfer().

Signed-off-by: default avatarJuha Yrjola <juha.yrjola@solidboot.com>
Signed-off-by: default avatarCarlos Eduardo Aguiar <carlos.aguiar@indt.org.br>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
Signed-off-by: default avatarPierre Ossman <drzeus@drzeus.cx>
parent 5a0f3f1f
Loading
Loading
Loading
Loading
+60 −19
Original line number Diff line number Diff line
@@ -327,9 +327,9 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd)
}

static void
mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
mmc_omap_release_dma(struct mmc_omap_host *host, struct mmc_data *data,
		     int abort)
{
	if (host->dma_in_use) {
	enum dma_data_direction dma_data_dir;

	BUG_ON(host->dma_ch < 0);
@@ -344,9 +344,15 @@ mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
	dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len,
		     dma_data_dir);
}

static void
mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
{
	if (host->dma_in_use)
		mmc_omap_release_dma(host, data, data->error);

	host->data = NULL;
	host->sg_len = 0;
	clk_disable(host->fclk);

	/* NOTE:  MMC layer will sometimes poll-wait CMD13 next, issuing
	 * dozens of requests until the card finishes writing data.
@@ -354,14 +360,44 @@ mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
	 */

	if (!data->stop) {
		struct mmc_host *mmc;

		host->mrq = NULL;
		mmc_request_done(host->mmc, data->mrq);
		mmc = host->mmc;
		mmc_omap_release_slot(host->current_slot);
		mmc_request_done(mmc, data->mrq);
		return;
	}

	mmc_omap_start_command(host, data->stop);
}

static void
mmc_omap_abort_xfer(struct mmc_omap_host *host, struct mmc_data *data)
{
	int loops;
	u16 ie;

	if (host->dma_in_use)
		mmc_omap_release_dma(host, data, 1);

	host->data = NULL;
	host->sg_len = 0;

	ie = OMAP_MMC_READ(host, IE);
	OMAP_MMC_WRITE(host, IE, 0);
	OMAP_MMC_WRITE(host, CMD, 1 << 7);
	loops = 0;
	while (!(OMAP_MMC_READ(host, STAT) & OMAP_MMC_STAT_END_OF_CMD)) {
		udelay(1);
		loops++;
		if (loops == 100000)
			break;
	}
	OMAP_MMC_WRITE(host, STAT, OMAP_MMC_STAT_END_OF_CMD);
	OMAP_MMC_WRITE(host, IE, ie);
}

static void
mmc_omap_end_of_data(struct mmc_omap_host *host, struct mmc_data *data)
{
@@ -439,9 +475,14 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
	}

	if (host->data == NULL || cmd->error) {
		struct mmc_host *mmc;

		if (host->data != NULL)
			mmc_omap_abort_xfer(host, host->data);
		host->mrq = NULL;
		clk_disable(host->fclk);
		mmc_request_done(host->mmc, cmd->mrq);
		mmc = host->mmc;
		mmc_omap_release_slot(host->current_slot);
		mmc_request_done(mmc, cmd->mrq);
	}
}