rapidio/tsi721_dma: add channel mask and queue size parameters
[cascardo/linux.git] / drivers / rapidio / devices / tsi721_dma.c
index 155cae1..13c669b 100644 (file)
 
 #include "tsi721.h"
 
-#define TSI721_DMA_TX_QUEUE_SZ 16      /* number of transaction descriptors */
-
 #ifdef CONFIG_PCI_MSI
 static irqreturn_t tsi721_bdma_msix(int irq, void *ptr);
 #endif
 static int tsi721_submit_sg(struct tsi721_tx_desc *desc);
 
 static unsigned int dma_desc_per_channel = 128;
-module_param(dma_desc_per_channel, uint, S_IWUSR | S_IRUGO);
+module_param(dma_desc_per_channel, uint, S_IRUGO);
 MODULE_PARM_DESC(dma_desc_per_channel,
                 "Number of DMA descriptors per channel (default: 128)");
 
+static unsigned int dma_txqueue_sz = 16;
+module_param(dma_txqueue_sz, uint, S_IRUGO);
+MODULE_PARM_DESC(dma_txqueue_sz,
+                "DMA Transactions Queue Size (default: 16)");
+
+static u8 dma_sel = 0x7f;
+module_param(dma_sel, byte, S_IRUGO);
+MODULE_PARM_DESC(dma_sel,
+                "DMA Channel Selection Mask (default: 0x7f = all)");
+
 static inline struct tsi721_bdma_chan *to_tsi721_chan(struct dma_chan *chan)
 {
        return container_of(chan, struct tsi721_bdma_chan, dchan);
@@ -732,7 +740,7 @@ static int tsi721_alloc_chan_resources(struct dma_chan *dchan)
        tsi_debug(DMA, &dchan->dev->device, "DMAC%d", bdma_chan->id);
 
        if (bdma_chan->bd_base)
-               return TSI721_DMA_TX_QUEUE_SZ;
+               return dma_txqueue_sz;
 
        /* Initialize BDMA channel */
        if (tsi721_bdma_ch_init(bdma_chan, dma_desc_per_channel)) {
@@ -742,7 +750,7 @@ static int tsi721_alloc_chan_resources(struct dma_chan *dchan)
        }
 
        /* Allocate queue of transaction descriptors */
-       desc = kcalloc(TSI721_DMA_TX_QUEUE_SZ, sizeof(struct tsi721_tx_desc),
+       desc = kcalloc(dma_txqueue_sz, sizeof(struct tsi721_tx_desc),
                        GFP_ATOMIC);
        if (!desc) {
                tsi_err(&dchan->dev->device,
@@ -754,7 +762,7 @@ static int tsi721_alloc_chan_resources(struct dma_chan *dchan)
 
        bdma_chan->tx_desc = desc;
 
-       for (i = 0; i < TSI721_DMA_TX_QUEUE_SZ; i++) {
+       for (i = 0; i < dma_txqueue_sz; i++) {
                dma_async_tx_descriptor_init(&desc[i].txd, dchan);
                desc[i].txd.tx_submit = tsi721_tx_submit;
                desc[i].txd.flags = DMA_CTRL_ACK;
@@ -766,7 +774,7 @@ static int tsi721_alloc_chan_resources(struct dma_chan *dchan)
        bdma_chan->active = true;
        tsi721_bdma_interrupt_enable(bdma_chan, 1);
 
-       return TSI721_DMA_TX_QUEUE_SZ;
+       return dma_txqueue_sz;
 }
 
 static void tsi721_sync_dma_irq(struct tsi721_bdma_chan *bdma_chan)
@@ -962,7 +970,7 @@ void tsi721_dma_stop_all(struct tsi721_device *priv)
        int i;
 
        for (i = 0; i < TSI721_DMA_MAXCH; i++) {
-               if (i != TSI721_DMACH_MAINT)
+               if ((i != TSI721_DMACH_MAINT) && (dma_sel & (1 << i)))
                        tsi721_dma_stop(&priv->bdma[i]);
        }
 }
@@ -979,7 +987,7 @@ int tsi721_register_dma(struct tsi721_device *priv)
        for (i = 0; i < TSI721_DMA_MAXCH; i++) {
                struct tsi721_bdma_chan *bdma_chan = &priv->bdma[i];
 
-               if (i == TSI721_DMACH_MAINT)
+               if ((i == TSI721_DMACH_MAINT) || (dma_sel & (1 << i)) == 0)
                        continue;
 
                bdma_chan->regs = priv->regs + TSI721_DMAC_BASE(i);