Skip to content

Instantly share code, notes, and snippets.

@HiassofT
Created December 21, 2015 17:41
Show Gist options
  • Save HiassofT/639a2069d56b2874fce9 to your computer and use it in GitHub Desktop.
Save HiassofT/639a2069d56b2874fce9 to your computer and use it in GitHub Desktop.
cyclic code diff to upstream+dmapool patch
index 996c4b0..773b23e9 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -358,9 +376,18 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
struct bcm2835_desc *d;
dma_addr_t dev_addr;
unsigned int es, sync_type;
- unsigned int frame;
+ unsigned int frame, max_size;
int i;
+ if (!buf_len || !period_len)
+ return NULL;
+
+ if (buf_len % period_len) {
+ dev_err(chan->device->dev,
+ "Buffer length should be a multiple of period\n");
+ return NULL;
+ }
+
/* Grab configuration */
if (!is_slave_direction(direction)) {
dev_err(chan->device->dev, "%s: bad direction?\n", __func__);
@@ -386,6 +413,18 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
return NULL;
}
+ if (c->ch >= 8) /* LITE channel */
+ max_size = MAX_LITE_TRANSFER;
+ else
+ max_size = MAX_NORMAL_TRANSFER;
+
+ if (period_len > max_size) {
+ dev_err(chan->device->dev,
+ "Period length %d larger than maximum %d\n",
+ period_len, max_size);
+ return NULL;
+ }
+
/* Now allocate and setup the descriptor. */
d = kzalloc(sizeof(*d), GFP_NOWAIT);
if (!d)
@@ -446,12 +485,14 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
/*
* Next block is the next frame.
- * This DMA engine driver currently only supports cyclic DMA.
+ * This function is called on cyclic DMA transfers.
* Therefore, wrap around at number of frames.
*/
control_block->next = d->cb_list[((frame + 1) % d->frames)].paddr;
}
+ c->cyclic = true;
+
return vchan_tx_prep(&c->vc, &d->vd, flags);
error_cb:
i--;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment