Skip to content

Commit

Permalink
DMAENGINE: generic channel status v2
Browse files Browse the repository at this point in the history
Convert the device_is_tx_complete() operation on the
DMA engine to a generic device_tx_status()operation which
can return three states, DMA_TX_RUNNING, DMA_TX_COMPLETE,
DMA_TX_PAUSED.

[dan.j.williams@intel.com: update for timberdale]
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Maciej Sosnowski <maciej.sosnowski@intel.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: Li Yang <leoli@freescale.com>
Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
Cc: Magnus Damm <damm@opensource.se>
Cc: Liam Girdwood <lrg@slimlogic.co.uk>
Cc: Joe Perches <joe@perches.com>
Cc: Roland Dreier <rdreier@cisco.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
Linus Walleij authored and djbw committed Mar 26, 2010
1 parent c3635c7 commit 0793448
Show file tree
Hide file tree
Showing 19 changed files with 203 additions and 172 deletions.
7 changes: 0 additions & 7 deletions arch/arm/mach-u300/include/mach/coh901318.h
Expand Up @@ -102,13 +102,6 @@ struct coh901318_platform {
const int max_channels;
};

/**
* coh901318_get_bytes_left() - Get number of bytes left on a current transfer
* @chan: dma channel handle
* return number of bytes left, or negative on error
*/
u32 coh901318_get_bytes_left(struct dma_chan *chan);

