提交 ab59a510 编写于 作者: H Huang Shijie 提交者: Vinod Koul

IMX/SDMA : save the real count for one DMA transaction.

When we use the SDMA in the UART driver(such as imx6q), we will
meet one situation:
  Assume we set 64 bytes for the RX DMA buffer.
  The RX DMA buffer has received some data, but not full.
  An Aging DMA request will be received by the SDMA controller if we enable the
  IDDMAEN(UCR4[6]) in this case.

So the UART driver needs to know the count of the real received bytes,
and push them to upper layer.

Add two new fields to sdmac, and update the `residue` in sdma_tx_status().
Signed-off-by: NHuang Shijie <b32955@freescale.com>
Signed-off-by: NVinod Koul <vinod.koul@linux.intel.com>
上级 6d0709d2
...@@ -268,6 +268,8 @@ struct sdma_channel { ...@@ -268,6 +268,8 @@ struct sdma_channel {
struct dma_async_tx_descriptor desc; struct dma_async_tx_descriptor desc;
dma_cookie_t last_completed; dma_cookie_t last_completed;
enum dma_status status; enum dma_status status;
unsigned int chn_count;
unsigned int chn_real_count;
}; };
#define IMX_DMA_SG_LOOP (1 << 0) #define IMX_DMA_SG_LOOP (1 << 0)
...@@ -503,6 +505,7 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac) ...@@ -503,6 +505,7 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
struct sdma_buffer_descriptor *bd; struct sdma_buffer_descriptor *bd;
int i, error = 0; int i, error = 0;
sdmac->chn_real_count = 0;
/* /*
* non loop mode. Iterate over all descriptors, collect * non loop mode. Iterate over all descriptors, collect
* errors and call callback function * errors and call callback function
...@@ -512,6 +515,7 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac) ...@@ -512,6 +515,7 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
if (bd->mode.status & (BD_DONE | BD_RROR)) if (bd->mode.status & (BD_DONE | BD_RROR))
error = -EIO; error = -EIO;
sdmac->chn_real_count += bd->mode.count;
} }
if (error) if (error)
...@@ -519,9 +523,9 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac) ...@@ -519,9 +523,9 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
else else
sdmac->status = DMA_SUCCESS; sdmac->status = DMA_SUCCESS;
sdmac->last_completed = sdmac->desc.cookie;
if (sdmac->desc.callback) if (sdmac->desc.callback)
sdmac->desc.callback(sdmac->desc.callback_param); sdmac->desc.callback(sdmac->desc.callback_param);
sdmac->last_completed = sdmac->desc.cookie;
} }
static void mxc_sdma_handle_channel(struct sdma_channel *sdmac) static void mxc_sdma_handle_channel(struct sdma_channel *sdmac)
...@@ -941,6 +945,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( ...@@ -941,6 +945,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
goto err_out; goto err_out;
} }
sdmac->chn_count = 0;
for_each_sg(sgl, sg, sg_len, i) { for_each_sg(sgl, sg, sg_len, i) {
struct sdma_buffer_descriptor *bd = &sdmac->bd[i]; struct sdma_buffer_descriptor *bd = &sdmac->bd[i];
int param; int param;
...@@ -957,6 +962,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( ...@@ -957,6 +962,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
} }
bd->mode.count = count; bd->mode.count = count;
sdmac->chn_count += count;
if (sdmac->word_size > DMA_SLAVE_BUSWIDTH_4_BYTES) { if (sdmac->word_size > DMA_SLAVE_BUSWIDTH_4_BYTES) {
ret = -EINVAL; ret = -EINVAL;
...@@ -1120,7 +1126,8 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan, ...@@ -1120,7 +1126,8 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
last_used = chan->cookie; last_used = chan->cookie;
dma_set_tx_state(txstate, sdmac->last_completed, last_used, 0); dma_set_tx_state(txstate, sdmac->last_completed, last_used,
sdmac->chn_count - sdmac->chn_real_count);
return sdmac->status; return sdmac->status;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册