diff options
author | Chen Liangjun <b36089@freescale.com> | 2012-08-02 12:34:30 +0800 |
---|---|---|
committer | Chen Liangjun <b36089@freescale.com> | 2012-08-02 15:06:29 +0800 |
commit | 57b4747af965999a2cb7efbdc76b3841621f398b (patch) | |
tree | 534c73464fc5a0916f55cc67984986f638834e72 /drivers/dma | |
parent | 614556c6c57fa76b6ec207d7c32f9c291d7b0528 (diff) |
ENGR00219160 SDMA: replace SDMA LOOP/NORMAL type with enum struct
For common DMA enguine, only slave_sg mode and cyclic mode is support.
However, SDMA can meet more kinds of DMA operation mode requirement. The
origin flags NORMAL and LOOP can no longer satisfy SDMA user's need.
In this patch,
1 Construct a new enum sdma_mode to declare more kind of SDMA
modes. This new variable would replace the old flags.
2 Init sdma_mode to unvalid every time allocating a SDMA channel
to avoid last SDMA channel configuration's impact.
Signed-off-by: Chen Liangjun <b36089@freescale.com>
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/imx-sdma.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index dc539f91efc6..d4caaa4ad966 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -226,6 +226,14 @@ struct sdma_context_data { struct sdma_engine; +enum sdma_mode { + SDMA_MODE_INVALID = 0, + SDMA_MODE_LOOP, + SDMA_MODE_NORMAL, + SDMA_MODE_P2P, + SDMA_MODE_NO_BD, +}; + /** * struct sdma_channel - housekeeping for a SDMA channel * @@ -257,7 +265,7 @@ struct sdma_channel { unsigned int pc_to_device; unsigned int device_to_device; unsigned int other_script; - unsigned long flags; + enum sdma_mode mode; dma_addr_t per_address, per_address2; u32 event_mask0, event_mask1; u32 watermark_level; @@ -272,10 +280,6 @@ struct sdma_channel { unsigned int chn_real_count; }; -#define IMX_DMA_SG_LOOP (1 << 0) -#define IMX_DMA_INT_OTHER (1 << 1) -#define IMX_DMA_INT_P2P (1 << 2) - #define MAX_DMA_CHANNELS 32 #define MXC_SDMA_DEFAULT_PRIORITY 1 #define MXC_SDMA_MIN_PRIORITY 1 @@ -514,12 +518,20 @@ static void mxc_sdma_handle_channel(struct sdma_channel *sdmac) if (sdmac->channel == 0) return; - if (sdmac->flags & IMX_DMA_SG_LOOP) + switch (sdmac->mode) { + case SDMA_MODE_LOOP: sdma_handle_channel_loop(sdmac); - else if (sdmac->flags & IMX_DMA_INT_OTHER) - sdma_handle_other_intr(sdmac); - else + break; + case SDMA_MODE_NORMAL: mxc_sdma_handle_channel_normal(sdmac); + break; + case SDMA_MODE_NO_BD: + sdma_handle_other_intr(sdmac); + break; + default: + pr_err("Unvalid SDMA MODE!\n"); + break; + } } static irqreturn_t sdma_int_handler(int irq, void *dev_id) @@ -956,6 +968,9 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan) /* txd.flags will be overwritten in prep funcs */ sdmac->desc.flags = DMA_CTRL_ACK; + /* Set SDMA channel mode to unvalid to avoid misconfig */ + sdmac->mode = SDMA_MODE_INVALID; + return 0; } @@ -996,7 +1011,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( return NULL; sdmac->status = DMA_IN_PROGRESS; - sdmac->flags = 0; + sdmac->mode = SDMA_MODE_NORMAL; dev_dbg(sdma->dev, "setting up %d entries for channel %d.\n", sg_len, channel); @@ -1100,14 +1115,14 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( switch (sdmac->direction) { case DMA_DEV_TO_DEV: - sdmac->flags |= IMX_DMA_INT_P2P; + sdmac->mode = SDMA_MODE_P2P; break; case DMA_TRANS_NONE: - sdmac->flags |= IMX_DMA_INT_OTHER; + sdmac->mode = SDMA_MODE_NO_BD; break; case DMA_MEM_TO_DEV: case DMA_DEV_TO_MEM: - sdmac->flags |= IMX_DMA_SG_LOOP; + sdmac->mode = SDMA_MODE_LOOP; break; default: pr_err("SDMA direction is not support!"); |