Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 255213
b: refs/heads/master
c: 9782aff
h: refs/heads/master
i:
  255211: 23b1978
v: v3
  • Loading branch information
Per Forlin authored and Chris Ball committed Jul 20, 2011
1 parent 27ca299 commit 0c89e96
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: aa8b683a7d392271ed349c6ab9f36b8c313794b7
refs/heads/master: 9782aff8df7e32e7745cc484f34ec471d9251651
87 changes: 83 additions & 4 deletions trunk/drivers/mmc/host/omap_hsmmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@
#define OMAP_HSMMC_WRITE(base, reg, val) \
__raw_writel((val), (base) + OMAP_HSMMC_##reg)

struct omap_hsmmc_next {
unsigned int dma_len;
s32 cookie;
};

struct omap_hsmmc_host {
struct device *dev;
struct mmc_host *mmc;
Expand Down Expand Up @@ -184,6 +189,7 @@ struct omap_hsmmc_host {
int reqs_blocked;
int use_reg;
int req_in_progress;
struct omap_hsmmc_next next_data;

struct omap_mmc_platform_data *pdata;
};
Expand Down Expand Up @@ -1346,8 +1352,9 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data)
return;
}

dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
omap_hsmmc_get_dma_dir(host, data));
if (!data->host_cookie)
dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
omap_hsmmc_get_dma_dir(host, data));

req_in_progress = host->req_in_progress;
dma_ch = host->dma_ch;
Expand All @@ -1365,6 +1372,45 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data)
}
}

static int omap_hsmmc_pre_dma_transfer(struct omap_hsmmc_host *host,
struct mmc_data *data,
struct omap_hsmmc_next *next)
{
int dma_len;

if (!next && data->host_cookie &&
data->host_cookie != host->next_data.cookie) {
printk(KERN_WARNING "[%s] invalid cookie: data->host_cookie %d"
" host->next_data.cookie %d\n",
__func__, data->host_cookie, host->next_data.cookie);
data->host_cookie = 0;
}

/* Check if next job is already prepared */
if (next ||
(!next && data->host_cookie != host->next_data.cookie)) {
dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
data->sg_len,
omap_hsmmc_get_dma_dir(host, data));

} else {
dma_len = host->next_data.dma_len;
host->next_data.dma_len = 0;
}


if (dma_len == 0)
return -EINVAL;

if (next) {
next->dma_len = dma_len;
data->host_cookie = ++next->cookie < 0 ? 1 : next->cookie;
} else
host->dma_len = dma_len;

return 0;
}

/*
* Routine to configure and start DMA for the MMC card
*/
Expand Down Expand Up @@ -1398,9 +1444,10 @@ static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host,
mmc_hostname(host->mmc), ret);
return ret;
}
ret = omap_hsmmc_pre_dma_transfer(host, data, NULL);
if (ret)
return ret;

host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
data->sg_len, omap_hsmmc_get_dma_dir(host, data));
host->dma_ch = dma_ch;
host->dma_sg_idx = 0;

Expand Down Expand Up @@ -1480,6 +1527,35 @@ omap_hsmmc_prepare_data(struct omap_hsmmc_host *host, struct mmc_request *req)
return 0;
}

static void omap_hsmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq,
int err)
{
struct omap_hsmmc_host *host = mmc_priv(mmc);
struct mmc_data *data = mrq->data;

if (host->use_dma) {
dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
omap_hsmmc_get_dma_dir(host, data));
data->host_cookie = 0;
}
}

static void omap_hsmmc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq,
bool is_first_req)
{
struct omap_hsmmc_host *host = mmc_priv(mmc);

if (mrq->data->host_cookie) {
mrq->data->host_cookie = 0;
return ;
}

if (host->use_dma)
if (omap_hsmmc_pre_dma_transfer(host, mrq->data,
&host->next_data))
mrq->data->host_cookie = 0;
}

/*
* Request function. for read/write operation
*/
Expand Down Expand Up @@ -1928,6 +2004,8 @@ static int omap_hsmmc_disable_fclk(struct mmc_host *mmc, int lazy)
static const struct mmc_host_ops omap_hsmmc_ops = {
.enable = omap_hsmmc_enable_fclk,
.disable = omap_hsmmc_disable_fclk,
.post_req = omap_hsmmc_post_req,
.pre_req = omap_hsmmc_pre_req,
.request = omap_hsmmc_request,
.set_ios = omap_hsmmc_set_ios,
.get_cd = omap_hsmmc_get_cd,
Expand Down Expand Up @@ -2077,6 +2155,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
host->mapbase = res->start;
host->base = ioremap(host->mapbase, SZ_4K);
host->power_mode = MMC_POWER_OFF;
host->next_data.cookie = 1;

platform_set_drvdata(pdev, host);
INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect);
Expand Down

0 comments on commit 0c89e96

Please sign in to comment.