@@ -775,21 +775,23 @@ static void sdma_start_desc(struct sdma_channel *sdmac)
static void sdma_update_channel_loop(struct sdma_channel *sdmac)
{
struct sdma_buffer_descriptor *bd;
- int error = 0;
- enum dma_status old_status = sdmac->status;
+ struct sdma_desc *desc = sdmac->desc;
+ int error = 0, cnt = 0;
+ enum dma_status old_status = sdmac->status;
/*
* loop mode. Iterate over descriptors, re-setup them and
* call callback function.
*/
- while (sdmac->desc) {
- struct sdma_desc *desc = sdmac->desc;
+ while (desc) {
bd = &desc->bd[desc->buf_tail];
if (bd->mode.status & BD_DONE)
break;
+ cnt++;
+
if (bd->mode.status & BD_RROR) {
bd->mode.status &= ~BD_RROR;
sdmac->status = DMA_ERROR;
@@ -822,6 +824,17 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
if (error)
sdmac->status = old_status;
}
+
+ /* In some situations it may happen that the sdma does not found any
+ * usable descriptor in the ring to put data into. The channel is
+ * stopped then. While there is no specific error condition we can
+ * check for, a necessary condition is that all available buffers for
+ * the current channel have been written to by the sdma script. In
+ * this case and after we have made the buffers available again,
+ * we restart the channel.
+ */
+ if (cnt >= desc->num_bd)
+ sdma_enable_channel(sdmac->sdma, sdmac->channel);
}
static void mxc_sdma_handle_channel_normal(struct sdma_channel *data)