/**
* coh901318_filter_id() - DMA channel filter function
* @chan: dma channel handle
Expand Down
29 changes: 15 additions & 14 deletions drivers/dma/at_hdmac.c
Expand Up @@ -798,29 +798,25 @@ static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd)
}

/**
* atc_is_tx_complete - poll for transaction completion
* atc_tx_status - poll for transaction completion
* @chan: DMA channel
* @cookie: transaction identifier to check status of
* @done: if not %NULL, updated with last completed transaction
* @used: if not %NULL, updated with last used transaction
* @txstate: if not %NULL updated with transaction state
*
* If @done and @used are passed in, upon return they reflect the driver
* If @txstate is passed in, upon return it reflect the driver
* internal state and can be used with dma_async_is_complete() to check
* the status of multiple cookies without re-checking hardware state.
*/
static enum dma_status
atc_is_tx_complete(struct dma_chan *chan,
atc_tx_status(struct dma_chan *chan,
dma_cookie_t cookie,
dma_cookie_t *done, dma_cookie_t *used)
struct dma_tx_state *txstate)
{
struct at_dma_chan *atchan = to_at_dma_chan(chan);
dma_cookie_t last_used;
dma_cookie_t last_complete;
enum dma_status ret;

dev_vdbg(chan2dev(chan), "is_tx_complete: %d (d%d, u%d)\n",
cookie, done ? *done : 0, used ? *used : 0);

spin_lock_bh(&atchan->lock);

last_complete = atchan->completed_cookie;
Expand All @@ -838,10 +834,15 @@ atc_is_tx_complete(struct dma_chan *chan,

spin_unlock_bh(&atchan->lock);

if (done)
*done = last_complete;
if (used)
*used = last_used;
if (txstate) {
txstate->last = last_complete;
txstate->used = last_used;
txstate->residue = 0;
}

dev_vdbg(chan2dev(chan), "tx_status: %d (d%d, u%d)\n",
cookie, last_complete ? last_complete : 0,
last_used ? last_used : 0);

return ret;
}
Expand Down Expand Up @@ -1087,7 +1088,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
/* set base routines */
atdma->dma_common.device_alloc_chan_resources = atc_alloc_chan_resources;
atdma->dma_common.device_free_chan_resources = atc_free_chan_resources;
atdma->dma_common.device_is_tx_complete = atc_is_tx_complete;
atdma->dma_common.device_tx_status = atc_tx_status;
atdma->dma_common.device_issue_pending = atc_issue_pending;
atdma->dma_common.dev = &pdev->dev;

Expand Down
25 changes: 13 additions & 12 deletions drivers/dma/coh901318.c
Expand Up @@ -426,7 +426,7 @@ static inline u32 coh901318_get_bytes_in_lli(struct coh901318_lli *in_lli)
* absolute measures, but for a rough guess you can still call
* it.
*/
u32 coh901318_get_bytes_left(struct dma_chan *chan)
static u32 coh901318_get_bytes_left(struct dma_chan *chan)
{
struct coh901318_chan *cohc = to_coh901318_chan(chan);
struct coh901318_desc *cohd;
Expand Down Expand Up @@ -503,8 +503,6 @@ u32 coh901318_get_bytes_left(struct dma_chan *chan)

return left;
}
EXPORT_SYMBOL(coh901318_get_bytes_left);


/*
* Pauses a transfer without losing data. Enables power save.
Expand Down Expand Up @@ -1136,9 +1134,8 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
}

static enum dma_status
coh901318_is_tx_complete(struct dma_chan *chan,
dma_cookie_t cookie, dma_cookie_t *done,
dma_cookie_t *used)
coh901318_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
struct dma_tx_state *txstate)
{
struct coh901318_chan *cohc = to_coh901318_chan(chan);
dma_cookie_t last_used;
Expand All @@ -1150,10 +1147,14 @@ coh901318_is_tx_complete(struct dma_chan *chan,

ret = dma_async_is_complete(cookie, last_complete, last_used);

if (done)
*done = last_complete;
if (used)
*used = last_used;
if (txstate) {
txstate->last = last_complete;
txstate->used = last_used;
txstate->residue = coh901318_get_bytes_left(chan);
}

if (ret == DMA_IN_PROGRESS && cohc->stopped)
ret = DMA_PAUSED;

return ret;
}
Expand Down Expand Up @@ -1356,7 +1357,7 @@ static int __init coh901318_probe(struct platform_device *pdev)
base->dma_slave.device_alloc_chan_resources = coh901318_alloc_chan_resources;
base->dma_slave.device_free_chan_resources = coh901318_free_chan_resources;
base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg;
base->dma_slave.device_is_tx_complete = coh901318_is_tx_complete;
base->dma_slave.device_tx_status = coh901318_tx_status;
base->dma_slave.device_issue_pending = coh901318_issue_pending;
base->dma_slave.device_control = coh901318_control;
base->dma_slave.dev = &pdev->dev;
Expand All @@ -1376,7 +1377,7 @@ static int __init coh901318_probe(struct platform_device *pdev)
base->dma_memcpy.device_alloc_chan_resources = coh901318_alloc_chan_resources;
base->dma_memcpy.device_free_chan_resources = coh901318_free_chan_resources;
base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy;
base->dma_memcpy.device_is_tx_complete = coh901318_is_tx_complete;
base->dma_memcpy.device_tx_status = coh901318_tx_status;
base->dma_memcpy.device_issue_pending = coh901318_issue_pending;
base->dma_memcpy.device_control = coh901318_control;
base->dma_memcpy.dev = &pdev->dev;
Expand Down
2 changes: 1 addition & 1 deletion drivers/dma/dmaengine.c
Expand Up @@ -698,7 +698,7 @@ int dma_async_device_register(struct dma_device *device)

BUG_ON(!device->device_alloc_chan_resources);
BUG_ON(!device->device_free_chan_resources);
BUG_ON(!device->device_is_tx_complete);
BUG_ON(!device->device_tx_status);
BUG_ON(!device->device_issue_pending);
BUG_ON(!device->dev);

Expand Down
17 changes: 9 additions & 8 deletions drivers/dma/dw_dmac.c
Expand Up @@ -819,9 +819,9 @@ static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd)
}

static enum dma_status
dwc_is_tx_complete(struct dma_chan *chan,
dma_cookie_t cookie,
dma_cookie_t *done, dma_cookie_t *used)
dwc_tx_status(struct dma_chan *chan,
dma_cookie_t cookie,
struct dma_tx_state *txstate)
{
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
dma_cookie_t last_used;
Expand All @@ -841,10 +841,11 @@ dwc_is_tx_complete(struct dma_chan *chan,
ret = dma_async_is_complete(cookie, last_complete, last_used);
}

if (done)
*done = last_complete;
if (used)
*used = last_used;
if (txstate) {
txstate->last = last_complete;
txstate->used = last_used;
txstate->residue = 0;
}

return ret;
}
Expand Down Expand Up @@ -1346,7 +1347,7 @@ static int __init dw_probe(struct platform_device *pdev)
dw->dma.device_prep_slave_sg = dwc_prep_slave_sg;
dw->dma.device_control = dwc_control;

dw->dma.device_is_tx_complete = dwc_is_tx_complete;
dw->dma.device_tx_status = dwc_tx_status;
dw->dma.device_issue_pending = dwc_issue_pending;

dma_writel(dw, CFG, DW_CFG_DMA_EN);
Expand Down
19 changes: 9 additions & 10 deletions drivers/dma/fsldma.c
Expand Up @@ -971,13 +971,12 @@ static void fsl_dma_memcpy_issue_pending(struct dma_chan *dchan)
}

/**
* fsl_dma_is_complete - Determine the DMA status
* fsl_tx_status - Determine the DMA status
* @chan : Freescale DMA channel
*/
static enum dma_status fsl_dma_is_complete(struct dma_chan *dchan,
static enum dma_status fsl_tx_status(struct dma_chan *dchan,
dma_cookie_t cookie,
dma_cookie_t *done,
dma_cookie_t *used)
struct dma_tx_state *txstate)
{
struct fsldma_chan *chan = to_fsl_chan(dchan);
dma_cookie_t last_used;
Expand All @@ -988,11 +987,11 @@ static enum dma_status fsl_dma_is_complete(struct dma_chan *dchan,
last_used = dchan->cookie;
last_complete = chan->completed_cookie;

if (done)
*done = last_complete;

if (used)
*used = last_used;
if (txstate) {
txstate->last = last_complete;
txstate->used = last_used;
txstate->residue = 0;
}

return dma_async_is_complete(cookie, last_complete, last_used);
}
Expand Down Expand Up @@ -1336,7 +1335,7 @@ static int __devinit fsldma_of_probe(struct of_device *op,
fdev->common.device_free_chan_resources = fsl_dma_free_chan_resources;
fdev->common.device_prep_dma_interrupt = fsl_dma_prep_interrupt;
fdev->common.device_prep_dma_memcpy = fsl_dma_prep_memcpy;
fdev->common.device_is_tx_complete = fsl_dma_is_complete;
fdev->common.device_tx_status = fsl_tx_status;
fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending;
fdev->common.device_prep_slave_sg = fsl_dma_prep_slave_sg;
fdev->common.device_control = fsl_dma_device_control;
Expand Down
12 changes: 6 additions & 6 deletions drivers/dma/ioat/dma.c
Expand Up @@ -726,18 +726,18 @@ static void ioat1_timer_event(unsigned long data)
}

enum dma_status
ioat_is_dma_complete(struct dma_chan *c, dma_cookie_t cookie,
dma_cookie_t *done, dma_cookie_t *used)
ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie,
struct dma_tx_state *txstate)
{
struct ioat_chan_common *chan = to_chan_common(c);
struct ioatdma_device *device = chan->device;

if (ioat_is_complete(c, cookie, done, used) == DMA_SUCCESS)
if (ioat_tx_status(c, cookie, txstate) == DMA_SUCCESS)
return DMA_SUCCESS;

device->cleanup_fn((unsigned long) c);

return ioat_is_complete(c, cookie, done, used);
return ioat_tx_status(c, cookie, txstate);
}

static void ioat1_dma_start_null_desc(struct ioat_dma_chan *ioat)
Expand Down Expand Up @@ -857,7 +857,7 @@ int __devinit ioat_dma_self_test(struct ioatdma_device *device)
tmo = wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000));

