drm/nouveau: require reservations for nouveau_fence_sync and nouveau_bo_fence
[deliverable/linux.git] / drivers / dma / sun6i-dma.c
index e9f99bbc985ea766e7488ffd9edc5f1569efb92a..1f92a56fd2b6c38279872a2257d997b9ec2ff9ca 100644 (file)
@@ -248,20 +248,11 @@ static inline int convert_burst(u32 maxburst, u8 *burst)
 
 static inline int convert_buswidth(enum dma_slave_buswidth addr_width, u8 *width)
 {
-       switch (addr_width) {
-       case DMA_SLAVE_BUSWIDTH_1_BYTE:
-               *width = 0;
-               break;
-       case DMA_SLAVE_BUSWIDTH_2_BYTES:
-               *width = 1;
-               break;
-       case DMA_SLAVE_BUSWIDTH_4_BYTES:
-               *width = 2;
-               break;
-       default:
+       if ((addr_width < DMA_SLAVE_BUSWIDTH_1_BYTE) ||
+           (addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES))
                return -EINVAL;
-       }
 
+       *width = addr_width >> 1;
        return 0;
 }
 
@@ -571,8 +562,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
        v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
        if (!v_lli) {
                dev_err(sdev->slave.dev, "Failed to alloc lli memory\n");
-               kfree(txd);
-               return NULL;
+               goto err_txd_free;
        }
 
        ret = sun6i_dma_cfg_lli(v_lli, src, dest, len, sconfig);
@@ -592,6 +582,8 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
 
 err_dma_free:
        dma_pool_free(sdev->pool, v_lli, p_lli);
+err_txd_free:
+       kfree(txd);
        return NULL;
 }
 
@@ -623,17 +615,15 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
 
        for_each_sg(sgl, sg, sg_len, i) {
                v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
-               if (!v_lli) {
-                       kfree(txd);
-                       return NULL;
-               }
+               if (!v_lli)
+                       goto err_lli_free;
 
                if (dir == DMA_MEM_TO_DEV) {
                        ret = sun6i_dma_cfg_lli(v_lli, sg_dma_address(sg),
                                                sconfig->dst_addr, sg_dma_len(sg),
                                                sconfig);
                        if (ret)
-                               goto err_dma_free;
+                               goto err_cur_lli_free;
 
                        v_lli->cfg |= DMA_CHAN_CFG_DST_IO_MODE |
                                DMA_CHAN_CFG_SRC_LINEAR_MODE |
@@ -641,7 +631,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
                                DMA_CHAN_CFG_DST_DRQ(vchan->port);
 
                        dev_dbg(chan2dev(chan),
-                               "%s; chan: %d, dest: %pad, src: %pad, len: %zu. flags: 0x%08lx\n",
+                               "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n",
                                __func__, vchan->vc.chan.chan_id,
                                &sconfig->dst_addr, &sg_dma_address(sg),
                                sg_dma_len(sg), flags);
@@ -651,7 +641,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
                                                sg_dma_address(sg), sg_dma_len(sg),
                                                sconfig);
                        if (ret)
-                               goto err_dma_free;
+                               goto err_cur_lli_free;
 
                        v_lli->cfg |= DMA_CHAN_CFG_DST_LINEAR_MODE |
                                DMA_CHAN_CFG_SRC_IO_MODE |
@@ -659,7 +649,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
                                DMA_CHAN_CFG_SRC_DRQ(vchan->port);
 
                        dev_dbg(chan2dev(chan),
-                               "%s; chan: %d, dest: %pad, src: %pad, len: %zu. flags: 0x%08lx\n",
+                               "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n",
                                __func__, vchan->vc.chan.chan_id,
                                &sg_dma_address(sg), &sconfig->src_addr,
                                sg_dma_len(sg), flags);
@@ -674,8 +664,12 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
 
        return vchan_tx_prep(&vchan->vc, &txd->vd, flags);
 
-err_dma_free:
+err_cur_lli_free:
        dma_pool_free(sdev->pool, v_lli, p_lli);
+err_lli_free:
+       for (prev = txd->v_lli; prev; prev = prev->v_lli_next)
+               dma_pool_free(sdev->pool, prev, virt_to_phys(prev));
+       kfree(txd);
        return NULL;
 }
 
@@ -845,8 +839,8 @@ static inline void sun6i_kill_tasklet(struct sun6i_dma_dev *sdev)
        /* Prevent spurious interrupts from scheduling the tasklet */
        atomic_inc(&sdev->tasklet_shutdown);
 
-       /* Make sure all interrupts are handled */
-       synchronize_irq(sdev->irq);
+       /* Make sure we won't have any further interrupts */
+       devm_free_irq(sdev->slave.dev, sdev->irq, sdev);
 
        /* Actually prevent the tasklet from being scheduled */
        tasklet_kill(&sdev->task);
This page took 0.031487 seconds and 5 git commands to generate.