|
@@ -54,8 +54,7 @@ static void sdhci_finish_command(struct sdhci_host *);
|
|
static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
|
|
static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
|
|
static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable);
|
|
static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable);
|
|
static int sdhci_pre_dma_transfer(struct sdhci_host *host,
|
|
static int sdhci_pre_dma_transfer(struct sdhci_host *host,
|
|
- struct mmc_data *data,
|
|
|
|
- struct sdhci_host_next *next);
|
|
|
|
|
|
+ struct mmc_data *data);
|
|
static int sdhci_do_get_cd(struct sdhci_host *host);
|
|
static int sdhci_do_get_cd(struct sdhci_host *host);
|
|
|
|
|
|
#ifdef CONFIG_PM
|
|
#ifdef CONFIG_PM
|
|
@@ -495,7 +494,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host,
|
|
goto fail;
|
|
goto fail;
|
|
BUG_ON(host->align_addr & host->align_mask);
|
|
BUG_ON(host->align_addr & host->align_mask);
|
|
|
|
|
|
- host->sg_count = sdhci_pre_dma_transfer(host, data, NULL);
|
|
|
|
|
|
+ host->sg_count = sdhci_pre_dma_transfer(host, data);
|
|
if (host->sg_count < 0)
|
|
if (host->sg_count < 0)
|
|
goto unmap_align;
|
|
goto unmap_align;
|
|
|
|
|
|
@@ -634,9 +633,11 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if (!data->host_cookie)
|
|
|
|
|
|
+ if (data->host_cookie == COOKIE_MAPPED) {
|
|
dma_unmap_sg(mmc_dev(host->mmc), data->sg,
|
|
dma_unmap_sg(mmc_dev(host->mmc), data->sg,
|
|
data->sg_len, direction);
|
|
data->sg_len, direction);
|
|
|
|
+ data->host_cookie = COOKIE_UNMAPPED;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
|
|
static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
|
|
@@ -832,7 +833,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
|
|
} else {
|
|
} else {
|
|
int sg_cnt;
|
|
int sg_cnt;
|
|
|
|
|
|
- sg_cnt = sdhci_pre_dma_transfer(host, data, NULL);
|
|
|
|
|
|
+ sg_cnt = sdhci_pre_dma_transfer(host, data);
|
|
if (sg_cnt <= 0) {
|
|
if (sg_cnt <= 0) {
|
|
/*
|
|
/*
|
|
* This only happens when someone fed
|
|
* This only happens when someone fed
|
|
@@ -948,11 +949,13 @@ static void sdhci_finish_data(struct sdhci_host *host)
|
|
if (host->flags & SDHCI_USE_ADMA)
|
|
if (host->flags & SDHCI_USE_ADMA)
|
|
sdhci_adma_table_post(host, data);
|
|
sdhci_adma_table_post(host, data);
|
|
else {
|
|
else {
|
|
- if (!data->host_cookie)
|
|
|
|
|
|
+ if (data->host_cookie == COOKIE_MAPPED) {
|
|
dma_unmap_sg(mmc_dev(host->mmc),
|
|
dma_unmap_sg(mmc_dev(host->mmc),
|
|
data->sg, data->sg_len,
|
|
data->sg, data->sg_len,
|
|
(data->flags & MMC_DATA_READ) ?
|
|
(data->flags & MMC_DATA_READ) ?
|
|
DMA_FROM_DEVICE : DMA_TO_DEVICE);
|
|
DMA_FROM_DEVICE : DMA_TO_DEVICE);
|
|
|
|
+ data->host_cookie = COOKIE_UNMAPPED;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2116,49 +2119,36 @@ static void sdhci_post_req(struct mmc_host *mmc, struct mmc_request *mrq,
|
|
struct mmc_data *data = mrq->data;
|
|
struct mmc_data *data = mrq->data;
|
|
|
|
|
|
if (host->flags & SDHCI_REQ_USE_DMA) {
|
|
if (host->flags & SDHCI_REQ_USE_DMA) {
|
|
- if (data->host_cookie)
|
|
|
|
|
|
+ if (data->host_cookie == COOKIE_GIVEN ||
|
|
|
|
+ data->host_cookie == COOKIE_MAPPED)
|
|
dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
|
|
dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
|
|
data->flags & MMC_DATA_WRITE ?
|
|
data->flags & MMC_DATA_WRITE ?
|
|
DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
|
DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
|
- mrq->data->host_cookie = 0;
|
|
|
|
|
|
+ data->host_cookie = COOKIE_UNMAPPED;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static int sdhci_pre_dma_transfer(struct sdhci_host *host,
|
|
static int sdhci_pre_dma_transfer(struct sdhci_host *host,
|
|
- struct mmc_data *data,
|
|
|
|
- struct sdhci_host_next *next)
|
|
|
|
|
|
+ struct mmc_data *data)
|
|
{
|
|
{
|
|
int sg_count;
|
|
int sg_count;
|
|
|
|
|
|
- if (!next && data->host_cookie &&
|
|
|
|
- data->host_cookie != host->next_data.cookie) {
|
|
|
|
- pr_debug(DRIVER_NAME "[%s] invalid cookie: %d, next-cookie %d\n",
|
|
|
|
- __func__, data->host_cookie, host->next_data.cookie);
|
|
|
|
- data->host_cookie = 0;
|
|
|
|
|
|
+ if (data->host_cookie == COOKIE_MAPPED) {
|
|
|
|
+ data->host_cookie = COOKIE_GIVEN;
|
|
|
|
+ return data->sg_count;
|
|
}
|
|
}
|
|
|
|
|
|
- /* Check if next job is already prepared */
|
|
|
|
- if (next ||
|
|
|
|
- (!next && data->host_cookie != host->next_data.cookie)) {
|
|
|
|
- sg_count = dma_map_sg(mmc_dev(host->mmc), data->sg,
|
|
|
|
- data->sg_len,
|
|
|
|
- data->flags & MMC_DATA_WRITE ?
|
|
|
|
- DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
- sg_count = host->next_data.sg_count;
|
|
|
|
- host->next_data.sg_count = 0;
|
|
|
|
- }
|
|
|
|
|
|
+ WARN_ON(data->host_cookie == COOKIE_GIVEN);
|
|
|
|
|
|
|
|
+ sg_count = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
|
|
|
|
+ data->flags & MMC_DATA_WRITE ?
|
|
|
|
+ DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
|
|
|
|
|
if (sg_count == 0)
|
|
if (sg_count == 0)
|
|
- return -EINVAL;
|
|
|
|
|
|
+ return -ENOSPC;
|
|
|
|
|
|
- if (next) {
|
|
|
|
- next->sg_count = sg_count;
|
|
|
|
- data->host_cookie = ++next->cookie < 0 ? 1 : next->cookie;
|
|
|
|
- } else
|
|
|
|
- host->sg_count = sg_count;
|
|
|
|
|
|
+ data->sg_count = sg_count;
|
|
|
|
+ data->host_cookie = COOKIE_MAPPED;
|
|
|
|
|
|
return sg_count;
|
|
return sg_count;
|
|
}
|
|
}
|
|
@@ -2168,16 +2158,10 @@ static void sdhci_pre_req(struct mmc_host *mmc, struct mmc_request *mrq,
|
|
{
|
|
{
|
|
struct sdhci_host *host = mmc_priv(mmc);
|
|
struct sdhci_host *host = mmc_priv(mmc);
|
|
|
|
|
|
- if (mrq->data->host_cookie) {
|
|
|
|
- mrq->data->host_cookie = 0;
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
|
|
+ mrq->data->host_cookie = COOKIE_UNMAPPED;
|
|
|
|
|
|
if (host->flags & SDHCI_REQ_USE_DMA)
|
|
if (host->flags & SDHCI_REQ_USE_DMA)
|
|
- if (sdhci_pre_dma_transfer(host,
|
|
|
|
- mrq->data,
|
|
|
|
- &host->next_data) < 0)
|
|
|
|
- mrq->data->host_cookie = 0;
|
|
|
|
|
|
+ sdhci_pre_dma_transfer(host, mrq->data);
|
|
}
|
|
}
|
|
|
|
|
|
static void sdhci_card_event(struct mmc_host *mmc)
|
|
static void sdhci_card_event(struct mmc_host *mmc)
|
|
@@ -3049,7 +3033,6 @@ int sdhci_add_host(struct sdhci_host *host)
|
|
host->max_clk = host->ops->get_max_clock(host);
|
|
host->max_clk = host->ops->get_max_clock(host);
|
|
}
|
|
}
|
|
|
|
|
|
- host->next_data.cookie = 1;
|
|
|
|
/*
|
|
/*
|
|
* In case of Host Controller v3.00, find out whether clock
|
|
* In case of Host Controller v3.00, find out whether clock
|
|
* multiplier is supported.
|
|
* multiplier is supported.
|