Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 233284
b: refs/heads/master
c: 8179661
h: refs/heads/master
v: v3
  • Loading branch information
Russell King - ARM Linux authored and Dan Williams committed Jan 31, 2011
1 parent f7c1813 commit 8c8a253
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 7 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: fb526210b2b961b5d590b89fd8f45c0ca5769688
refs/heads/master: 8179661694595eb3a4f2ff9bb0b73acbb7d2f4a9
21 changes: 15 additions & 6 deletions trunk/drivers/dma/amba-pl08x.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/dmapool.h>
#include <linux/dmaengine.h>
#include <linux/amba/bus.h>
Expand Down Expand Up @@ -235,25 +236,33 @@ static void pl08x_start_txd(struct pl08x_dma_chan *plchan,
}

/*
* Overall DMAC remains enabled always.
* Pause the channel by setting the HALT bit.
*
* Disabling individual channels could lose data.
* For M->P transfers, pause the DMAC first and then stop the peripheral -
* the FIFO can only drain if the peripheral is still requesting data.
* (note: this can still timeout if the DMAC FIFO never drains of data.)
*
* Disable the peripheral DMA after disabling the DMAC in order to allow
* the DMAC FIFO to drain, and hence allow the channel to show inactive
* For P->M transfers, disable the peripheral first to stop it filling
* the DMAC FIFO, and then pause the DMAC.
*/
static void pl08x_pause_phy_chan(struct pl08x_phy_chan *ch)
{
u32 val;
int timeout;

/* Set the HALT bit and wait for the FIFO to drain */
val = readl(ch->base + PL080_CH_CONFIG);
val |= PL080_CONFIG_HALT;
writel(val, ch->base + PL080_CH_CONFIG);

/* Wait for channel inactive */
while (pl08x_phy_channel_busy(ch))
cpu_relax();
for (timeout = 1000; timeout; timeout--) {
if (!pl08x_phy_channel_busy(ch))
break;
udelay(1);
}
if (pl08x_phy_channel_busy(ch))
pr_err("pl08x: channel%u timeout waiting for pause\n", ch->id);
}

static void pl08x_resume_phy_chan(struct pl08x_phy_chan *ch)
Expand Down

0 comments on commit 8c8a253

Please sign in to comment.