.. | .. |
---|
162 | 162 | bool enabled_2d; |
---|
163 | 163 | int slot_2d; |
---|
164 | 164 | unsigned int irq; |
---|
| 165 | + struct dma_slave_config config; |
---|
165 | 166 | }; |
---|
166 | 167 | |
---|
167 | 168 | enum imx_dma_type { |
---|
.. | .. |
---|
172 | 173 | |
---|
173 | 174 | struct imxdma_engine { |
---|
174 | 175 | struct device *dev; |
---|
175 | | - struct device_dma_parameters dma_parms; |
---|
176 | 176 | struct dma_device dma_device; |
---|
177 | 177 | void __iomem *base; |
---|
178 | 178 | struct clk *dma_ahb; |
---|
.. | .. |
---|
277 | 277 | /* |
---|
278 | 278 | * imxdma_sg_next - prepare next chunk for scatter-gather DMA emulation |
---|
279 | 279 | */ |
---|
280 | | -static inline int imxdma_sg_next(struct imxdma_desc *d) |
---|
| 280 | +static inline void imxdma_sg_next(struct imxdma_desc *d) |
---|
281 | 281 | { |
---|
282 | 282 | struct imxdma_channel *imxdmac = to_imxdma_chan(d->desc.chan); |
---|
283 | 283 | struct imxdma_engine *imxdma = imxdmac->imxdma; |
---|
284 | 284 | struct scatterlist *sg = d->sg; |
---|
285 | | - unsigned long now; |
---|
| 285 | + size_t now; |
---|
286 | 286 | |
---|
287 | 287 | now = min_t(size_t, d->len, sg_dma_len(sg)); |
---|
288 | 288 | if (d->len != IMX_DMA_LENGTH_LOOP) |
---|
.. | .. |
---|
302 | 302 | imx_dmav1_readl(imxdma, DMA_DAR(imxdmac->channel)), |
---|
303 | 303 | imx_dmav1_readl(imxdma, DMA_SAR(imxdmac->channel)), |
---|
304 | 304 | imx_dmav1_readl(imxdma, DMA_CNTR(imxdmac->channel))); |
---|
305 | | - |
---|
306 | | - return now; |
---|
307 | 305 | } |
---|
308 | 306 | |
---|
309 | 307 | static void imxdma_enable_hw(struct imxdma_desc *d) |
---|
.. | .. |
---|
557 | 555 | * We fall-through here intentionally, since a 2D transfer is |
---|
558 | 556 | * similar to MEMCPY just adding the 2D slot configuration. |
---|
559 | 557 | */ |
---|
| 558 | + fallthrough; |
---|
560 | 559 | case IMXDMA_DESC_MEMCPY: |
---|
561 | 560 | imx_dmav1_writel(imxdma, d->src, DMA_SAR(imxdmac->channel)); |
---|
562 | 561 | imx_dmav1_writel(imxdma, d->dest, DMA_DAR(imxdmac->channel)); |
---|
.. | .. |
---|
613 | 612 | return 0; |
---|
614 | 613 | } |
---|
615 | 614 | |
---|
616 | | -static void imxdma_tasklet(unsigned long data) |
---|
| 615 | +static void imxdma_tasklet(struct tasklet_struct *t) |
---|
617 | 616 | { |
---|
618 | | - struct imxdma_channel *imxdmac = (void *)data; |
---|
| 617 | + struct imxdma_channel *imxdmac = from_tasklet(imxdmac, t, dma_tasklet); |
---|
619 | 618 | struct imxdma_engine *imxdma = imxdmac->imxdma; |
---|
620 | 619 | struct imxdma_desc *desc, *next_desc; |
---|
621 | 620 | unsigned long flags; |
---|
.. | .. |
---|
675 | 674 | return 0; |
---|
676 | 675 | } |
---|
677 | 676 | |
---|
678 | | -static int imxdma_config(struct dma_chan *chan, |
---|
679 | | - struct dma_slave_config *dmaengine_cfg) |
---|
| 677 | +static int imxdma_config_write(struct dma_chan *chan, |
---|
| 678 | + struct dma_slave_config *dmaengine_cfg, |
---|
| 679 | + enum dma_transfer_direction direction) |
---|
680 | 680 | { |
---|
681 | 681 | struct imxdma_channel *imxdmac = to_imxdma_chan(chan); |
---|
682 | 682 | struct imxdma_engine *imxdma = imxdmac->imxdma; |
---|
683 | 683 | unsigned int mode = 0; |
---|
684 | 684 | |
---|
685 | | - if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) { |
---|
| 685 | + if (direction == DMA_DEV_TO_MEM) { |
---|
686 | 686 | imxdmac->per_address = dmaengine_cfg->src_addr; |
---|
687 | 687 | imxdmac->watermark_level = dmaengine_cfg->src_maxburst; |
---|
688 | 688 | imxdmac->word_size = dmaengine_cfg->src_addr_width; |
---|
.. | .. |
---|
719 | 719 | /* Set burst length */ |
---|
720 | 720 | imx_dmav1_writel(imxdma, imxdmac->watermark_level * |
---|
721 | 721 | imxdmac->word_size, DMA_BLR(imxdmac->channel)); |
---|
| 722 | + |
---|
| 723 | + return 0; |
---|
| 724 | +} |
---|
| 725 | + |
---|
| 726 | +static int imxdma_config(struct dma_chan *chan, |
---|
| 727 | + struct dma_slave_config *dmaengine_cfg) |
---|
| 728 | +{ |
---|
| 729 | + struct imxdma_channel *imxdmac = to_imxdma_chan(chan); |
---|
| 730 | + |
---|
| 731 | + memcpy(&imxdmac->config, dmaengine_cfg, sizeof(*dmaengine_cfg)); |
---|
722 | 732 | |
---|
723 | 733 | return 0; |
---|
724 | 734 | } |
---|
.. | .. |
---|
821 | 831 | dma_length += sg_dma_len(sg); |
---|
822 | 832 | } |
---|
823 | 833 | |
---|
| 834 | + imxdma_config_write(chan, &imxdmac->config, direction); |
---|
| 835 | + |
---|
824 | 836 | switch (imxdmac->word_size) { |
---|
825 | 837 | case DMA_SLAVE_BUSWIDTH_4_BYTES: |
---|
826 | 838 | if (sg_dma_len(sgl) & 3 || sgl->dma_address & 3) |
---|
.. | .. |
---|
904 | 916 | } |
---|
905 | 917 | desc->desc.callback = NULL; |
---|
906 | 918 | desc->desc.callback_param = NULL; |
---|
| 919 | + |
---|
| 920 | + imxdma_config_write(chan, &imxdmac->config, direction); |
---|
907 | 921 | |
---|
908 | 922 | return &desc->desc; |
---|
909 | 923 | } |
---|
.. | .. |
---|
1156 | 1170 | INIT_LIST_HEAD(&imxdmac->ld_free); |
---|
1157 | 1171 | INIT_LIST_HEAD(&imxdmac->ld_active); |
---|
1158 | 1172 | |
---|
1159 | | - tasklet_init(&imxdmac->dma_tasklet, imxdma_tasklet, |
---|
1160 | | - (unsigned long)imxdmac); |
---|
| 1173 | + tasklet_setup(&imxdmac->dma_tasklet, imxdma_tasklet); |
---|
1161 | 1174 | imxdmac->chan.device = &imxdma->dma_device; |
---|
1162 | 1175 | dma_cookie_init(&imxdmac->chan); |
---|
1163 | 1176 | imxdmac->channel = i; |
---|
.. | .. |
---|
1183 | 1196 | platform_set_drvdata(pdev, imxdma); |
---|
1184 | 1197 | |
---|
1185 | 1198 | imxdma->dma_device.copy_align = DMAENGINE_ALIGN_4_BYTES; |
---|
1186 | | - imxdma->dma_device.dev->dma_parms = &imxdma->dma_parms; |
---|
1187 | 1199 | dma_set_max_seg_size(imxdma->dma_device.dev, 0xffffff); |
---|
1188 | 1200 | |
---|
1189 | 1201 | ret = dma_async_device_register(&imxdma->dma_device); |
---|