Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 321120
b: refs/heads/master
c: 3850e22
h: refs/heads/master
v: v3
  • Loading branch information
Russell King committed Jul 31, 2012
1 parent a27e2c5 commit 086fa05
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 6 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: 7bedaa5537604f34d1d63c5ec7891e559d2a61ed
refs/heads/master: 3850e22f5146d2ff5b66f1b7460d4720d5f1b6c7
69 changes: 64 additions & 5 deletions trunk/drivers/dma/omap-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,73 @@ static void omap_dma_free_chan_resources(struct dma_chan *chan)
dev_info(c->vc.chan.device->dev, "freeing channel for %u\n", c->dma_sig);
}

static size_t omap_dma_sg_size(struct omap_sg *sg)
{
return sg->en * sg->fn;
}

static size_t omap_dma_desc_size(struct omap_desc *d)
{
unsigned i;
size_t size;

for (size = i = 0; i < d->sglen; i++)
size += omap_dma_sg_size(&d->sg[i]);

return size * es_bytes[d->es];
}

static size_t omap_dma_desc_size_pos(struct omap_desc *d, dma_addr_t addr)
{
unsigned i;
size_t size, es_size = es_bytes[d->es];

for (size = i = 0; i < d->sglen; i++) {
size_t this_size = omap_dma_sg_size(&d->sg[i]) * es_size;

if (size)
size += this_size;
else if (addr >= d->sg[i].addr &&
addr < d->sg[i].addr + this_size)
size += d->sg[i].addr + this_size - addr;
}
return size;
}

static enum dma_status omap_dma_tx_status(struct dma_chan *chan,
dma_cookie_t cookie, struct dma_tx_state *txstate)
{
/*
* FIXME: do we need to return pending bytes?
* We have no users of that info at the moment...
*/
return dma_cookie_status(chan, cookie, txstate);
struct omap_chan *c = to_omap_dma_chan(chan);
struct virt_dma_desc *vd;
enum dma_status ret;
unsigned long flags;

ret = dma_cookie_status(chan, cookie, txstate);
if (ret == DMA_SUCCESS || !txstate)
return ret;

spin_lock_irqsave(&c->vc.lock, flags);
vd = vchan_find_desc(&c->vc, cookie);
if (vd) {
txstate->residue = omap_dma_desc_size(to_omap_dma_desc(&vd->tx));
} else if (c->desc && c->desc->vd.tx.cookie == cookie) {
struct omap_desc *d = c->desc;
dma_addr_t pos;

if (d->dir == DMA_MEM_TO_DEV)
pos = omap_get_dma_src_pos(c->dma_ch);
else if (d->dir == DMA_DEV_TO_MEM)
pos = omap_get_dma_dst_pos(c->dma_ch);
else
pos = 0;

txstate->residue = omap_dma_desc_size_pos(d, pos);
} else {
txstate->residue = 0;
}
spin_unlock_irqrestore(&c->vc.lock, flags);

return ret;
}

static void omap_dma_issue_pending(struct dma_chan *chan)
Expand Down

0 comments on commit 086fa05

Please sign in to comment.