if (tmo == 0 ||
dma->device_is_tx_complete(dma_chan, cookie, NULL, NULL)
dma->device_tx_status(dma_chan, cookie, NULL)
!= DMA_SUCCESS) {
dev_err(dev, "Self-test copy timed out, disabling\n");
err = -ENODEV;
Expand Down Expand Up @@ -1198,7 +1198,7 @@ int __devinit ioat1_dma_probe(struct ioatdma_device *device, int dca)
dma->device_issue_pending = ioat1_dma_memcpy_issue_pending;
dma->device_alloc_chan_resources = ioat1_dma_alloc_chan_resources;
dma->device_free_chan_resources = ioat1_dma_free_chan_resources;
dma->device_is_tx_complete = ioat_is_dma_complete;
dma->device_tx_status = ioat_dma_tx_status;

err = ioat_probe(device);
if (err)
Expand Down
22 changes: 11 additions & 11 deletions drivers/dma/ioat/dma.h
Expand Up @@ -142,15 +142,14 @@ static inline struct ioat_dma_chan *to_ioat_chan(struct dma_chan *c)
}

/**
* ioat_is_complete - poll the status of an ioat transaction
* ioat_tx_status - poll the status of an ioat transaction
* @c: channel handle
* @cookie: transaction identifier
* @done: if set, updated with last completed transaction
* @used: if set, updated with last used transaction
* @txstate: if set, updated with the transaction state
*/
static inline enum dma_status
ioat_is_complete(struct dma_chan *c, dma_cookie_t cookie,
dma_cookie_t *done, dma_cookie_t *used)
ioat_tx_status(struct dma_chan *c, dma_cookie_t cookie,
struct dma_tx_state *txstate)
{
struct ioat_chan_common *chan = to_chan_common(c);
dma_cookie_t last_used;
Expand All @@ -159,10 +158,11 @@ ioat_is_complete(struct dma_chan *c, dma_cookie_t cookie,
last_used = c->cookie;
last_complete = chan->completed_cookie;

if (done)
*done = last_complete;
if (used)
*used = last_used;
if (txstate) {
txstate->last = last_complete;
txstate->used = last_used;
txstate->residue = 0;
}

return dma_async_is_complete(cookie, last_complete, last_used);
}
Expand Down Expand Up @@ -338,8 +338,8 @@ struct dca_provider * __devinit ioat_dca_init(struct pci_dev *pdev,
unsigned long ioat_get_current_completion(struct ioat_chan_common *chan);
void ioat_init_channel(struct ioatdma_device *device,
struct ioat_chan_common *chan, int idx);
enum dma_status ioat_is_dma_complete(struct dma_chan *c, dma_cookie_t cookie,
dma_cookie_t *done, dma_cookie_t *used);
enum dma_status ioat_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie,
struct dma_tx_state *txstate);
void ioat_dma_unmap(struct ioat_chan_common *chan, enum dma_ctrl_flags flags,
size_t len, struct ioat_dma_descriptor *hw);
bool ioat_cleanup_preamble(struct ioat_chan_common *chan,
Expand Down
2 changes: 1 addition & 1 deletion drivers/dma/ioat/dma_v2.c
Expand Up @@ -854,7 +854,7 @@ int __devinit ioat2_dma_probe(struct ioatdma_device *device, int dca)
dma->device_issue_pending = ioat2_issue_pending;
dma->device_alloc_chan_resources = ioat2_alloc_chan_resources;
dma->device_free_chan_resources = ioat2_free_chan_resources;
dma->device_is_tx_complete = ioat_is_dma_complete;
dma->device_tx_status = ioat_tx_status;

err = ioat_probe(device);
if (err)
Expand Down

0 comments on commit 0793448

Please sign in to comment.