diff options
| author | Mark Brown <broonie@kernel.org> | 2026-10-03 00:55:14 +0200 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-10-03 00:55:14 +0200 |
| commit | 2ff4c6346f73d6da57c3bceb5b651ce795924920 (patch) | |
| tree | c83e15983bfc4e10d8b552a6634b477406075df7 /drivers | |
| parent | a575d0e290d021f245d6795a3596ce334af8a91e (diff) | |
| parent | 0a8dda0a15d3926422d286567f945a05328a4ac6 (diff) | |
| download | linux-next-2ff4c6346f73d6da57c3bceb5b651ce795924920.tar.gz linux-next-2ff4c6346f73d6da57c3bceb5b651ce795924920.zip | |
Merge branch 'next' of https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine.git
# Conflicts:
# Documentation/devicetree/bindings/usb/am33xx-usb.txt
# Documentation/devicetree/bindings/usb/da8xx-usb.txt
Diffstat (limited to 'drivers')
58 files changed, 1328 insertions, 1087 deletions
diff --git a/drivers/dma/altera-msgdma.c b/drivers/dma/altera-msgdma.c index e23e5b441a24..412f4bce1d4a 100644 --- a/drivers/dma/altera-msgdma.c +++ b/drivers/dma/altera-msgdma.c @@ -847,11 +847,6 @@ static int msgdma_probe(struct platform_device *pdev) if (mdev->irq < 0) return -ENXIO; - ret = devm_request_irq(&pdev->dev, mdev->irq, msgdma_irq_handler, - 0, dev_name(&pdev->dev), mdev); - if (ret) - return ret; - tasklet_setup(&mdev->irq_tasklet, msgdma_tasklet); dma_cookie_init(&mdev->dmachan); @@ -863,6 +858,11 @@ static int msgdma_probe(struct platform_device *pdev) INIT_LIST_HEAD(&mdev->done_list); INIT_LIST_HEAD(&mdev->free_list); + ret = devm_request_irq(&pdev->dev, mdev->irq, msgdma_irq_handler, + 0, dev_name(&pdev->dev), mdev); + if (ret) + return ret; + dma_dev = &mdev->dmadev; /* Set DMA capabilities */ diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 5e88fd44812d..543c2eb8cfa8 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -2500,8 +2500,8 @@ DEFINE_SHOW_ATTRIBUTE(pl08x_debugfs); static void init_pl08x_debugfs(struct pl08x_driver_data *pl08x) { /* Expose a simple debugfs interface to view all clocks */ - debugfs_create_file(dev_name(&pl08x->adev->dev), S_IFREG | S_IRUGO, - NULL, pl08x, &pl08x_debugfs_fops); + debugfs_create_file("stats", 0444, pl08x->memcpy.dbg_dev_root, + pl08x, &pl08x_debugfs_fops); } #else diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c index 14a5ee14a481..9a1c79c12268 100644 --- a/drivers/dma/apple-admac.c +++ b/drivers/dma/apple-admac.c @@ -39,10 +39,14 @@ #define FLAG_DESC_NOTIFY BIT(16) +#define T8122_UNK_28_VAL 0x200000 + #define REG_TX_START 0x0000 #define REG_TX_STOP 0x0004 #define REG_RX_START 0x0008 #define REG_RX_STOP 0x000c +#define REG_UNK_28 0x0028 +#define REG_UNK_2C 0x002c #define REG_IMPRINT 0x0090 #define REG_TX_SRAM_SIZE 0x0094 #define REG_RX_SRAM_SIZE 0x0098 @@ -85,6 +89,10 @@ struct admac_data; struct admac_tx; +struct admac_hw { + bool set_unk28; +}; + struct admac_chan { unsigned int no; struct admac_data *host; @@ -127,6 +135,7 @@ struct admac_data { struct mutex cache_alloc_lock; struct admac_sram txcache, rxcache; + const struct admac_hw *hw; int irq; int irq_index; int nchannels; @@ -747,6 +756,11 @@ static int admac_device_config(struct dma_chan *chan, u32 bus_width = readl_relaxed(ad->base + REG_BUS_WIDTH(adchan->no)) & ~(BUS_WIDTH_WORD_SIZE | BUS_WIDTH_FRAME_SIZE); + if (ad->hw->set_unk28) { + writel_relaxed(T8122_UNK_28_VAL, ad->base + REG_UNK_28); + writel_relaxed(T8122_UNK_28_VAL, ad->base + REG_UNK_2C); + } + switch (is_tx ? config->dst_addr_width : config->src_addr_width) { case DMA_SLAVE_BUSWIDTH_1_BYTE: wordsize = 1; @@ -800,11 +814,18 @@ static int admac_device_config(struct dma_chan *chan, return 0; } +static const struct admac_hw admac_base_hw = {}; + +static const struct admac_hw admac_t8122_hw = { + .set_unk28 = true, +}; + static int admac_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct admac_data *ad; struct dma_device *dma; + const struct admac_hw *hw; int nchannels; int err, irq, i; @@ -822,6 +843,8 @@ static int admac_probe(struct platform_device *pdev) ad->dev = &pdev->dev; ad->nchannels = nchannels; mutex_init(&ad->cache_alloc_lock); + hw = of_device_get_match_data(&pdev->dev); + ad->hw = hw ? hw : &admac_base_hw; /* * The controller has 4 IRQ outputs. Try them all until @@ -936,6 +959,7 @@ static void admac_remove(struct platform_device *pdev) } static const struct of_device_id admac_of_match[] = { + { .compatible = "apple,t8122-admac", .data = &admac_t8122_hw }, { .compatible = "apple,t8103-admac", }, { .compatible = "apple,admac", }, { } diff --git a/drivers/dma/arm-dma350.c b/drivers/dma/arm-dma350.c index 09403aca8bb0..52f5242ea332 100644 --- a/drivers/dma/arm-dma350.c +++ b/drivers/dma/arm-dma350.c @@ -512,7 +512,7 @@ static int d350_alloc_chan_resources(struct dma_chan *chan) { struct d350_chan *dch = to_d350_chan(chan); int ret = request_irq(dch->irq, d350_irq, IRQF_SHARED, - dev_name(&dch->vc.chan.dev->device), dch); + vchan_chan_name(&dch->vc), dch); if (!ret) writel_relaxed(CH_INTREN_DONE | CH_INTREN_ERR, dch->base + CH_INTREN); diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index e5b30a57c477..3fedc907db63 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -244,7 +244,7 @@ struct at_desc { /* Memset temporary buffer */ bool memset_buffer; dma_addr_t memset_paddr; - int *memset_vaddr; + u32 *memset_vaddr; struct atdma_sg sg[] __counted_by(sglen); }; @@ -381,23 +381,18 @@ static inline struct at_dma *to_at_dma(struct dma_device *ddev) /*-- Helper functions ------------------------------------------------*/ -static struct device *chan2dev(struct dma_chan *chan) -{ - return &chan->dev->device; -} - #if defined(VERBOSE_DEBUG) static void vdbg_dump_regs(struct at_dma_chan *atchan) { struct at_dma *atdma = to_at_dma(atchan->vc.chan.device); - dev_err(chan2dev(&atchan->vc.chan), + dev_err(vchan_chan_dev(&atchan->vc), " channel %d : imr = 0x%x, chsr = 0x%x\n", atchan->vc.chan.chan_id, dma_readl(atdma, EBCIMR), dma_readl(atdma, CHSR)); - dev_err(chan2dev(&atchan->vc.chan), + dev_err(vchan_chan_dev(&atchan->vc), " channel: s0x%x d0x%x ctrl0x%x:0x%x cfg0x%x l0x%x\n", channel_readl(atchan, SADDR), channel_readl(atchan, DADDR), @@ -412,7 +407,7 @@ static void vdbg_dump_regs(struct at_dma_chan *atchan) {} static void atc_dump_lli(struct at_dma_chan *atchan, struct at_lli *lli) { - dev_crit(chan2dev(&atchan->vc.chan), + dev_crit(vchan_chan_dev(&atchan->vc), "desc: s%pad d%pad ctrl0x%x:0x%x l%pad\n", &lli->saddr, &lli->daddr, lli->ctrla, lli->ctrlb, &lli->dscr); @@ -790,8 +785,8 @@ static void atc_handle_error(struct at_dma_chan *atchan, unsigned int i) * controller flagged an error instead of scribbling over * random memory locations. */ - dev_crit(chan2dev(&atchan->vc.chan), "Bad descriptor submitted for DMA!\n"); - dev_crit(chan2dev(&atchan->vc.chan), "cookie: %d\n", + dev_crit(vchan_chan_dev(&atchan->vc), "Bad descriptor submitted for DMA!\n"); + dev_crit(vchan_chan_dev(&atchan->vc), "cookie: %d\n", desc->vd.tx.cookie); for (i = 0; i < desc->sglen; i++) atc_dump_lli(atchan, desc->sg[i].lli); @@ -886,7 +881,7 @@ atc_prep_dma_interleaved(struct dma_chan *chan, first = xt->sgl; - dev_info(chan2dev(chan), + dev_info(dmaengine_chan_dev(chan), "%s: src=%pad, dest=%pad, numf=%zu, frame_size=%zu, flags=0x%lx\n", __func__, &xt->src_start, &xt->dst_start, xt->numf, xt->frame_size, flags); @@ -903,7 +898,7 @@ atc_prep_dma_interleaved(struct dma_chan *chan, if ((chunk->size != xt->sgl->size) || (dmaengine_get_dst_icg(xt, chunk) != dmaengine_get_dst_icg(xt, first)) || (dmaengine_get_src_icg(xt, chunk) != dmaengine_get_src_icg(xt, first))) { - dev_err(chan2dev(chan), + dev_err(dmaengine_chan_dev(chan), "%s: the controller can transfer only identical chunks\n", __func__); return NULL; @@ -916,7 +911,7 @@ atc_prep_dma_interleaved(struct dma_chan *chan, xfer_count = len >> dwidth; if (xfer_count > ATC_BTSIZE_MAX) { - dev_err(chan2dev(chan), "%s: buffer is too big\n", __func__); + dev_err(dmaengine_chan_dev(chan), "%s: buffer is too big\n", __func__); return NULL; } @@ -983,11 +978,11 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, u32 ctrla; u32 ctrlb; - dev_dbg(chan2dev(chan), "prep_dma_memcpy: d%pad s%pad l0x%zx f0x%lx\n", + dev_dbg(dmaengine_chan_dev(chan), "prep_dma_memcpy: d%pad s%pad l0x%zx f0x%lx\n", &dest, &src, len, flags); if (unlikely(!len)) { - dev_err(chan2dev(chan), "prep_dma_memcpy: length is zero!\n"); + dev_err(dmaengine_chan_dev(chan), "prep_dma_memcpy: length is zero!\n"); return NULL; } @@ -1062,7 +1057,7 @@ static int atdma_create_memset_lli(struct dma_chan *chan, xfer_count = len >> 2; if (xfer_count > ATC_BTSIZE_MAX) { - dev_err(chan2dev(chan), "%s: buffer is too big\n", __func__); + dev_err(dmaengine_chan_dev(chan), "%s: buffer is too big\n", __func__); return -EINVAL; } @@ -1097,28 +1092,28 @@ atc_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value, struct at_dma_chan *atchan = to_at_dma_chan(chan); struct at_dma *atdma = to_at_dma(chan->device); struct at_desc *desc; - void __iomem *vaddr; + u32 *vaddr; dma_addr_t paddr; char fill_pattern; int ret; - dev_vdbg(chan2dev(chan), "%s: d%pad v0x%x l0x%zx f0x%lx\n", __func__, + dev_vdbg(dmaengine_chan_dev(chan), "%s: d%pad v0x%x l0x%zx f0x%lx\n", __func__, &dest, value, len, flags); if (unlikely(!len)) { - dev_dbg(chan2dev(chan), "%s: length is zero!\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s: length is zero!\n", __func__); return NULL; } if (!is_dma_fill_aligned(chan->device, dest, 0, len)) { - dev_dbg(chan2dev(chan), "%s: buffer is not aligned\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: buffer is not aligned\n", __func__); return NULL; } vaddr = dma_pool_alloc(atdma->memset_pool, GFP_NOWAIT, &paddr); if (!vaddr) { - dev_err(chan2dev(chan), "%s: couldn't allocate buffer\n", + dev_err(dmaengine_chan_dev(chan), "%s: couldn't allocate buffer\n", __func__); return NULL; } @@ -1126,10 +1121,10 @@ atc_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value, /* Only the first byte of value is to be used according to dmaengine */ fill_pattern = (char)value; - *(u32*)vaddr = (fill_pattern << 24) | - (fill_pattern << 16) | - (fill_pattern << 8) | - fill_pattern; + *vaddr = (fill_pattern << 24) | + (fill_pattern << 16) | + (fill_pattern << 8) | + fill_pattern; desc = kzalloc_flex(*desc, sg, 1, GFP_ATOMIC); if (!desc) @@ -1168,28 +1163,28 @@ atc_prep_dma_memset_sg(struct dma_chan *chan, struct at_dma *atdma = to_at_dma(chan->device); struct at_desc *desc; struct scatterlist *sg; - void __iomem *vaddr; + u32 *vaddr; dma_addr_t paddr; size_t total_len = 0; int i; int ret; - dev_vdbg(chan2dev(chan), "%s: v0x%x l0x%x f0x%lx\n", __func__, + dev_vdbg(dmaengine_chan_dev(chan), "%s: v0x%x l0x%x f0x%lx\n", __func__, value, sg_len, flags); if (unlikely(!sgl || !sg_len)) { - dev_dbg(chan2dev(chan), "%s: scatterlist is empty!\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: scatterlist is empty!\n", __func__); return NULL; } vaddr = dma_pool_alloc(atdma->memset_pool, GFP_NOWAIT, &paddr); if (!vaddr) { - dev_err(chan2dev(chan), "%s: couldn't allocate buffer\n", + dev_err(dmaengine_chan_dev(chan), "%s: couldn't allocate buffer\n", __func__); return NULL; } - *(u32*)vaddr = value; + *vaddr = value; desc = kzalloc_flex(*desc, sg, sg_len, GFP_ATOMIC); if (!desc) @@ -1200,11 +1195,11 @@ atc_prep_dma_memset_sg(struct dma_chan *chan, dma_addr_t dest = sg_dma_address(sg); size_t len = sg_dma_len(sg); - dev_vdbg(chan2dev(chan), "%s: d%pad, l0x%zx\n", + dev_vdbg(dmaengine_chan_dev(chan), "%s: d%pad, l0x%zx\n", __func__, &dest, len); if (!is_dma_fill_aligned(chan->device, dest, 0, len)) { - dev_err(chan2dev(chan), "%s: buffer is not aligned\n", + dev_err(dmaengine_chan_dev(chan), "%s: buffer is not aligned\n", __func__); goto err_free_desc; } @@ -1264,13 +1259,13 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, struct scatterlist *sg; size_t total_len = 0; - dev_vdbg(chan2dev(chan), "prep_slave_sg (%d): %s f0x%lx\n", + dev_vdbg(dmaengine_chan_dev(chan), "prep_slave_sg (%d): %s f0x%lx\n", sg_len, direction == DMA_MEM_TO_DEV ? "TO DEVICE" : "FROM DEVICE", flags); if (unlikely(!atslave || !sg_len)) { - dev_dbg(chan2dev(chan), "prep_slave_sg: sg length is zero!\n"); + dev_dbg(dmaengine_chan_dev(chan), "prep_slave_sg: sg length is zero!\n"); return NULL; } @@ -1310,7 +1305,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, mem = sg_dma_address(sg); len = sg_dma_len(sg); if (unlikely(!len)) { - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "prep_slave_sg: sg(%d) data length is zero\n", i); goto err; } @@ -1359,7 +1354,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, mem = sg_dma_address(sg); len = sg_dma_len(sg); if (unlikely(!len)) { - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "prep_slave_sg: sg(%d) data length is zero\n", i); goto err; } @@ -1392,7 +1387,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return vchan_tx_prep(&atchan->vc, &desc->vd, flags); err_desc_get: - dev_err(chan2dev(chan), "not enough descriptors available\n"); + dev_err(dmaengine_chan_dev(chan), "not enough descriptors available\n"); err: atdma_desc_free(&desc->vd); return NULL; @@ -1503,19 +1498,19 @@ atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, unsigned int periods = buf_len / period_len; unsigned int i; - dev_vdbg(chan2dev(chan), "prep_dma_cyclic: %s buf@%pad - %d (%zu/%zu)\n", + dev_vdbg(dmaengine_chan_dev(chan), "prep_dma_cyclic: %s buf@%pad - %d (%zu/%zu)\n", direction == DMA_MEM_TO_DEV ? "TO DEVICE" : "FROM DEVICE", &buf_addr, periods, buf_len, period_len); if (unlikely(!atslave || !buf_len || !period_len)) { - dev_dbg(chan2dev(chan), "prep_dma_cyclic: length is zero!\n"); + dev_dbg(dmaengine_chan_dev(chan), "prep_dma_cyclic: length is zero!\n"); return NULL; } was_cyclic = test_and_set_bit(ATC_IS_CYCLIC, &atchan->status); if (was_cyclic) { - dev_dbg(chan2dev(chan), "prep_dma_cyclic: channel in use!\n"); + dev_dbg(dmaengine_chan_dev(chan), "prep_dma_cyclic: channel in use!\n"); return NULL; } @@ -1561,7 +1556,7 @@ static int atc_config(struct dma_chan *chan, { struct at_dma_chan *atchan = to_at_dma_chan(chan); - dev_vdbg(chan2dev(chan), "%s\n", __func__); + dev_vdbg(dmaengine_chan_dev(chan), "%s\n", __func__); /* Check if it is chan is configured for slave transfers */ if (!chan->private) @@ -1582,7 +1577,7 @@ static int atc_pause(struct dma_chan *chan) int chan_id = atchan->vc.chan.chan_id; unsigned long flags; - dev_vdbg(chan2dev(chan), "%s\n", __func__); + dev_vdbg(dmaengine_chan_dev(chan), "%s\n", __func__); spin_lock_irqsave(&atchan->vc.lock, flags); @@ -1601,7 +1596,7 @@ static int atc_resume(struct dma_chan *chan) int chan_id = atchan->vc.chan.chan_id; unsigned long flags; - dev_vdbg(chan2dev(chan), "%s\n", __func__); + dev_vdbg(dmaengine_chan_dev(chan), "%s\n", __func__); if (!atc_chan_is_paused(atchan)) return 0; @@ -1625,7 +1620,7 @@ static int atc_terminate_all(struct dma_chan *chan) LIST_HEAD(list); - dev_vdbg(chan2dev(chan), "%s\n", __func__); + dev_vdbg(dmaengine_chan_dev(chan), "%s\n", __func__); /* * This is only called when something went wrong elsewhere, so @@ -1691,13 +1686,13 @@ atc_tx_status(struct dma_chan *chan, spin_unlock_irqrestore(&atchan->vc.lock, flags); if (unlikely(ret < 0)) { - dev_vdbg(chan2dev(chan), "get residual bytes error\n"); + dev_vdbg(dmaengine_chan_dev(chan), "get residual bytes error\n"); return DMA_ERROR; } else { dma_set_residue(txstate, residue); } - dev_vdbg(chan2dev(chan), "tx_status %d: cookie = %d residue = %u\n", + dev_vdbg(dmaengine_chan_dev(chan), "tx_status %d: cookie = %d residue = %u\n", dma_status, cookie, residue); return dma_status; @@ -1729,11 +1724,11 @@ static int atc_alloc_chan_resources(struct dma_chan *chan) struct at_dma_slave *atslave; u32 cfg; - dev_vdbg(chan2dev(chan), "alloc_chan_resources\n"); + dev_vdbg(dmaengine_chan_dev(chan), "alloc_chan_resources\n"); /* ASSERT: channel is idle */ if (atc_chan_is_enabled(atchan)) { - dev_dbg(chan2dev(chan), "DMA channel not idle ?\n"); + dev_dbg(dmaengine_chan_dev(chan), "DMA channel not idle ?\n"); return -EIO; } @@ -1782,7 +1777,7 @@ static void atc_free_chan_resources(struct dma_chan *chan) chan->private = NULL; } - dev_vdbg(chan2dev(chan), "free_chan_resources: done\n"); + dev_vdbg(dmaengine_chan_dev(chan), "free_chan_resources: done\n"); } #ifdef CONFIG_OF @@ -1940,6 +1935,20 @@ static void at_dma_off(struct at_dma *atdma) cpu_relax(); } +static void at_dma_cleanup_channels(struct at_dma *atdma) +{ + struct dma_chan *chan, *_chan; + int i = 0; + + list_for_each_entry_safe(chan, _chan, &atdma->dma_device.channels, + device_node) { + /* Disable interrupts */ + atc_disable_chan_irq(atdma, i++); + tasklet_kill(&to_at_dma_chan(chan)->vc.task); + list_del(&chan->device_node); + } +} + static int __init at_dma_probe(struct platform_device *pdev) { struct at_dma *atdma; @@ -1980,20 +1989,16 @@ static int __init at_dma_probe(struct platform_device *pdev) atdma->dma_device.cap_mask = plat_dat->cap_mask; atdma->all_chan_mask = (1 << plat_dat->nr_channels) - 1; - atdma->clk = devm_clk_get(&pdev->dev, "dma_clk"); + atdma->clk = devm_clk_get_enabled(&pdev->dev, "dma_clk"); if (IS_ERR(atdma->clk)) return PTR_ERR(atdma->clk); - err = clk_prepare_enable(atdma->clk); - if (err) - return err; - /* force dma off, just in case */ at_dma_off(atdma); err = request_irq(irq, at_dma_interrupt, 0, "at_hdmac", atdma); if (err) - goto err_irq; + return err; platform_set_drvdata(pdev, atdma); @@ -2105,38 +2110,30 @@ static int __init at_dma_probe(struct platform_device *pdev) err_of_dma_controller_register: dma_async_device_unregister(&atdma->dma_device); err_dma_async_device_register: + disable_irq(platform_get_irq(pdev, 0)); + at_dma_cleanup_channels(atdma); dma_pool_destroy(atdma->memset_pool); err_memset_pool_create: dma_pool_destroy(atdma->lli_pool); err_desc_pool_create: - free_irq(platform_get_irq(pdev, 0), atdma); -err_irq: - clk_disable_unprepare(atdma->clk); + free_irq(irq, atdma); return err; } static void at_dma_remove(struct platform_device *pdev) { struct at_dma *atdma = platform_get_drvdata(pdev); - struct dma_chan *chan, *_chan; at_dma_off(atdma); if (pdev->dev.of_node) of_dma_controller_free(pdev->dev.of_node); dma_async_device_unregister(&atdma->dma_device); - dma_pool_destroy(atdma->memset_pool); - dma_pool_destroy(atdma->lli_pool); free_irq(platform_get_irq(pdev, 0), atdma); - list_for_each_entry_safe(chan, _chan, &atdma->dma_device.channels, - device_node) { - /* Disable interrupts */ - atc_disable_chan_irq(atdma, chan->chan_id); - list_del(&chan->device_node); - } - - clk_disable_unprepare(atdma->clk); + at_dma_cleanup_channels(atdma); + dma_pool_destroy(atdma->memset_pool); + dma_pool_destroy(atdma->lli_pool); } static void at_dma_shutdown(struct platform_device *pdev) @@ -2169,7 +2166,7 @@ static void atc_suspend_cyclic(struct at_dma_chan *atchan) /* Channel should be paused by user * do it anyway even if it is not done already */ if (!atc_chan_is_paused(atchan)) { - dev_warn(chan2dev(chan), + dev_warn(dmaengine_chan_dev(chan), "cyclic channel not paused, should be done by channel user\n"); atc_pause(chan); } diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 901971e8bae6..d40a8b40dddc 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -324,11 +324,6 @@ static inline struct at_xdmac_chan *to_at_xdmac_chan(struct dma_chan *dchan) return container_of(dchan, struct at_xdmac_chan, chan); } -static struct device *chan2dev(struct dma_chan *chan) -{ - return &chan->dev->device; -} - static inline struct at_xdmac *to_at_xdmac(struct dma_device *ddev) { return container_of(ddev, struct at_xdmac, dma); @@ -459,7 +454,7 @@ static void at_xdmac_start_xfer(struct at_xdmac_chan *atchan, if (ret < 0) return; - dev_vdbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, first); + dev_vdbg(dmaengine_chan_dev(&atchan->chan), "%s: desc 0x%p\n", __func__, first); /* Set transfer as active to not try to start it again. */ first->active_xfer = true; @@ -496,7 +491,7 @@ static void at_xdmac_start_xfer(struct at_xdmac_chan *atchan, | AT_XDMAC_CNDC_NDE; at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, reg); - dev_vdbg(chan2dev(&atchan->chan), + dev_vdbg(dmaengine_chan_dev(&atchan->chan), "%s: CC=0x%08x CNDA=0x%08x, CNDC=0x%08x, CSA=0x%08x, CDA=0x%08x, CUBC=0x%08x\n", __func__, at_xdmac_chan_read(atchan, AT_XDMAC_CC), at_xdmac_chan_read(atchan, AT_XDMAC_CNDA), @@ -524,12 +519,12 @@ static void at_xdmac_start_xfer(struct at_xdmac_chan *atchan, at_xdmac_chan_write(atchan, AT_XDMAC_CIE, reg | AT_XDMAC_CIE_LIE); at_xdmac_write(atxdmac, AT_XDMAC_GIE, atchan->mask); - dev_vdbg(chan2dev(&atchan->chan), + dev_vdbg(dmaengine_chan_dev(&atchan->chan), "%s: enable channel (0x%08x)\n", __func__, atchan->mask); wmb(); at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask); - dev_vdbg(chan2dev(&atchan->chan), + dev_vdbg(dmaengine_chan_dev(&atchan->chan), "%s: CC=0x%08x CNDA=0x%08x, CNDC=0x%08x, CSA=0x%08x, CDA=0x%08x, CUBC=0x%08x\n", __func__, at_xdmac_chan_read(atchan, AT_XDMAC_CC), at_xdmac_chan_read(atchan, AT_XDMAC_CNDA), @@ -552,7 +547,7 @@ static dma_cookie_t at_xdmac_tx_submit(struct dma_async_tx_descriptor *tx) list_add_tail(&desc->xfer_node, &atchan->xfers_list); spin_unlock_irqrestore(&atchan->lock, irqflags); - dev_vdbg(chan2dev(tx->chan), "%s: atchan 0x%p, add desc 0x%p to xfers_list\n", + dev_vdbg(dmaengine_chan_dev(tx->chan), "%s: atchan 0x%p, add desc 0x%p to xfers_list\n", __func__, atchan, desc); return cookie; @@ -612,7 +607,7 @@ static void at_xdmac_queue_desc(struct dma_chan *chan, prev->lld.mbr_nda = desc->tx_dma_desc.phys; prev->lld.mbr_ubc |= AT_XDMAC_MBR_UBC_NDE; - dev_dbg(chan2dev(chan), "%s: chain lld: prev=0x%p, mbr_nda=%pad\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: chain lld: prev=0x%p, mbr_nda=%pad\n", __func__, prev, &prev->lld.mbr_nda); } @@ -624,7 +619,7 @@ static inline void at_xdmac_increment_block_count(struct dma_chan *chan, desc->lld.mbr_bc++; - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s: incrementing the block count of the desc 0x%p\n", __func__, desc); } @@ -680,13 +675,13 @@ static int at_xdmac_compute_chan_conf(struct dma_chan *chan, csize = ffs(atchan->sconfig.src_maxburst) - 1; if (csize < 0) { - dev_err(chan2dev(chan), "invalid src maxburst value\n"); + dev_err(dmaengine_chan_dev(chan), "invalid src maxburst value\n"); return -EINVAL; } atchan->cfg |= AT_XDMAC_CC_CSIZE(csize); dwidth = ffs(atchan->sconfig.src_addr_width) - 1; if (dwidth < 0) { - dev_err(chan2dev(chan), "invalid src addr width value\n"); + dev_err(dmaengine_chan_dev(chan), "invalid src addr width value\n"); return -EINVAL; } atchan->cfg |= AT_XDMAC_CC_DWIDTH(dwidth); @@ -705,19 +700,19 @@ static int at_xdmac_compute_chan_conf(struct dma_chan *chan, csize = ffs(atchan->sconfig.dst_maxburst) - 1; if (csize < 0) { - dev_err(chan2dev(chan), "invalid src maxburst value\n"); + dev_err(dmaengine_chan_dev(chan), "invalid src maxburst value\n"); return -EINVAL; } atchan->cfg |= AT_XDMAC_CC_CSIZE(csize); dwidth = ffs(atchan->sconfig.dst_addr_width) - 1; if (dwidth < 0) { - dev_err(chan2dev(chan), "invalid dst addr width value\n"); + dev_err(dmaengine_chan_dev(chan), "invalid dst addr width value\n"); return -EINVAL; } atchan->cfg |= AT_XDMAC_CC_DWIDTH(dwidth); } - dev_dbg(chan2dev(chan), "%s: cfg=0x%08x\n", __func__, atchan->cfg); + dev_dbg(dmaengine_chan_dev(chan), "%s: cfg=0x%08x\n", __func__, atchan->cfg); return 0; } @@ -746,7 +741,7 @@ static int at_xdmac_set_slave_config(struct dma_chan *chan, struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); if (at_xdmac_check_slave_config(sconfig)) { - dev_err(chan2dev(chan), "invalid slave configuration\n"); + dev_err(dmaengine_chan_dev(chan), "invalid slave configuration\n"); return -EINVAL; } @@ -772,11 +767,11 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return NULL; if (!is_slave_direction(direction)) { - dev_err(chan2dev(chan), "invalid DMA direction\n"); + dev_err(dmaengine_chan_dev(chan), "invalid DMA direction\n"); return NULL; } - dev_dbg(chan2dev(chan), "%s: sg_len=%d, dir=%s, flags=0x%lx\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: sg_len=%d, dir=%s, flags=0x%lx\n", __func__, sg_len, direction == DMA_MEM_TO_DEV ? "to device" : "from device", flags); @@ -795,15 +790,15 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, len = sg_dma_len(sg); mem = sg_dma_address(sg); if (unlikely(!len)) { - dev_err(chan2dev(chan), "sg data length is zero\n"); + dev_err(dmaengine_chan_dev(chan), "sg data length is zero\n"); goto spin_unlock; } - dev_dbg(chan2dev(chan), "%s: * sg%d len=%u, mem=0x%08x\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: * sg%d len=%u, mem=0x%08x\n", __func__, i, len, mem); desc = at_xdmac_get_desc(atchan); if (!desc) { - dev_err(chan2dev(chan), "can't get descriptor\n"); + dev_err(dmaengine_chan_dev(chan), "can't get descriptor\n"); if (first) list_splice_tail_init(&first->descs_list, &atchan->free_descs_list); @@ -828,7 +823,7 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | (len >> fixed_dwidth); /* microblock length */ desc->lld.mbr_cfg = (atchan->cfg & ~AT_XDMAC_CC_DWIDTH_MASK) | AT_XDMAC_CC_DWIDTH(fixed_dwidth); - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n", __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc); @@ -840,7 +835,7 @@ at_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (!first) first = desc; - dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", __func__, desc, first); list_add_tail(&desc->desc_node, &first->descs_list); xfer_size += len; @@ -869,17 +864,17 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, int i; unsigned long irqflags; - dev_dbg(chan2dev(chan), "%s: buf_addr=%pad, buf_len=%zd, period_len=%zd, dir=%s, flags=0x%lx\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: buf_addr=%pad, buf_len=%zd, period_len=%zd, dir=%s, flags=0x%lx\n", __func__, &buf_addr, buf_len, period_len, direction == DMA_MEM_TO_DEV ? "mem2per" : "per2mem", flags); if (!is_slave_direction(direction)) { - dev_err(chan2dev(chan), "invalid DMA direction\n"); + dev_err(dmaengine_chan_dev(chan), "invalid DMA direction\n"); return NULL; } if (test_and_set_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status)) { - dev_err(chan2dev(chan), "channel currently used\n"); + dev_err(dmaengine_chan_dev(chan), "channel currently used\n"); return NULL; } @@ -892,7 +887,7 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, spin_lock_irqsave(&atchan->lock, irqflags); desc = at_xdmac_get_desc(atchan); if (!desc) { - dev_err(chan2dev(chan), "can't get descriptor\n"); + dev_err(dmaengine_chan_dev(chan), "can't get descriptor\n"); if (first) list_splice_tail_init(&first->descs_list, &atchan->free_descs_list); @@ -900,7 +895,7 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, return NULL; } spin_unlock_irqrestore(&atchan->lock, irqflags); - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s: desc=0x%p, tx_dma_desc.phys=%pad\n", __func__, desc, &desc->tx_dma_desc.phys); @@ -917,7 +912,7 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, | AT_XDMAC_MBR_UBC_NSEN | period_len >> at_xdmac_get_dwidth(desc->lld.mbr_cfg); - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n", __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc); @@ -929,7 +924,7 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, if (!first) first = desc; - dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", __func__, desc, first); list_add_tail(&desc->desc_node, &first->descs_list); } @@ -956,16 +951,16 @@ static inline u32 at_xdmac_align_width(struct dma_chan *chan, dma_addr_t addr) */ if (!(addr & 7)) { width = AT_XDMAC_CC_DWIDTH_DWORD; - dev_dbg(chan2dev(chan), "%s: dwidth: double word\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s: dwidth: double word\n", __func__); } else if (!(addr & 3)) { width = AT_XDMAC_CC_DWIDTH_WORD; - dev_dbg(chan2dev(chan), "%s: dwidth: word\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s: dwidth: word\n", __func__); } else if (!(addr & 1)) { width = AT_XDMAC_CC_DWIDTH_HALFWORD; - dev_dbg(chan2dev(chan), "%s: dwidth: half word\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s: dwidth: half word\n", __func__); } else { width = AT_XDMAC_CC_DWIDTH_BYTE; - dev_dbg(chan2dev(chan), "%s: dwidth: byte\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s: dwidth: byte\n", __func__); } return width; @@ -1005,7 +1000,7 @@ at_xdmac_interleaved_queue_desc(struct dma_chan *chan, dwidth = at_xdmac_align_width(chan, src | dst | chunk->size); if (chunk->size >= (AT_XDMAC_MBR_UBC_UBLEN_MAX << dwidth)) { - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s: chunk too big (%zu, max size %lu)...\n", __func__, chunk->size, AT_XDMAC_MBR_UBC_UBLEN_MAX << dwidth); @@ -1013,7 +1008,7 @@ at_xdmac_interleaved_queue_desc(struct dma_chan *chan, } if (prev) - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "Adding items at the end of desc 0x%p\n", prev); if (xt->src_inc) { @@ -1034,7 +1029,7 @@ at_xdmac_interleaved_queue_desc(struct dma_chan *chan, desc = at_xdmac_get_desc(atchan); spin_unlock_irqrestore(&atchan->lock, flags); if (!desc) { - dev_err(chan2dev(chan), "can't get descriptor\n"); + dev_err(dmaengine_chan_dev(chan), "can't get descriptor\n"); return NULL; } @@ -1053,7 +1048,7 @@ at_xdmac_interleaved_queue_desc(struct dma_chan *chan, | ublen; desc->lld.mbr_cfg = chan_cc; - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x, mbr_cfg=0x%08x\n", __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc, desc->lld.mbr_cfg); @@ -1087,7 +1082,7 @@ at_xdmac_prep_interleaved(struct dma_chan *chan, if ((xt->numf > 1) && (xt->frame_size > 1)) return NULL; - dev_dbg(chan2dev(chan), "%s: src=%pad, dest=%pad, numf=%zu, frame_size=%zu, flags=0x%lx\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: src=%pad, dest=%pad, numf=%zu, frame_size=%zu, flags=0x%lx\n", __func__, &xt->src_start, &xt->dst_start, xt->numf, xt->frame_size, flags); @@ -1106,7 +1101,7 @@ at_xdmac_prep_interleaved(struct dma_chan *chan, for (i = 0; i < xt->numf - 1; i++) at_xdmac_increment_block_count(chan, first); - dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", __func__, first, first); list_add_tail(&first->desc_node, &first->descs_list); } else { @@ -1122,7 +1117,7 @@ at_xdmac_prep_interleaved(struct dma_chan *chan, src_skip = chunk->size + src_icg; dst_skip = chunk->size + dst_icg; - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s: chunk size=%zu, src icg=%zu, dst icg=%zu\n", __func__, chunk->size, src_icg, dst_icg); @@ -1140,7 +1135,7 @@ at_xdmac_prep_interleaved(struct dma_chan *chan, if (!first) first = desc; - dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", __func__, desc, first); list_add_tail(&desc->desc_node, &first->descs_list); @@ -1193,7 +1188,7 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | AT_XDMAC_CC_TYPE_MEM_TRAN; unsigned long irqflags; - dev_dbg(chan2dev(chan), "%s: src=%pad, dest=%pad, len=%zd, flags=0x%lx\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: src=%pad, dest=%pad, len=%zd, flags=0x%lx\n", __func__, &src, &dest, len, flags); if (unlikely(!len)) @@ -1205,13 +1200,13 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, while (remaining_size) { struct at_xdmac_desc *desc = NULL; - dev_dbg(chan2dev(chan), "%s: remaining_size=%zu\n", __func__, remaining_size); + dev_dbg(dmaengine_chan_dev(chan), "%s: remaining_size=%zu\n", __func__, remaining_size); spin_lock_irqsave(&atchan->lock, irqflags); desc = at_xdmac_get_desc(atchan); spin_unlock_irqrestore(&atchan->lock, irqflags); if (!desc) { - dev_err(chan2dev(chan), "can't get descriptor\n"); + dev_err(dmaengine_chan_dev(chan), "can't get descriptor\n"); if (first) list_splice_tail_init(&first->descs_list, &atchan->free_descs_list); @@ -1227,7 +1222,7 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, else xfer_size = remaining_size; - dev_dbg(chan2dev(chan), "%s: xfer_size=%zu\n", __func__, xfer_size); + dev_dbg(dmaengine_chan_dev(chan), "%s: xfer_size=%zu\n", __func__, xfer_size); /* Check remaining length and change data width if needed. */ dwidth = at_xdmac_align_width(chan, @@ -1246,7 +1241,7 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, | ublen; desc->lld.mbr_cfg = chan_cc; - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x, mbr_cfg=0x%08x\n", __func__, &desc->lld.mbr_sa, &desc->lld.mbr_da, desc->lld.mbr_ubc, desc->lld.mbr_cfg); @@ -1258,7 +1253,7 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, if (!first) first = desc; - dev_dbg(chan2dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", __func__, desc, first); list_add_tail(&desc->desc_node, &first->descs_list); } @@ -1306,7 +1301,7 @@ static struct at_xdmac_desc *at_xdmac_memset_create_desc(struct dma_chan *chan, dwidth = at_xdmac_align_width(chan, dst_addr); if (len >= (AT_XDMAC_MBR_UBC_UBLEN_MAX << dwidth)) { - dev_err(chan2dev(chan), + dev_err(dmaengine_chan_dev(chan), "%s: Transfer too large, aborting...\n", __func__); return NULL; @@ -1316,7 +1311,7 @@ static struct at_xdmac_desc *at_xdmac_memset_create_desc(struct dma_chan *chan, desc = at_xdmac_get_desc(atchan); spin_unlock_irqrestore(&atchan->lock, flags); if (!desc) { - dev_err(chan2dev(chan), "can't get descriptor\n"); + dev_err(dmaengine_chan_dev(chan), "can't get descriptor\n"); return NULL; } @@ -1338,7 +1333,7 @@ static struct at_xdmac_desc *at_xdmac_memset_create_desc(struct dma_chan *chan, | ublen; desc->lld.mbr_cfg = chan_cc; - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s: lld: mbr_da=%pad, mbr_ds=0x%08x, mbr_ubc=0x%08x, mbr_cfg=0x%08x\n", __func__, &desc->lld.mbr_da, desc->lld.mbr_ds, desc->lld.mbr_ubc, desc->lld.mbr_cfg); @@ -1353,7 +1348,7 @@ at_xdmac_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value, struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); struct at_xdmac_desc *desc; - dev_dbg(chan2dev(chan), "%s: dest=%pad, len=%zu, pattern=0x%x, flags=0x%lx\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: dest=%pad, len=%zu, pattern=0x%x, flags=0x%lx\n", __func__, &dest, len, value, flags); if (unlikely(!len)) @@ -1386,12 +1381,12 @@ at_xdmac_prep_dma_memset_sg(struct dma_chan *chan, struct scatterlist *sgl, if (!sgl) return NULL; - dev_dbg(chan2dev(chan), "%s: sg_len=%d, value=0x%x, flags=0x%lx\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: sg_len=%d, value=0x%x, flags=0x%lx\n", __func__, sg_len, value, flags); /* Prepare descriptors. */ for_each_sg(sgl, sg, sg_len, i) { - dev_dbg(chan2dev(chan), "%s: dest=%pad, len=%d, pattern=0x%x, flags=0x%lx\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: dest=%pad, len=%d, pattern=0x%x, flags=0x%lx\n", __func__, &sg_dma_address(sg), sg_dma_len(sg), value, flags); desc = at_xdmac_memset_create_desc(chan, atchan, @@ -1433,7 +1428,7 @@ at_xdmac_prep_dma_memset_sg(struct dma_chan *chan, struct scatterlist *sgl, if (ppdesc && pdesc) { if ((stride == pstride) && (sg_dma_len(ppsg) == sg_dma_len(psg))) { - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s: desc 0x%p can be merged with desc 0x%p\n", __func__, pdesc, ppdesc); @@ -1481,7 +1476,7 @@ at_xdmac_prep_dma_memset_sg(struct dma_chan *chan, struct scatterlist *sgl, */ list_add_tail(&desc->desc_node, &first->descs_list); - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s: add desc 0x%p to descs_list 0x%p\n", __func__, desc, first); } @@ -1496,7 +1491,7 @@ at_xdmac_prep_dma_memset_sg(struct dma_chan *chan, struct scatterlist *sgl, */ if ((i == (sg_len - 1)) && sg_dma_len(psg) == sg_dma_len(sg)) { - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s: desc 0x%p can be merged with desc 0x%p\n", __func__, desc, pdesc); @@ -1667,7 +1662,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, dma_set_residue(txstate, residue); - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s: desc=0x%p, tx_dma_desc.phys=%pad, tx_status=%d, cookie=%d, residue=%d\n", __func__, desc, &desc->tx_dma_desc.phys, ret, cookie, residue); @@ -1690,7 +1685,7 @@ static void at_xdmac_advance_work(struct at_xdmac_chan *atchan) desc = list_first_entry(&atchan->xfers_list, struct at_xdmac_desc, xfer_node); - dev_vdbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, desc); + dev_vdbg(dmaengine_chan_dev(&atchan->chan), "%s: desc 0x%p\n", __func__, desc); if (!desc->active_xfer) at_xdmac_start_xfer(atchan, desc); } @@ -1701,7 +1696,7 @@ static void at_xdmac_handle_cyclic(struct at_xdmac_chan *atchan) struct dma_async_tx_descriptor *txd; spin_lock_irq(&atchan->lock); - dev_dbg(chan2dev(&atchan->chan), "%s: status=0x%08x\n", + dev_dbg(dmaengine_chan_dev(&atchan->chan), "%s: status=0x%08x\n", __func__, atchan->irq_status); if (list_empty(&atchan->xfers_list)) { spin_unlock_irq(&atchan->lock); @@ -1733,11 +1728,11 @@ static void at_xdmac_handle_error(struct at_xdmac_chan *atchan) * descriptors queued (if any). */ if (atchan->irq_status & AT_XDMAC_CIS_RBEIS) - dev_err(chan2dev(&atchan->chan), "read bus error!!!"); + dev_err(dmaengine_chan_dev(&atchan->chan), "read bus error!!!"); if (atchan->irq_status & AT_XDMAC_CIS_WBEIS) - dev_err(chan2dev(&atchan->chan), "write bus error!!!"); + dev_err(dmaengine_chan_dev(&atchan->chan), "write bus error!!!"); if (atchan->irq_status & AT_XDMAC_CIS_ROIS) - dev_err(chan2dev(&atchan->chan), "request overflow error!!!"); + dev_err(dmaengine_chan_dev(&atchan->chan), "request overflow error!!!"); /* Channel must be disabled first as it's not done automatically */ at_xdmac_write(atxdmac, AT_XDMAC_GD, atchan->mask); @@ -1749,7 +1744,7 @@ static void at_xdmac_handle_error(struct at_xdmac_chan *atchan) xfer_node); /* Print bad descriptor's details if needed */ - dev_dbg(chan2dev(&atchan->chan), + dev_dbg(dmaengine_chan_dev(&atchan->chan), "%s: lld: mbr_sa=%pad, mbr_da=%pad, mbr_ubc=0x%08x\n", __func__, &bad_desc->lld.mbr_sa, &bad_desc->lld.mbr_da, bad_desc->lld.mbr_ubc); @@ -1775,7 +1770,7 @@ static void at_xdmac_tasklet(struct tasklet_struct *t) spin_lock_irq(&atchan->lock); - dev_dbg(chan2dev(&atchan->chan), "%s: status=0x%08x\n", + dev_dbg(dmaengine_chan_dev(&atchan->chan), "%s: status=0x%08x\n", __func__, atchan->irq_status); if (!(atchan->irq_status & AT_XDMAC_CIS_LIS) && @@ -1789,9 +1784,9 @@ static void at_xdmac_tasklet(struct tasklet_struct *t) desc = list_first_entry(&atchan->xfers_list, struct at_xdmac_desc, xfer_node); - dev_vdbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, desc); + dev_vdbg(dmaengine_chan_dev(&atchan->chan), "%s: desc 0x%p\n", __func__, desc); if (!desc->active_xfer) { - dev_err(chan2dev(&atchan->chan), "Xfer not active: exiting"); + dev_err(dmaengine_chan_dev(&atchan->chan), "Xfer not active: exiting"); spin_unlock_irq(&atchan->lock); return; } @@ -1852,7 +1847,7 @@ static irqreturn_t at_xdmac_interrupt(int irq, void *dev_id) dev_vdbg(atxdmac->dma.dev, "%s: chan%d: imr=0x%x, status=0x%x\n", __func__, i, chan_imr, chan_status); - dev_vdbg(chan2dev(&atchan->chan), + dev_vdbg(dmaengine_chan_dev(&atchan->chan), "%s: CC=0x%08x CNDA=0x%08x, CNDC=0x%08x, CSA=0x%08x, CDA=0x%08x, CUBC=0x%08x\n", __func__, at_xdmac_chan_read(atchan, AT_XDMAC_CC), @@ -1879,7 +1874,7 @@ static void at_xdmac_issue_pending(struct dma_chan *chan) struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); unsigned long flags; - dev_dbg(chan2dev(&atchan->chan), "%s\n", __func__); + dev_dbg(dmaengine_chan_dev(&atchan->chan), "%s\n", __func__); spin_lock_irqsave(&atchan->lock, flags); at_xdmac_advance_work(atchan); @@ -1895,7 +1890,7 @@ static int at_xdmac_device_config(struct dma_chan *chan, int ret; unsigned long flags; - dev_dbg(chan2dev(chan), "%s\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s\n", __func__); spin_lock_irqsave(&atchan->lock, flags); ret = at_xdmac_set_slave_config(chan, config); @@ -1931,7 +1926,7 @@ static int at_xdmac_device_pause(struct dma_chan *chan) unsigned long flags; int ret; - dev_dbg(chan2dev(chan), "%s\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s\n", __func__); if (test_and_set_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status)) return 0; @@ -1971,7 +1966,7 @@ static int at_xdmac_device_resume(struct dma_chan *chan) unsigned long flags; int ret; - dev_dbg(chan2dev(chan), "%s\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s\n", __func__); ret = pm_runtime_resume_and_get(atxdmac->dev); if (ret < 0) @@ -2004,7 +1999,7 @@ static int at_xdmac_device_terminate_all(struct dma_chan *chan) unsigned long flags; int ret; - dev_dbg(chan2dev(chan), "%s\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s\n", __func__); ret = pm_runtime_resume_and_get(atxdmac->dev); if (ret < 0) @@ -2045,13 +2040,13 @@ static int at_xdmac_alloc_chan_resources(struct dma_chan *chan) int i; if (at_xdmac_chan_is_enabled(atchan)) { - dev_err(chan2dev(chan), + dev_err(dmaengine_chan_dev(chan), "can't allocate channel resources (channel enabled)\n"); return -EIO; } if (!list_empty(&atchan->free_descs_list)) { - dev_err(chan2dev(chan), + dev_err(dmaengine_chan_dev(chan), "can't allocate channel resources (channel not free from a previous use)\n"); return -EIO; } @@ -2060,11 +2055,11 @@ static int at_xdmac_alloc_chan_resources(struct dma_chan *chan) desc = at_xdmac_alloc_desc(chan, GFP_KERNEL); if (!desc) { if (i == 0) { - dev_warn(chan2dev(chan), + dev_warn(dmaengine_chan_dev(chan), "can't allocate any descriptors\n"); return -EIO; } - dev_warn(chan2dev(chan), + dev_warn(dmaengine_chan_dev(chan), "only %d descriptors have been allocated\n", i); break; } @@ -2073,7 +2068,7 @@ static int at_xdmac_alloc_chan_resources(struct dma_chan *chan) dma_cookie_init(chan); - dev_dbg(chan2dev(chan), "%s: allocated %d descriptors\n", __func__, i); + dev_dbg(dmaengine_chan_dev(chan), "%s: allocated %d descriptors\n", __func__, i); return i; } @@ -2085,7 +2080,7 @@ static void at_xdmac_free_chan_resources(struct dma_chan *chan) struct at_xdmac_desc *desc, *_desc; list_for_each_entry_safe(desc, _desc, &atchan->free_descs_list, desc_node) { - dev_dbg(chan2dev(chan), "%s: freeing descriptor %p\n", __func__, desc); + dev_dbg(dmaengine_chan_dev(chan), "%s: freeing descriptor %p\n", __func__, desc); list_del(&desc->desc_node); dma_pool_free(atxdmac->at_xdmac_desc_pool, desc, desc->tx_dma_desc.phys); } @@ -2148,7 +2143,7 @@ static int __maybe_unused atmel_xdmac_suspend(struct device *dev) atchan->save_cc = at_xdmac_chan_read(atchan, AT_XDMAC_CC); if (at_xdmac_chan_is_cyclic(atchan)) { if (!at_xdmac_chan_is_paused(atchan)) { - dev_warn(chan2dev(chan), "%s: channel %d not paused\n", + dev_warn(dmaengine_chan_dev(chan), "%s: channel %d not paused\n", __func__, chan->chan_id); at_xdmac_device_pause_internal(atchan); at_xdmac_runtime_suspend_descriptors(atchan); diff --git a/drivers/dma/bestcomm/ata.c b/drivers/dma/bestcomm/ata.c index 502a45d76adc..40126f3f189e 100644 --- a/drivers/dma/bestcomm/ata.c +++ b/drivers/dma/bestcomm/ata.c @@ -55,7 +55,6 @@ bcom_ata_init(int queue_len, int maxbufsize) { struct bcom_task *tsk; struct bcom_ata_var *var; - struct bcom_ata_inc *inc; /* Prefetch breaks ATA DMA. Turn it off for ATA DMA */ bcom_disable_prefetch(); @@ -69,7 +68,6 @@ bcom_ata_init(int queue_len, int maxbufsize) bcom_ata_reset_bd(tsk); var = (struct bcom_ata_var *) bcom_task_var(tsk->tasknum); - inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum); if (bcom_load_image(tsk->tasknum, bcom_ata_task)) { bcom_task_free(tsk); diff --git a/drivers/dma/bestcomm/bestcomm.c b/drivers/dma/bestcomm/bestcomm.c index 432b43520ddc..241a91936fe8 100644 --- a/drivers/dma/bestcomm/bestcomm.c +++ b/drivers/dma/bestcomm/bestcomm.c @@ -13,7 +13,6 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/of.h> -#include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/platform_device.h> #include <asm/io.h> @@ -365,13 +364,19 @@ bcom_engine_cleanup(void) static int mpc52xx_bcom_probe(struct platform_device *op) { struct device_node *ofn_sram; - struct resource res_bcom; + struct resource *res_bcom; + void __iomem *regs; int rv; /* Inform user we're ok so far */ printk(KERN_INFO "DMA: MPC52xx BestComm driver\n"); + /* Get, reserve & map io */ + regs = devm_platform_get_and_ioremap_resource(op, 0, &res_bcom); + if (IS_ERR(regs)) + return PTR_ERR(regs); + /* Get the bestcomm node */ of_node_get(op->dev.of_node); @@ -402,35 +407,13 @@ static int mpc52xx_bcom_probe(struct platform_device *op) /* Save the node */ bcom_eng->ofnode = op->dev.of_node; - /* Get, reserve & map io */ - if (of_address_to_resource(op->dev.of_node, 0, &res_bcom)) { - printk(KERN_ERR DRIVER_NAME ": " - "Can't get resource\n"); - rv = -EINVAL; - goto error_sramclean; - } - - if (!request_mem_region(res_bcom.start, resource_size(&res_bcom), - DRIVER_NAME)) { - printk(KERN_ERR DRIVER_NAME ": " - "Can't request registers region\n"); - rv = -EBUSY; - goto error_sramclean; - } - - bcom_eng->regs_base = res_bcom.start; - bcom_eng->regs = ioremap(res_bcom.start, sizeof(struct mpc52xx_sdma)); - if (!bcom_eng->regs) { - printk(KERN_ERR DRIVER_NAME ": " - "Can't map registers\n"); - rv = -ENOMEM; - goto error_release; - } + bcom_eng->regs = regs; + bcom_eng->regs_base = res_bcom->start; /* Now, do the real init */ rv = bcom_engine_init(); if (rv) - goto error_unmap; + goto error_sramclean; /* Done ! */ printk(KERN_INFO "DMA: MPC52xx BestComm engine @%08lx ok !\n", @@ -439,12 +422,9 @@ static int mpc52xx_bcom_probe(struct platform_device *op) return 0; /* Error path */ -error_unmap: - iounmap(bcom_eng->regs); -error_release: - release_mem_region(res_bcom.start, sizeof(struct mpc52xx_sdma)); error_sramclean: kfree(bcom_eng); + bcom_eng = NULL; bcom_sram_cleanup(); error_ofput: of_node_put(op->dev.of_node); @@ -463,10 +443,6 @@ static void mpc52xx_bcom_remove(struct platform_device *op) /* Cleanup SRAM */ bcom_sram_cleanup(); - /* Release regs */ - iounmap(bcom_eng->regs); - release_mem_region(bcom_eng->regs_base, sizeof(struct mpc52xx_sdma)); - /* Release the node */ of_node_put(bcom_eng->ofnode); diff --git a/drivers/dma/bestcomm/gen_bd.c b/drivers/dma/bestcomm/gen_bd.c index 8a24a5cbc263..3b4fabb4d12b 100644 --- a/drivers/dma/bestcomm/gen_bd.c +++ b/drivers/dma/bestcomm/gen_bd.c @@ -81,7 +81,7 @@ struct bcom_gen_bd_priv { /* Task support code */ /* ======================================================================== */ -struct bcom_task * +static struct bcom_task * bcom_gen_bd_rx_init(int queue_len, phys_addr_t fifo, int initiator, int ipr, int maxbufsize) { @@ -108,7 +108,6 @@ bcom_gen_bd_rx_init(int queue_len, phys_addr_t fifo, return tsk; } -EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_init); int bcom_gen_bd_rx_reset(struct bcom_task *tsk) @@ -166,7 +165,7 @@ bcom_gen_bd_rx_release(struct bcom_task *tsk) EXPORT_SYMBOL_GPL(bcom_gen_bd_rx_release); -extern struct bcom_task * +static struct bcom_task * bcom_gen_bd_tx_init(int queue_len, phys_addr_t fifo, int initiator, int ipr) { @@ -192,7 +191,6 @@ bcom_gen_bd_tx_init(int queue_len, phys_addr_t fifo, return tsk; } -EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_init); int bcom_gen_bd_tx_reset(struct bcom_task *tsk) @@ -254,17 +252,23 @@ EXPORT_SYMBOL_GPL(bcom_gen_bd_tx_release); */ /** - * bcom_psc_parameters - Bestcomm initialization value table for PSC devices + * struct bcom_psc_params - Bestcomm initialization value table for PSC devices + * @rx_initiator: RX initiator ID + * @rx_ipr: RX interrupt priority register value + * @tx_initiator: TX initiator ID + * @tx_ipr: TX interrupt priority register value * * This structure is only used internally. It is a lookup table for PSC * specific parameters to bestcomm tasks. */ -static struct bcom_psc_params { +struct bcom_psc_params { int rx_initiator; int rx_ipr; int tx_initiator; int tx_ipr; -} bcom_psc_params[] = { +}; + +static const struct bcom_psc_params bcom_psc_params[] = { [0] = { .rx_initiator = BCOM_INITIATOR_PSC1_RX, .rx_ipr = BCOM_IPR_PSC1_RX, @@ -315,7 +319,7 @@ static struct bcom_psc_params { struct bcom_task * bcom_psc_gen_bd_rx_init(unsigned psc_num, int queue_len, phys_addr_t fifo, int maxbufsize) { - if (psc_num >= MPC52xx_PSC_MAXNUM) + if (psc_num >= ARRAY_SIZE(bcom_psc_params)) return NULL; return bcom_gen_bd_rx_init(queue_len, fifo, @@ -336,6 +340,9 @@ EXPORT_SYMBOL_GPL(bcom_psc_gen_bd_rx_init); struct bcom_task * bcom_psc_gen_bd_tx_init(unsigned psc_num, int queue_len, phys_addr_t fifo) { + if (psc_num >= ARRAY_SIZE(bcom_psc_params)) + return NULL; + struct psc; return bcom_gen_bd_tx_init(queue_len, fifo, bcom_psc_params[psc_num].tx_initiator, diff --git a/drivers/dma/dma-jz4780.c b/drivers/dma/dma-jz4780.c index 6070dfdb7114..ac2094e65ecf 100644 --- a/drivers/dma/dma-jz4780.c +++ b/drivers/dma/dma-jz4780.c @@ -687,12 +687,12 @@ static bool jz4780_dma_chan_irq(struct jz4780_dma_dev *jzdma, jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DCS, 0); if (dcs & JZ_DMA_DCS_AR) { - dev_warn(&jzchan->vchan.chan.dev->device, + dev_warn(vchan_chan_dev(&jzchan->vchan), "address error (DCS=0x%x)\n", dcs); } if (dcs & JZ_DMA_DCS_HLT) { - dev_warn(&jzchan->vchan.chan.dev->device, + dev_warn(vchan_chan_dev(&jzchan->vchan), "channel halt (DCS=0x%x)\n", dcs); } @@ -721,7 +721,7 @@ static bool jz4780_dma_chan_irq(struct jz4780_dma_dev *jzdma, } } } else { - dev_err(&jzchan->vchan.chan.dev->device, + dev_err(vchan_chan_dev(&jzchan->vchan), "channel IRQ with no active transfer\n"); } @@ -760,12 +760,12 @@ static int jz4780_dma_alloc_chan_resources(struct dma_chan *chan) { struct jz4780_dma_chan *jzchan = to_jz4780_dma_chan(chan); - jzchan->desc_pool = dma_pool_create(dev_name(&chan->dev->device), + jzchan->desc_pool = dma_pool_create(dma_chan_name(chan), chan->device->dev, JZ_DMA_DESC_BLOCK_SIZE, PAGE_SIZE, 0); if (!jzchan->desc_pool) { - dev_err(&chan->dev->device, + dev_err(dmaengine_chan_dev(chan), "failed to allocate descriptor pool\n"); return -ENOMEM; } diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index c71763047126..cc1c0a7c9f33 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -879,10 +879,10 @@ found: return chan; chan->slave = dev; - if (sysfs_create_link(&chan->dev->device.kobj, &dev->kobj, + if (sysfs_create_link(&dmaengine_chan_dev(chan)->kobj, &dev->kobj, DMA_SLAVE_NAME)) dev_warn(dev, "Cannot create DMA %s symlink\n", DMA_SLAVE_NAME); - if (sysfs_create_link(&dev->kobj, &chan->dev->device.kobj, chan->name)) + if (sysfs_create_link(&dev->kobj, &dmaengine_chan_dev(chan)->kobj, chan->name)) dev_warn(dev, "Cannot create DMA %s symlink\n", chan->name); return chan; @@ -928,7 +928,7 @@ void dma_release_channel(struct dma_chan *chan) dma_chan_put(chan); if (chan->slave) { - sysfs_remove_link(&chan->dev->device.kobj, DMA_SLAVE_NAME); + sysfs_remove_link(&dmaengine_chan_dev(chan)->kobj, DMA_SLAVE_NAME); sysfs_remove_link(&chan->slave->kobj, chan->name); kfree(chan->name); chan->name = NULL; @@ -1094,8 +1094,8 @@ static int __dma_async_device_channel_register(struct dma_device *device, chan->local = alloc_percpu(typeof(*chan->local)); if (!chan->local) return -ENOMEM; - chan->dev = kzalloc_obj(*chan->dev); - if (!chan->dev) { + chan->chan_dev = kzalloc_obj(*chan->chan_dev); + if (!chan->chan_dev) { rc = -ENOMEM; goto err_free_local; } @@ -1112,17 +1112,17 @@ static int __dma_async_device_channel_register(struct dma_device *device, goto err_free_dev; } - chan->dev->device.class = &dma_devclass; - chan->dev->device.parent = device->dev; - chan->dev->chan = chan; - chan->dev->dev_id = device->dev_id; + dmaengine_chan_dev(chan)->class = &dma_devclass; + dmaengine_chan_dev(chan)->parent = device->dev; + chan->chan_dev->chan = chan; + chan->chan_dev->dev_id = device->dev_id; spin_lock_init(&chan->lock); if (!name) - dev_set_name(&chan->dev->device, "dma%dchan%d", device->dev_id, chan->chan_id); + dev_set_name(dmaengine_chan_dev(chan), "dma%dchan%d", device->dev_id, chan->chan_id); else - dev_set_name(&chan->dev->device, "%s", name); - rc = device_register(&chan->dev->device); + dev_set_name(dmaengine_chan_dev(chan), "%s", name); + rc = device_register(dmaengine_chan_dev(chan)); if (rc) goto err_out_ida; chan->client_count = 0; @@ -1133,7 +1133,7 @@ static int __dma_async_device_channel_register(struct dma_device *device, err_out_ida: ida_free(&device->chan_ida, chan->chan_id); err_free_dev: - kfree(chan->dev); + kfree(chan->chan_dev); err_free_local: free_percpu(chan->local); chan->local = NULL; @@ -1166,10 +1166,10 @@ static void __dma_async_device_channel_unregister(struct dma_device *device, __func__, chan->client_count); mutex_lock(&dma_list_mutex); device->chancnt--; - chan->dev->chan = NULL; + chan->chan_dev->chan = NULL; mutex_unlock(&dma_list_mutex); ida_free(&device->chan_ida, chan->chan_id); - device_unregister(&chan->dev->device); + device_unregister(dmaengine_chan_dev(chan)); free_percpu(chan->local); } @@ -1301,9 +1301,9 @@ err_out: if (chan->local == NULL) continue; mutex_lock(&dma_list_mutex); - chan->dev->chan = NULL; + chan->chan_dev->chan = NULL; mutex_unlock(&dma_list_mutex); - device_unregister(&chan->dev->device); + device_unregister(dmaengine_chan_dev(chan)); free_percpu(chan->local); } return rc; diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c index eebed2474210..7520c78f55cc 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -7,6 +7,7 @@ * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> */ +#include <linux/bitfield.h> #include <linux/bitops.h> #include <linux/delay.h> #include <linux/device.h> @@ -101,23 +102,25 @@ static inline void axi_chan_config_write(struct axi_dma_chan *chan, { u32 cfg_lo, cfg_hi; - cfg_lo = (config->dst_multblk_type << CH_CFG_L_DST_MULTBLK_TYPE_POS | - config->src_multblk_type << CH_CFG_L_SRC_MULTBLK_TYPE_POS); if (chan->chip->dw->hdata->reg_map_8_channels && !chan->chip->dw->hdata->use_cfg2) { - cfg_hi = config->tt_fc << CH_CFG_H_TT_FC_POS | - config->hs_sel_src << CH_CFG_H_HS_SEL_SRC_POS | - config->hs_sel_dst << CH_CFG_H_HS_SEL_DST_POS | - config->src_per << CH_CFG_H_SRC_PER_POS | - config->dst_per << CH_CFG_H_DST_PER_POS | - config->prior << CH_CFG_H_PRIORITY_POS; + cfg_lo = FIELD_PREP(CH_CFG_L_DST_MULTBLK_TYPE, config->dst_multblk_type) | + FIELD_PREP(CH_CFG_L_SRC_MULTBLK_TYPE, config->src_multblk_type); + cfg_hi = FIELD_PREP(CH_CFG_H_TT_FC, config->tt_fc) | + FIELD_PREP(CH_CFG_H_HS_SEL_SRC, config->hs_sel_src) | + FIELD_PREP(CH_CFG_H_HS_SEL_DST, config->hs_sel_dst) | + FIELD_PREP(CH_CFG_H_SRC_PER, config->src_per) | + FIELD_PREP(CH_CFG_H_DST_PER, config->dst_per) | + FIELD_PREP(CH_CFG_H_PRIORITY, config->prior); } else { - cfg_lo |= config->src_per << CH_CFG2_L_SRC_PER_POS | - config->dst_per << CH_CFG2_L_DST_PER_POS; - cfg_hi = config->tt_fc << CH_CFG2_H_TT_FC_POS | - config->hs_sel_src << CH_CFG2_H_HS_SEL_SRC_POS | - config->hs_sel_dst << CH_CFG2_H_HS_SEL_DST_POS | - config->prior << CH_CFG2_H_PRIORITY_POS; + cfg_lo = FIELD_PREP(CH_CFG_L_DST_MULTBLK_TYPE, config->dst_multblk_type) | + FIELD_PREP(CH_CFG_L_SRC_MULTBLK_TYPE, config->src_multblk_type) | + FIELD_PREP(CH_CFG2_L_SRC_PER, config->src_per) | + FIELD_PREP(CH_CFG2_L_DST_PER, config->dst_per); + cfg_hi = FIELD_PREP(CH_CFG2_H_TT_FC, config->tt_fc) | + FIELD_PREP(CH_CFG2_H_HS_SEL_SRC, config->hs_sel_src) | + FIELD_PREP(CH_CFG2_H_HS_SEL_DST, config->hs_sel_dst) | + FIELD_PREP(CH_CFG2_H_PRIORITY, config->prior); } axi_chan_iowrite32(chan, CH_CFG_L, cfg_lo); axi_chan_iowrite32(chan, CH_CFG_H, cfg_hi); @@ -316,7 +319,7 @@ static struct axi_dma_lli *axi_desc_get(struct axi_dma_chan *chan, lli = dma_pool_zalloc(chan->desc_pool, GFP_NOWAIT, &phys); if (unlikely(!lli)) { - dev_err(chan2dev(chan), "%s: not enough descriptors available\n", + dev_err(vchan_chan_dev(&chan->vc), "%s: not enough descriptors available\n", axi_chan_name(chan)); return NULL; } @@ -342,7 +345,7 @@ static void axi_desc_put(struct axi_dma_desc *desc) kfree(desc->hw_desc); kfree(desc); atomic_sub(descs_put, &chan->descs_allocated); - dev_vdbg(chan2dev(chan), "%s: %d descs put, %d still allocated\n", + dev_vdbg(vchan_chan_dev(&chan->vc), "%s: %d descs put, %d still allocated\n", axi_chan_name(chan), descs_put, atomic_read(&chan->descs_allocated)); } @@ -431,7 +434,7 @@ static void axi_chan_block_xfer_start(struct axi_dma_chan *chan, u8 lms = 0; /* Select AXI0 master for LLI fetching */ if (unlikely(axi_chan_is_hw_enable(chan))) { - dev_err(chan2dev(chan), "%s is non-idle!\n", + dev_err(vchan_chan_dev(&chan->vc), "%s is non-idle!\n", axi_chan_name(chan)); return; @@ -490,7 +493,7 @@ static void axi_chan_start_first_queued(struct axi_dma_chan *chan) return; desc = vd_to_axi_desc(vd); - dev_vdbg(chan2dev(chan), "%s: started %u\n", axi_chan_name(chan), + dev_vdbg(vchan_chan_dev(&chan->vc), "%s: started %u\n", axi_chan_name(chan), vd->tx.cookie); axi_chan_block_xfer_start(chan, desc); } @@ -524,23 +527,22 @@ static int dma_chan_alloc_chan_resources(struct dma_chan *dchan) /* ASSERT: channel is idle */ if (axi_chan_is_hw_enable(chan)) { - dev_err(chan2dev(chan), "%s is non-idle!\n", + dev_err(vchan_chan_dev(&chan->vc), "%s is non-idle!\n", axi_chan_name(chan)); pm_runtime_put(chan->chip->dev); return -EBUSY; } /* LLI address must be aligned to a 64-byte boundary */ - chan->desc_pool = dma_pool_create(dev_name(chan2dev(chan)), - chan->chip->dev, + chan->desc_pool = dma_pool_create(dma_chan_name(dchan), chan->chip->dev, sizeof(struct axi_dma_lli), 64, 0); if (!chan->desc_pool) { - dev_err(chan2dev(chan), "No memory for descriptors\n"); + dev_err(vchan_chan_dev(&chan->vc), "No memory for descriptors\n"); pm_runtime_put(chan->chip->dev); return -ENOMEM; } - dev_vdbg(dchan2dev(dchan), "%s: allocating\n", axi_chan_name(chan)); + dev_vdbg(dmaengine_chan_dev(dchan), "%s: allocating\n", axi_chan_name(chan)); return 0; } @@ -551,7 +553,7 @@ static void dma_chan_free_chan_resources(struct dma_chan *dchan) /* ASSERT: channel is idle */ if (axi_chan_is_hw_enable(chan)) - dev_err(dchan2dev(dchan), "%s is non-idle!\n", + dev_err(dmaengine_chan_dev(dchan), "%s is non-idle!\n", axi_chan_name(chan)); axi_chan_disable(chan); @@ -561,7 +563,7 @@ static void dma_chan_free_chan_resources(struct dma_chan *dchan) dma_pool_destroy(chan->desc_pool); chan->desc_pool = NULL; - dev_vdbg(dchan2dev(dchan), + dev_vdbg(dmaengine_chan_dev(dchan), "%s: free resources, descriptor still allocated: %u\n", axi_chan_name(chan), atomic_read(&chan->descs_allocated)); @@ -677,19 +679,19 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan, case DMA_MEM_TO_DEV: reg_width = __ffs(chan->config.dst_addr_width); device_addr = chan->config.dst_addr; - ctllo = reg_width << CH_CTL_L_DST_WIDTH_POS | - mem_width << CH_CTL_L_SRC_WIDTH_POS | - DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_DST_INC_POS | - DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS; + ctllo = FIELD_PREP(CH_CTL_L_DST_WIDTH, reg_width) | + FIELD_PREP(CH_CTL_L_SRC_WIDTH, mem_width) | + FIELD_PREP(CH_CTL_L_DST_INC, DWAXIDMAC_CH_CTL_L_NOINC) | + FIELD_PREP(CH_CTL_L_SRC_INC, DWAXIDMAC_CH_CTL_L_INC); block_ts = len >> mem_width; break; case DMA_DEV_TO_MEM: reg_width = __ffs(chan->config.src_addr_width); device_addr = chan->config.src_addr; - ctllo = reg_width << CH_CTL_L_SRC_WIDTH_POS | - mem_width << CH_CTL_L_DST_WIDTH_POS | - DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS | - DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_SRC_INC_POS; + ctllo = FIELD_PREP(CH_CTL_L_SRC_WIDTH, reg_width) | + FIELD_PREP(CH_CTL_L_DST_WIDTH, mem_width) | + FIELD_PREP(CH_CTL_L_DST_INC, DWAXIDMAC_CH_CTL_L_INC) | + FIELD_PREP(CH_CTL_L_SRC_INC, DWAXIDMAC_CH_CTL_L_NOINC); block_ts = len >> reg_width; break; default: @@ -706,10 +708,10 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan, ctlhi = CH_CTL_H_LLI_VALID; if (chan->chip->dw->hdata->restrict_axi_burst_len) { - burst_len = chan->chip->dw->hdata->axi_rw_burst_len; + burst_len = chan->chip->dw->hdata->axi_rw_burst_len - 1; ctlhi |= CH_CTL_H_ARLEN_EN | CH_CTL_H_AWLEN_EN | - burst_len << CH_CTL_H_ARLEN_POS | - burst_len << CH_CTL_H_AWLEN_POS; + FIELD_PREP(CH_CTL_H_ARLEN, burst_len) | + FIELD_PREP(CH_CTL_H_AWLEN, burst_len); } hw_desc->lli->ctl_hi = cpu_to_le32(ctlhi); @@ -724,8 +726,8 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan, hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1); - ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS | - DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS; + ctllo |= FIELD_PREP(CH_CTL_L_DST_MSIZE, DWAXIDMAC_BURST_TRANS_LEN_4) | + FIELD_PREP(CH_CTL_L_SRC_MSIZE, DWAXIDMAC_BURST_TRANS_LEN_4); hw_desc->lli->ctl_lo = cpu_to_le32(ctllo); set_desc_src_master(hw_desc); @@ -930,7 +932,7 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr, u64 llp = 0; u8 lms = 0; /* Select AXI0 master for LLI fetching */ - dev_dbg(chan2dev(chan), "%s: memcpy: src: %pad dst: %pad length: %zd flags: %#lx", + dev_dbg(vchan_chan_dev(&chan->vc), "%s: memcpy: src: %pad dst: %pad length: %zd flags: %#lx", axi_chan_name(chan), &src_adr, &dst_adr, len, flags); max_block_ts = chan->chip->dw->hdata->block_size[chan->id]; @@ -975,21 +977,21 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr, reg = CH_CTL_H_LLI_VALID; if (chan->chip->dw->hdata->restrict_axi_burst_len) { - u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len; + u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len - 1; - reg |= (CH_CTL_H_ARLEN_EN | - burst_len << CH_CTL_H_ARLEN_POS | - CH_CTL_H_AWLEN_EN | - burst_len << CH_CTL_H_AWLEN_POS); + reg |= CH_CTL_H_ARLEN_EN | + FIELD_PREP(CH_CTL_H_ARLEN, burst_len) | + CH_CTL_H_AWLEN_EN | + FIELD_PREP(CH_CTL_H_AWLEN, burst_len); } hw_desc->lli->ctl_hi = cpu_to_le32(reg); - reg = (DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS | - DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS | - xfer_width << CH_CTL_L_DST_WIDTH_POS | - xfer_width << CH_CTL_L_SRC_WIDTH_POS | - DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS | - DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS); + reg = FIELD_PREP(CH_CTL_L_DST_MSIZE, DWAXIDMAC_BURST_TRANS_LEN_4) | + FIELD_PREP(CH_CTL_L_SRC_MSIZE, DWAXIDMAC_BURST_TRANS_LEN_4) | + FIELD_PREP(CH_CTL_L_DST_WIDTH, xfer_width) | + FIELD_PREP(CH_CTL_L_SRC_WIDTH, xfer_width) | + FIELD_PREP(CH_CTL_L_DST_INC, DWAXIDMAC_CH_CTL_L_INC) | + FIELD_PREP(CH_CTL_L_SRC_INC, DWAXIDMAC_CH_CTL_L_INC); hw_desc->lli->ctl_lo = cpu_to_le32(reg); set_desc_src_master(hw_desc); @@ -1035,11 +1037,11 @@ static void axi_chan_dump_lli(struct axi_dma_chan *chan, struct axi_dma_hw_desc *desc) { if (!desc->lli) { - dev_err(dchan2dev(&chan->vc.chan), "NULL LLI\n"); + dev_err(vchan_chan_dev(&chan->vc), "NULL LLI\n"); return; } - dev_err(dchan2dev(&chan->vc.chan), + dev_err(vchan_chan_dev(&chan->vc), "SAR: 0x%llx DAR: 0x%llx LLP: 0x%llx BTS 0x%x CTL: 0x%x:%08x", le64_to_cpu(desc->lli->sar), le64_to_cpu(desc->lli->dar), @@ -1052,10 +1054,7 @@ static void axi_chan_dump_lli(struct axi_dma_chan *chan, static void axi_chan_list_dump_lli(struct axi_dma_chan *chan, struct axi_dma_desc *desc_head) { - int count = atomic_read(&chan->descs_allocated); - int i; - - for (i = 0; i < count; i++) + for (unsigned int i = 0; i < desc_head->nr_hw_descs; i++) axi_chan_dump_lli(chan, &desc_head->hw_desc[i]); } @@ -1071,7 +1070,7 @@ static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status) /* The bad descriptor currently is in the head of vc list */ vd = vchan_next_desc(&chan->vc); if (!vd) { - dev_err(chan2dev(chan), "BUG: %s, IRQ with no descriptors\n", + dev_err(vchan_chan_dev(&chan->vc), "BUG: %s, IRQ with no descriptors\n", axi_chan_name(chan)); goto out; } @@ -1079,7 +1078,7 @@ static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status) list_del(&vd->node); /* WARN about bad descriptor */ - dev_err(chan2dev(chan), + dev_err(vchan_chan_dev(&chan->vc), "Bad descriptor submitted for %s, cookie: %d, irq: 0x%08x\n", axi_chan_name(chan), vd->tx.cookie, status); axi_chan_list_dump_lli(chan, vd_to_axi_desc(vd)); @@ -1105,7 +1104,7 @@ static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan) spin_lock_irqsave(&chan->vc.lock, flags); if (unlikely(axi_chan_is_hw_enable(chan))) { - dev_err(chan2dev(chan), "BUG: %s caught DWAXIDMAC_IRQ_DMA_TRF, but channel not idle!\n", + dev_err(vchan_chan_dev(&chan->vc), "BUG: %s caught DWAXIDMAC_IRQ_DMA_TRF, but channel not idle!\n", axi_chan_name(chan)); axi_chan_disable(chan); } @@ -1113,7 +1112,7 @@ static void axi_chan_block_xfer_complete(struct axi_dma_chan *chan) /* The completed descriptor currently is in the head of vc list */ vd = vchan_next_desc(&chan->vc); if (!vd) { - dev_err(chan2dev(chan), "BUG: %s, IRQ with no descriptors\n", + dev_err(vchan_chan_dev(&chan->vc), "BUG: %s, IRQ with no descriptors\n", axi_chan_name(chan)); goto out; } @@ -1193,7 +1192,7 @@ static int dma_chan_terminate_all(struct dma_chan *dchan) ret = readl_poll_timeout_atomic(chan->chip->regs + DMAC_CHEN, val, !(val & chan_active), 1000, 50000); if (ret == -ETIMEDOUT) - dev_warn(dchan2dev(dchan), + dev_warn(dmaengine_chan_dev(dchan), "%s failed to stop\n", axi_chan_name(chan)); if (chan->direction != DMA_MEM_TO_MEM) @@ -1210,7 +1209,7 @@ static int dma_chan_terminate_all(struct dma_chan *dchan) vchan_dma_desc_free_list(&chan->vc, &head); - dev_vdbg(dchan2dev(dchan), "terminated: %s\n", axi_chan_name(chan)); + dev_vdbg(dmaengine_chan_dev(dchan), "terminated: %s\n", axi_chan_name(chan)); return 0; } @@ -1320,8 +1319,7 @@ static int axi_dma_suspend(struct axi_dma_chip *chip) axi_dma_irq_disable(chip); axi_dma_disable(chip); - clk_disable_unprepare(chip->core_clk); - clk_disable_unprepare(chip->cfgr_clk); + clk_bulk_disable_unprepare(ARRAY_SIZE(chip->clks), chip->clks); return 0; } @@ -1330,11 +1328,7 @@ static int axi_dma_resume(struct axi_dma_chip *chip) { int ret; - ret = clk_prepare_enable(chip->cfgr_clk); - if (ret < 0) - return ret; - - ret = clk_prepare_enable(chip->core_clk); + ret = clk_bulk_prepare_enable(ARRAY_SIZE(chip->clks), chip->clks); if (ret < 0) return ret; @@ -1524,13 +1518,11 @@ static int dw_probe(struct platform_device *pdev) chip->dw->hdata->use_cfg2 = !!(flags & AXI_DMA_FLAG_USE_CFG2); - chip->core_clk = devm_clk_get(chip->dev, "core-clk"); - if (IS_ERR(chip->core_clk)) - return PTR_ERR(chip->core_clk); - - chip->cfgr_clk = devm_clk_get(chip->dev, "cfgr-clk"); - if (IS_ERR(chip->cfgr_clk)) - return PTR_ERR(chip->cfgr_clk); + chip->clks[0].id = "core-clk"; + chip->clks[1].id = "cfgr-clk"; + ret = devm_clk_bulk_get(chip->dev, ARRAY_SIZE(chip->clks), chip->clks); + if (ret) + return dev_err_probe(chip->dev, ret, "failed to get clocks\n"); ret = parse_device_properties(chip); if (ret) @@ -1640,10 +1632,13 @@ static void dw_remove(struct platform_device *pdev) struct dw_axi_dma *dw = chip->dw; struct axi_dma_chan *chan, *_chan; u32 i; + int ret; /* Enable clk before accessing to registers */ - clk_prepare_enable(chip->cfgr_clk); - clk_prepare_enable(chip->core_clk); + ret = clk_bulk_prepare_enable(ARRAY_SIZE(chip->clks), chip->clks); + if (ret) + dev_warn(chip->dev, "failed to enable clocks before remove: %d\n", + ret); axi_dma_irq_disable(chip); for (i = 0; i < dw->hdata->nr_channels; i++) { axi_chan_disable(&chip->dw->chan[i]); diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h index 67cc199e24d1..d8dd07efe60f 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h @@ -69,8 +69,7 @@ struct axi_dma_chip { int irq[DMAC_MAX_CHANNELS]; void __iomem *regs; void __iomem *apb_regs; - struct clk *core_clk; - struct clk *cfgr_clk; + struct clk_bulk_data clks[2]; struct dw_axi_dma *dw; }; @@ -119,16 +118,6 @@ struct axi_dma_chan_config { u8 hs_sel_src; }; -static inline struct device *dchan2dev(struct dma_chan *dchan) -{ - return &dchan->dev->device; -} - -static inline struct device *chan2dev(struct axi_dma_chan *chan) -{ - return &chan->vc.chan.dev->device; -} - static inline struct axi_dma_desc *vd_to_axi_desc(struct virt_dma_desc *vd) { return container_of(vd, struct axi_dma_desc, vd); @@ -234,9 +223,9 @@ static inline struct axi_dma_chan *dchan_to_axi_dma_chan(struct dma_chan *dchan) /* CH_CTL_H */ #define CH_CTL_H_ARLEN_EN BIT(6) -#define CH_CTL_H_ARLEN_POS 7 +#define CH_CTL_H_ARLEN GENMASK(14, 7) #define CH_CTL_H_AWLEN_EN BIT(15) -#define CH_CTL_H_AWLEN_POS 16 +#define CH_CTL_H_AWLEN GENMASK(23, 16) enum { DWAXIDMAC_ARWLEN_1 = 0, @@ -258,8 +247,8 @@ enum { /* CH_CTL_L */ #define CH_CTL_L_LAST_WRITE_EN BIT(30) -#define CH_CTL_L_DST_MSIZE_POS 18 -#define CH_CTL_L_SRC_MSIZE_POS 14 +#define CH_CTL_L_DST_MSIZE GENMASK(21, 18) +#define CH_CTL_L_SRC_MSIZE GENMASK(17, 14) enum { DWAXIDMAC_BURST_TRANS_LEN_1 = 0, @@ -274,11 +263,11 @@ enum { DWAXIDMAC_BURST_TRANS_LEN_1024 }; -#define CH_CTL_L_DST_WIDTH_POS 11 -#define CH_CTL_L_SRC_WIDTH_POS 8 +#define CH_CTL_L_DST_WIDTH GENMASK(13, 11) +#define CH_CTL_L_SRC_WIDTH GENMASK(10, 8) -#define CH_CTL_L_DST_INC_POS 6 -#define CH_CTL_L_SRC_INC_POS 4 +#define CH_CTL_L_DST_INC BIT(6) +#define CH_CTL_L_SRC_INC BIT(4) enum { DWAXIDMAC_CH_CTL_L_INC = 0, DWAXIDMAC_CH_CTL_L_NOINC @@ -288,17 +277,17 @@ enum { #define CH_CTL_L_SRC_MAST BIT(0) /* CH_CFG_H */ -#define CH_CFG_H_PRIORITY_POS 17 -#define CH_CFG_H_DST_PER_POS 12 -#define CH_CFG_H_SRC_PER_POS 7 -#define CH_CFG_H_HS_SEL_DST_POS 4 -#define CH_CFG_H_HS_SEL_SRC_POS 3 +#define CH_CFG_H_PRIORITY GENMASK(19, 17) +#define CH_CFG_H_DST_PER GENMASK(15, 12) +#define CH_CFG_H_SRC_PER GENMASK(10, 7) +#define CH_CFG_H_HS_SEL_DST BIT(4) +#define CH_CFG_H_HS_SEL_SRC BIT(3) enum { DWAXIDMAC_HS_SEL_HW = 0, DWAXIDMAC_HS_SEL_SW }; -#define CH_CFG_H_TT_FC_POS 0 +#define CH_CFG_H_TT_FC GENMASK(2, 0) enum { DWAXIDMAC_TT_FC_MEM_TO_MEM_DMAC = 0, DWAXIDMAC_TT_FC_MEM_TO_PER_DMAC, @@ -311,8 +300,8 @@ enum { }; /* CH_CFG_L */ -#define CH_CFG_L_DST_MULTBLK_TYPE_POS 2 -#define CH_CFG_L_SRC_MULTBLK_TYPE_POS 0 +#define CH_CFG_L_DST_MULTBLK_TYPE GENMASK(3, 2) +#define CH_CFG_L_SRC_MULTBLK_TYPE GENMASK(1, 0) enum { DWAXIDMAC_MBLK_TYPE_CONTIGUOUS = 0, DWAXIDMAC_MBLK_TYPE_RELOAD, @@ -321,13 +310,13 @@ enum { }; /* CH_CFG2 */ -#define CH_CFG2_L_SRC_PER_POS 4 -#define CH_CFG2_L_DST_PER_POS 11 +#define CH_CFG2_L_SRC_PER GENMASK(9, 4) +#define CH_CFG2_L_DST_PER GENMASK(16, 11) -#define CH_CFG2_H_TT_FC_POS 0 -#define CH_CFG2_H_HS_SEL_SRC_POS 3 -#define CH_CFG2_H_HS_SEL_DST_POS 4 -#define CH_CFG2_H_PRIORITY_POS 20 +#define CH_CFG2_H_TT_FC GENMASK(2, 0) +#define CH_CFG2_H_HS_SEL_SRC BIT(3) +#define CH_CFG2_H_HS_SEL_DST BIT(4) +#define CH_CFG2_H_PRIORITY GENMASK(19, 15) /** * DW AXI DMA channel interrupts diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index 03b2c2188351..e2eba6d72b53 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -13,6 +13,7 @@ #include <linux/dmaengine.h> #include <linux/err.h> #include <linux/interrupt.h> +#include <linux/io.h> #include <linux/irq.h> #include <linux/dma/edma.h> #include <linux/dma-mapping.h> @@ -30,9 +31,9 @@ struct dw_edma_desc *vd2dw_edma_desc(struct virt_dma_desc *vd) return container_of(vd, struct dw_edma_desc, vd); } -enum dw_edma_irq_event { - DW_EDMA_IRQ_DONE = BIT(0), - DW_EDMA_IRQ_ABORT = BIT(1), +enum dw_edma_deferred_event { + DW_EDMA_DEFERRED_DONE = BIT(0), + DW_EDMA_DEFERRED_ABORT = BIT(1), }; static inline @@ -51,13 +52,19 @@ dw_edma_alloc_desc(struct dw_edma_chan *chan, size_t nburst) { struct dw_edma_desc *desc; + /* + * For now, a descriptor that does not fit would stall the channel + * forever: reject it up front. + */ + if (!chan->non_ll && nburst > chan->ll_max - 1) + return NULL; + desc = kzalloc_flex(*desc, burst, nburst, GFP_NOWAIT); if (unlikely(!desc)) return NULL; desc->chan = chan; desc->nburst = nburst; - desc->cb = true; return desc; } @@ -67,38 +74,122 @@ static void vchan_free_desc(struct virt_dma_desc *vdesc) kfree(vd2dw_edma_desc(vdesc)); } -static void dw_edma_core_start(struct dw_edma_desc *desc, bool first) +/* Must be called with vc.lock held. */ +static void +dw_edma_set_request(struct dw_edma_chan *chan, enum dw_edma_request request) { - struct dw_edma_chan *chan = desc->chan; - size_t i = 0; + chan->request = request; +} - if (chan->non_ll) { - chan->dw->core->non_ll_start(chan, &desc->burst[desc->start_burst]); - desc->done_burst = desc->start_burst; - desc->start_burst += 1; +static void dw_hdma_set_callback_result(struct virt_dma_desc *vd, + enum dmaengine_tx_result result) +{ + u32 residue = 0; + struct dw_edma_desc *desc; + struct dmaengine_result *res; + + if (!vd->tx.callback_result) return; + + desc = vd2dw_edma_desc(vd); + if (desc) { + residue = desc->alloc_sz; + + if (result == DMA_TRANS_NOERROR) + residue -= desc->burst[desc->start_burst - 1].xfer_sz; + else if (desc->done_burst) + residue -= desc->burst[desc->done_burst - 1].xfer_sz; } - for (i = 0; i + desc->start_burst < desc->nburst; i++) { - u32 idx = i + desc->start_burst; + res = &vd->tx_result; + res->result = result; + res->residue = residue; +} - if (i == chan->ll_max) - break; +static void dw_edma_core_reset_ll(struct dw_edma_chan *chan) +{ + u32 i; + + chan->ll_head = 0; + chan->ll_done = 0; + /* Drop stale CB bits before reusing the circular LL ring. */ + for (i = 0; i < chan->ll_max; i++) + dw_edma_core_ll_clear(chan, i); + chan->cb = true; + + dw_edma_core_ll_link(chan, chan->ll_max, chan->cb, + chan->ll_region.paddr); + + dw_edma_core_ch_enable(chan); + chan->ll_valid = true; +} - dw_edma_core_ll_data(chan, &desc->burst[idx], - i, desc->cb, - idx == desc->nburst - 1 || i == chan->ll_max - 1); +static u32 dw_edma_core_get_ll_dist(struct dw_edma_chan *chan, u32 from, u32 to) +{ + return (to + chan->ll_max - from) % chan->ll_max; +} + +static u32 dw_edma_core_get_used_num(struct dw_edma_chan *chan) +{ + return dw_edma_core_get_ll_dist(chan, chan->ll_done, chan->ll_head); +} + +static u32 dw_edma_core_get_free_num(struct dw_edma_chan *chan) +{ + /* Keep one data entry free so equal indices mean an empty ring. */ + return chan->ll_max - 1 - dw_edma_core_get_used_num(chan); +} + +static bool dw_edma_ll_pending(struct dw_edma_chan *chan) +{ + return chan->ll_head != chan->ll_done; +} + +static void dw_edma_core_ll_start(struct dw_edma_desc *desc) +{ + struct dw_edma_chan *chan = desc->chan; + size_t i; + u32 free; + + free = dw_edma_core_get_free_num(chan); + for (i = desc->start_burst; i < desc->nburst && free; i++, free--) { + /* + * Refresh the link element before filling the last data slot so + * the next lap has the updated CB value. + */ + if (chan->ll_head == chan->ll_max - 1) + dw_edma_core_ll_link(chan, chan->ll_max, chan->cb, + chan->ll_region.paddr); + + dw_edma_core_ll_data(chan, &desc->burst[i], + chan->ll_head, chan->cb, + i == desc->nburst - 1 || free == 1); + + chan->ll_head++; + + if (chan->ll_head == chan->ll_max) { + chan->cb = !chan->cb; + chan->ll_head = 0; + } } desc->done_burst = desc->start_burst; - desc->start_burst += i; + desc->start_burst = i; +} - dw_edma_core_ll_link(chan, i, desc->cb, chan->ll_region.paddr); +static void dw_edma_core_start(struct dw_edma_desc *desc) +{ + struct dw_edma_chan *chan = desc->chan; - if (first) - dw_edma_core_ch_enable(chan); + if (chan->non_ll) { + chan->dw->core->non_ll_start(chan, + &desc->burst[desc->start_burst]); + desc->done_burst = desc->start_burst; + desc->start_burst += 1; + return; + } - dw_edma_core_ch_doorbell(chan); + dw_edma_core_ll_start(desc); } static int dw_edma_start_transfer(struct dw_edma_chan *chan) @@ -114,9 +205,10 @@ static int dw_edma_start_transfer(struct dw_edma_chan *chan) if (!desc) return 0; - dw_edma_core_start(desc, !desc->start_burst); + if (!chan->non_ll && !chan->ll_valid) + dw_edma_core_reset_ll(chan); - desc->cb = !desc->cb; + dw_edma_core_start(desc); return 1; } @@ -150,6 +242,46 @@ static void dw_edma_terminate_all_descs(struct dw_edma_chan *chan) dw_edma_terminate_vdesc_list(&chan->vc.desc_submitted); } +/* Must be called with vc.lock held after the channel has stopped. */ +static void dw_edma_finish_termination(struct dw_edma_chan *chan) +{ + dw_edma_terminate_all_descs(chan); + + /* Preserve a clean ring; resync only if entries remain published. */ + if (!chan->non_ll && dw_edma_ll_pending(chan)) + dw_edma_core_reset_ll(chan); + + dw_edma_set_request(chan, EDMA_REQ_NONE); + chan->status = EDMA_ST_IDLE; +} + +static void dw_edma_core_ll_sync(struct dw_edma_chan *chan) +{ + /* + * Remote controller registers and LL memory may be reached through + * different paths. Complete posted LL writes before the doorbell. + */ + if (!(chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL)) + readl(chan->ll_region.vaddr.io); +} + +/* Must be called with vc.lock held for an LL channel. */ +static void dw_edma_core_ch_doorbell(struct dw_edma_chan *chan) +{ + dw_edma_core_ll_sync(chan); + dw_edma_core_do_ch_doorbell(chan); +} + +/* Must be called with vc.lock held. */ +static void dw_edma_core_ch_maybe_doorbell(struct dw_edma_chan *chan) +{ + if (chan->non_ll || chan->request != EDMA_REQ_NONE || + chan->status != EDMA_ST_BUSY || !dw_edma_ll_pending(chan)) + return; + + dw_edma_core_ch_doorbell(chan); +} + static void dw_edma_device_caps(struct dma_chan *dchan, struct dma_slave_caps *caps) { @@ -253,7 +385,7 @@ static int dw_edma_device_pause(struct dma_chan *dchan) else if (chan->request != EDMA_REQ_NONE) err = -EPERM; else - chan->request = EDMA_REQ_PAUSE; + dw_edma_set_request(chan, EDMA_REQ_PAUSE); return err; } @@ -275,6 +407,7 @@ static int dw_edma_device_resume(struct dma_chan *dchan) chan->status = EDMA_ST_BUSY; if (!dw_edma_start_transfer(chan)) chan->status = EDMA_ST_IDLE; + dw_edma_core_ch_maybe_doorbell(chan); } return err; @@ -290,24 +423,22 @@ static int dw_edma_device_terminate_all(struct dma_chan *dchan) if (!chan->configured) { dw_edma_terminate_all_descs(chan); } else if (chan->status == EDMA_ST_PAUSE) { - dw_edma_terminate_all_descs(chan); - chan->status = EDMA_ST_IDLE; + dw_edma_finish_termination(chan); } else if (chan->status == EDMA_ST_IDLE) { - dw_edma_terminate_all_descs(chan); + dw_edma_finish_termination(chan); } else if (dw_edma_core_ch_status(chan) == DMA_COMPLETE) { /* * The channel is in a false BUSY state, probably didn't * receive or lost an interrupt */ - dw_edma_terminate_all_descs(chan); - chan->status = EDMA_ST_IDLE; + dw_edma_finish_termination(chan); } else if (chan->request > EDMA_REQ_PAUSE) { err = -EPERM; } else { - chan->request = EDMA_REQ_STOP; + dw_edma_set_request(chan, EDMA_REQ_STOP); } if (chan->status == EDMA_ST_IDLE) - chan->request = EDMA_REQ_NONE; + dw_edma_set_request(chan, EDMA_REQ_NONE); return err; } @@ -323,6 +454,7 @@ static void dw_edma_device_issue_pending(struct dma_chan *dchan) chan->status == EDMA_ST_IDLE) { chan->status = EDMA_ST_BUSY; dw_edma_start_transfer(chan); + dw_edma_core_ch_maybe_doorbell(chan); } spin_unlock_irqrestore(&chan->vc.lock, flags); } @@ -588,77 +720,62 @@ dw_edma_device_prep_interleaved_dma(struct dma_chan *dchan, return dw_edma_device_transfer(&xfer, dw_edma_device_get_config(dchan, NULL)); } -static void dw_hdma_set_callback_result(struct virt_dma_desc *vd, - enum dmaengine_tx_result result) +/* Must be called with vc.lock held. */ +static void dw_edma_done_interrupt_locked(struct dw_edma_chan *chan) { - u32 residue = 0; struct dw_edma_desc *desc; - struct dmaengine_result *res; + struct virt_dma_desc *vd; - if (!vd->tx.callback_result) + lockdep_assert_held(&chan->vc.lock); + + if (chan->status == EDMA_ST_PAUSE) return; - desc = vd2dw_edma_desc(vd); - if (desc) { - residue = desc->alloc_sz; + switch (chan->request) { + case EDMA_REQ_NONE: + case EDMA_REQ_PAUSE: + vd = vchan_next_desc(&chan->vc); + if (!vd) + break; - if (result == DMA_TRANS_NOERROR) - residue -= desc->burst[desc->start_burst - 1].xfer_sz; - else if (desc->done_burst) - residue -= desc->burst[desc->done_burst - 1].xfer_sz; - } + desc = vd2dw_edma_desc(vd); + if (desc->start_burst >= desc->nburst) { + dw_hdma_set_callback_result(vd, DMA_TRANS_NOERROR); + list_del(&vd->node); + vchan_cookie_complete(vd); + if (!chan->non_ll) + chan->ll_done = chan->ll_head; + } - res = &vd->tx_result; - res->result = result; - res->residue = residue; + if (chan->request == EDMA_REQ_PAUSE) { + dw_edma_set_request(chan, EDMA_REQ_NONE); + chan->status = EDMA_ST_PAUSE; + break; + } + + chan->status = dw_edma_start_transfer(chan) ? EDMA_ST_BUSY : EDMA_ST_IDLE; + break; + + case EDMA_REQ_STOP: + vd = vchan_next_desc(&chan->vc); + if (!vd) + break; + + dw_edma_finish_termination(chan); + break; + + default: + break; + } + dw_edma_core_ch_maybe_doorbell(chan); } static void dw_edma_done_interrupt(struct dw_edma_chan *chan) { - struct dw_edma_desc *desc; - struct virt_dma_desc *vd; unsigned long flags; spin_lock_irqsave(&chan->vc.lock, flags); - if (chan->status == EDMA_ST_PAUSE) { - spin_unlock_irqrestore(&chan->vc.lock, flags); - return; - } - - vd = vchan_next_desc(&chan->vc); - if (vd) { - switch (chan->request) { - case EDMA_REQ_NONE: - case EDMA_REQ_PAUSE: - desc = vd2dw_edma_desc(vd); - if (desc->start_burst >= desc->nburst) { - dw_hdma_set_callback_result(vd, - DMA_TRANS_NOERROR); - list_del(&vd->node); - vchan_cookie_complete(vd); - } - - if (chan->request == EDMA_REQ_PAUSE) { - chan->request = EDMA_REQ_NONE; - chan->status = EDMA_ST_PAUSE; - break; - } - - /* Continue transferring if there are remaining chunks or issued requests. - */ - chan->status = dw_edma_start_transfer(chan) ? EDMA_ST_BUSY : EDMA_ST_IDLE; - break; - - case EDMA_REQ_STOP: - dw_edma_terminate_all_descs(chan); - chan->request = EDMA_REQ_NONE; - chan->status = EDMA_ST_IDLE; - break; - - default: - break; - } - } + dw_edma_done_interrupt_locked(chan); spin_unlock_irqrestore(&chan->vc.lock, flags); } @@ -676,7 +793,9 @@ static void dw_edma_abort_interrupt(struct dw_edma_chan *chan) list_del(&vd->node); vchan_cookie_complete(vd); } - chan->request = EDMA_REQ_NONE; + if (!chan->non_ll) + dw_edma_core_reset_ll(chan); + dw_edma_set_request(chan, EDMA_REQ_NONE); chan->status = EDMA_ST_IDLE; spin_unlock_irqrestore(&chan->vc.lock, flags); } @@ -690,28 +809,32 @@ static void dw_edma_irq_work(struct work_struct *work) do { events = atomic_xchg(&chan->irq_pending, 0); - if (events & DW_EDMA_IRQ_DONE) + if (events & DW_EDMA_DEFERRED_DONE) dw_edma_done_interrupt(chan); - if (events & DW_EDMA_IRQ_ABORT) + if (events & DW_EDMA_DEFERRED_ABORT) dw_edma_abort_interrupt(chan); } while (atomic_read(&chan->irq_pending)); } static void dw_edma_queue_irq_work(struct dw_edma_chan *chan, - enum dw_edma_irq_event event) + unsigned int events) { - atomic_or(event, &chan->irq_pending); + atomic_or(events, &chan->irq_pending); queue_work(chan->dw->wq, &chan->irq_work); } -static void dw_edma_done_interrupt_deferred(struct dw_edma_chan *chan) +static void dw_edma_record_irq(struct dw_edma_chan *chan, unsigned int events) { - dw_edma_queue_irq_work(chan, DW_EDMA_IRQ_DONE); -} + unsigned int pending = 0; -static void dw_edma_abort_interrupt_deferred(struct dw_edma_chan *chan) -{ - dw_edma_queue_irq_work(chan, DW_EDMA_IRQ_ABORT); + if (events & (DW_EDMA_IRQ_DONE | DW_EDMA_IRQ_PROGRESS | + DW_EDMA_IRQ_STOP)) + pending |= DW_EDMA_DEFERRED_DONE; + if (events & DW_EDMA_IRQ_ABORT) + pending |= DW_EDMA_DEFERRED_ABORT; + + if (pending) + dw_edma_queue_irq_work(chan, pending); } static void dw_edma_emul_irq_ack(struct irq_data *d) @@ -812,8 +935,7 @@ static inline irqreturn_t dw_edma_interrupt_write_inner(int irq, void *data) struct dw_edma_irq *dw_irq = data; return dw_edma_core_handle_int(dw_irq, EDMA_DIR_WRITE, - dw_edma_done_interrupt_deferred, - dw_edma_abort_interrupt_deferred); + dw_edma_record_irq); } static inline irqreturn_t dw_edma_interrupt_read_inner(int irq, void *data) @@ -821,8 +943,7 @@ static inline irqreturn_t dw_edma_interrupt_read_inner(int irq, void *data) struct dw_edma_irq *dw_irq = data; return dw_edma_core_handle_int(dw_irq, EDMA_DIR_READ, - dw_edma_done_interrupt_deferred, - dw_edma_abort_interrupt_deferred); + dw_edma_record_irq); } static inline irqreturn_t dw_edma_interrupt_write(int irq, void *data) @@ -863,6 +984,9 @@ static int dw_edma_alloc_chan_resources(struct dma_chan *dchan) if (chan->status != EDMA_ST_IDLE) return -EBUSY; + /* The hardware context may have been invalidated while unowned. */ + chan->ll_valid = false; + return 0; } @@ -954,6 +1078,13 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc) else chan->ll_region = chip->ll_region_rd[chan->id]; + if (!chip->cfg_non_ll && chan->ll_region.sz < 3 * EDMA_LL_SZ) { + dev_err(dev, + "channel %s[%u]: LL region has fewer than 2 data entries\n", + str_write_read(chan->dir == EDMA_DIR_WRITE), + chan->id); + return -EINVAL; + } chan->ll_max = chan->ll_region.sz / EDMA_LL_SZ - 1; dev_vdbg(dev, "L. List:\tChannel %s[%u] max_cnt=%u\n", diff --git a/drivers/dma/dw-edma/dw-edma-core.h b/drivers/dma/dw-edma/dw-edma-core.h index f6a5ad317567..76fd5a41a707 100644 --- a/drivers/dma/dw-edma/dw-edma-core.h +++ b/drivers/dma/dw-edma/dw-edma-core.h @@ -41,6 +41,13 @@ enum dw_edma_xfer_type { EDMA_XFER_INTERLEAVED }; +enum dw_edma_irq_event { + DW_EDMA_IRQ_DONE = BIT(0), + DW_EDMA_IRQ_PROGRESS = BIT(1), + DW_EDMA_IRQ_STOP = BIT(2), + DW_EDMA_IRQ_ABORT = BIT(3), +}; + struct dw_edma_chan; struct dw_edma_chunk; @@ -60,7 +67,6 @@ struct dw_edma_desc { size_t done_burst; size_t start_burst; - u8 cb; size_t nburst; struct dw_edma_burst burst[] __counted_by(nburst); }; @@ -72,8 +78,32 @@ struct dw_edma_chan { enum dw_edma_dir dir; u8 func_no; - u32 ll_max; + /* + * New LL entries are appended at ll_head. Entries between ll_done + * and ll_head, modulo the LL ring, are owned by DMA; the rest are + * owned by software. + * + * software-owned DMA-owned software-owned + * +---------------+-------------------+---------------+ + * ^ ^ ^ + * 0 ll_done ll_head + * + * The link entry points back to the region start. ll_head == ll_done + * means all entries are software-owned and previous DMA work is + * done. + * + * Software always keeps at least one free entry, so the ring is + * never completely DMA-owned. That keeps a hardware-reported physical + * LL index unique within the current ll_done..ll_head producer window. + */ + u32 ll_head; + u32 ll_done; + + u32 ll_max; /* Data entries */ struct dw_edma_region ll_region; /* Linked list */ + bool ll_valid; /* LL context programmed */ + + bool cb; struct msi_msg msi; @@ -124,7 +154,8 @@ struct dw_edma { const struct dw_edma_core_ops *core; }; -typedef void (*dw_edma_handler_t)(struct dw_edma_chan *); +typedef void (*dw_edma_handler_t)(struct dw_edma_chan *chan, + unsigned int events); struct dw_edma_core_ops { void (*off)(struct dw_edma *dw); @@ -133,11 +164,14 @@ struct dw_edma_core_ops { u16 (*ch_count)(struct dw_edma *dw, enum dw_edma_dir dir); enum dma_status (*ch_status)(struct dw_edma_chan *chan); irqreturn_t (*handle_int)(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir, - dw_edma_handler_t done, dw_edma_handler_t abort); + dw_edma_handler_t handler); void (*non_ll_start)(struct dw_edma_chan *chan, struct dw_edma_burst *child); void (*ll_data)(struct dw_edma_chan *chan, struct dw_edma_burst *burst, u32 idx, bool cb, bool irq); void (*ll_link)(struct dw_edma_chan *chan, u32 idx, bool cb, u64 addr); + void (*ll_clear)(struct dw_edma_chan *chan, u32 idx); + int (*ll_cur_idx)(struct dw_edma_chan *chan); + void (*ll_irq_clear)(struct dw_edma_chan *chan); void (*ch_doorbell)(struct dw_edma_chan *chan); void (*ch_enable)(struct dw_edma_chan *chan); void (*ch_config)(struct dw_edma_chan *chan); @@ -181,6 +215,15 @@ struct dw_edma_chan *dchan2dw_edma_chan(struct dma_chan *dchan) return vc2dw_edma_chan(to_virt_chan(dchan)); } +/* + * Return the current LL entry index. A negative value means that the channel + * context is not initialized or was lost after a link reset. + */ +static inline int dw_edma_core_ll_cur_idx(struct dw_edma_chan *chan) +{ + return chan->dw->core->ll_cur_idx(chan); +} + static inline u64 dw_edma_core_get_ll_paddr(struct dw_edma_chan *chan) { if (chan->dir == EDMA_DIR_WRITE) @@ -221,9 +264,9 @@ enum dma_status dw_edma_core_ch_status(struct dw_edma_chan *chan) static inline irqreturn_t dw_edma_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir, - dw_edma_handler_t done, dw_edma_handler_t abort) + dw_edma_handler_t handler) { - return dw_irq->dw->core->handle_int(dw_irq, dir, done, abort); + return dw_irq->dw->core->handle_int(dw_irq, dir, handler); } static inline @@ -245,7 +288,17 @@ dw_edma_core_ll_link(struct dw_edma_chan *chan, u32 idx, bool cb, u64 addr) chan->dw->core->ll_link(chan, idx, cb, addr); } -static inline void dw_edma_core_ch_doorbell(struct dw_edma_chan *chan) +static inline void dw_edma_core_ll_clear(struct dw_edma_chan *chan, u32 idx) +{ + chan->dw->core->ll_clear(chan, idx); +} + +static inline void dw_edma_core_ll_irq_clear(struct dw_edma_chan *chan) +{ + chan->dw->core->ll_irq_clear(chan); +} + +static inline void dw_edma_core_do_ch_doorbell(struct dw_edma_chan *chan) { chan->dw->core->ch_doorbell(chan); } diff --git a/drivers/dma/dw-edma/dw-edma-pcie.c b/drivers/dma/dw-edma/dw-edma-pcie.c index 9f237ba916de..fab4faf68b77 100644 --- a/drivers/dma/dw-edma/dw-edma-pcie.c +++ b/drivers/dma/dw-edma/dw-edma-pcie.c @@ -33,6 +33,8 @@ #define DW_PCIE_XILINX_MDB_VSEC_ID 0x20 #define DW_PCIE_XILINX_MDB_VSEC_DMA_BAR GENMASK(10, 8) #define DW_PCIE_XILINX_MDB_VSEC_DMA_MAP GENMASK(2, 0) +/* AMD CPM6 (Xilinx) supported cap */ +#define DW_PCIE_XILINX_CPM6_VSEC_CH_SEP GENMASK(18, 16) #define DW_PCIE_XILINX_MDB_VSEC_DMA_WR_CH GENMASK(9, 0) #define DW_PCIE_XILINX_MDB_VSEC_DMA_RD_CH GENMASK(25, 16) @@ -76,6 +78,7 @@ struct dw_edma_pcie_data { u16 rd_ch_cnt; u64 devmem_phys_off; bool cfg_non_ll; + u32 ch_space_sz; }; struct dw_edma_pcie_match_data { @@ -130,6 +133,7 @@ static const struct dw_edma_pcie_data snps_edda_data = { .irqs = 1, .wr_ch_cnt = 2, .rd_ch_cnt = 2, + .ch_space_sz = 256, }; static const struct dw_edma_pcie_data xilinx_mdb_data = { @@ -143,6 +147,7 @@ static const struct dw_edma_pcie_data xilinx_mdb_data = { .irqs = 1, .wr_ch_cnt = 8, .rd_ch_cnt = 8, + .ch_space_sz = 256, }; static const struct dw_edma_pcie_data xilinx_cpm6_dma_data = { @@ -156,6 +161,7 @@ static const struct dw_edma_pcie_data xilinx_cpm6_dma_data = { .irqs = 1, .wr_ch_cnt = 8, .rd_ch_cnt = 8, + .ch_space_sz = 512, }; static void dw_edma_set_chan_region_offset(struct dw_edma_pcie_data *pdata, @@ -208,6 +214,13 @@ static int dw_edma_pcie_irq_vector(struct device *dev, unsigned int nr) return pci_irq_vector(to_pci_dev(dev), nr); } +static u32 dw_edma_get_ch_space_sz(u32 val) +{ + if (val > 0 && val <= 7) + return 256 << val; + return 256; +} + static u64 dw_edma_pcie_address(struct device *dev, phys_addr_t cpu_addr) { struct pci_dev *pdev = to_pci_dev(dev); @@ -298,6 +311,10 @@ static void dw_edma_pcie_get_xilinx_dma_data(struct pci_dev *pdev, pdata->mf = map; pdata->rg.bar = FIELD_GET(DW_PCIE_XILINX_MDB_VSEC_DMA_BAR, val); + if (pdev->device == PCI_DEVICE_ID_XILINX_B00F) + pdata->ch_space_sz = dw_edma_get_ch_space_sz + (FIELD_GET(DW_PCIE_XILINX_CPM6_VSEC_CH_SEP, val)); + pci_read_config_dword(pdev, vsec + 0xc, &val); pdata->wr_ch_cnt = min(pdata->wr_ch_cnt, FIELD_GET(DW_PCIE_XILINX_MDB_VSEC_DMA_WR_CH, val)); @@ -477,6 +494,7 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, chip->nr_irqs = nr_irqs; chip->ops = match->plat_ops; chip->cfg_non_ll = dma_data->cfg_non_ll; + chip->ch_space_sz = dma_data->ch_space_sz; chip->ll_wr_cnt = dma_data->wr_ch_cnt; chip->ll_rd_cnt = dma_data->rd_ch_cnt; diff --git a/drivers/dma/dw-edma/dw-edma-v0-core.c b/drivers/dma/dw-edma/dw-edma-v0-core.c index abc1bd4c0be2..c053cb4c2844 100644 --- a/drivers/dma/dw-edma/dw-edma-v0-core.c +++ b/drivers/dma/dw-edma/dw-edma-v0-core.c @@ -336,7 +336,7 @@ static void dw_edma_v0_core_clear_abort_int(struct dw_edma_chan *chan) static irqreturn_t dw_edma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir, - dw_edma_handler_t done, dw_edma_handler_t abort) + dw_edma_handler_t handler) { struct dw_edma *dw = dw_irq->dw; unsigned long total, pos, val; @@ -375,7 +375,7 @@ dw_edma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir, continue; dw_edma_v0_core_clear_done_int(chan); - done(chan); + handler(chan, DW_EDMA_IRQ_DONE); ret = IRQ_HANDLED; } @@ -389,7 +389,7 @@ dw_edma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir, continue; dw_edma_v0_core_clear_abort_int(chan); - abort(chan); + handler(chan, DW_EDMA_IRQ_ABORT); ret = IRQ_HANDLED; } @@ -480,20 +480,6 @@ static void dw_edma_v0_core_ch_enable(struct dw_edma_chan *chan) upper_32_bits(chan->ll_region.paddr)); } -static void dw_edma_v0_sync_ll_data(struct dw_edma_chan *chan) -{ - /* - * In case of remote eDMA engine setup, the DW PCIe RP/EP internal - * configuration registers and application memory are normally accessed - * over different buses. Ensure LL-data reaches the memory before the - * doorbell register is toggled by issuing the dummy-read from the remote - * LL memory in a hope that the MRd TLP will return only after the - * last MWr TLP is completed - */ - if (!(chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL)) - readl(chan->ll_region.vaddr.io); -} - static void dw_edma_v0_core_ch_config(struct dw_edma_chan *chan) { struct dw_edma *dw = chan->dw; @@ -605,17 +591,49 @@ dw_edma_v0_core_ll_link(struct dw_edma_chan *chan, u32 idx, bool cb, u64 addr) dw_edma_v0_write_ll_link(chan, idx, control, addr); } +static void dw_edma_v0_core_ll_clear(struct dw_edma_chan *chan, u32 idx) +{ + ptrdiff_t ofs = idx * sizeof(struct dw_edma_v0_lli); + + if (chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL) { + struct dw_edma_v0_lli *lli = chan->ll_region.vaddr.mem + ofs; + + lli->control = 0; + } else { + struct dw_edma_v0_lli __iomem *lli = chan->ll_region.vaddr.io + ofs; + + writel(0, &lli->control); + } +} + static void dw_edma_v0_core_ch_doorbell(struct dw_edma_chan *chan) { struct dw_edma *dw = chan->dw; - dw_edma_v0_sync_ll_data(chan); - /* Doorbell */ SET_RW_32(dw, chan->dir, doorbell, FIELD_PREP(EDMA_V0_DOORBELL_CH_MASK, chan->id)); } +static int dw_edma_v0_core_ll_cur_idx(struct dw_edma_chan *chan) +{ + u32 base, val; + + val = GET_CH_32(chan->dw, chan->dir, chan->id, llp.lsb); + base = lower_32_bits(dw_edma_core_get_ll_paddr(chan)); + + /* + * LL regions stay within one 4 GiB address window. Reject an all-ones + * MMIO value. If the low word is zero, use the high word to distinguish + * a nonzero boundary address from an unprogrammed all-zero context. + */ + if (val == U32_MAX || + (!val && !GET_CH_32(chan->dw, chan->dir, chan->id, llp.msb))) + return -EINVAL; + + return (val - base) / EDMA_LL_SZ; +} + /* eDMA debugfs callbacks */ static void dw_edma_v0_core_debugfs_on(struct dw_edma *dw) { @@ -650,6 +668,9 @@ static const struct dw_edma_core_ops dw_edma_v0_core = { .handle_int = dw_edma_v0_core_handle_int, .ll_data = dw_edma_v0_core_ll_data, .ll_link = dw_edma_v0_core_ll_link, + .ll_clear = dw_edma_v0_core_ll_clear, + .ll_cur_idx = dw_edma_v0_core_ll_cur_idx, + .ll_irq_clear = dw_edma_v0_core_clear_done_int, .ch_doorbell = dw_edma_v0_core_ch_doorbell, .ch_enable = dw_edma_v0_core_ch_enable, .ch_config = dw_edma_v0_core_ch_config, diff --git a/drivers/dma/dw-edma/dw-hdma-v0-core.c b/drivers/dma/dw-edma/dw-hdma-v0-core.c index 36ee72efcd31..d42cb4ad49a2 100644 --- a/drivers/dma/dw-edma/dw-hdma-v0-core.c +++ b/drivers/dma/dw-edma/dw-hdma-v0-core.c @@ -23,18 +23,23 @@ enum dw_hdma_control { DW_HDMA_V0_LLE = BIT(9), }; -static inline struct dw_hdma_v0_regs __iomem *__dw_regs(struct dw_edma *dw) -{ - return dw->chip->reg_base; -} - static inline struct dw_hdma_v0_ch_regs __iomem * __dw_ch_regs(struct dw_edma *dw, enum dw_edma_dir dir, u16 ch) { - if (dir == EDMA_DIR_WRITE) - return &(__dw_regs(dw)->ch[ch].wr); - else - return &(__dw_regs(dw)->ch[ch].rd); + u32 ch_base; + + /* + * For Write, the channel register index starts at + * wr_base(ch_idx) = (2 * ch_idx) * ch_space_sz + * + * For Read channel, + * rd_base(ch_idx) = (2 * ch_idx + 1) * ch_space_sz + */ + ch_base = 2 * ch; + if (dir == EDMA_DIR_READ) + ch_base += 1; + + return dw->chip->reg_base + (ch_base * dw->chip->ch_space_sz); } #define SET_CH_32(dw, dir, ch, name, value) \ @@ -174,7 +179,7 @@ static u32 dw_hdma_v0_core_status_int(struct dw_edma_chan *chan) static irqreturn_t dw_hdma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir, - dw_edma_handler_t done, dw_edma_handler_t abort) + dw_edma_handler_t handler) { struct dw_edma *dw = dw_irq->dw; unsigned long total, pos, val; @@ -200,14 +205,14 @@ dw_hdma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir, val = dw_hdma_v0_core_status_int(chan); if (FIELD_GET(HDMA_V0_STOP_INT_MASK, val)) { dw_hdma_v0_core_clear_done_int(chan); - done(chan); + handler(chan, DW_EDMA_IRQ_STOP); ret = IRQ_HANDLED; } if (FIELD_GET(HDMA_V0_ABORT_INT_MASK, val)) { dw_hdma_v0_core_clear_abort_int(chan); - abort(chan); + handler(chan, DW_EDMA_IRQ_ABORT); ret = IRQ_HANDLED; } @@ -282,20 +287,6 @@ static void dw_hdma_v0_core_ch_enable(struct dw_edma_chan *chan) HDMA_V0_CONSUMER_CYCLE_STAT | HDMA_V0_CONSUMER_CYCLE_BIT); } -static void dw_hdma_v0_sync_ll_data(struct dw_edma_chan *chan) -{ - /* - * In case of remote HDMA engine setup, the DW PCIe RP/EP internal - * configuration registers and application memory are normally accessed - * over different buses. Ensure LL-data reaches the memory before the - * doorbell register is toggled by issuing the dummy-read from the remote - * LL memory in a hope that the MRd TLP will return only after the - * last MWr TLP is completed - */ - if (!(chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL)) - readl(chan->ll_region.vaddr.io); -} - static void dw_hdma_v0_core_non_ll_start(struct dw_edma_chan *chan, struct dw_edma_burst *child) { @@ -374,16 +365,48 @@ dw_hdma_v0_core_ll_link(struct dw_edma_chan *chan, u32 idx, bool cb, u64 addr) dw_hdma_v0_write_ll_link(chan, idx, control, addr); } +static void dw_hdma_v0_core_ll_clear(struct dw_edma_chan *chan, u32 idx) +{ + ptrdiff_t ofs = idx * sizeof(struct dw_hdma_v0_lli); + + if (chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL) { + struct dw_hdma_v0_lli *lli = chan->ll_region.vaddr.mem + ofs; + + lli->control = 0; + } else { + struct dw_hdma_v0_lli __iomem *lli = chan->ll_region.vaddr.io + ofs; + + writel(0, &lli->control); + } +} + static void dw_hdma_v0_core_ch_doorbell(struct dw_edma_chan *chan) { struct dw_edma *dw = chan->dw; - dw_hdma_v0_sync_ll_data(chan); - /* Doorbell */ SET_CH_32(dw, chan->dir, chan->id, doorbell, HDMA_V0_DOORBELL_START); } +static int dw_hdma_v0_core_ll_cur_idx(struct dw_edma_chan *chan) +{ + u32 base, val; + + val = GET_CH_32(chan->dw, chan->dir, chan->id, llp.lsb); + base = lower_32_bits(dw_edma_core_get_ll_paddr(chan)); + + /* + * LL regions stay within one 4 GiB address window. Reject an all-ones + * MMIO value. If the low word is zero, use the high word to distinguish + * a nonzero boundary address from an unprogrammed all-zero context. + */ + if (val == U32_MAX || + (!val && !GET_CH_32(chan->dw, chan->dir, chan->id, llp.msb))) + return -EINVAL; + + return (val - base) / EDMA_LL_SZ; +} + /* HDMA debugfs callbacks */ static void dw_hdma_v0_core_debugfs_on(struct dw_edma *dw) { @@ -406,6 +429,9 @@ static const struct dw_edma_core_ops dw_hdma_v0_core = { .non_ll_start = dw_hdma_v0_core_non_ll_start, .ll_data = dw_hdma_v0_core_ll_data, .ll_link = dw_hdma_v0_core_ll_link, + .ll_clear = dw_hdma_v0_core_ll_clear, + .ll_cur_idx = dw_hdma_v0_core_ll_cur_idx, + .ll_irq_clear = dw_hdma_v0_core_clear_done_int, .ch_doorbell = dw_hdma_v0_core_ch_doorbell, .ch_enable = dw_hdma_v0_core_ch_enable, .ch_config = dw_hdma_v0_core_ch_config, diff --git a/drivers/dma/dw-edma/dw-hdma-v0-debugfs.c b/drivers/dma/dw-edma/dw-hdma-v0-debugfs.c index dcdc57fe976c..3fa16e045a58 100644 --- a/drivers/dma/dw-edma/dw-hdma-v0-debugfs.c +++ b/drivers/dma/dw-edma/dw-hdma-v0-debugfs.c @@ -13,22 +13,17 @@ #include "dw-hdma-v0-regs.h" #include "dw-edma-core.h" -#define REGS_ADDR(dw, name) \ - ({ \ - struct dw_hdma_v0_regs __iomem *__regs = (dw)->chip->reg_base; \ - \ - (void __iomem *)&__regs->name; \ - }) - #define REGS_CH_ADDR(dw, name, _dir, _ch) \ ({ \ - struct dw_hdma_v0_ch_regs __iomem *__ch_regs; \ + struct dw_hdma_v0_ch_regs __iomem *__ch_regs; \ + off_t __off = (dw)->chip->ch_space_sz; \ \ - if (_dir == EDMA_DIR_READ) \ - __ch_regs = REGS_ADDR(dw, ch[_ch].rd); \ + if ((_dir) == EDMA_DIR_READ) \ + __off *= (2 * (_ch) + 1); \ else \ - __ch_regs = REGS_ADDR(dw, ch[_ch].wr); \ + __off *= (2 * (_ch)); \ \ + __ch_regs = ((dw)->chip->reg_base + __off); \ (void __iomem *)&__ch_regs->name; \ }) diff --git a/drivers/dma/dw-edma/dw-hdma-v0-regs.h b/drivers/dma/dw-edma/dw-hdma-v0-regs.h index 2124c162a62f..b88226cdd791 100644 --- a/drivers/dma/dw-edma/dw-hdma-v0-regs.h +++ b/drivers/dma/dw-edma/dw-hdma-v0-regs.h @@ -85,16 +85,6 @@ struct dw_hdma_v0_ch_regs { }; } msi_abort; u32 msi_msgdata; /* 0x00a8 */ - u32 padding_2[21]; /* 0x00ac..0x00fc */ -} __packed; - -struct dw_hdma_v0_ch { - struct dw_hdma_v0_ch_regs wr; /* 0x0000 */ - struct dw_hdma_v0_ch_regs rd; /* 0x0100 */ -} __packed; - -struct dw_hdma_v0_regs { - struct dw_hdma_v0_ch ch[HDMA_V0_MAX_NR_CH]; /* 0x0000..0x0fa8 */ } __packed; struct dw_hdma_v0_lli { diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index dd75f97a33b3..575b7bb6af9a 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c @@ -41,11 +41,6 @@ /*----------------------------------------------------------------------*/ -static struct device *chan2dev(struct dma_chan *chan) -{ - return &chan->dev->device; -} - static struct dw_desc *dwc_first_active(struct dw_dma_chan *dwc) { return to_dw_desc(dwc->active_list.next); @@ -69,7 +64,7 @@ static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx) list_add_tail(&desc->desc_node, &dwc->queue); spin_unlock_irqrestore(&dwc->lock, flags); - dev_vdbg(chan2dev(tx->chan), "%s: queued %u\n", + dev_vdbg(dmaengine_chan_dev(tx->chan), "%s: queued %u\n", __func__, desc->txd.cookie); return cookie; @@ -127,7 +122,7 @@ static void dwc_initialize(struct dw_dma_chan *dwc) static inline void dwc_dump_chan_regs(struct dw_dma_chan *dwc) { - dev_err(chan2dev(&dwc->chan), + dev_err(dmaengine_chan_dev(&dwc->chan), " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n", channel_readl(dwc, SAR), channel_readl(dwc, DAR), @@ -177,7 +172,7 @@ static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first) /* ASSERT: channel is idle */ if (dma_readl(dw, CH_EN) & dwc->mask) { - dev_err(chan2dev(&dwc->chan), + dev_err(dmaengine_chan_dev(&dwc->chan), "%s: BUG: Attempted to start non-idle channel\n", __func__); dwc_dump_chan_regs(dwc); @@ -190,7 +185,7 @@ static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first) was_soft_llp = test_and_set_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags); if (was_soft_llp) { - dev_err(chan2dev(&dwc->chan), + dev_err(dmaengine_chan_dev(&dwc->chan), "BUG: Attempted to start new LLP transfer inside ongoing one\n"); return; } @@ -223,7 +218,7 @@ static void dwc_dostart_first_queued(struct dw_dma_chan *dwc) list_move(dwc->queue.next, &dwc->active_list); desc = dwc_first_active(dwc); - dev_vdbg(chan2dev(&dwc->chan), "%s: started %u\n", __func__, desc->txd.cookie); + dev_vdbg(dmaengine_chan_dev(&dwc->chan), "%s: started %u\n", __func__, desc->txd.cookie); dwc_dostart(dwc, desc); } @@ -238,7 +233,7 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc, unsigned long flags; struct dmaengine_desc_callback cb; - dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie); + dev_vdbg(dmaengine_chan_dev(&dwc->chan), "descriptor %u complete\n", txd->cookie); spin_lock_irqsave(&dwc->lock, flags); dma_cookie_complete(txd); @@ -265,7 +260,7 @@ static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc) spin_lock_irqsave(&dwc->lock, flags); if (dma_readl(dw, CH_EN) & dwc->mask) { - dev_err(chan2dev(&dwc->chan), + dev_err(dmaengine_chan_dev(&dwc->chan), "BUG: XFER bit set, but channel not idle!\n"); /* Try to continue after resetting the channel... */ @@ -353,12 +348,12 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) } if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) { - dev_vdbg(chan2dev(&dwc->chan), "%s: soft LLP mode\n", __func__); + dev_vdbg(dmaengine_chan_dev(&dwc->chan), "%s: soft LLP mode\n", __func__); spin_unlock_irqrestore(&dwc->lock, flags); return; } - dev_vdbg(chan2dev(&dwc->chan), "%s: llp=%pad\n", __func__, &llp); + dev_vdbg(dmaengine_chan_dev(&dwc->chan), "%s: llp=%pad\n", __func__, &llp); list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) { /* Initial residue value */ @@ -398,7 +393,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) spin_lock_irqsave(&dwc->lock, flags); } - dev_err(chan2dev(&dwc->chan), + dev_err(dmaengine_chan_dev(&dwc->chan), "BUG: All descriptors done, but channel not idle!\n"); /* Try to continue after resetting the channel... */ @@ -410,7 +405,7 @@ static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc) static inline void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_desc *desc) { - dev_crit(chan2dev(&dwc->chan), " desc: s0x%x d0x%x l0x%x c0x%x:%x\n", + dev_crit(dmaengine_chan_dev(&dwc->chan), " desc: s0x%x d0x%x l0x%x c0x%x:%x\n", lli_read(desc, sar), lli_read(desc, dar), lli_read(desc, llp), @@ -449,7 +444,7 @@ static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc) * controller flagged an error instead of scribbling over * random memory locations. */ - dev_WARN(chan2dev(&dwc->chan), "Bad descriptor submitted for DMA!\n" + dev_WARN(dmaengine_chan_dev(&dwc->chan), "Bad descriptor submitted for DMA!\n" " cookie: %d\n", bad_desc->txd.cookie); dwc_dump_lli(dwc, bad_desc); list_for_each_entry(child, &bad_desc->tx_list, desc_node) @@ -552,12 +547,12 @@ dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, u32 ctllo, ctlhi; u8 lms = DWC_LLP_LMS(m_master); - dev_vdbg(chan2dev(chan), + dev_vdbg(dmaengine_chan_dev(chan), "%s: d%pad s%pad l0x%zx f0x%lx\n", __func__, &dest, &src, len, flags); if (unlikely(!len)) { - dev_dbg(chan2dev(chan), "%s: length is zero!\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s: length is zero!\n", __func__); return NULL; } @@ -630,7 +625,7 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, struct scatterlist *sg; size_t total_len = 0; - dev_vdbg(chan2dev(chan), "%s\n", __func__); + dev_vdbg(dmaengine_chan_dev(chan), "%s\n", __func__); if (unlikely(!is_slave_direction(direction) || !sg_len)) return NULL; @@ -754,7 +749,7 @@ slave_sg_fromdev_fill_desc: return &first->txd; err_desc_get: - dev_err(chan2dev(chan), + dev_err(dmaengine_chan_dev(chan), "not enough descriptors available. Direction %d\n", direction); dwc_desc_put(dwc, first); return NULL; @@ -1063,11 +1058,11 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) struct dw_dma_chan *dwc = to_dw_dma_chan(chan); struct dw_dma *dw = to_dw_dma(chan->device); - dev_vdbg(chan2dev(chan), "%s\n", __func__); + dev_vdbg(dmaengine_chan_dev(chan), "%s\n", __func__); /* ASSERT: channel is idle */ if (dma_readl(dw, CH_EN) & dwc->mask) { - dev_dbg(chan2dev(chan), "DMA channel not idle?\n"); + dev_dbg(dmaengine_chan_dev(chan), "DMA channel not idle?\n"); return -EIO; } @@ -1083,7 +1078,7 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan) * We need controller-specific data to set up slave transfers. */ if (chan->private && !dw_dma_filter(chan, chan->private)) { - dev_warn(chan2dev(chan), "Wrong controller-specific data\n"); + dev_warn(dmaengine_chan_dev(chan), "Wrong controller-specific data\n"); return -EINVAL; } @@ -1101,7 +1096,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) struct dw_dma *dw = to_dw_dma(chan->device); unsigned long flags; - dev_dbg(chan2dev(chan), "%s: descs allocated=%u\n", __func__, + dev_dbg(dmaengine_chan_dev(chan), "%s: descs allocated=%u\n", __func__, dwc->descs_allocated); /* ASSERT: channel is idle */ @@ -1126,7 +1121,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan) if (!dw->in_use) do_dw_dma_off(dw); - dev_vdbg(chan2dev(chan), "%s: done\n", __func__); + dev_vdbg(dmaengine_chan_dev(chan), "%s: done\n", __func__); } static void dwc_caps(struct dma_chan *chan, struct dma_slave_caps *caps) diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c index 311e55a97ba9..cbfe74fc8d71 100644 --- a/drivers/dma/ep93xx_dma.c +++ b/drivers/dma/ep93xx_dma.c @@ -250,11 +250,6 @@ struct ep93xx_edma_data { size_t num_channels; }; -static inline struct device *chan2dev(struct ep93xx_dma_chan *edmac) -{ - return &edmac->chan.dev->device; -} - static struct ep93xx_dma_chan *to_ep93xx_dma_chan(struct dma_chan *chan) { return container_of(chan, struct ep93xx_dma_chan, chan); @@ -415,7 +410,7 @@ static void m2p_hw_shutdown(struct ep93xx_dma_chan *edmac) m2p_set_control(edmac, 0); while (m2p_channel_state(edmac) != M2P_STATE_IDLE) - dev_warn(chan2dev(edmac), "M2P: Not yet IDLE\n"); + dev_warn(dmaengine_chan_dev(&edmac->chan), "M2P: Not yet IDLE\n"); } static void m2p_fill_desc(struct ep93xx_dma_chan *edmac) @@ -425,7 +420,7 @@ static void m2p_fill_desc(struct ep93xx_dma_chan *edmac) desc = ep93xx_dma_get_active(edmac); if (!desc) { - dev_warn(chan2dev(edmac), "M2P: empty descriptor list\n"); + dev_warn(dmaengine_chan_dev(&edmac->chan), "M2P: empty descriptor list\n"); return; } @@ -479,7 +474,7 @@ static int m2p_hw_interrupt(struct ep93xx_dma_chan *edmac) * Revisit this when there is a mechanism to report back the * errors. */ - dev_err(chan2dev(edmac), + dev_err(dmaengine_chan_dev(&edmac->chan), "DMA transfer failed! Details:\n" "\tcookie : %d\n" "\tsrc_addr : 0x%08x\n" @@ -586,7 +581,7 @@ static void m2m_fill_desc(struct ep93xx_dma_chan *edmac) desc = ep93xx_dma_get_active(edmac); if (!desc) { - dev_warn(chan2dev(edmac), "M2M: empty descriptor list\n"); + dev_warn(dmaengine_chan_dev(&edmac->chan), "M2M: empty descriptor list\n"); return; } @@ -849,7 +844,7 @@ static irqreturn_t ep93xx_dma_interrupt(int irq, void *dev_id) desc = ep93xx_dma_get_active(edmac); if (!desc) { - dev_warn(chan2dev(edmac), + dev_warn(dmaengine_chan_dev(&edmac->chan), "got interrupt while active list is empty\n"); spin_unlock(&edmac->lock); return IRQ_NONE; @@ -867,7 +862,7 @@ static irqreturn_t ep93xx_dma_interrupt(int irq, void *dev_id) break; default: - dev_warn(chan2dev(edmac), "unknown interrupt!\n"); + dev_warn(dmaengine_chan_dev(&edmac->chan), "unknown interrupt!\n"); ret = IRQ_NONE; break; } @@ -967,7 +962,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan) desc = kzalloc_obj(*desc); if (!desc) { - dev_warn(chan2dev(edmac), "not enough descriptors\n"); + dev_warn(dmaengine_chan_dev(&edmac->chan), "not enough descriptors\n"); break; } @@ -1044,7 +1039,7 @@ ep93xx_dma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, for (offset = 0; offset < len; offset += bytes) { desc = ep93xx_dma_desc_get(edmac); if (!desc) { - dev_warn(chan2dev(edmac), "couldn't get descriptor\n"); + dev_warn(dmaengine_chan_dev(&edmac->chan), "couldn't get descriptor\n"); goto fail; } @@ -1091,13 +1086,13 @@ ep93xx_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, int i; if (!edmac->edma->m2m && dir != ep93xx_dma_chan_direction(chan)) { - dev_warn(chan2dev(edmac), + dev_warn(dmaengine_chan_dev(&edmac->chan), "channel was configured with different direction\n"); return NULL; } if (test_bit(EP93XX_DMA_IS_CYCLIC, &edmac->flags)) { - dev_warn(chan2dev(edmac), + dev_warn(dmaengine_chan_dev(&edmac->chan), "channel is already used for cyclic transfers\n"); return NULL; } @@ -1109,14 +1104,14 @@ ep93xx_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, size_t len = sg_dma_len(sg); if (len > DMA_MAX_CHAN_BYTES) { - dev_warn(chan2dev(edmac), "too big transfer size %zu\n", + dev_warn(dmaengine_chan_dev(&edmac->chan), "too big transfer size %zu\n", len); goto fail; } desc = ep93xx_dma_desc_get(edmac); if (!desc) { - dev_warn(chan2dev(edmac), "couldn't get descriptor\n"); + dev_warn(dmaengine_chan_dev(&edmac->chan), "couldn't get descriptor\n"); goto fail; } @@ -1172,19 +1167,19 @@ ep93xx_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr, size_t offset = 0; if (!edmac->edma->m2m && dir != ep93xx_dma_chan_direction(chan)) { - dev_warn(chan2dev(edmac), + dev_warn(dmaengine_chan_dev(&edmac->chan), "channel was configured with different direction\n"); return NULL; } if (test_and_set_bit(EP93XX_DMA_IS_CYCLIC, &edmac->flags)) { - dev_warn(chan2dev(edmac), + dev_warn(dmaengine_chan_dev(&edmac->chan), "channel is already used for cyclic transfers\n"); return NULL; } if (period_len > DMA_MAX_CHAN_BYTES) { - dev_warn(chan2dev(edmac), "too big period length %zu\n", + dev_warn(dmaengine_chan_dev(&edmac->chan), "too big period length %zu\n", period_len); return NULL; } @@ -1196,7 +1191,7 @@ ep93xx_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr, for (offset = 0; offset < buf_len; offset += period_len) { desc = ep93xx_dma_desc_get(edmac); if (!desc) { - dev_warn(chan2dev(edmac), "couldn't get descriptor\n"); + dev_warn(dmaengine_chan_dev(&edmac->chan), "couldn't get descriptor\n"); goto fail; } diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c index d9fb717b5b53..6934ac882697 100644 --- a/drivers/dma/fsl-edma-main.c +++ b/drivers/dma/fsl-edma-main.c @@ -326,13 +326,16 @@ static struct dma_chan *fsl_edma3_xlate(struct of_phandle_args *dma_spec, if ((dma_spec->args[2] & FSL_EDMA_ODD_CH) && !(i & 0x1)) continue; + chan = dma_get_slave_channel(chan); + if (!chan) + return NULL; + fsl_chan->srcid = dma_spec->args[0]; fsl_chan->priority = dma_spec->args[1]; fsl_chan->is_rxchan = dma_spec->args[2] & FSL_EDMA_RX; fsl_chan->is_remote = dma_spec->args[2] & FSL_EDMA_REMOTE; fsl_chan->is_multi_fifo = dma_spec->args[2] & FSL_EDMA_MULTI_FIFO; - chan = dma_get_slave_channel(chan); chan->device->privatecnt++; return chan; } diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c index 2d86f61105e5..9cc289f7129e 100644 --- a/drivers/dma/fsl_raid.c +++ b/drivers/dma/fsl_raid.c @@ -162,6 +162,7 @@ static void fsl_re_dequeue(struct tasklet_struct *t) struct fsl_re_hw_desc *hwdesc; unsigned long flags; unsigned int count, oub_count; + LIST_HEAD(completed); int found; fsl_re_cleanup_descs(re_chan); @@ -182,8 +183,7 @@ static void fsl_re_dequeue(struct tasklet_struct *t) } if (found) { - fsl_re_desc_done(desc); - list_move_tail(&desc->node, &re_chan->ack_q); + list_move_tail(&desc->node, &completed); } else { dev_err(re_chan->dev, "found hwdesc not in sw queue, discard it\n"); @@ -196,6 +196,17 @@ static void fsl_re_dequeue(struct tasklet_struct *t) FSL_RE_RMVD_JOB(1)); } spin_unlock_irqrestore(&re_chan->desc_lock, flags); + + /* Invoke the client callbacks outside the channel lock. The callback + * may submit new work which re-acquires desc_lock, so holding it here + * would deadlock. + */ + list_for_each_entry_safe(desc, _desc, &completed, node) { + fsl_re_desc_done(desc); + spin_lock_irqsave(&re_chan->desc_lock, flags); + list_move_tail(&desc->node, &re_chan->ack_q); + spin_unlock_irqrestore(&re_chan->desc_lock, flags); + } } /* Per Job Ring interrupt handler */ @@ -295,8 +306,8 @@ static struct fsl_re_desc *fsl_re_chan_alloc_desc(struct fsl_re_chan *re_chan, if (!desc) return NULL; - cf = dma_pool_alloc(re_chan->re_dev->cf_desc_pool, GFP_NOWAIT, - &paddr); + cf = dma_pool_zalloc(re_chan->re_dev->cf_desc_pool, GFP_NOWAIT, + &paddr); if (!cf) { kfree(desc); return NULL; @@ -350,7 +361,7 @@ static struct dma_async_tx_descriptor *fsl_re_prep_dma_genq( cdb |= FSL_RE_INTR_ON_ERROR << FSL_RE_CDB_ERROR_SHIFT; cdb |= FSL_RE_DATA_DEP << FSL_RE_CDB_DEPEND_SHIFT; xor = desc->cdb_addr; - xor->cdb32 = cdb; + xor->cdb32 = cpu_to_be32(cdb); if (scf) { /* compute q = src0*coef0^src1*coef1^..., * is GF(8) mult */ @@ -470,7 +481,7 @@ static struct dma_async_tx_descriptor *fsl_re_prep_dma_pq( cdb |= FSL_RE_DATA_DEP << FSL_RE_CDB_DEPEND_SHIFT; pq = desc->cdb_addr; - pq->cdb32 = cdb; + pq->cdb32 = cpu_to_be32(cdb); p = pq->gfm_q1; /* Init gfm_q1[] */ @@ -553,7 +564,7 @@ static struct dma_async_tx_descriptor *fsl_re_prep_dma_memcpy( cdb |= FSL_RE_DATA_DEP << FSL_RE_CDB_DEPEND_SHIFT; move = desc->cdb_addr; - move->cdb32 = cdb; + move->cdb32 = cpu_to_be32(cdb); /* Filling frame 0 of CFD with move CDB */ cf = desc->cf_addr; @@ -584,8 +595,8 @@ static int fsl_re_alloc_chan_resources(struct dma_chan *chan) if (!desc) break; - cf = dma_pool_alloc(re_chan->re_dev->cf_desc_pool, GFP_KERNEL, - &paddr); + cf = dma_pool_zalloc(re_chan->re_dev->cf_desc_pool, GFP_KERNEL, + &paddr); if (!cf) { kfree(desc); break; @@ -603,18 +614,15 @@ static int fsl_re_alloc_chan_resources(struct dma_chan *chan) static void fsl_re_free_chan_resources(struct dma_chan *chan) { struct fsl_re_chan *re_chan; - struct fsl_re_desc *desc; + struct fsl_re_desc *desc, *_desc; re_chan = container_of(chan, struct fsl_re_chan, chan); - while (re_chan->alloc_count--) { - desc = list_first_entry(&re_chan->free_q, - struct fsl_re_desc, - node); - + list_for_each_entry_safe(desc, _desc, &re_chan->free_q, node) { list_del(&desc->node); dma_pool_free(re_chan->re_dev->cf_desc_pool, desc->cf_addr, desc->cf_paddr); kfree(desc); + re_chan->alloc_count--; } if (!list_empty(&re_chan->free_q)) diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 22d62d958abd..99a878ed1444 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -681,7 +681,7 @@ static void fsldma_cleanup_descriptors(struct fsldma_chan *chan) /** * fsl_dma_alloc_chan_resources - Allocate resources for DMA channel. - * @chan : Freescale DMA channel + * @dchan : Freescale DMA channel * * This function will create a dma pool for descriptor allocation. * @@ -738,7 +738,7 @@ static void fsldma_free_desc_list_reverse(struct fsldma_chan *chan, /** * fsl_dma_free_chan_resources - Free all resources of the channel. - * @chan : Freescale DMA channel + * @dchan : Freescale DMA channel */ static void fsl_dma_free_chan_resources(struct dma_chan *dchan) { @@ -873,7 +873,7 @@ static int fsl_dma_device_config(struct dma_chan *dchan, /** * fsl_dma_memcpy_issue_pending - Issue the DMA start command - * @chan : Freescale DMA channel + * @dchan : Freescale DMA channel */ static void fsl_dma_memcpy_issue_pending(struct dma_chan *dchan) { @@ -886,7 +886,9 @@ static void fsl_dma_memcpy_issue_pending(struct dma_chan *dchan) /** * fsl_tx_status - Determine the DMA status - * @chan : Freescale DMA channel + * @dchan : Freescale DMA channel + * @cookie : DMA transaction identifier + * @txstate : DMA transaction state */ static enum dma_status fsl_tx_status(struct dma_chan *dchan, dma_cookie_t cookie, @@ -1205,6 +1207,7 @@ out_return: static void fsl_dma_chan_remove(struct fsldma_chan *chan) { + tasklet_kill(&chan->tasklet); irq_dispose_mapping(chan->irq); list_del(&chan->common.device_node); iounmap(chan->regs); @@ -1216,8 +1219,13 @@ static int fsldma_of_probe(struct platform_device *op) struct fsldma_device *fdev; struct device_node *child; unsigned int i; + int irq; int err; + irq = platform_get_irq_optional(op, 0); + if (irq == -EPROBE_DEFER) + return irq; + fdev = kzalloc_obj(*fdev); if (!fdev) { err = -ENOMEM; @@ -1238,7 +1246,9 @@ static int fsldma_of_probe(struct platform_device *op) } /* map the channel IRQ if it exists, but don't hookup the handler yet */ - fdev->irq = irq_of_parse_and_map(op->dev.of_node, 0); + fdev->irq = irq; + if (fdev->irq < 0) + fdev->irq = 0; dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask); dma_cap_set(DMA_SLAVE, fdev->common.cap_mask); @@ -1300,7 +1310,6 @@ out_free_fdev: if (fdev->chan[i]) fsl_dma_chan_remove(fdev->chan[i]); } - irq_dispose_mapping(fdev->irq); iounmap(fdev->regs); out_free: kfree(fdev); @@ -1322,7 +1331,6 @@ static void fsldma_of_remove(struct platform_device *op) if (fdev->chan[i]) fsl_dma_chan_remove(fdev->chan[i]); } - irq_dispose_mapping(fdev->irq); iounmap(fdev->regs); kfree(fdev); diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index 5fcd1befc92d..657629b100fa 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c @@ -25,11 +25,6 @@ /* ---------------------------------------------------------------------- */ -static struct device *chan2dev(struct dma_chan *chan) -{ - return &chan->dev->device; -} - /* ---------------------------------------------------------------------- */ static void idma64_off(struct idma64 *idma64) @@ -507,11 +502,10 @@ static int idma64_alloc_chan_resources(struct dma_chan *chan) struct idma64_chan *idma64c = to_idma64_chan(chan); /* Create a pool of consistent memory blocks for hardware descriptors */ - idma64c->pool = dma_pool_create(dev_name(chan2dev(chan)), - chan->device->dev, + idma64c->pool = dma_pool_create(dma_chan_name(chan), chan->device->dev, sizeof(struct idma64_lli), 8, 0); if (!idma64c->pool) { - dev_err(chan2dev(chan), "No memory for descriptors\n"); + dev_err(dmaengine_chan_dev(chan), "No memory for descriptors\n"); return -ENOMEM; } diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c index b3765ba15803..a3192d49b6c8 100644 --- a/drivers/dma/img-mdc-dma.c +++ b/drivers/dma/img-mdc-dma.c @@ -738,7 +738,7 @@ static int mdc_alloc_chan_resources(struct dma_chan *chan) struct mdc_chan *mchan = to_mdc_chan(chan); struct device *dev = mdma2dev(mchan->mdma); - return pm_runtime_get_sync(dev); + return pm_runtime_resume_and_get(dev); } static void mdc_free_chan_resources(struct dma_chan *chan) diff --git a/drivers/dma/loongson/loongson1-apb-dma.c b/drivers/dma/loongson/loongson1-apb-dma.c index 89786cbd20ab..46b4bfef45e2 100644 --- a/drivers/dma/loongson/loongson1-apb-dma.c +++ b/drivers/dma/loongson/loongson1-apb-dma.c @@ -89,11 +89,6 @@ static irqreturn_t ls1x_dma_irq_handler(int irq, void *data); #define to_ls1x_dma_desc(d) \ container_of(d, struct ls1x_dma_desc, vd) -static inline struct device *chan2dev(struct dma_chan *chan) -{ - return &chan->dev->device; -} - static inline int ls1x_dma_query(struct ls1x_dma_chan *chan, dma_addr_t *lli_phys) { @@ -107,7 +102,7 @@ static inline int ls1x_dma_query(struct ls1x_dma_chan *chan, ret = readl_poll_timeout_atomic(chan->reg_base + LS1X_DMA_CTRL, val, !(val & LS1X_DMA_ASK_VALID), 0, 3000); if (ret) - dev_err(chan2dev(dchan), "failed to query DMA\n"); + dev_err(dmaengine_chan_dev(dchan), "failed to query DMA\n"); return ret; } @@ -116,7 +111,7 @@ static inline int ls1x_dma_start(struct ls1x_dma_chan *chan, dma_addr_t *lli_phys) { struct dma_chan *dchan = &chan->vc.chan; - struct device *dev = chan2dev(dchan); + struct device *dev = dmaengine_chan_dev(dchan); int val, ret; val = *lli_phys & LS1X_DMA_LLI_ADDR_MASK; @@ -143,7 +138,7 @@ static inline void ls1x_dma_stop(struct ls1x_dma_chan *chan) static void ls1x_dma_free_chan_resources(struct dma_chan *dchan) { struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan); - struct device *dev = chan2dev(dchan); + struct device *dev = dmaengine_chan_dev(dchan); dma_free_coherent(dev, sizeof(struct ls1x_dma_lli), chan->curr_lli, chan->curr_lli->phys); @@ -156,7 +151,7 @@ static void ls1x_dma_free_chan_resources(struct dma_chan *dchan) static int ls1x_dma_alloc_chan_resources(struct dma_chan *dchan) { struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan); - struct device *dev = chan2dev(dchan); + struct device *dev = dmaengine_chan_dev(dchan); dma_addr_t phys; int ret; @@ -219,7 +214,7 @@ static int ls1x_dma_prep_lli(struct dma_chan *dchan, struct ls1x_dma_desc *desc, { struct ls1x_dma_chan *chan = to_ls1x_dma_chan(dchan); struct ls1x_dma_lli *lli, *prev = NULL, *first = NULL; - struct device *dev = chan2dev(dchan); + struct device *dev = dmaengine_chan_dev(dchan); struct list_head *pos = NULL; struct scatterlist *sg; unsigned int dev_addr, cmd, i; @@ -299,7 +294,7 @@ ls1x_dma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, { struct ls1x_dma_desc *desc; - dev_dbg(chan2dev(dchan), "sg_len=%u flags=0x%lx dir=%s\n", + dev_dbg(dmaengine_chan_dev(dchan), "sg_len=%u flags=0x%lx dir=%s\n", sg_len, flags, dmaengine_get_direction_text(dir)); desc = ls1x_dma_alloc_desc(); @@ -325,7 +320,7 @@ ls1x_dma_prep_dma_cyclic(struct dma_chan *dchan, dma_addr_t buf_addr, unsigned int i; int ret; - dev_dbg(chan2dev(dchan), + dev_dbg(dmaengine_chan_dev(dchan), "buf_len=%zu period_len=%zu flags=0x%lx dir=%s\n", buf_len, period_len, flags, dmaengine_get_direction_text(dir)); @@ -450,7 +445,7 @@ static enum dma_status ls1x_dma_tx_status(struct dma_chan *dchan, if (lli->hw[LS1X_DMADESC_NEXT] == next_phys) break; - dev_dbg(chan2dev(dchan), "current lli_phys=%pad", + dev_dbg(dmaengine_chan_dev(dchan), "current lli_phys=%pad", &lli->phys); /* count the residues */ @@ -489,7 +484,7 @@ static irqreturn_t ls1x_dma_irq_handler(int irq, void *data) { struct ls1x_dma_chan *chan = data; struct dma_chan *dchan = &chan->vc.chan; - struct device *dev = chan2dev(dchan); + struct device *dev = dmaengine_chan_dev(dchan); struct virt_dma_desc *vd; scoped_guard(spinlock, &chan->vc.lock) { diff --git a/drivers/dma/loongson/loongson2-apb-cmc-dma.c b/drivers/dma/loongson/loongson2-apb-cmc-dma.c index 1c9a542edc85..bc336947e31a 100644 --- a/drivers/dma/loongson/loongson2-apb-cmc-dma.c +++ b/drivers/dma/loongson/loongson2-apb-cmc-dma.c @@ -90,7 +90,7 @@ struct loongson2_cmc_dma_chan { struct dma_slave_config dma_sconfig; struct loongson2_cmc_dma_desc *desc; u32 id; - u32 irq; + int irq; u32 next_sg; struct loongson2_cmc_dma_chan_reg chan_reg; }; @@ -134,11 +134,6 @@ static struct loongson2_cmc_dma_desc *to_lmdma_desc(struct virt_dma_desc *vdesc) return container_of(vdesc, struct loongson2_cmc_dma_desc, vdesc); } -static struct device *chan2dev(struct loongson2_cmc_dma_chan *lchan) -{ - return &lchan->vchan.chan.dev->device; -} - static u32 loongson2_cmc_dma_read(struct loongson2_cmc_dma_dev *lddev, u32 reg, u32 id) { return readl(lddev->base + (reg + lddev->chan_reg_offset * id)); @@ -302,7 +297,7 @@ static irqreturn_t loongson2_cmc_dma_chan_irq(int irq, void *devid) { struct loongson2_cmc_dma_chan *lchan = devid; struct loongson2_cmc_dma_dev *lddev = lmdma_get_dev(lchan); - struct device *dev = chan2dev(lchan); + struct device *dev = vchan_chan_dev(&lchan->vchan); u32 ists, status, ccr; scoped_guard(spinlock, &lchan->vchan.lock) { @@ -337,7 +332,7 @@ static void loongson2_cmc_dma_issue_pending(struct dma_chan *chan) guard(spinlock_irqsave)(&lchan->vchan.lock); if (vchan_issue_pending(&lchan->vchan) && !lchan->desc) { - dev_dbg(chan2dev(lchan), "vchan %pK: issued\n", &lchan->vchan); + dev_dbg(vchan_chan_dev(&lchan->vchan), "vchan %pK: issued\n", &lchan->vchan); loongson2_cmc_dma_start_transfer(lchan); } } @@ -347,7 +342,7 @@ static int loongson2_cmc_dma_set_xfer_param(struct loongson2_cmc_dma_chan *lchan enum dma_slave_buswidth *buswidth, u32 buf_len) { struct dma_slave_config sconfig = lchan->dma_sconfig; - struct device *dev = chan2dev(lchan); + struct device *dev = vchan_chan_dev(&lchan->vchan); int dev_width; u32 ccr; @@ -409,7 +404,7 @@ loongson2_cmc_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, num_items = DIV_ROUND_UP(sg_dma_len(sg), buswidth); if (num_items >= LOONSON2_CMCDMA_MAX_DATA_ITEMS) { - dev_err(chan2dev(lchan), "Number of items not supported\n"); + dev_err(vchan_chan_dev(&lchan->vchan), "Number of items not supported\n"); kfree(desc); return ERR_PTR(-EINVAL); } @@ -447,7 +442,7 @@ loongson2_cmc_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, si num_items = DIV_ROUND_UP(period_len, buswidth); if (num_items >= LOONSON2_CMCDMA_MAX_DATA_ITEMS) { - dev_err(chan2dev(lchan), "Number of items not supported\n"); + dev_err(vchan_chan_dev(&lchan->vchan), "Number of items not supported\n"); return ERR_PTR(-EINVAL); } @@ -678,7 +673,7 @@ static int loongson2_cmc_dma_probe(struct platform_device *pdev) return lchan->irq; ret = devm_request_irq(dev, lchan->irq, loongson2_cmc_dma_chan_irq, IRQF_SHARED, - dev_name(chan2dev(lchan)), lchan); + vchan_chan_name(&lchan->vchan), lchan); if (ret) return ret; } diff --git a/drivers/dma/loongson/loongson2-apb-dma.c b/drivers/dma/loongson/loongson2-apb-dma.c index aceb069e71fc..16a0c1c60d59 100644 --- a/drivers/dma/loongson/loongson2-apb-dma.c +++ b/drivers/dma/loongson/loongson2-apb-dma.c @@ -161,11 +161,6 @@ static inline struct ls2x_dma_priv *to_ldma_priv(struct dma_device *ddev) return container_of(ddev, struct ls2x_dma_priv, ddev); } -static struct device *chan2dev(struct dma_chan *chan) -{ - return &chan->dev->device; -} - static void ls2x_dma_desc_free(struct virt_dma_desc *vdesc) { struct ls2x_dma_chan *lchan = to_ldma_chan(vdesc->tx.chan); @@ -282,11 +277,11 @@ static int ls2x_dma_alloc_chan_resources(struct dma_chan *chan) struct ls2x_dma_chan *lchan = to_ldma_chan(chan); /* Create a pool of consistent memory blocks for hardware descriptors */ - lchan->pool = dma_pool_create(dev_name(chan2dev(chan)), + lchan->pool = dma_pool_create(dma_chan_name(chan), chan->device->dev, PAGE_SIZE, __alignof__(struct ls2x_dma_hw_desc), 0); if (!lchan->pool) { - dev_err(chan2dev(chan), "No memory for descriptors\n"); + dev_err(dmaengine_chan_dev(chan), "No memory for descriptors\n"); return -ENOMEM; } diff --git a/drivers/dma/mediatek/mtk-hsdma.c b/drivers/dma/mediatek/mtk-hsdma.c index a43412ff5edd..27cb370106c7 100644 --- a/drivers/dma/mediatek/mtk-hsdma.c +++ b/drivers/dma/mediatek/mtk-hsdma.c @@ -848,17 +848,27 @@ static int mtk_hsdma_hw_init(struct mtk_hsdma_device *hsdma) { int err; - pm_runtime_enable(hsdma2dev(hsdma)); - pm_runtime_get_sync(hsdma2dev(hsdma)); + err = devm_pm_runtime_enable(hsdma2dev(hsdma)); + if (err) + return err; + + err = pm_runtime_resume_and_get(hsdma2dev(hsdma)); + if (err < 0) + return err; err = clk_prepare_enable(hsdma->clk); if (err) - return err; + goto err_put_pm; mtk_dma_write(hsdma, MTK_HSDMA_INT_ENABLE, 0); mtk_dma_write(hsdma, MTK_HSDMA_GLO, MTK_HSDMA_GLO_DEFAULT); return 0; + +err_put_pm: + pm_runtime_put_sync(hsdma2dev(hsdma)); + + return err; } static int mtk_hsdma_hw_deinit(struct mtk_hsdma_device *hsdma) @@ -868,7 +878,6 @@ static int mtk_hsdma_hw_deinit(struct mtk_hsdma_device *hsdma) clk_disable_unprepare(hsdma->clk); pm_runtime_put_sync(hsdma2dev(hsdma)); - pm_runtime_disable(hsdma2dev(hsdma)); return 0; } @@ -983,7 +992,9 @@ static int mtk_hsdma_probe(struct platform_device *pdev) goto err_unregister; } - mtk_hsdma_hw_init(hsdma); + err = mtk_hsdma_hw_init(hsdma); + if (err) + goto err_free; err = devm_request_irq(&pdev->dev, hsdma->irq, mtk_hsdma_irq, 0, @@ -991,7 +1002,7 @@ static int mtk_hsdma_probe(struct platform_device *pdev) if (err) { dev_err(&pdev->dev, "request_irq failed with err %d\n", err); - goto err_free; + goto err_deinit; } platform_set_drvdata(pdev, hsdma); @@ -1000,8 +1011,9 @@ static int mtk_hsdma_probe(struct platform_device *pdev) return 0; -err_free: +err_deinit: mtk_hsdma_hw_deinit(hsdma); +err_free: of_dma_controller_free(pdev->dev.of_node); err_unregister: dma_async_device_unregister(dd); diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c index ed520737882b..8abd24e2ffc7 100644 --- a/drivers/dma/mmp_pdma.c +++ b/drivers/dma/mmp_pdma.c @@ -564,8 +564,7 @@ static int mmp_pdma_alloc_chan_resources(struct dma_chan *dchan) if (chan->desc_pool) return 1; - chan->desc_pool = dma_pool_create(dev_name(&dchan->dev->device), - chan->dev, + chan->desc_pool = dma_pool_create(dma_chan_name(dchan), chan->dev, sizeof(struct mmp_pdma_desc_sw), __alignof__(struct mmp_pdma_desc_sw), 0); diff --git a/drivers/dma/moxart-dma.c b/drivers/dma/moxart-dma.c index 442f5aa16031..28be93eed4cc 100644 --- a/drivers/dma/moxart-dma.c +++ b/drivers/dma/moxart-dma.c @@ -154,11 +154,6 @@ static const unsigned int es_bytes[] = { [MOXART_DMA_DATA_TYPE_S32] = 4, }; -static struct device *chan2dev(struct dma_chan *chan) -{ - return &chan->dev->device; -} - static inline struct moxart_chan *to_moxart_dma_chan(struct dma_chan *c) { return container_of(c, struct moxart_chan, vc.chan); @@ -182,7 +177,7 @@ static int moxart_terminate_all(struct dma_chan *chan) LIST_HEAD(head); u32 ctrl; - dev_dbg(chan2dev(chan), "%s: ch=%p\n", __func__, ch); + dev_dbg(dmaengine_chan_dev(chan), "%s: ch=%p\n", __func__, ch); spin_lock_irqsave(&ch->vc.lock, flags); @@ -272,7 +267,7 @@ static struct dma_async_tx_descriptor *moxart_prep_slave_sg( unsigned int i; if (!is_slave_direction(dir)) { - dev_err(chan2dev(chan), "%s: invalid DMA direction\n", + dev_err(dmaengine_chan_dev(chan), "%s: invalid DMA direction\n", __func__); return NULL; } @@ -296,7 +291,7 @@ static struct dma_async_tx_descriptor *moxart_prep_slave_sg( es = MOXART_DMA_DATA_TYPE_S32; break; default: - dev_err(chan2dev(chan), "%s: unsupported data width (%u)\n", + dev_err(dmaengine_chan_dev(chan), "%s: unsupported data width (%u)\n", __func__, dev_width); return NULL; } @@ -341,7 +336,7 @@ static int moxart_alloc_chan_resources(struct dma_chan *chan) { struct moxart_chan *ch = to_moxart_dma_chan(chan); - dev_dbg(chan2dev(chan), "%s: allocating channel #%u\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: allocating channel #%u\n", __func__, ch->ch_num); ch->allocated = 1; @@ -354,7 +349,7 @@ static void moxart_free_chan_resources(struct dma_chan *chan) vchan_free_chan_resources(&ch->vc); - dev_dbg(chan2dev(chan), "%s: freeing channel #%u\n", + dev_dbg(dmaengine_chan_dev(chan), "%s: freeing channel #%u\n", __func__, ch->ch_num); ch->allocated = 0; } @@ -379,7 +374,7 @@ static void moxart_set_transfer_params(struct moxart_chan *ch, unsigned int len) */ writel(d->dma_cycles, ch->base + REG_OFF_CYCLES); - dev_dbg(chan2dev(&ch->vc.chan), "%s: set %u DMA cycles (len=%u)\n", + dev_dbg(vchan_chan_dev(&ch->vc), "%s: set %u DMA cycles (len=%u)\n", __func__, d->dma_cycles, len); } @@ -460,7 +455,7 @@ static size_t moxart_dma_desc_size_in_flight(struct moxart_chan *ch) completed_cycles = (ch->desc->dma_cycles - cycles); size -= completed_cycles << es_bytes[ch->desc->es]; - dev_dbg(chan2dev(&ch->vc.chan), "%s: size=%zu\n", __func__, size); + dev_dbg(vchan_chan_dev(&ch->vc), "%s: size=%zu\n", __func__, size); return size; } @@ -517,7 +512,7 @@ static irqreturn_t moxart_dma_interrupt(int irq, void *devid) unsigned int i; u32 ctrl; - dev_dbg(chan2dev(&ch->vc.chan), "%s\n", __func__); + dev_dbg(vchan_chan_dev(&ch->vc), "%s\n", __func__); for (i = 0; i < APB_DMA_MAX_CHANNEL; i++, ch++) { if (!ch->allocated) @@ -525,7 +520,7 @@ static irqreturn_t moxart_dma_interrupt(int irq, void *devid) ctrl = readl(ch->base + REG_OFF_CTRL); - dev_dbg(chan2dev(&ch->vc.chan), "%s: ch=%p ch->base=%p ctrl=%x\n", + dev_dbg(vchan_chan_dev(&ch->vc), "%s: ch=%p ch->base=%p ctrl=%x\n", __func__, ch, ch->base, ctrl); if (ctrl & APB_DMA_FIN_INT_STS) { diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 25ed61f1b089..c4e0dce3ca64 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -583,8 +583,13 @@ mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, while (src_cnt--) { /* Check if a new window needs to get added for 'src' */ ret = mv_xor_add_io_win(mv_chan, src[src_cnt]); - if (ret) + if (ret) { + spin_lock_bh(&mv_chan->lock); + list_move_tail(&sw_desc->node, + &mv_chan->free_slots); + spin_unlock_bh(&mv_chan->lock); return NULL; + } mv_desc_set_src_addr(sw_desc, src_cnt, src[src_cnt]); } } @@ -1162,6 +1167,7 @@ mv_xor_channel_add(struct mv_xor_device *xordev, err_free_irq: free_irq(mv_chan->irq, mv_chan); + tasklet_kill(&mv_chan->irq_tasklet); err_free_dma: dma_free_wc(&pdev->dev, MV_XOR_POOL_SIZE, mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool); diff --git a/drivers/dma/nbpfaxi.c b/drivers/dma/nbpfaxi.c index 05d7321629cc..744cd14d7872 100644 --- a/drivers/dma/nbpfaxi.c +++ b/drivers/dma/nbpfaxi.c @@ -1202,7 +1202,7 @@ static irqreturn_t nbpf_chan_irq(int irq, void *dev) nbpf_status_ack(chan); - dev_dbg(&chan->dma_chan.dev->device, "%s()\n", __func__); + dev_dbg(dmaengine_chan_dev(&chan->dma_chan), "%s()\n", __func__); spin_lock(&chan->lock); desc = chan->running; diff --git a/drivers/dma/owl-dma.c b/drivers/dma/owl-dma.c index 7c80572fc71d..9dc88d804a2e 100644 --- a/drivers/dma/owl-dma.c +++ b/drivers/dma/owl-dma.c @@ -292,11 +292,6 @@ static inline struct owl_dma *to_owl_dma(struct dma_device *dd) return container_of(dd, struct owl_dma, dma); } -static struct device *chan2dev(struct dma_chan *chan) -{ - return &chan->dev->device; -} - static inline struct owl_dma_vchan *to_owl_vchan(struct dma_chan *chan) { return container_of(chan, struct owl_dma_vchan, vc.chan); @@ -573,7 +568,7 @@ static int owl_dma_start_next_txd(struct owl_dma_vchan *vchan) spin_unlock_irqrestore(&od->lock, flags); - dev_dbg(chan2dev(&vchan->vc.chan), "starting pchan %d\n", pchan->id); + dev_dbg(vchan_chan_dev(&vchan->vc), "starting pchan %d\n", pchan->id); /* Start DMA transfer for this pchan */ pchan_writel(pchan, OWL_DMAX_START, 0x1); @@ -757,7 +752,7 @@ static int owl_dma_resume(struct dma_chan *chan) if (!vchan->pchan && !vchan->txd) return 0; - dev_dbg(chan2dev(chan), "vchan %p: resume\n", &vchan->vc); + dev_dbg(dmaengine_chan_dev(chan), "vchan %p: resume\n", &vchan->vc); spin_lock_irqsave(&vchan->vc.lock, flags); @@ -888,7 +883,7 @@ static struct dma_async_tx_descriptor for (offset = 0; offset < len; offset += bytes) { lli = owl_dma_alloc_lli(od); if (!lli) { - dev_warn(chan2dev(chan), "failed to allocate lli\n"); + dev_warn(dmaengine_chan_dev(chan), "failed to allocate lli\n"); goto err_txd_free; } @@ -898,7 +893,7 @@ static struct dma_async_tx_descriptor bytes, DMA_MEM_TO_MEM, &vchan->cfg, txd->cyclic); if (ret) { - dev_warn(chan2dev(chan), "failed to config lli\n"); + dev_warn(dmaengine_chan_dev(chan), "failed to config lli\n"); goto err_txd_free; } @@ -947,7 +942,7 @@ static struct dma_async_tx_descriptor lli = owl_dma_alloc_lli(od); if (!lli) { - dev_err(chan2dev(chan), "failed to allocate lli"); + dev_err(dmaengine_chan_dev(chan), "failed to allocate lli"); goto err_txd_free; } @@ -962,7 +957,7 @@ static struct dma_async_tx_descriptor ret = owl_dma_cfg_lli(vchan, lli, src, dst, len, dir, sconfig, txd->cyclic); if (ret) { - dev_warn(chan2dev(chan), "failed to config lli"); + dev_warn(dmaengine_chan_dev(chan), "failed to config lli"); goto err_txd_free; } @@ -1003,7 +998,7 @@ static struct dma_async_tx_descriptor for (i = 0; i < periods; i++) { lli = owl_dma_alloc_lli(od); if (!lli) { - dev_warn(chan2dev(chan), "failed to allocate lli"); + dev_warn(dmaengine_chan_dev(chan), "failed to allocate lli"); goto err_txd_free; } @@ -1018,7 +1013,7 @@ static struct dma_async_tx_descriptor ret = owl_dma_cfg_lli(vchan, lli, src, dst, period_len, dir, sconfig, txd->cyclic); if (ret) { - dev_warn(chan2dev(chan), "failed to config lli"); + dev_warn(dmaengine_chan_dev(chan), "failed to config lli"); goto err_txd_free; } diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index bf805f1024f6..88baf7ffec37 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c @@ -150,11 +150,6 @@ static inline struct pch_dma *to_pd(struct dma_device *ddev) return container_of(ddev, struct pch_dma, dma); } -static inline struct device *chan2dev(struct dma_chan *chan) -{ - return &chan->dev->device; -} - static inline struct pch_dma_desc *pdc_first_active(struct pch_dma_chan *pd_chan) { @@ -189,7 +184,7 @@ static void pdc_enable_irq(struct dma_chan *chan, int enable) dma_writel(pd, CTL2, val); - dev_dbg(chan2dev(chan), "pdc_enable_irq: chan %d -> %x\n", + dev_dbg(dmaengine_chan_dev(chan), "pdc_enable_irq: chan %d -> %x\n", chan->chan_id, val); } @@ -237,7 +232,7 @@ static void pdc_set_dir(struct dma_chan *chan) dma_writel(pd, CTL3, val); } - dev_dbg(chan2dev(chan), "pdc_set_dir: chan %d -> %x\n", + dev_dbg(dmaengine_chan_dev(chan), "pdc_set_dir: chan %d -> %x\n", chan->chan_id, val); } @@ -271,7 +266,7 @@ static void pdc_set_mode(struct dma_chan *chan, u32 mode) dma_writel(pd, CTL3, val); } - dev_dbg(chan2dev(chan), "pdc_set_mode: chan %d -> %x\n", + dev_dbg(dmaengine_chan_dev(chan), "pdc_set_mode: chan %d -> %x\n", chan->chan_id, val); } @@ -314,18 +309,18 @@ static bool pdc_is_idle(struct pch_dma_chan *pd_chan) static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) { if (!pdc_is_idle(pd_chan)) { - dev_err(chan2dev(&pd_chan->chan), + dev_err(dmaengine_chan_dev(&pd_chan->chan), "BUG: Attempt to start non-idle channel\n"); return; } - dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n", + dev_dbg(dmaengine_chan_dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n", pd_chan->chan.chan_id, desc->regs.dev_addr); - dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n", + dev_dbg(dmaengine_chan_dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n", pd_chan->chan.chan_id, desc->regs.mem_addr); - dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> size: %x\n", + dev_dbg(dmaengine_chan_dev(&pd_chan->chan), "chan %d -> size: %x\n", pd_chan->chan.chan_id, desc->regs.size); - dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n", + dev_dbg(dmaengine_chan_dev(&pd_chan->chan), "chan %d -> next: %x\n", pd_chan->chan.chan_id, desc->regs.next); if (list_empty(&desc->tx_list)) { @@ -382,8 +377,8 @@ static void pdc_handle_error(struct pch_dma_chan *pd_chan) if (!list_empty(&pd_chan->active_list)) pdc_dostart(pd_chan, pdc_first_active(pd_chan)); - dev_crit(chan2dev(&pd_chan->chan), "Bad descriptor submitted\n"); - dev_crit(chan2dev(&pd_chan->chan), "descriptor cookie: %d\n", + dev_crit(dmaengine_chan_dev(&pd_chan->chan), "Bad descriptor submitted\n"); + dev_crit(dmaengine_chan_dev(&pd_chan->chan), "descriptor cookie: %d\n", bad_desc->txd.cookie); pdc_chain_complete(pd_chan, bad_desc); @@ -450,10 +445,10 @@ static struct pch_dma_desc *pdc_desc_get(struct pch_dma_chan *pd_chan) ret = desc; break; } - dev_dbg(chan2dev(&pd_chan->chan), "desc %p not ACKed\n", desc); + dev_dbg(dmaengine_chan_dev(&pd_chan->chan), "desc %p not ACKed\n", desc); } spin_unlock(&pd_chan->lock); - dev_dbg(chan2dev(&pd_chan->chan), "scanned %d descriptors\n", i); + dev_dbg(dmaengine_chan_dev(&pd_chan->chan), "scanned %d descriptors\n", i); if (!ret) { ret = pdc_alloc_desc(&pd_chan->chan, GFP_ATOMIC); @@ -462,7 +457,7 @@ static struct pch_dma_desc *pdc_desc_get(struct pch_dma_chan *pd_chan) pd_chan->descs_allocated++; spin_unlock(&pd_chan->lock); } else { - dev_err(chan2dev(&pd_chan->chan), + dev_err(dmaengine_chan_dev(&pd_chan->chan), "failed to alloc desc\n"); } } @@ -489,7 +484,7 @@ static int pd_alloc_chan_resources(struct dma_chan *chan) int i; if (!pdc_is_idle(pd_chan)) { - dev_dbg(chan2dev(chan), "DMA channel not idle ?\n"); + dev_dbg(dmaengine_chan_dev(chan), "DMA channel not idle ?\n"); return -EIO; } @@ -500,7 +495,7 @@ static int pd_alloc_chan_resources(struct dma_chan *chan) desc = pdc_alloc_desc(chan, GFP_KERNEL); if (!desc) { - dev_warn(chan2dev(chan), + dev_warn(dmaengine_chan_dev(chan), "Only allocated %d initial descriptors\n", i); break; } @@ -573,7 +568,7 @@ static struct dma_async_tx_descriptor *pd_prep_slave_sg(struct dma_chan *chan, int i; if (unlikely(!sg_len)) { - dev_info(chan2dev(chan), "prep_slave_sg: length is zero!\n"); + dev_info(dmaengine_chan_dev(chan), "prep_slave_sg: length is zero!\n"); return NULL; } @@ -639,7 +634,7 @@ static struct dma_async_tx_descriptor *pd_prep_slave_sg(struct dma_chan *chan, return &first->txd; err_desc_get: - dev_err(chan2dev(chan), "failed to get desc or wrong parameters\n"); + dev_err(dmaengine_chan_dev(chan), "failed to get desc or wrong parameters\n"); pdc_desc_put(pd_chan, first); return NULL; } @@ -671,7 +666,7 @@ static void pdc_tasklet(struct tasklet_struct *t) unsigned long flags; if (!pdc_is_idle(pd_chan)) { - dev_err(chan2dev(&pd_chan->chan), + dev_err(dmaengine_chan_dev(&pd_chan->chan), "BUG: handle non-idle channel in tasklet\n"); return; } diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 6214d9000db8..c2d0b473b8f4 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2953,8 +2953,8 @@ DEFINE_SHOW_ATTRIBUTE(pl330_debugfs); static inline void init_pl330_debugfs(struct pl330_dmac *pl330) { - pl330->dbgfs = debugfs_create_file(dev_name(pl330->ddma.dev), - S_IFREG | 0444, NULL, pl330, + pl330->dbgfs = debugfs_create_file("stats", 0444, + pl330->ddma.dbg_dev_root, pl330, &pl330_debugfs_fops); } diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c index fc43124fefa8..4f0d1d531f01 100644 --- a/drivers/dma/pxa_dma.c +++ b/drivers/dma/pxa_dma.c @@ -149,7 +149,7 @@ struct pxad_device { ({ \ u32 _v; \ _v = readl_relaxed((phy)->base + _reg((phy)->idx)); \ - dev_vdbg(&phy->vchan->vc.chan.dev->device, \ + dev_vdbg(vchan_chan_dev(&phy->vchan->vc), \ "%s(): readl(%s): 0x%08x\n", __func__, #_reg, \ _v); \ _v; \ @@ -157,14 +157,14 @@ struct pxad_device { #define phy_writel(phy, val, _reg) \ do { \ writel((val), (phy)->base + _reg((phy)->idx)); \ - dev_vdbg(&phy->vchan->vc.chan.dev->device, \ + dev_vdbg(vchan_chan_dev(&phy->vchan->vc), \ "%s(): writel(0x%08x, %s)\n", \ __func__, (u32)(val), #_reg); \ } while (0) #define phy_writel_relaxed(phy, val, _reg) \ do { \ writel_relaxed((val), (phy)->base + _reg((phy)->idx)); \ - dev_vdbg(&phy->vchan->vc.chan.dev->device, \ + dev_vdbg(vchan_chan_dev(&phy->vchan->vc), \ "%s(): writel_relaxed(0x%08x, %s)\n", \ __func__, (u32)(val), #_reg); \ } while (0) @@ -396,7 +396,7 @@ static struct pxad_phy *lookup_phy(struct pxad_chan *pchan) out_unlock: spin_unlock_irqrestore(&pdev->phy_lock, flags); - dev_dbg(&pchan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&pchan->vc), "%s(): phy=%p(%d)\n", __func__, found, found ? found->idx : -1); @@ -409,7 +409,7 @@ static void pxad_free_phy(struct pxad_chan *chan) unsigned long flags; u32 reg; - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): freeing\n", __func__); if (!chan->phy) return; @@ -454,7 +454,7 @@ static void phy_enable(struct pxad_phy *phy, bool misaligned) if (!phy->vchan) return; - dev_dbg(&phy->vchan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&phy->vchan->vc), "%s(); phy=%p(%d) misaligned=%d\n", __func__, phy, phy->idx, misaligned); @@ -483,7 +483,7 @@ static void phy_disable(struct pxad_phy *phy) return; dcsr = phy_readl_relaxed(phy, DCSR); - dev_dbg(&phy->vchan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&phy->vchan->vc), "%s(): phy=%p(%d)\n", __func__, phy, phy->idx); phy_writel(phy, dcsr & ~PXA_DCSR_RUN & ~PXA_DCSR_STOPIRQEN, DCSR); } @@ -491,12 +491,12 @@ static void phy_disable(struct pxad_phy *phy) static void pxad_launch_chan(struct pxad_chan *chan, struct pxad_desc_sw *desc) { - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): desc=%p\n", __func__, desc); if (!chan->phy) { chan->phy = lookup_phy(chan); if (!chan->phy) { - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): no free dma channel\n", __func__); return; } @@ -592,7 +592,7 @@ static unsigned int clear_chan_irq(struct pxad_phy *phy) dcsr = phy_readl_relaxed(phy, DCSR); phy_writel(phy, dcsr, DCSR); if ((dcsr & PXA_DCSR_BUSERR) && (phy->vchan)) - dev_warn(&phy->vchan->vc.chan.dev->device, + dev_warn(vchan_chan_dev(&phy->vchan->vc), "%s(chan=%p): PXA_DCSR_BUSERR\n", __func__, &phy->vchan); @@ -617,7 +617,7 @@ static irqreturn_t pxad_chan_handler(int irq, void *dev_id) spin_lock(&chan->vc.lock); list_for_each_entry_safe(vd, tmp, &chan->vc.desc_issued, node) { vd_completed = is_desc_completed(vd); - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): checking txd %p[%x]: completed=%d dcsr=0x%x\n", __func__, vd, vd->tx.cookie, vd_completed, dcsr); @@ -640,7 +640,7 @@ static irqreturn_t pxad_chan_handler(int irq, void *dev_id) } if (!chan->bus_error && dcsr & PXA_DCSR_STOPSTATE) { - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): channel stopped, submitted_empty=%d issued_empty=%d", __func__, list_empty(&chan->vc.desc_submitted), @@ -694,7 +694,7 @@ static int pxad_alloc_chan_resources(struct dma_chan *dchan) __alignof__(struct pxad_desc_hw), 0); if (!chan->desc_pool) { - dev_err(&chan->vc.chan.dev->device, + dev_err(vchan_chan_dev(&chan->vc), "%s(): unable to allocate descriptor pool\n", __func__); return -ENOMEM; @@ -750,7 +750,7 @@ pxad_alloc_desc(struct pxad_chan *chan, unsigned int nb_hw_desc) for (i = 0; i < nb_hw_desc; i++) { desc = dma_pool_alloc(sw_desc->desc_pool, GFP_NOWAIT, &dma); if (!desc) { - dev_err(&chan->vc.chan.dev->device, + dev_err(vchan_chan_dev(&chan->vc), "%s(): Couldn't allocate the %dth hw_desc from dma_pool %p\n", __func__, i, sw_desc->desc_pool); sw_desc->nb_desc = i; @@ -787,7 +787,7 @@ static dma_cookie_t pxad_tx_submit(struct dma_async_tx_descriptor *tx) if (list_empty(&vc->desc_submitted) && pxad_try_hotchain(vc, vd)) { list_move_tail(&vd->node, &vc->desc_issued); - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): txd %p[%x]: submitted (hot linked)\n", __func__, vd, cookie); goto out; @@ -810,7 +810,7 @@ static dma_cookie_t pxad_tx_submit(struct dma_async_tx_descriptor *tx) else vd_chained = NULL; } - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): txd %p[%x]: submitted (%s linked)\n", __func__, vd, cookie, vd_chained ? "cold" : "not"); list_move_tail(&vd->node, &vc->desc_submitted); @@ -833,7 +833,7 @@ static void pxad_issue_pending(struct dma_chan *dchan) vd_first = list_first_entry(&chan->vc.desc_submitted, struct virt_dma_desc, node); - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): txd %p[%x]", __func__, vd_first, vd_first->tx.cookie); vchan_issue_pending(&chan->vc); @@ -853,7 +853,7 @@ pxad_tx_prep(struct virt_dma_chan *vc, struct virt_dma_desc *vd, INIT_LIST_HEAD(&vd->node); tx = vchan_tx_prep(vc, vd, tx_flags); tx->tx_submit = pxad_tx_submit; - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): vc=%p txd=%p[%x] flags=0x%lx\n", __func__, vc, vd, vd->tx.cookie, tx_flags); @@ -892,7 +892,7 @@ static void pxad_get_config(struct pxad_chan *chan, *dcmd |= PXA_DCMD_BURST32 | PXA_DCMD_INCTRGADDR | PXA_DCMD_INCSRCADDR; - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): dev_addr=0x%x maxburst=%d width=%d dir=%d\n", __func__, dev_addr, maxburst, width, dir); @@ -926,7 +926,7 @@ pxad_prep_memcpy(struct dma_chan *dchan, if (!dchan || !len) return NULL; - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): dma_dst=0x%lx dma_src=0x%lx len=%zu flags=%lx\n", __func__, (unsigned long)dma_dst, (unsigned long)dma_src, len, flags); @@ -975,7 +975,7 @@ pxad_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, return NULL; pxad_get_config(chan, dir, &dcmd, &dsadr, &dtadr); - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): dir=%d flags=%lx\n", __func__, dir, flags); nb_desc = sg_nents_for_dma(sgl, sg_len, PDMA_MAX_DESC_BYTES); @@ -1022,7 +1022,7 @@ pxad_prep_dma_cyclic(struct dma_chan *dchan, if (!dchan || !len || !period_len) return NULL; if ((dir != DMA_DEV_TO_MEM) && (dir != DMA_MEM_TO_DEV)) { - dev_err(&chan->vc.chan.dev->device, + dev_err(vchan_chan_dev(&chan->vc), "Unsupported direction for cyclic DMA\n"); return NULL; } @@ -1033,7 +1033,7 @@ pxad_prep_dma_cyclic(struct dma_chan *dchan, pxad_get_config(chan, dir, &dcmd, &dsadr, &dtadr); dcmd |= PXA_DCMD_ENDIRQEN | (PXA_DCMD_LENGTH & period_len); - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): buf_addr=0x%lx len=%zu period=%zu dir=%d flags=%lx\n", __func__, (unsigned long)buf_addr, len, period_len, dir, flags); @@ -1081,14 +1081,14 @@ static int pxad_terminate_all(struct dma_chan *dchan) struct pxad_phy *phy; LIST_HEAD(head); - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): vchan %p: terminate all\n", __func__, &chan->vc); spin_lock_irqsave(&chan->vc.lock, flags); vchan_get_all_descriptors(&chan->vc, &head); list_for_each_entry(vd, &head, node) { - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): cancelling txd %p[%x] (completed=%d)", __func__, vd, vd->tx.cookie, is_desc_completed(vd)); } @@ -1178,7 +1178,7 @@ static unsigned int pxad_residue(struct pxad_chan *chan, out: spin_unlock_irqrestore(&chan->vc.lock, flags); - dev_dbg(&chan->vc.chan.dev->device, + dev_dbg(vchan_chan_dev(&chan->vc), "%s(): txd %p[%x] sw_desc=%p: %d\n", __func__, vd, cookie, sw_desc, residue); return residue; diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c index a5055a6273af..c41bfac65ddf 100644 --- a/drivers/dma/qcom/gpi.c +++ b/drivers/dma/qcom/gpi.c @@ -1965,16 +1965,19 @@ static int gpi_ch_init(struct gchan *gchan) error_start_chan: for (i = i - 1; i >= 0; i--) { gpi_stop_chan(&gpii->gchan[i]); - gpi_send_cmd(gpii, gchan, GPI_CH_CMD_RESET); + gpi_send_cmd(gpii, &gpii->gchan[i], GPI_CH_CMD_RESET); } i = 2; error_alloc_chan: for (i = i - 1; i >= 0; i--) - gpi_reset_chan(gchan, GPI_CH_CMD_DE_ALLOC); + gpi_reset_chan(&gpii->gchan[i], GPI_CH_CMD_DE_ALLOC); error_alloc_ev_ring: gpi_disable_interrupts(gpii); error_config_int: gpi_free_ring(&gpii->ev_ring, gpii); + write_lock_irq(&gpii->pm_lock); + gpii->pm_state = DISABLE_STATE; + write_unlock_irq(&gpii->pm_lock); exit_gpi_init: return ret; } @@ -2065,6 +2068,8 @@ static int gpi_alloc_chan_resources(struct dma_chan *chan) goto xfer_alloc_err; ret = gpi_ch_init(gchan); + if (ret) + gpi_free_ring(&gchan->ch_ring, gpii); mutex_unlock(&gpii->ctrl_lock); diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c index 19b32a23c882..60b3067a0099 100644 --- a/drivers/dma/sprd-dma.c +++ b/drivers/dma/sprd-dma.c @@ -208,8 +208,7 @@ struct sprd_dma_chn { struct sprd_dma_dev { struct dma_device dma_dev; void __iomem *glb_base; - struct clk *clk; - struct clk *ashb_clk; + struct clk_bulk_data clks[2]; int irq; u32 total_chns; struct sprd_dma_chn channels[] __counted_by(total_chns); @@ -260,31 +259,12 @@ static void sprd_dma_chn_update(struct sprd_dma_chn *schan, u32 reg, static int sprd_dma_enable(struct sprd_dma_dev *sdev) { - int ret; - - ret = clk_prepare_enable(sdev->clk); - if (ret) - return ret; - - /* - * The ashb_clk is optional and only for AGCP DMA controller, so we - * need add one condition to check if the ashb_clk need enable. - */ - if (!IS_ERR(sdev->ashb_clk)) - ret = clk_prepare_enable(sdev->ashb_clk); - - return ret; + return clk_bulk_prepare_enable(ARRAY_SIZE(sdev->clks), sdev->clks); } static void sprd_dma_disable(struct sprd_dma_dev *sdev) { - clk_disable_unprepare(sdev->clk); - - /* - * Need to check if we need disable the optional ashb_clk for AGCP DMA. - */ - if (!IS_ERR(sdev->ashb_clk)) - clk_disable_unprepare(sdev->ashb_clk); + clk_bulk_disable_unprepare(ARRAY_SIZE(sdev->clks), sdev->clks); } static void sprd_dma_set_uid(struct sprd_dma_chn *schan) @@ -1140,16 +1120,17 @@ static int sprd_dma_probe(struct platform_device *pdev) if (!sdev) return -ENOMEM; - sdev->clk = devm_clk_get(&pdev->dev, "enable"); - if (IS_ERR(sdev->clk)) { - dev_err(&pdev->dev, "get enable clock failed\n"); - return PTR_ERR(sdev->clk); - } + /* The ashb_eb clock is optional and only present for AGCP DMA */ + sdev->clks[0].id = "enable"; + sdev->clks[1].id = "ashb_eb"; + ret = devm_clk_bulk_get_optional(&pdev->dev, ARRAY_SIZE(sdev->clks), + sdev->clks); + if (ret) + return dev_err_probe(&pdev->dev, ret, "get clocks failed\n"); - /* ashb clock is optional for AGCP DMA */ - sdev->ashb_clk = devm_clk_get(&pdev->dev, "ashb_eb"); - if (IS_ERR(sdev->ashb_clk)) - dev_warn(&pdev->dev, "no optional ashb eb clock\n"); + if (!sdev->clks[0].clk) + return dev_err_probe(&pdev->dev, -ENOENT, + "get enable clock failed\n"); /* * We have three DMA controllers: AP DMA, AON DMA and AGCP DMA. For AGCP diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c index d9547017f3bd..35dbff5f9f1a 100644 --- a/drivers/dma/st_fdma.c +++ b/drivers/dma/st_fdma.c @@ -268,7 +268,7 @@ static int st_fdma_alloc_chan_res(struct dma_chan *chan) struct st_fdma_chan *fchan = to_st_fdma_chan(chan); /* Create the dma pool for descriptor allocation */ - fchan->node_pool = dma_pool_create(dev_name(&chan->dev->device), + fchan->node_pool = dma_pool_create(dma_chan_name(chan), fchan->fdev->dev, sizeof(struct st_fdma_hw_node), __alignof__(struct st_fdma_hw_node), diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 0d9ffa3e2663..05e797496cae 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -623,11 +623,6 @@ struct d40_base { struct d40_chan phy_chans[]; }; -static struct device *chan2dev(struct d40_chan *d40c) -{ - return &d40c->chan.dev->device; -} - static bool chan_is_physical(struct d40_chan *chan) { return chan->log_num == D40_PHY_CHAN; @@ -648,7 +643,7 @@ static void __iomem *chan_base(struct d40_chan *chan) dev_err(dev, "[%s] " format, __func__, ## arg) #define chan_err(d40c, format, arg...) \ - d40_err(chan2dev(d40c), format, ## arg) + d40_err(dmaengine_chan_dev(&d40c->chan), format, ## arg) static int d40_set_runtime_config_write(struct dma_chan *chan, struct dma_slave_config *config, @@ -1243,7 +1238,7 @@ static void __d40_config_set_event(struct d40_chan *d40c, } if (tries != 99) - dev_dbg(chan2dev(d40c), + dev_dbg(dmaengine_chan_dev(&d40c->chan), "[%s] workaround enable S%cLNK (%d tries)\n", __func__, reg == D40_CHAN_REG_SSLNK ? 'S' : 'D', 100 - tries); @@ -1924,7 +1919,7 @@ found_phy: i = d40c->dma_cfg.phy_channel; if ((i != phy_num) && (i != phy_num + 1)) { - dev_err(chan2dev(d40c), + dev_err(dmaengine_chan_dev(&d40c->chan), "invalid fixed phy channel %d\n", i); return -EINVAL; } @@ -1933,7 +1928,7 @@ found_phy: is_log, first_phy_user)) goto found_log; - dev_err(chan2dev(d40c), + dev_err(dmaengine_chan_dev(&d40c->chan), "could not allocate fixed phy channel %d\n", i); return -EINVAL; } @@ -2446,7 +2441,7 @@ static int d40_alloc_chan_resources(struct dma_chan *chan) d40c->dst_def_cfg |= BIT(D40_SREG_CFG_LOG_GIM_POS); } - dev_dbg(chan2dev(d40c), "allocated %s channel (phy %d%s)\n", + dev_dbg(dmaengine_chan_dev(&d40c->chan), "allocated %s channel (phy %d%s)\n", chan_is_logical(d40c) ? "logical" : "physical", d40c->phy_chan->num, d40c->dma_cfg.use_fixed_channel ? ", fixed" : ""); diff --git a/drivers/dma/stm32/stm32-dma.c b/drivers/dma/stm32/stm32-dma.c index d3ad78562a14..4688cebaf7f7 100644 --- a/drivers/dma/stm32/stm32-dma.c +++ b/drivers/dma/stm32/stm32-dma.c @@ -248,11 +248,6 @@ static struct stm32_dma_desc *to_stm32_dma_desc(struct virt_dma_desc *vdesc) return container_of(vdesc, struct stm32_dma_desc, vdesc); } -static struct device *chan2dev(struct stm32_dma_chan *chan) -{ - return &chan->vchan.chan.dev->device; -} - static u32 stm32_dma_read(struct stm32_dma_device *dmadev, u32 reg) { return readl_relaxed(dmadev->base + reg); @@ -274,7 +269,7 @@ static int stm32_dma_get_width(struct stm32_dma_chan *chan, case DMA_SLAVE_BUSWIDTH_4_BYTES: return STM32_DMA_WORD; default: - dev_err(chan2dev(chan), "Dma bus width not supported\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Dma bus width not supported\n"); return -EINVAL; } } @@ -374,7 +369,7 @@ static int stm32_dma_get_burst(struct stm32_dma_chan *chan, u32 maxburst) case 16: return STM32_DMA_BURST_INCR16; default: - dev_err(chan2dev(chan), "Dma burst size not supported\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Dma burst size not supported\n"); return -EINVAL; } } @@ -487,7 +482,7 @@ static void stm32_dma_stop(struct stm32_dma_chan *chan) /* Clear interrupt status if it is there */ status = stm32_dma_irq_status(chan); if (status) { - dev_dbg(chan2dev(chan), "%s(): clearing interrupt: 0x%08x\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "%s(): clearing interrupt: 0x%08x\n", __func__, status); stm32_dma_irq_clear(chan, status); } @@ -536,12 +531,12 @@ static void stm32_dma_dump_reg(struct stm32_dma_chan *chan) u32 sm1ar = stm32_dma_read(dmadev, STM32_DMA_SM1AR(chan->id)); u32 sfcr = stm32_dma_read(dmadev, STM32_DMA_SFCR(chan->id)); - dev_dbg(chan2dev(chan), "SCR: 0x%08x\n", scr); - dev_dbg(chan2dev(chan), "NDTR: 0x%08x\n", ndtr); - dev_dbg(chan2dev(chan), "SPAR: 0x%08x\n", spar); - dev_dbg(chan2dev(chan), "SM0AR: 0x%08x\n", sm0ar); - dev_dbg(chan2dev(chan), "SM1AR: 0x%08x\n", sm1ar); - dev_dbg(chan2dev(chan), "SFCR: 0x%08x\n", sfcr); + dev_dbg(vchan_chan_dev(&chan->vchan), "SCR: 0x%08x\n", scr); + dev_dbg(vchan_chan_dev(&chan->vchan), "NDTR: 0x%08x\n", ndtr); + dev_dbg(vchan_chan_dev(&chan->vchan), "SPAR: 0x%08x\n", spar); + dev_dbg(vchan_chan_dev(&chan->vchan), "SM0AR: 0x%08x\n", sm0ar); + dev_dbg(vchan_chan_dev(&chan->vchan), "SM1AR: 0x%08x\n", sm1ar); + dev_dbg(vchan_chan_dev(&chan->vchan), "SFCR: 0x%08x\n", sfcr); } static void stm32_dma_sg_inc(struct stm32_dma_chan *chan) @@ -613,7 +608,7 @@ static void stm32_dma_start_transfer(struct stm32_dma_chan *chan) reg->dma_scr |= STM32_DMA_SCR_EN; stm32_dma_write(dmadev, STM32_DMA_SCR(chan->id), reg->dma_scr); - dev_dbg(chan2dev(chan), "vchan %p: started\n", &chan->vchan); + dev_dbg(vchan_chan_dev(&chan->vchan), "vchan %p: started\n", &chan->vchan); } static void stm32_dma_configure_next_sg(struct stm32_dma_chan *chan) @@ -630,12 +625,12 @@ static void stm32_dma_configure_next_sg(struct stm32_dma_chan *chan) if (dma_scr & STM32_DMA_SCR_CT) { dma_sm0ar = sg_req->chan_reg.dma_sm0ar; stm32_dma_write(dmadev, STM32_DMA_SM0AR(id), dma_sm0ar); - dev_dbg(chan2dev(chan), "CT=1 <=> SM0AR: 0x%08x\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "CT=1 <=> SM0AR: 0x%08x\n", stm32_dma_read(dmadev, STM32_DMA_SM0AR(id))); } else { dma_sm1ar = sg_req->chan_reg.dma_sm1ar; stm32_dma_write(dmadev, STM32_DMA_SM1AR(id), dma_sm1ar); - dev_dbg(chan2dev(chan), "CT=0 <=> SM1AR: 0x%08x\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "CT=0 <=> SM1AR: 0x%08x\n", stm32_dma_read(dmadev, STM32_DMA_SM1AR(id))); } } @@ -676,7 +671,7 @@ static void stm32_dma_handle_chan_paused(struct stm32_dma_chan *chan) chan->status = DMA_PAUSED; - dev_dbg(chan2dev(chan), "vchan %p: paused\n", &chan->vchan); + dev_dbg(vchan_chan_dev(&chan->vchan), "vchan %p: paused\n", &chan->vchan); } static void stm32_dma_post_resume_reconfigure(struct stm32_dma_chan *chan) @@ -728,7 +723,7 @@ static void stm32_dma_post_resume_reconfigure(struct stm32_dma_chan *chan) dma_scr |= STM32_DMA_SCR_EN; stm32_dma_write(dmadev, STM32_DMA_SCR(chan->id), dma_scr); - dev_dbg(chan2dev(chan), "vchan %p: reconfigured after pause/resume\n", &chan->vchan); + dev_dbg(vchan_chan_dev(&chan->vchan), "vchan %p: reconfigured after pause/resume\n", &chan->vchan); } static void stm32_dma_handle_chan_done(struct stm32_dma_chan *chan, u32 scr) @@ -775,16 +770,16 @@ static irqreturn_t stm32_dma_chan_irq(int irq, void *devid) if (sfcr & STM32_DMA_SFCR_FEIE) { if (!(scr & STM32_DMA_SCR_EN) && !(status & STM32_DMA_TCI)) - dev_err(chan2dev(chan), "FIFO Error\n"); + dev_err(vchan_chan_dev(&chan->vchan), "FIFO Error\n"); else - dev_dbg(chan2dev(chan), "FIFO over/underrun\n"); + dev_dbg(vchan_chan_dev(&chan->vchan), "FIFO over/underrun\n"); } } if (status & STM32_DMA_DMEI) { stm32_dma_irq_clear(chan, STM32_DMA_DMEI); status &= ~STM32_DMA_DMEI; if (sfcr & STM32_DMA_SCR_DMEIE) - dev_dbg(chan2dev(chan), "Direct mode overrun\n"); + dev_dbg(vchan_chan_dev(&chan->vchan), "Direct mode overrun\n"); } if (status & STM32_DMA_TCI) { @@ -803,9 +798,9 @@ static irqreturn_t stm32_dma_chan_irq(int irq, void *devid) if (status) { stm32_dma_irq_clear(chan, status); - dev_err(chan2dev(chan), "DMA error: status=0x%08x\n", status); + dev_err(vchan_chan_dev(&chan->vchan), "DMA error: status=0x%08x\n", status); if (!(scr & STM32_DMA_SCR_EN)) - dev_err(chan2dev(chan), "chan disabled by HW\n"); + dev_err(vchan_chan_dev(&chan->vchan), "chan disabled by HW\n"); } spin_unlock(&chan->vchan.lock); @@ -820,7 +815,7 @@ static void stm32_dma_issue_pending(struct dma_chan *c) spin_lock_irqsave(&chan->vchan.lock, flags); if (vchan_issue_pending(&chan->vchan) && !chan->desc && !chan->busy) { - dev_dbg(chan2dev(chan), "vchan %p: issued\n", &chan->vchan); + dev_dbg(vchan_chan_dev(&chan->vchan), "vchan %p: issued\n", &chan->vchan); stm32_dma_start_transfer(chan); } @@ -922,7 +917,7 @@ static int stm32_dma_resume(struct dma_chan *c) spin_unlock_irqrestore(&chan->vchan.lock, flags); - dev_dbg(chan2dev(chan), "vchan %p: resumed\n", &chan->vchan); + dev_dbg(vchan_chan_dev(&chan->vchan), "vchan %p: resumed\n", &chan->vchan); return 0; } @@ -1059,7 +1054,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan, break; default: - dev_err(chan2dev(chan), "Dma direction is not supported\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Dma direction is not supported\n"); return -EINVAL; } @@ -1092,12 +1087,12 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_slave_sg( int i, ret; if (!chan->config_init) { - dev_err(chan2dev(chan), "dma channel is not configured\n"); + dev_err(vchan_chan_dev(&chan->vchan), "dma channel is not configured\n"); return NULL; } if (sg_len < 1) { - dev_err(chan2dev(chan), "Invalid segment length %d\n", sg_len); + dev_err(vchan_chan_dev(&chan->vchan), "Invalid segment length %d\n", sg_len); return NULL; } @@ -1129,7 +1124,7 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_slave_sg( nb_data_items = desc->sg_req[i].len / buswidth; if (nb_data_items > STM32_DMA_ALIGNED_MAX_DATA_ITEMS) { - dev_err(chan2dev(chan), "nb items not supported\n"); + dev_err(vchan_chan_dev(&chan->vchan), "nb items not supported\n"); goto err; } @@ -1164,17 +1159,17 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_cyclic( int i, ret; if (!buf_len || !period_len) { - dev_err(chan2dev(chan), "Invalid buffer/period len\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Invalid buffer/period len\n"); return NULL; } if (!chan->config_init) { - dev_err(chan2dev(chan), "dma channel is not configured\n"); + dev_err(vchan_chan_dev(&chan->vchan), "dma channel is not configured\n"); return NULL; } if (buf_len % period_len) { - dev_err(chan2dev(chan), "buf_len not multiple of period_len\n"); + dev_err(vchan_chan_dev(&chan->vchan), "buf_len not multiple of period_len\n"); return NULL; } @@ -1185,7 +1180,7 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_cyclic( * terminating the DMA. */ if (chan->busy) { - dev_err(chan2dev(chan), "Request not allowed when dma busy\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Request not allowed when dma busy\n"); return NULL; } @@ -1196,7 +1191,7 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_cyclic( nb_data_items = period_len / buswidth; if (nb_data_items > STM32_DMA_ALIGNED_MAX_DATA_ITEMS) { - dev_err(chan2dev(chan), "number of items not supported\n"); + dev_err(vchan_chan_dev(&chan->vchan), "number of items not supported\n"); return NULL; } @@ -1478,7 +1473,7 @@ static void stm32_dma_free_chan_resources(struct dma_chan *c) struct stm32_dma_device *dmadev = stm32_dma_get_dev(chan); unsigned long flags; - dev_dbg(chan2dev(chan), "Freeing channel %d\n", chan->id); + dev_dbg(vchan_chan_dev(&chan->vchan), "Freeing channel %d\n", chan->id); if (chan->busy) { spin_lock_irqsave(&chan->vchan.lock, flags); @@ -1668,7 +1663,7 @@ static int stm32_dma_probe(struct platform_device *pdev) ret = devm_request_irq(&pdev->dev, chan->irq, stm32_dma_chan_irq, 0, - dev_name(chan2dev(chan)), chan); + vchan_chan_name(&chan->vchan), chan); if (ret) { dev_err(&pdev->dev, "request_irq failed with err %d channel %d\n", diff --git a/drivers/dma/stm32/stm32-dma3.c b/drivers/dma/stm32/stm32-dma3.c index 4724e7fa0008..4fe226541efa 100644 --- a/drivers/dma/stm32/stm32-dma3.c +++ b/drivers/dma/stm32/stm32-dma3.c @@ -328,11 +328,6 @@ static inline struct stm32_dma3_swdesc *to_stm32_dma3_swdesc(struct virt_dma_des return container_of(vdesc, struct stm32_dma3_swdesc, vdesc); } -static struct device *chan2dev(struct stm32_dma3_chan *chan) -{ - return &chan->vchan.chan.dev->device; -} - static struct device *ddata2dev(struct stm32_dma3_ddata *ddata) { return ddata->dma_dev.dev; @@ -341,7 +336,7 @@ static struct device *ddata2dev(struct stm32_dma3_ddata *ddata) static void stm32_dma3_chan_dump_reg(struct stm32_dma3_chan *chan) { struct stm32_dma3_ddata *ddata = to_stm32_dma3_ddata(chan); - struct device *dev = chan2dev(chan); + struct device *dev = vchan_chan_dev(&chan->vchan); u32 id = chan->id, offset; offset = STM32_DMA3_SECCFGR; @@ -381,21 +376,21 @@ static void stm32_dma3_chan_dump_hwdesc(struct stm32_dma3_chan *chan, for (i = 0; i < swdesc->lli_size; i++) { hwdesc = swdesc->lli[i].hwdesc; if (i) - dev_dbg(chan2dev(chan), "V\n"); - dev_dbg(chan2dev(chan), "[%d]@%pad\n", i, &swdesc->lli[i].hwdesc_addr); - dev_dbg(chan2dev(chan), "| C%dTR1: %08x\n", chan->id, hwdesc->ctr1); - dev_dbg(chan2dev(chan), "| C%dTR2: %08x\n", chan->id, hwdesc->ctr2); - dev_dbg(chan2dev(chan), "| C%dBR1: %08x\n", chan->id, hwdesc->cbr1); - dev_dbg(chan2dev(chan), "| C%dSAR: %08x\n", chan->id, hwdesc->csar); - dev_dbg(chan2dev(chan), "| C%dDAR: %08x\n", chan->id, hwdesc->cdar); - dev_dbg(chan2dev(chan), "| C%dLLR: %08x\n", chan->id, hwdesc->cllr); + dev_dbg(vchan_chan_dev(&chan->vchan), "V\n"); + dev_dbg(vchan_chan_dev(&chan->vchan), "[%d]@%pad\n", i, &swdesc->lli[i].hwdesc_addr); + dev_dbg(vchan_chan_dev(&chan->vchan), "| C%dTR1: %08x\n", chan->id, hwdesc->ctr1); + dev_dbg(vchan_chan_dev(&chan->vchan), "| C%dTR2: %08x\n", chan->id, hwdesc->ctr2); + dev_dbg(vchan_chan_dev(&chan->vchan), "| C%dBR1: %08x\n", chan->id, hwdesc->cbr1); + dev_dbg(vchan_chan_dev(&chan->vchan), "| C%dSAR: %08x\n", chan->id, hwdesc->csar); + dev_dbg(vchan_chan_dev(&chan->vchan), "| C%dDAR: %08x\n", chan->id, hwdesc->cdar); + dev_dbg(vchan_chan_dev(&chan->vchan), "| C%dLLR: %08x\n", chan->id, hwdesc->cllr); } if (swdesc->cyclic) { - dev_dbg(chan2dev(chan), "|\n"); - dev_dbg(chan2dev(chan), "-->[0]@%pad\n", &swdesc->lli[0].hwdesc_addr); + dev_dbg(vchan_chan_dev(&chan->vchan), "|\n"); + dev_dbg(vchan_chan_dev(&chan->vchan), "-->[0]@%pad\n", &swdesc->lli[0].hwdesc_addr); } else { - dev_dbg(chan2dev(chan), "X\n"); + dev_dbg(vchan_chan_dev(&chan->vchan), "X\n"); } } @@ -411,7 +406,7 @@ static struct stm32_dma3_swdesc *stm32_dma3_chan_desc_alloc(struct stm32_dma3_ch * addressed, so abort the allocation. */ if ((count * 32) > CLLR_LA) { - dev_err(chan2dev(chan), "Transfer is too big (> %luB)\n", STM32_DMA3_MAX_SEG_SIZE); + dev_err(vchan_chan_dev(&chan->vchan), "Transfer is too big (> %luB)\n", STM32_DMA3_MAX_SEG_SIZE); return NULL; } @@ -438,7 +433,7 @@ static struct stm32_dma3_swdesc *stm32_dma3_chan_desc_alloc(struct stm32_dma3_ch return swdesc; err_pool_free: - dev_err(chan2dev(chan), "Failed to alloc descriptors\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Failed to alloc descriptors\n"); while (--i >= 0) dma_pool_free(chan->lli_pool, swdesc->lli[i].hwdesc, swdesc->lli[i].hwdesc_addr); kfree(swdesc); @@ -468,7 +463,7 @@ static void stm32_dma3_chan_vdesc_free(struct virt_dma_desc *vdesc) static void stm32_dma3_check_user_setting(struct stm32_dma3_chan *chan) { struct stm32_dma3_ddata *ddata = to_stm32_dma3_ddata(chan); - struct device *dev = chan2dev(chan); + struct device *dev = vchan_chan_dev(&chan->vchan); u32 ctr1 = readl_relaxed(ddata->base + STM32_DMA3_CTR1(chan->id)); u32 cbr1 = readl_relaxed(ddata->base + STM32_DMA3_CBR1(chan->id)); u32 csar = readl_relaxed(ddata->base + STM32_DMA3_CSAR(chan->id)); @@ -579,7 +574,7 @@ static int stm32_dma3_chan_prep_hw(struct stm32_dma3_chan *chan, enum dma_transf u32 sap = FIELD_GET(STM32_DMA3_DT_SAP, tr_conf), sap_max_dw; u32 dap = FIELD_GET(STM32_DMA3_DT_DAP, tr_conf), dap_max_dw; - dev_dbg(chan2dev(chan), "%s from %pad to %pad\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "%s from %pad to %pad\n", dmaengine_get_direction_text(dir), &src_addr, &dst_addr); sdw = chan->dma_config.src_addr_width ? : get_chan_max_dw(sap, chan->max_burst); @@ -589,12 +584,12 @@ static int stm32_dma3_chan_prep_hw(struct stm32_dma3_chan *chan, enum dma_transf /* Following conditions would raise User Setting Error interrupt */ if (!(dma_device.src_addr_widths & BIT(sdw)) || !(dma_device.dst_addr_widths & BIT(ddw))) { - dev_err(chan2dev(chan), "Bus width (src=%u, dst=%u) not supported\n", sdw, ddw); + dev_err(vchan_chan_dev(&chan->vchan), "Bus width (src=%u, dst=%u) not supported\n", sdw, ddw); return -EINVAL; } if (ddata->ports_max_dw[1] == DW_INVALID && (sap || dap)) { - dev_err(chan2dev(chan), "Only one master port, port 1 is not supported\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Only one master port, port 1 is not supported\n"); return -EINVAL; } @@ -602,7 +597,7 @@ static int stm32_dma3_chan_prep_hw(struct stm32_dma3_chan *chan, enum dma_transf dap_max_dw = ddata->ports_max_dw[dap]; if ((port_is_ahb(sap_max_dw) && sdw == DMA_SLAVE_BUSWIDTH_8_BYTES) || (port_is_ahb(dap_max_dw) && ddw == DMA_SLAVE_BUSWIDTH_8_BYTES)) { - dev_err(chan2dev(chan), + dev_err(vchan_chan_dev(&chan->vchan), "8 bytes buswidth (src=%u, dst=%u) not supported on port (sap=%u, dap=%u\n", sdw, ddw, sap, dap); return -EINVAL; @@ -659,7 +654,7 @@ static int stm32_dma3_chan_prep_hw(struct stm32_dma3_chan *chan, enum dma_transf _ctr1 |= FIELD_PREP(CTR1_PAM, CTR1_PAM_PACK_UNPACK); /* Should never reach this case as ddw is clamped down */ if (len & (ddw - 1)) { - dev_err(chan2dev(chan), + dev_err(vchan_chan_dev(&chan->vchan), "Packing mode is enabled and len is not multiple of ddw"); return -EINVAL; } @@ -695,7 +690,7 @@ static int stm32_dma3_chan_prep_hw(struct stm32_dma3_chan *chan, enum dma_transf _ctr1 |= FIELD_PREP(CTR1_PAM, CTR1_PAM_PACK_UNPACK); /* Should never reach this case as ddw is clamped down */ if (len & (ddw - 1)) { - dev_err(chan2dev(chan), + dev_err(vchan_chan_dev(&chan->vchan), "Packing mode is enabled and len is not multiple of ddw\n"); return -EINVAL; } @@ -740,7 +735,7 @@ static int stm32_dma3_chan_prep_hw(struct stm32_dma3_chan *chan, enum dma_transf _ctr1 |= FIELD_PREP(CTR1_PAM, CTR1_PAM_PACK_UNPACK); /* Should never reach this case as ddw is clamped down */ if (len & (ddw - 1)) { - dev_err(chan2dev(chan), + dev_err(vchan_chan_dev(&chan->vchan), "Packing mode is enabled and len is not multiple of ddw"); return -EINVAL; } @@ -752,7 +747,7 @@ static int stm32_dma3_chan_prep_hw(struct stm32_dma3_chan *chan, enum dma_transf break; default: - dev_err(chan2dev(chan), "Direction %s not supported\n", + dev_err(vchan_chan_dev(&chan->vchan), "Direction %s not supported\n", dmaengine_get_direction_text(dir)); return -EINVAL; } @@ -761,7 +756,7 @@ static int stm32_dma3_chan_prep_hw(struct stm32_dma3_chan *chan, enum dma_transf *ctr1 = _ctr1; *ctr2 = _ctr2; - dev_dbg(chan2dev(chan), "%s: sdw=%u bytes sbl=%u beats ddw=%u bytes dbl=%u beats\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "%s: sdw=%u bytes sbl=%u beats ddw=%u bytes dbl=%u beats\n", __func__, sdw, sbl_max, ddw, dbl_max); return 0; @@ -807,7 +802,7 @@ static void stm32_dma3_chan_start(struct stm32_dma3_chan *chan) chan->dma_status = DMA_IN_PROGRESS; - dev_dbg(chan2dev(chan), "vchan %p: started\n", &chan->vchan); + dev_dbg(vchan_chan_dev(&chan->vchan), "vchan %p: started\n", &chan->vchan); } static int stm32_dma3_chan_suspend(struct stm32_dma3_chan *chan, bool susp) @@ -871,7 +866,7 @@ static void stm32_dma3_chan_set_residue(struct stm32_dma3_chan *chan, struct dma_tx_state *txstate) { struct stm32_dma3_ddata *ddata = to_stm32_dma3_ddata(chan); - struct device *dev = chan2dev(chan); + struct device *dev = vchan_chan_dev(&chan->vchan); struct stm32_dma3_hwdesc *hwdesc; u32 residue, curr_lli, csr, cdar, cbr1, cllr, bndt, fifol; bool pack_unpack; @@ -921,7 +916,7 @@ static void stm32_dma3_chan_set_residue(struct stm32_dma3_chan *chan, /* Get current hwdesc and cumulate residue of pending hwdesc BNDT */ ret = stm32_dma3_chan_get_curr_hwdesc(swdesc, cllr, &residue); if (ret < 0) { - dev_err(chan2dev(chan), "Can't get residue: current hwdesc not found\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Can't get residue: current hwdesc not found\n"); return; } curr_lli = ret; @@ -957,7 +952,7 @@ static void stm32_dma3_chan_set_residue(struct stm32_dma3_chan *chan, skip_fifol_update: if (fifol) { - dev_dbg(chan2dev(chan), "%u byte(s) in the FIFO\n", fifol); + dev_dbg(vchan_chan_dev(&chan->vchan), "%u byte(s) in the FIFO\n", fifol); dma_set_in_flight_bytes(txstate, fifol); /* * Residue is already accurate for DMA_MEM_TO_DEV as BNDT reflects data read from @@ -987,7 +982,7 @@ static int stm32_dma3_chan_stop(struct stm32_dma3_chan *chan) /* Suspend the channel */ ret = stm32_dma3_chan_suspend(chan, true); if (ret) - dev_warn(chan2dev(chan), "%s: timeout, data might be lost\n", __func__); + dev_warn(vchan_chan_dev(&chan->vchan), "%s: timeout, data might be lost\n", __func__); } /* @@ -1034,7 +1029,7 @@ static irqreturn_t stm32_dma3_chan_irq(int irq, void *devid) } if (csr & CSR_USEF && ccr & CCR_USEIE) { - dev_err(chan2dev(chan), "User setting error\n"); + dev_err(vchan_chan_dev(&chan->vchan), "User setting error\n"); chan->dma_status = DMA_ERROR; /* CCR.EN automatically cleared by HW */ stm32_dma3_check_user_setting(chan); @@ -1042,14 +1037,14 @@ static irqreturn_t stm32_dma3_chan_irq(int irq, void *devid) } if (csr & CSR_ULEF && ccr & CCR_ULEIE) { - dev_err(chan2dev(chan), "Update link transfer error\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Update link transfer error\n"); chan->dma_status = DMA_ERROR; /* CCR.EN automatically cleared by HW */ stm32_dma3_chan_reset(chan); } if (csr & CSR_DTEF && ccr & CCR_DTEIE) { - dev_err(chan2dev(chan), "Data transfer error\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Data transfer error\n"); chan->dma_status = DMA_ERROR; /* CCR.EN automatically cleared by HW */ stm32_dma3_chan_reset(chan); @@ -1087,13 +1082,13 @@ static int stm32_dma3_get_chan_sem(struct stm32_dma3_chan *chan) goto bad_cid; chan->semaphore_taken = true; - dev_dbg(chan2dev(chan), "under CID1 control (semcr=0x%08x)\n", csemcr); + dev_dbg(vchan_chan_dev(&chan->vchan), "under CID1 control (semcr=0x%08x)\n", csemcr); return 0; bad_cid: chan->semaphore_taken = false; - dev_err(chan2dev(chan), "not under CID1 control (in-use by CID%d)\n", ccid); + dev_err(vchan_chan_dev(&chan->vchan), "not under CID1 control (in-use by CID%d)\n", ccid); return -EACCES; } @@ -1105,7 +1100,7 @@ static void stm32_dma3_put_chan_sem(struct stm32_dma3_chan *chan) if (chan->semaphore_taken) { writel_relaxed(0, ddata->base + STM32_DMA3_CSEMCR(chan->id)); chan->semaphore_taken = false; - dev_dbg(chan2dev(chan), "no more under CID1 control\n"); + dev_dbg(vchan_chan_dev(&chan->vchan), "no more under CID1 control\n"); } } @@ -1126,11 +1121,11 @@ static int stm32_dma3_alloc_chan_resources(struct dma_chan *c) goto err_put_sync; } - chan->lli_pool = dmam_pool_create(dev_name(&c->dev->device), c->device->dev, + chan->lli_pool = dmam_pool_create(dma_chan_name(c), c->device->dev, sizeof(struct stm32_dma3_hwdesc), __alignof__(struct stm32_dma3_hwdesc), SZ_64K); if (!chan->lli_pool) { - dev_err(chan2dev(chan), "Failed to create LLI pool\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Failed to create LLI pool\n"); ret = -ENOMEM; goto err_put_sync; } @@ -1366,7 +1361,7 @@ static struct dma_async_tx_descriptor *stm32_dma3_prep_slave_sg(struct dma_chan } if (count != sg_len && chan->tcem != CTR2_TCEM_CHANNEL) - dev_warn(chan2dev(chan), "Linked-list refactored, %d items instead of %d\n", + dev_warn(vchan_chan_dev(&chan->vchan), "Linked-list refactored, %d items instead of %d\n", count, sg_len); /* Enable Error interrupts */ @@ -1401,12 +1396,12 @@ static struct dma_async_tx_descriptor *stm32_dma3_prep_dma_cyclic(struct dma_cha return NULL; if (!buf_len || !period_len || period_len > STM32_DMA3_MAX_BLOCK_SIZE) { - dev_err(chan2dev(chan), "Invalid buffer/period length\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Invalid buffer/period length\n"); return NULL; } if (buf_len % period_len) { - dev_err(chan2dev(chan), "Buffer length not multiple of period length\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Buffer length not multiple of period length\n"); return NULL; } @@ -1428,7 +1423,7 @@ static struct dma_async_tx_descriptor *stm32_dma3_prep_dma_cyclic(struct dma_cha ret = stm32_dma3_chan_prep_hw(chan, DMA_DEV_TO_MEM, &swdesc->ccr, &ctr1, &ctr2, src, dst, period_len); } else { - dev_err(chan2dev(chan), "Invalid direction\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Invalid direction\n"); ret = -EINVAL; } @@ -1502,7 +1497,7 @@ static int stm32_dma3_pause(struct dma_chan *c) chan->dma_status = DMA_PAUSED; - dev_dbg(chan2dev(chan), "vchan %p: paused\n", &chan->vchan); + dev_dbg(vchan_chan_dev(&chan->vchan), "vchan %p: paused\n", &chan->vchan); return 0; } @@ -1515,7 +1510,7 @@ static int stm32_dma3_resume(struct dma_chan *c) chan->dma_status = DMA_IN_PROGRESS; - dev_dbg(chan2dev(chan), "vchan %p: resumed\n", &chan->vchan); + dev_dbg(vchan_chan_dev(&chan->vchan), "vchan %p: resumed\n", &chan->vchan); return 0; } @@ -1540,7 +1535,7 @@ static int stm32_dma3_terminate_all(struct dma_chan *c) spin_unlock_irqrestore(&chan->vchan.lock, flags); vchan_dma_desc_free_list(&chan->vchan, &head); - dev_dbg(chan2dev(chan), "vchan %p: terminated\n", &chan->vchan); + dev_dbg(vchan_chan_dev(&chan->vchan), "vchan %p: terminated\n", &chan->vchan); return 0; } @@ -1593,7 +1588,7 @@ static void stm32_dma3_issue_pending(struct dma_chan *c) spin_lock_irqsave(&chan->vchan.lock, flags); if (vchan_issue_pending(&chan->vchan) && !chan->swdesc) { - dev_dbg(chan2dev(chan), "vchan %p: issued\n", &chan->vchan); + dev_dbg(vchan_chan_dev(&chan->vchan), "vchan %p: issued\n", &chan->vchan); stm32_dma3_chan_start(chan); } @@ -1892,10 +1887,10 @@ static int stm32_dma3_probe(struct platform_device *pdev) chan->irq = ret; ret = devm_request_irq(&pdev->dev, chan->irq, stm32_dma3_chan_irq, 0, - dev_name(chan2dev(chan)), chan); + vchan_chan_name(&chan->vchan), chan); if (ret) { dev_err_probe(&pdev->dev, ret, "Failed to request channel %s IRQ\n", - dev_name(chan2dev(chan))); + vchan_chan_name(&chan->vchan)); goto err_clk_disable; } } diff --git a/drivers/dma/stm32/stm32-mdma.c b/drivers/dma/stm32/stm32-mdma.c index e3bbdc9ee36e..04639e4b554e 100644 --- a/drivers/dma/stm32/stm32-mdma.c +++ b/drivers/dma/stm32/stm32-mdma.c @@ -276,11 +276,6 @@ static struct stm32_mdma_desc *to_stm32_mdma_desc(struct virt_dma_desc *vdesc) return container_of(vdesc, struct stm32_mdma_desc, vdesc); } -static struct device *chan2dev(struct stm32_mdma_chan *chan) -{ - return &chan->vchan.chan.dev->device; -} - static struct device *mdma2dev(struct stm32_mdma_device *mdma_dev) { return mdma_dev->ddev.dev; @@ -334,7 +329,7 @@ static struct stm32_mdma_desc *stm32_mdma_alloc_desc( return desc; err: - dev_err(chan2dev(chan), "Failed to allocate descriptor\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Failed to allocate descriptor\n"); while (--i >= 0) dma_pool_free(chan->desc_pool, desc->node[i].hwdesc, desc->node[i].hwdesc_phys); @@ -364,7 +359,7 @@ static int stm32_mdma_get_width(struct stm32_mdma_chan *chan, case DMA_SLAVE_BUSWIDTH_8_BYTES: return ffs(width) - 1; default: - dev_err(chan2dev(chan), "Dma bus width %i not supported\n", + dev_err(vchan_chan_dev(&chan->vchan), "Dma bus width %i not supported\n", width); return -EINVAL; } @@ -422,7 +417,7 @@ static int stm32_mdma_disable_chan(struct stm32_mdma_chan *chan) dmadev->base + STM32_MDMA_CISR(id), cisr, (cisr & STM32_MDMA_CISR_CTCIF), 10, 1000); if (ret) { - dev_err(chan2dev(chan), "%s: timeout!\n", __func__); + dev_err(vchan_chan_dev(&chan->vchan), "%s: timeout!\n", __func__); return -EBUSY; } } @@ -444,7 +439,7 @@ static void stm32_mdma_stop(struct stm32_mdma_chan *chan) /* Clear interrupt status if it is there */ status = stm32_mdma_read(dmadev, STM32_MDMA_CISR(chan->id)); if (status) { - dev_dbg(chan2dev(chan), "%s(): clearing interrupt: 0x%08x\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "%s(): clearing interrupt: 0x%08x\n", __func__, status); stm32_mdma_set_bits(dmadev, STM32_MDMA_CIFCR(chan->id), status); } @@ -513,7 +508,7 @@ static int stm32_mdma_set_xfer_param(struct stm32_mdma_chan *chan, /* Check burst size constraints */ if (src_maxburst * src_addr_width > STM32_MDMA_MAX_BURST || dst_maxburst * dst_addr_width > STM32_MDMA_MAX_BURST) { - dev_err(chan2dev(chan), + dev_err(vchan_chan_dev(&chan->vchan), "burst size * bus width higher than %d bytes\n", STM32_MDMA_MAX_BURST); return -EINVAL; @@ -521,7 +516,7 @@ static int stm32_mdma_set_xfer_param(struct stm32_mdma_chan *chan, if ((!is_power_of_2(src_maxburst) && src_maxburst > 0) || (!is_power_of_2(dst_maxburst) && dst_maxburst > 0)) { - dev_err(chan2dev(chan), "burst size must be a power of 2\n"); + dev_err(vchan_chan_dev(&chan->vchan), "burst size must be a power of 2\n"); return -EINVAL; } @@ -658,7 +653,7 @@ static int stm32_mdma_set_xfer_param(struct stm32_mdma_chan *chan, break; default: - dev_err(chan2dev(chan), "Dma direction is not supported\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Dma direction is not supported\n"); return -EINVAL; } @@ -672,16 +667,16 @@ static int stm32_mdma_set_xfer_param(struct stm32_mdma_chan *chan, static void stm32_mdma_dump_hwdesc(struct stm32_mdma_chan *chan, struct stm32_mdma_desc_node *node) { - dev_dbg(chan2dev(chan), "hwdesc: %pad\n", &node->hwdesc_phys); - dev_dbg(chan2dev(chan), "CTCR: 0x%08x\n", node->hwdesc->ctcr); - dev_dbg(chan2dev(chan), "CBNDTR: 0x%08x\n", node->hwdesc->cbndtr); - dev_dbg(chan2dev(chan), "CSAR: 0x%08x\n", node->hwdesc->csar); - dev_dbg(chan2dev(chan), "CDAR: 0x%08x\n", node->hwdesc->cdar); - dev_dbg(chan2dev(chan), "CBRUR: 0x%08x\n", node->hwdesc->cbrur); - dev_dbg(chan2dev(chan), "CLAR: 0x%08x\n", node->hwdesc->clar); - dev_dbg(chan2dev(chan), "CTBR: 0x%08x\n", node->hwdesc->ctbr); - dev_dbg(chan2dev(chan), "CMAR: 0x%08x\n", node->hwdesc->cmar); - dev_dbg(chan2dev(chan), "CMDR: 0x%08x\n\n", node->hwdesc->cmdr); + dev_dbg(vchan_chan_dev(&chan->vchan), "hwdesc: %pad\n", &node->hwdesc_phys); + dev_dbg(vchan_chan_dev(&chan->vchan), "CTCR: 0x%08x\n", node->hwdesc->ctcr); + dev_dbg(vchan_chan_dev(&chan->vchan), "CBNDTR: 0x%08x\n", node->hwdesc->cbndtr); + dev_dbg(vchan_chan_dev(&chan->vchan), "CSAR: 0x%08x\n", node->hwdesc->csar); + dev_dbg(vchan_chan_dev(&chan->vchan), "CDAR: 0x%08x\n", node->hwdesc->cdar); + dev_dbg(vchan_chan_dev(&chan->vchan), "CBRUR: 0x%08x\n", node->hwdesc->cbrur); + dev_dbg(vchan_chan_dev(&chan->vchan), "CLAR: 0x%08x\n", node->hwdesc->clar); + dev_dbg(vchan_chan_dev(&chan->vchan), "CTBR: 0x%08x\n", node->hwdesc->ctbr); + dev_dbg(vchan_chan_dev(&chan->vchan), "CMAR: 0x%08x\n", node->hwdesc->cmar); + dev_dbg(vchan_chan_dev(&chan->vchan), "CMDR: 0x%08x\n\n", node->hwdesc->cmdr); } static void stm32_mdma_setup_hwdesc(struct stm32_mdma_chan *chan, @@ -739,7 +734,7 @@ static int stm32_mdma_setup_xfer(struct stm32_mdma_chan *chan, for_each_sg(sgl, sg, sg_len, i) { if (sg_dma_len(sg) > STM32_MDMA_MAX_BLOCK_LEN) { - dev_err(chan2dev(chan), "Invalid block len\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Invalid block len\n"); return -EINVAL; } @@ -797,7 +792,7 @@ stm32_mdma_prep_slave_sg(struct dma_chan *c, struct scatterlist *sgl, * for allowing another request. */ if (chan->desc && chan->desc->cyclic) { - dev_err(chan2dev(chan), + dev_err(vchan_chan_dev(&chan->vchan), "Request not allowed when dma in cyclic mode\n"); return NULL; } @@ -858,18 +853,18 @@ stm32_mdma_prep_dma_cyclic(struct dma_chan *c, dma_addr_t buf_addr, * for allowing another request. */ if (chan->desc && chan->desc->cyclic) { - dev_err(chan2dev(chan), + dev_err(vchan_chan_dev(&chan->vchan), "Request not allowed when dma in cyclic mode\n"); return NULL; } if (!buf_len || !period_len || period_len > STM32_MDMA_MAX_BLOCK_LEN) { - dev_err(chan2dev(chan), "Invalid buffer/period len\n"); + dev_err(vchan_chan_dev(&chan->vchan), "Invalid buffer/period len\n"); return NULL; } if (buf_len % period_len) { - dev_err(chan2dev(chan), "buf_len not multiple of period_len\n"); + dev_err(vchan_chan_dev(&chan->vchan), "buf_len not multiple of period_len\n"); return NULL; } @@ -954,7 +949,7 @@ stm32_mdma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dest, dma_addr_t src, * to allow another request */ if (chan->desc && chan->desc->cyclic) { - dev_err(chan2dev(chan), + dev_err(vchan_chan_dev(&chan->vchan), "Request not allowed when dma in cyclic mode\n"); return NULL; } @@ -1116,25 +1111,25 @@ static void stm32_mdma_dump_reg(struct stm32_mdma_chan *chan) { struct stm32_mdma_device *dmadev = stm32_mdma_get_dev(chan); - dev_dbg(chan2dev(chan), "CCR: 0x%08x\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "CCR: 0x%08x\n", stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id))); - dev_dbg(chan2dev(chan), "CTCR: 0x%08x\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "CTCR: 0x%08x\n", stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id))); - dev_dbg(chan2dev(chan), "CBNDTR: 0x%08x\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "CBNDTR: 0x%08x\n", stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id))); - dev_dbg(chan2dev(chan), "CSAR: 0x%08x\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "CSAR: 0x%08x\n", stm32_mdma_read(dmadev, STM32_MDMA_CSAR(chan->id))); - dev_dbg(chan2dev(chan), "CDAR: 0x%08x\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "CDAR: 0x%08x\n", stm32_mdma_read(dmadev, STM32_MDMA_CDAR(chan->id))); - dev_dbg(chan2dev(chan), "CBRUR: 0x%08x\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "CBRUR: 0x%08x\n", stm32_mdma_read(dmadev, STM32_MDMA_CBRUR(chan->id))); - dev_dbg(chan2dev(chan), "CLAR: 0x%08x\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "CLAR: 0x%08x\n", stm32_mdma_read(dmadev, STM32_MDMA_CLAR(chan->id))); - dev_dbg(chan2dev(chan), "CTBR: 0x%08x\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "CTBR: 0x%08x\n", stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id))); - dev_dbg(chan2dev(chan), "CMAR: 0x%08x\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "CMAR: 0x%08x\n", stm32_mdma_read(dmadev, STM32_MDMA_CMAR(chan->id))); - dev_dbg(chan2dev(chan), "CMDR: 0x%08x\n", + dev_dbg(vchan_chan_dev(&chan->vchan), "CMDR: 0x%08x\n", stm32_mdma_read(dmadev, STM32_MDMA_CMDR(chan->id))); } @@ -1187,7 +1182,7 @@ static void stm32_mdma_start_transfer(struct stm32_mdma_chan *chan) chan->busy = true; - dev_dbg(chan2dev(chan), "vchan %p: started\n", &chan->vchan); + dev_dbg(vchan_chan_dev(&chan->vchan), "vchan %p: started\n", &chan->vchan); } static void stm32_mdma_issue_pending(struct dma_chan *c) @@ -1200,7 +1195,7 @@ static void stm32_mdma_issue_pending(struct dma_chan *c) if (!vchan_issue_pending(&chan->vchan)) goto end; - dev_dbg(chan2dev(chan), "vchan %p: issued\n", &chan->vchan); + dev_dbg(vchan_chan_dev(&chan->vchan), "vchan %p: issued\n", &chan->vchan); if (!chan->desc && !chan->busy) stm32_mdma_start_transfer(chan); @@ -1220,7 +1215,7 @@ static int stm32_mdma_pause(struct dma_chan *c) spin_unlock_irqrestore(&chan->vchan.lock, flags); if (!ret) - dev_dbg(chan2dev(chan), "vchan %p: pause\n", &chan->vchan); + dev_dbg(vchan_chan_dev(&chan->vchan), "vchan %p: pause\n", &chan->vchan); return ret; } @@ -1261,7 +1256,7 @@ static int stm32_mdma_resume(struct dma_chan *c) spin_unlock_irqrestore(&chan->vchan.lock, flags); - dev_dbg(chan2dev(chan), "vchan %p: resume\n", &chan->vchan); + dev_dbg(vchan_chan_dev(&chan->vchan), "vchan %p: resume\n", &chan->vchan); return 0; } @@ -1422,10 +1417,10 @@ static irqreturn_t stm32_mdma_irq_handler(int irq, void *devid) if (!(status & ien)) { spin_unlock(&chan->vchan.lock); if (chan->busy) - dev_warn(chan2dev(chan), + dev_warn(vchan_chan_dev(&chan->vchan), "spurious it (status=0x%04x, ien=0x%04x)\n", status, ien); else - dev_dbg(chan2dev(chan), + dev_dbg(vchan_chan_dev(&chan->vchan), "spurious it (status=0x%04x, ien=0x%04x)\n", status, ien); return IRQ_NONE; } @@ -1433,7 +1428,7 @@ static irqreturn_t stm32_mdma_irq_handler(int irq, void *devid) reg = STM32_MDMA_CIFCR(id); if (status & STM32_MDMA_CISR_TEIF) { - dev_err(chan2dev(chan), "Transfer Err: stat=0x%08x\n", + dev_err(vchan_chan_dev(&chan->vchan), "Transfer Err: stat=0x%08x\n", readl_relaxed(dmadev->base + STM32_MDMA_CESR(id))); stm32_mdma_set_bits(dmadev, reg, STM32_MDMA_CIFCR_CTEIF); status &= ~STM32_MDMA_CISR_TEIF; @@ -1468,9 +1463,9 @@ static irqreturn_t stm32_mdma_irq_handler(int irq, void *devid) if (status) { stm32_mdma_set_bits(dmadev, reg, status); - dev_err(chan2dev(chan), "DMA error: status=0x%08x\n", status); + dev_err(vchan_chan_dev(&chan->vchan), "DMA error: status=0x%08x\n", status); if (!(ccr & STM32_MDMA_CCR_EN)) - dev_err(chan2dev(chan), "chan disabled by HW\n"); + dev_err(vchan_chan_dev(&chan->vchan), "chan disabled by HW\n"); } spin_unlock(&chan->vchan.lock); @@ -1484,13 +1479,12 @@ static int stm32_mdma_alloc_chan_resources(struct dma_chan *c) struct stm32_mdma_device *dmadev = stm32_mdma_get_dev(chan); int ret; - chan->desc_pool = dmam_pool_create(dev_name(&c->dev->device), - c->device->dev, + chan->desc_pool = dmam_pool_create(dma_chan_name(c), c->device->dev, sizeof(struct stm32_mdma_hwdesc), __alignof__(struct stm32_mdma_hwdesc), 0); if (!chan->desc_pool) { - dev_err(chan2dev(chan), "failed to allocate descriptor pool\n"); + dev_err(vchan_chan_dev(&chan->vchan), "failed to allocate descriptor pool\n"); return -ENOMEM; } @@ -1511,7 +1505,7 @@ static void stm32_mdma_free_chan_resources(struct dma_chan *c) struct stm32_mdma_device *dmadev = stm32_mdma_get_dev(chan); unsigned long flags; - dev_dbg(chan2dev(chan), "Freeing channel %d\n", chan->id); + dev_dbg(vchan_chan_dev(&chan->vchan), "Freeing channel %d\n", chan->id); if (chan->busy) { spin_lock_irqsave(&chan->vchan.lock, flags); diff --git a/drivers/dma/sun4i-dma.c b/drivers/dma/sun4i-dma.c index d2321f7287d2..225e4a53502b 100644 --- a/drivers/dma/sun4i-dma.c +++ b/drivers/dma/sun4i-dma.c @@ -246,11 +246,6 @@ static struct sun4i_dma_contract *to_sun4i_dma_contract(struct virt_dma_desc *vd return container_of(vd, struct sun4i_dma_contract, vd); } -static struct device *chan2dev(struct dma_chan *chan) -{ - return &chan->dev->device; -} - static void set_dst_data_width_a10(u32 *p_cfg, s8 data_width) { *p_cfg |= SUN4I_DMA_CFG_DST_DATA_WIDTH(data_width); @@ -428,7 +423,7 @@ static int __execute_vchan_pending(struct sun4i_dma_dev *priv, * has already submitted some work, we can't do anything else */ if (vchan->processing) { - dev_dbg(chan2dev(&vchan->vc.chan), + dev_dbg(vchan_chan_dev(&vchan->vc), "processing something to this endpoint already\n"); ret = -EBUSY; goto release_pchan; @@ -438,7 +433,7 @@ static int __execute_vchan_pending(struct sun4i_dma_dev *priv, /* Figure out which contract we're working with today */ vd = vchan_next_desc(&vchan->vc); if (!vd) { - dev_dbg(chan2dev(&vchan->vc.chan), + dev_dbg(vchan_chan_dev(&vchan->vc), "No pending contract found"); ret = 0; goto release_pchan; @@ -449,7 +444,7 @@ static int __execute_vchan_pending(struct sun4i_dma_dev *priv, /* The contract has been completed so mark it as such */ list_del(&contract->vd.node); vchan_cookie_complete(&contract->vd); - dev_dbg(chan2dev(&vchan->vc.chan), + dev_dbg(vchan_chan_dev(&vchan->vc), "Empty contract found and marked complete"); } } while (list_empty(&contract->demands)); @@ -542,7 +537,7 @@ generate_ndma_promise(struct dma_chan *chan, dma_addr_t src, dma_addr_t dest, promise->cfg = SUN4I_DMA_CFG_LOADING | SUN4I_NDMA_CFG_BYTE_COUNT_MODE_REMAIN; - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "src burst %d, dst burst %d, src buswidth %d, dst buswidth %d", sconfig->src_maxburst, sconfig->dst_maxburst, sconfig->src_addr_width, sconfig->dst_addr_width); @@ -769,7 +764,7 @@ sun4i_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf, size_t len, u8 ram_type, io_mode, linear_mode; if (!is_slave_direction(dir)) { - dev_err(chan2dev(chan), "Invalid DMA direction\n"); + dev_err(dmaengine_chan_dev(chan), "Invalid DMA direction\n"); return NULL; } @@ -894,7 +889,7 @@ sun4i_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return NULL; if (!is_slave_direction(dir)) { - dev_err(chan2dev(chan), "Invalid DMA direction\n"); + dev_err(dmaengine_chan_dev(chan), "Invalid DMA direction\n"); return NULL; } diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c index 7704b016aed8..d4966b66b753 100644 --- a/drivers/dma/sun6i-dma.c +++ b/drivers/dma/sun6i-dma.c @@ -213,11 +213,6 @@ struct sun6i_dma_dev { u32 max_request; }; -static struct device *chan2dev(struct dma_chan *chan) -{ - return &chan->dev->device; -} - static inline struct sun6i_dma_dev *to_sun6i_dma_dev(struct dma_device *d) { return container_of(d, struct sun6i_dma_dev, slave); @@ -399,7 +394,7 @@ static inline void sun6i_dma_dump_lli(struct sun6i_vchan *vchan, struct sun6i_dma_lli *v_lli, dma_addr_t p_lli) { - dev_dbg(chan2dev(&vchan->vc.chan), + dev_dbg(vchan_chan_dev(&vchan->vc), "\n\tdesc:\tp - %pad v - 0x%p\n" "\t\tc - 0x%08x s - 0x%08x d - 0x%08x\n" "\t\tl - 0x%08x p - 0x%08x n - 0x%08x\n", @@ -408,16 +403,12 @@ static inline void sun6i_dma_dump_lli(struct sun6i_vchan *vchan, v_lli->len, v_lli->para, v_lli->p_lli_next); } -static void sun6i_dma_free_desc(struct virt_dma_desc *vd) +static void sun6i_dma_free_desc(struct sun6i_dma_dev *sdev, + struct sun6i_desc *txd) { - struct sun6i_desc *txd = to_sun6i_desc(&vd->tx); - struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(vd->tx.chan->device); struct sun6i_dma_lli *v_lli, *v_next; dma_addr_t p_lli, p_next; - if (unlikely(!txd)) - return; - p_lli = txd->p_lli; v_lli = txd->v_lli; @@ -434,6 +425,17 @@ static void sun6i_dma_free_desc(struct virt_dma_desc *vd) kfree(txd); } +static void sun6i_dma_free_desc_virt(struct virt_dma_desc *vd) +{ + struct sun6i_desc *txd = to_sun6i_desc(&vd->tx); + struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(vd->tx.chan->device); + + if (unlikely(!txd)) + return; + + sun6i_dma_free_desc(sdev, txd); +} + static int sun6i_dma_start_desc(struct sun6i_vchan *vchan) { struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(vchan->vc.chan.device); @@ -673,7 +675,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy( dma_addr_t p_lli; s8 burst, width; - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s; chan: %d, dest: %pad, src: %pad, len: %zu. flags: 0x%08lx\n", __func__, vchan->vc.chan.chan_id, &dest, &src, len, flags); @@ -734,7 +736,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( ret = set_config(sdev, sconfig, dir, &lli_cfg); if (ret) { - dev_err(chan2dev(chan), "Invalid DMA configuration\n"); + dev_err(dmaengine_chan_dev(chan), "Invalid DMA configuration\n"); return NULL; } @@ -758,7 +760,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE); - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%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), @@ -772,7 +774,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE); - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%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, @@ -782,7 +784,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( prev = sun6i_dma_lli_add(prev, v_lli, p_lli, txd); } - dev_dbg(chan2dev(chan), "First: %pad\n", &txd->p_lli); + dev_dbg(dmaengine_chan_dev(chan), "First: %pad\n", &txd->p_lli); for (p_lli = txd->p_lli, v_lli = txd->v_lli; v_lli; p_lli = v_lli->p_lli_next, v_lli = v_lli->v_lli_next) sun6i_dma_dump_lli(vchan, v_lli, p_lli); @@ -790,10 +792,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( return vchan_tx_prep(&vchan->vc, &txd->vd, flags); err_lli_free: - for (p_lli = txd->p_lli, v_lli = txd->v_lli; v_lli; - p_lli = v_lli->p_lli_next, v_lli = v_lli->v_lli_next) - dma_pool_free(sdev->pool, v_lli, p_lli); - kfree(txd); + sun6i_dma_free_desc(sdev, txd); return NULL; } @@ -817,7 +816,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic( ret = set_config(sdev, sconfig, dir, &lli_cfg); if (ret) { - dev_err(chan2dev(chan), "Invalid DMA configuration\n"); + dev_err(dmaengine_chan_dev(chan), "Invalid DMA configuration\n"); return NULL; } @@ -842,7 +841,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic( v_lli->cfg = lli_cfg; sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE); - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s; chan: %d, dest: %pad, src: %pad, len: %zu. flags: 0x%08lx\n", __func__, vchan->vc.chan.chan_id, &sconfig->dst_addr, &buf_addr, @@ -854,7 +853,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic( v_lli->cfg = lli_cfg; sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE); - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "%s; chan: %d, dest: %pad, src: %pad, len: %zu. flags: 0x%08lx\n", __func__, vchan->vc.chan.chan_id, &buf_addr, &sconfig->src_addr, @@ -871,10 +870,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic( return vchan_tx_prep(&vchan->vc, &txd->vd, flags); err_lli_free: - for (p_lli = txd->p_lli, v_lli = txd->v_lli; v_lli; - p_lli = v_lli->p_lli_next, v_lli = v_lli->v_lli_next) - dma_pool_free(sdev->pool, v_lli, p_lli); - kfree(txd); + sun6i_dma_free_desc(sdev, txd); return NULL; } @@ -894,7 +890,7 @@ static int sun6i_dma_pause(struct dma_chan *chan) struct sun6i_vchan *vchan = to_sun6i_vchan(chan); struct sun6i_pchan *pchan = vchan->phy; - dev_dbg(chan2dev(chan), "vchan %p: pause\n", &vchan->vc); + dev_dbg(dmaengine_chan_dev(chan), "vchan %p: pause\n", &vchan->vc); if (pchan) { writel(DMA_CHAN_PAUSE_PAUSE, @@ -915,7 +911,7 @@ static int sun6i_dma_resume(struct dma_chan *chan) struct sun6i_pchan *pchan = vchan->phy; unsigned long flags; - dev_dbg(chan2dev(chan), "vchan %p: resume\n", &vchan->vc); + dev_dbg(dmaengine_chan_dev(chan), "vchan %p: resume\n", &vchan->vc); spin_lock_irqsave(&vchan->vc.lock, flags); @@ -1024,13 +1020,13 @@ static void sun6i_dma_issue_pending(struct dma_chan *chan) if (!vchan->phy && list_empty(&vchan->node)) { list_add_tail(&vchan->node, &sdev->pending); tasklet_schedule(&sdev->task); - dev_dbg(chan2dev(chan), "vchan %p: issued\n", + dev_dbg(dmaengine_chan_dev(chan), "vchan %p: issued\n", &vchan->vc); } spin_unlock(&sdev->lock); } else { - dev_dbg(chan2dev(chan), "vchan %p: nothing to issue\n", + dev_dbg(dmaengine_chan_dev(chan), "vchan %p: nothing to issue\n", &vchan->vc); } @@ -1429,7 +1425,7 @@ static int sun6i_dma_probe(struct platform_device *pdev) struct sun6i_vchan *vchan = &sdc->vchans[i]; INIT_LIST_HEAD(&vchan->node); - vchan->vc.desc_free = sun6i_dma_free_desc; + vchan->vc.desc_free = sun6i_dma_free_desc_virt; vchan_init(&vchan->vc, &sdc->slave); } diff --git a/drivers/dma/switchtec_dma.c b/drivers/dma/switchtec_dma.c index c8e2169877e9..df58ca760176 100644 --- a/drivers/dma/switchtec_dma.c +++ b/drivers/dma/switchtec_dma.c @@ -406,7 +406,7 @@ static int disable_channel(struct switchtec_dma_chan *swdma_chan) static void switchtec_dma_cleanup_completed(struct switchtec_dma_chan *swdma_chan) { - struct device *chan_dev = &swdma_chan->dma_chan.dev->device; + struct device *chan_dev = dmaengine_chan_dev(&swdma_chan->dma_chan); struct switchtec_dma_desc *desc; struct switchtec_dma_hw_ce *ce; struct dmaengine_result res; @@ -851,7 +851,7 @@ static irqreturn_t switchtec_dma_chan_status_isr(int irq, void *dma) list_for_each_entry(chan, &dma_dev->channels, device_node) { swdma_chan = container_of(chan, struct switchtec_dma_chan, dma_chan); - chan_dev = &swdma_chan->dma_chan.dev->device; + chan_dev = dmaengine_chan_dev(&swdma_chan->dma_chan); chan_hw = swdma_chan->mmio_chan_hw; rcu_read_lock(); @@ -1009,19 +1009,19 @@ static int switchtec_dma_alloc_chan_resources(struct dma_chan *chan) perf_cfg = readl(&swdma_chan->mmio_chan_fw->perf_cfg); rcu_read_unlock(); - dev_dbg(&chan->dev->device, "Burst Size: 0x%x\n", + dev_dbg(dmaengine_chan_dev(chan), "Burst Size: 0x%x\n", FIELD_GET(PERF_BURST_SIZE_MASK, perf_cfg)); - dev_dbg(&chan->dev->device, "Burst Scale: 0x%x\n", + dev_dbg(dmaengine_chan_dev(chan), "Burst Scale: 0x%x\n", FIELD_GET(PERF_BURST_SCALE_MASK, perf_cfg)); - dev_dbg(&chan->dev->device, "Interval: 0x%x\n", + dev_dbg(dmaengine_chan_dev(chan), "Interval: 0x%x\n", FIELD_GET(PERF_INTERVAL_MASK, perf_cfg)); - dev_dbg(&chan->dev->device, "Arb Weight: 0x%x\n", + dev_dbg(dmaengine_chan_dev(chan), "Arb Weight: 0x%x\n", FIELD_GET(PERF_ARB_WEIGHT_MASK, perf_cfg)); - dev_dbg(&chan->dev->device, "MRRS: 0x%x\n", + dev_dbg(dmaengine_chan_dev(chan), "MRRS: 0x%x\n", FIELD_GET(PERF_MRRS_MASK, perf_cfg)); return SWITCHTEC_DMA_SQ_SIZE; diff --git a/drivers/dma/tegra186-gpc-dma.c b/drivers/dma/tegra186-gpc-dma.c index 64cedef1050a..e76c58f213d8 100644 --- a/drivers/dma/tegra186-gpc-dma.c +++ b/drivers/dma/tegra186-gpc-dma.c @@ -1537,7 +1537,7 @@ static int tegra_dma_probe(struct platform_device *pdev) * the channels available and registered for the DMA device are used. */ list_for_each_entry(chan, &tdma->dma_dev.channels, device_node) { - chdev = &chan->dev->device; + chdev = dmaengine_chan_dev(chan); tdc = to_tegra_dma_chan(chan); if (use_iommu_map) { @@ -1554,7 +1554,7 @@ static int tegra_dma_probe(struct platform_device *pdev) return dev_err_probe(chdev, -EINVAL, "Failed to get stream ID for channel %d\n", tdc->id); - chan->dev->chan_dma_dev = true; + chan->chan_dev->chan_dma_dev = true; } /* program stream-id for this channel */ diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 640b8a218c9a..7ff8c0241f61 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -256,7 +256,7 @@ txd_to_tegra_dma_desc(struct dma_async_tx_descriptor *td) static inline struct device *tdc2dev(struct tegra_dma_channel *tdc) { - return &tdc->dma_chan.dev->device; + return dmaengine_chan_dev(&tdc->dma_chan); } static dma_cookie_t tegra_dma_tx_submit(struct dma_async_tx_descriptor *tx); diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index fb21e0df5ab7..78a67cb9d6e0 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -422,16 +422,16 @@ static int navss_psil_unpair(struct udma_dev *ud, u32 src_thread, static void k3_configure_chan_coherency(struct dma_chan *chan, u32 asel) { - struct device *chan_dev = &chan->dev->device; + struct device *chan_dev = dmaengine_chan_dev(chan); if (asel == 0) { /* No special handling for the channel */ - chan->dev->chan_dma_dev = false; + chan->chan_dev->chan_dma_dev = false; dev_clear_dma_coherent(chan_dev); chan_dev->dma_parms = NULL; } else if (asel == 14 || asel == 15) { - chan->dev->chan_dma_dev = true; + chan->chan_dev->chan_dma_dev = true; dev_set_dma_coherent(chan_dev); dma_coerce_mask_and_coherent(chan_dev, DMA_BIT_MASK(48)); diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 4fc5119854ec..0acd7a36a3d0 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -90,14 +90,9 @@ struct timb_dma { struct tasklet_struct tasklet; struct timb_dma_chan channels[]; }; - -static struct device *chan2dev(struct dma_chan *chan) -{ - return &chan->dev->device; -} static struct device *chan2dmadev(struct dma_chan *chan) { - return chan2dev(chan)->parent->parent; + return dmaengine_chan_dev(chan)->parent->parent; } static struct timb_dma *tdchantotd(struct timb_dma_chan *td_chan) @@ -117,7 +112,7 @@ static void __td_enable_chan_irq(struct timb_dma_chan *td_chan) /* enable interrupt for this channel */ ier = ioread32(td->membase + TIMBDMA_IER); ier |= 1 << id; - dev_dbg(chan2dev(&td_chan->chan), "Enabling irq: %d, IER: 0x%x\n", id, + dev_dbg(dmaengine_chan_dev(&td_chan->chan), "Enabling irq: %d, IER: 0x%x\n", id, ier); iowrite32(ier, td->membase + TIMBDMA_IER); } @@ -131,7 +126,7 @@ static bool __td_dma_done_ack(struct timb_dma_chan *td_chan) u32 isr; bool done = false; - dev_dbg(chan2dev(&td_chan->chan), "Checking irq: %d, td: %p\n", id, td); + dev_dbg(dmaengine_chan_dev(&td_chan->chan), "Checking irq: %d, td: %p\n", id, td); isr = ioread32(td->membase + TIMBDMA_ISR) & (1 << id); if (isr) { @@ -146,18 +141,18 @@ static int td_fill_desc(struct timb_dma_chan *td_chan, u8 *dma_desc, struct scatterlist *sg, bool last) { if (sg_dma_len(sg) > USHRT_MAX) { - dev_err(chan2dev(&td_chan->chan), "Too big sg element\n"); + dev_err(dmaengine_chan_dev(&td_chan->chan), "Too big sg element\n"); return -EINVAL; } /* length must be word aligned */ if (sg_dma_len(sg) % sizeof(u32)) { - dev_err(chan2dev(&td_chan->chan), "Incorrect length: %d\n", + dev_err(dmaengine_chan_dev(&td_chan->chan), "Incorrect length: %d\n", sg_dma_len(sg)); return -EINVAL; } - dev_dbg(chan2dev(&td_chan->chan), "desc: %p, addr: 0x%llx\n", + dev_dbg(dmaengine_chan_dev(&td_chan->chan), "desc: %p, addr: 0x%llx\n", dma_desc, (unsigned long long)sg_dma_address(sg)); dma_desc[7] = (sg_dma_address(sg) >> 24) & 0xff; @@ -180,7 +175,7 @@ static void __td_start_dma(struct timb_dma_chan *td_chan) struct timb_dma_desc *td_desc; if (td_chan->ongoing) { - dev_err(chan2dev(&td_chan->chan), + dev_err(dmaengine_chan_dev(&td_chan->chan), "Transfer already ongoing\n"); return; } @@ -188,7 +183,7 @@ static void __td_start_dma(struct timb_dma_chan *td_chan) td_desc = list_entry(td_chan->active_list.next, struct timb_dma_desc, desc_node); - dev_dbg(chan2dev(&td_chan->chan), + dev_dbg(dmaengine_chan_dev(&td_chan->chan), "td_chan: %p, chan: %d, membase: %p\n", td_chan, td_chan->chan.chan_id, td_chan->membase); @@ -230,7 +225,7 @@ static void __td_finish(struct timb_dma_chan *td_chan) desc_node); txd = &td_desc->txd; - dev_dbg(chan2dev(&td_chan->chan), "descriptor %u complete\n", + dev_dbg(dmaengine_chan_dev(&td_chan->chan), "descriptor %u complete\n", txd->cookie); /* make sure to stop the transfer */ @@ -284,7 +279,7 @@ static void __td_start_next(struct timb_dma_chan *td_chan) td_desc = list_entry(td_chan->queue.next, struct timb_dma_desc, desc_node); - dev_dbg(chan2dev(&td_chan->chan), "%s: started %u\n", + dev_dbg(dmaengine_chan_dev(&td_chan->chan), "%s: started %u\n", __func__, td_desc->txd.cookie); list_move(&td_desc->desc_node, &td_chan->active_list); @@ -303,12 +298,12 @@ static dma_cookie_t td_tx_submit(struct dma_async_tx_descriptor *txd) cookie = dma_cookie_assign(txd); if (list_empty(&td_chan->active_list)) { - dev_dbg(chan2dev(txd->chan), "%s: started %u\n", __func__, + dev_dbg(dmaengine_chan_dev(txd->chan), "%s: started %u\n", __func__, txd->cookie); list_add_tail(&td_desc->desc_node, &td_chan->active_list); __td_start_dma(td_chan); } else { - dev_dbg(chan2dev(txd->chan), "tx_submit: queued %u\n", + dev_dbg(dmaengine_chan_dev(txd->chan), "tx_submit: queued %u\n", txd->cookie); list_add_tail(&td_desc->desc_node, &td_chan->queue); @@ -344,7 +339,7 @@ static struct timb_dma_desc *td_alloc_init_desc(struct timb_dma_chan *td_chan) err = dma_mapping_error(chan2dmadev(chan), td_desc->txd.phys); if (err) { - dev_err(chan2dev(chan), "DMA mapping error: %d\n", err); + dev_err(dmaengine_chan_dev(chan), "DMA mapping error: %d\n", err); goto err; } @@ -359,7 +354,7 @@ out: static void td_free_desc(struct timb_dma_desc *td_desc) { - dev_dbg(chan2dev(td_desc->txd.chan), "Freeing desc: %p\n", td_desc); + dev_dbg(dmaengine_chan_dev(td_desc->txd.chan), "Freeing desc: %p\n", td_desc); dma_unmap_single(chan2dmadev(td_desc->txd.chan), td_desc->txd.phys, td_desc->desc_list_len, DMA_TO_DEVICE); @@ -370,7 +365,7 @@ static void td_free_desc(struct timb_dma_desc *td_desc) static void td_desc_put(struct timb_dma_chan *td_chan, struct timb_dma_desc *td_desc) { - dev_dbg(chan2dev(&td_chan->chan), "Putting desc: %p\n", td_desc); + dev_dbg(dmaengine_chan_dev(&td_chan->chan), "Putting desc: %p\n", td_desc); spin_lock_bh(&td_chan->lock); list_add(&td_desc->desc_node, &td_chan->free_list); @@ -390,7 +385,7 @@ static struct timb_dma_desc *td_desc_get(struct timb_dma_chan *td_chan) ret = td_desc; break; } - dev_dbg(chan2dev(&td_chan->chan), "desc %p not ACKed\n", + dev_dbg(dmaengine_chan_dev(&td_chan->chan), "desc %p not ACKed\n", td_desc); } spin_unlock_bh(&td_chan->lock); @@ -404,7 +399,7 @@ static int td_alloc_chan_resources(struct dma_chan *chan) container_of(chan, struct timb_dma_chan, chan); int i; - dev_dbg(chan2dev(chan), "%s: entry\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s: entry\n", __func__); BUG_ON(!list_empty(&td_chan->free_list)); for (i = 0; i < td_chan->descs; i++) { @@ -413,7 +408,7 @@ static int td_alloc_chan_resources(struct dma_chan *chan) if (i) break; else { - dev_err(chan2dev(chan), + dev_err(dmaengine_chan_dev(chan), "Couldn't allocate any descriptors\n"); return -ENOMEM; } @@ -436,7 +431,7 @@ static void td_free_chan_resources(struct dma_chan *chan) struct timb_dma_desc *td_desc, *_td_desc; LIST_HEAD(list); - dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s: Entry\n", __func__); /* check that all descriptors are free */ BUG_ON(!list_empty(&td_chan->active_list)); @@ -447,7 +442,7 @@ static void td_free_chan_resources(struct dma_chan *chan) spin_unlock_bh(&td_chan->lock); list_for_each_entry_safe(td_desc, _td_desc, &list, desc_node) { - dev_dbg(chan2dev(chan), "%s: Freeing desc: %p\n", __func__, + dev_dbg(dmaengine_chan_dev(chan), "%s: Freeing desc: %p\n", __func__, td_desc); td_free_desc(td_desc); } @@ -458,11 +453,11 @@ static enum dma_status td_tx_status(struct dma_chan *chan, dma_cookie_t cookie, { enum dma_status ret; - dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s: Entry\n", __func__); ret = dma_cookie_status(chan, cookie, txstate); - dev_dbg(chan2dev(chan), "%s: exit, ret: %d\n", __func__, ret); + dev_dbg(dmaengine_chan_dev(chan), "%s: exit, ret: %d\n", __func__, ret); return ret; } @@ -472,7 +467,7 @@ static void td_issue_pending(struct dma_chan *chan) struct timb_dma_chan *td_chan = container_of(chan, struct timb_dma_chan, chan); - dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s: Entry\n", __func__); spin_lock_bh(&td_chan->lock); if (!list_empty(&td_chan->active_list)) @@ -499,20 +494,20 @@ static struct dma_async_tx_descriptor *td_prep_slave_sg(struct dma_chan *chan, unsigned int desc_usage = 0; if (!sgl || !sg_len) { - dev_err(chan2dev(chan), "%s: No SG list\n", __func__); + dev_err(dmaengine_chan_dev(chan), "%s: No SG list\n", __func__); return NULL; } /* even channels are for RX, odd for TX */ if (td_chan->direction != direction) { - dev_err(chan2dev(chan), + dev_err(dmaengine_chan_dev(chan), "Requesting channel in wrong direction\n"); return NULL; } td_desc = td_desc_get(td_chan); if (!td_desc) { - dev_err(chan2dev(chan), "Not enough descriptors available\n"); + dev_err(dmaengine_chan_dev(chan), "Not enough descriptors available\n"); return NULL; } @@ -521,14 +516,14 @@ static struct dma_async_tx_descriptor *td_prep_slave_sg(struct dma_chan *chan, for_each_sg(sgl, sg, sg_len, i) { int err; if (desc_usage > td_desc->desc_list_len) { - dev_err(chan2dev(chan), "No descriptor space\n"); + dev_err(dmaengine_chan_dev(chan), "No descriptor space\n"); return NULL; } err = td_fill_desc(td_chan, td_desc->desc_list + desc_usage, sg, i == (sg_len - 1)); if (err) { - dev_err(chan2dev(chan), "Failed to update desc: %d\n", + dev_err(dmaengine_chan_dev(chan), "Failed to update desc: %d\n", err); td_desc_put(td_chan, td_desc); return NULL; @@ -548,7 +543,7 @@ static int td_terminate_all(struct dma_chan *chan) container_of(chan, struct timb_dma_chan, chan); struct timb_dma_desc *td_desc, *_td_desc; - dev_dbg(chan2dev(chan), "%s: Entry\n", __func__); + dev_dbg(dmaengine_chan_dev(chan), "%s: Entry\n", __func__); /* first the easy part, put the queue into the free list */ spin_lock_bh(&td_chan->lock); diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index 05622b68a936..ecfaa6a76516 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -125,14 +125,9 @@ static struct txx9dmac_regs32 __iomem *__txx9dmac_regs32( #define dma_writel(ddev, name, val) \ (__is_dmac64(ddev) ? \ dma64_writel(ddev, name, val) : dma32_writel(ddev, name, val)) - -static struct device *chan2dev(struct dma_chan *chan) -{ - return &chan->dev->device; -} static struct device *chan2parent(struct dma_chan *chan) { - return chan->dev->device.parent; + return dmaengine_chan_dev(chan)->parent; } static struct txx9dmac_desc * @@ -218,12 +213,12 @@ static struct txx9dmac_desc *txx9dmac_desc_get(struct txx9dmac_chan *dc) ret = desc; break; } - dev_dbg(chan2dev(&dc->chan), "desc %p not ACKed\n", desc); + dev_dbg(dmaengine_chan_dev(&dc->chan), "desc %p not ACKed\n", desc); i++; } spin_unlock_bh(&dc->lock); - dev_vdbg(chan2dev(&dc->chan), "scanned %u descriptors on freelist\n", + dev_vdbg(dmaengine_chan_dev(&dc->chan), "scanned %u descriptors on freelist\n", i); if (!ret) { ret = txx9dmac_desc_alloc(dc, GFP_ATOMIC); @@ -232,7 +227,7 @@ static struct txx9dmac_desc *txx9dmac_desc_get(struct txx9dmac_chan *dc) dc->descs_allocated++; spin_unlock_bh(&dc->lock); } else - dev_err(chan2dev(&dc->chan), + dev_err(dmaengine_chan_dev(&dc->chan), "not enough descriptors available\n"); } return ret; @@ -267,11 +262,11 @@ static void txx9dmac_desc_put(struct txx9dmac_chan *dc, spin_lock_bh(&dc->lock); list_for_each_entry(child, &desc->tx_list, desc_node) - dev_vdbg(chan2dev(&dc->chan), + dev_vdbg(dmaengine_chan_dev(&dc->chan), "moving child desc %p to freelist\n", child); list_splice_init(&desc->tx_list, &dc->free_list); - dev_vdbg(chan2dev(&dc->chan), "moving desc %p to freelist\n", + dev_vdbg(dmaengine_chan_dev(&dc->chan), "moving desc %p to freelist\n", desc); list_add(&desc->desc_node, &dc->free_list); spin_unlock_bh(&dc->lock); @@ -283,7 +278,7 @@ static void txx9dmac_desc_put(struct txx9dmac_chan *dc, static void txx9dmac_dump_regs(struct txx9dmac_chan *dc) { if (is_dmac64(dc)) - dev_err(chan2dev(&dc->chan), + dev_err(dmaengine_chan_dev(&dc->chan), " CHAR: %#llx SAR: %#llx DAR: %#llx CNTR: %#x" " SAIR: %#x DAIR: %#x CCR: %#x CSR: %#x\n", (u64)channel64_read_CHAR(dc), @@ -295,7 +290,7 @@ static void txx9dmac_dump_regs(struct txx9dmac_chan *dc) channel64_readl(dc, CCR), channel64_readl(dc, CSR)); else - dev_err(chan2dev(&dc->chan), + dev_err(dmaengine_chan_dev(&dc->chan), " CHAR: %#x SAR: %#x DAR: %#x CNTR: %#x" " SAIR: %#x DAIR: %#x CCR: %#x CSR: %#x\n", channel32_readl(dc, CHAR), @@ -333,11 +328,11 @@ static void txx9dmac_dostart(struct txx9dmac_chan *dc, struct txx9dmac_slave *ds = dc->chan.private; u32 sai, dai; - dev_vdbg(chan2dev(&dc->chan), "dostart %u %p\n", + dev_vdbg(dmaengine_chan_dev(&dc->chan), "dostart %u %p\n", first->txd.cookie, first); /* ASSERT: channel is idle */ if (channel_readl(dc, CSR) & TXX9_DMA_CSR_XFACT) { - dev_err(chan2dev(&dc->chan), + dev_err(dmaengine_chan_dev(&dc->chan), "BUG: Attempted to start non-idle channel\n"); txx9dmac_dump_regs(dc); /* The tasklet will hopefully advance the queue... */ @@ -402,7 +397,7 @@ txx9dmac_descriptor_complete(struct txx9dmac_chan *dc, struct dmaengine_desc_callback cb; struct dma_async_tx_descriptor *txd = &desc->txd; - dev_vdbg(chan2dev(&dc->chan), "descriptor %u %p complete\n", + dev_vdbg(dmaengine_chan_dev(&dc->chan), "descriptor %u %p complete\n", txd->cookie, desc); dma_cookie_complete(txd); @@ -469,11 +464,11 @@ static void txx9dmac_dump_desc(struct txx9dmac_chan *dc, { if (is_dmac64(dc)) { #ifdef TXX9_DMA_USE_SIMPLE_CHAIN - dev_crit(chan2dev(&dc->chan), + dev_crit(dmaengine_chan_dev(&dc->chan), " desc: ch%#llx s%#llx d%#llx c%#x\n", (u64)desc->CHAR, desc->SAR, desc->DAR, desc->CNTR); #else - dev_crit(chan2dev(&dc->chan), + dev_crit(dmaengine_chan_dev(&dc->chan), " desc: ch%#llx s%#llx d%#llx c%#x" " si%#x di%#x cc%#x cs%#x\n", (u64)desc->CHAR, desc->SAR, desc->DAR, desc->CNTR, @@ -482,11 +477,11 @@ static void txx9dmac_dump_desc(struct txx9dmac_chan *dc, } else { struct txx9dmac_hwdesc32 *d = (struct txx9dmac_hwdesc32 *)desc; #ifdef TXX9_DMA_USE_SIMPLE_CHAIN - dev_crit(chan2dev(&dc->chan), + dev_crit(dmaengine_chan_dev(&dc->chan), " desc: ch%#x s%#x d%#x c%#x\n", d->CHAR, d->SAR, d->DAR, d->CNTR); #else - dev_crit(chan2dev(&dc->chan), + dev_crit(dmaengine_chan_dev(&dc->chan), " desc: ch%#x s%#x d%#x c%#x" " si%#x di%#x cc%#x cs%#x\n", d->CHAR, d->SAR, d->DAR, d->CNTR, @@ -506,7 +501,7 @@ static void txx9dmac_handle_error(struct txx9dmac_chan *dc, u32 csr) * borked. Since we don't have any way to report errors, we'll * just have to scream loudly and try to carry on. */ - dev_crit(chan2dev(&dc->chan), "Abnormal Chain Completion\n"); + dev_crit(dmaengine_chan_dev(&dc->chan), "Abnormal Chain Completion\n"); txx9dmac_dump_regs(dc); bad_desc = txx9dmac_first_active(dc); @@ -523,7 +518,7 @@ static void txx9dmac_handle_error(struct txx9dmac_chan *dc, u32 csr) if (!list_empty(&dc->active_list)) txx9dmac_dostart(dc, txx9dmac_first_active(dc)); - dev_crit(chan2dev(&dc->chan), + dev_crit(dmaengine_chan_dev(&dc->chan), "Bad descriptor submitted for DMA! (cookie: %d)\n", bad_desc->txd.cookie); txx9dmac_dump_desc(dc, &bad_desc->hwdesc); @@ -558,7 +553,7 @@ static void txx9dmac_scan_descriptors(struct txx9dmac_chan *dc) if (!(csr & TXX9_DMA_CSR_CHNEN)) chain = 0; /* last descriptor of this chain */ - dev_vdbg(chan2dev(&dc->chan), "scan_descriptors: char=%#llx\n", + dev_vdbg(dmaengine_chan_dev(&dc->chan), "scan_descriptors: char=%#llx\n", (u64)chain); list_for_each_entry_safe(desc, _desc, &dc->active_list, desc_node) { @@ -589,7 +584,7 @@ scan_done: return; } - dev_err(chan2dev(&dc->chan), + dev_err(dmaengine_chan_dev(&dc->chan), "BUG: All descriptors done, but channel not idle!\n"); /* Try to continue after resetting the channel... */ @@ -609,7 +604,7 @@ static void txx9dmac_chan_tasklet(struct tasklet_struct *t) dc = from_tasklet(dc, t, tasklet); csr = channel_readl(dc, CSR); - dev_vdbg(chan2dev(&dc->chan), "tasklet: status=%x\n", csr); + dev_vdbg(dmaengine_chan_dev(&dc->chan), "tasklet: status=%x\n", csr); spin_lock(&dc->lock); if (csr & (TXX9_DMA_CSR_ABCHC | TXX9_DMA_CSR_NCHNC | @@ -625,7 +620,7 @@ static irqreturn_t txx9dmac_chan_interrupt(int irq, void *dev_id) { struct txx9dmac_chan *dc = dev_id; - dev_vdbg(chan2dev(&dc->chan), "interrupt: status=%#x\n", + dev_vdbg(dmaengine_chan_dev(&dc->chan), "interrupt: status=%#x\n", channel_readl(dc, CSR)); tasklet_schedule(&dc->tasklet); @@ -654,7 +649,7 @@ static void txx9dmac_tasklet(struct tasklet_struct *t) if ((mcr >> (24 + i)) & 0x11) { dc = ddev->chan[i]; csr = channel_readl(dc, CSR); - dev_vdbg(chan2dev(&dc->chan), "tasklet: status=%x\n", + dev_vdbg(dmaengine_chan_dev(&dc->chan), "tasklet: status=%x\n", csr); spin_lock(&dc->lock); if (csr & (TXX9_DMA_CSR_ABCHC | TXX9_DMA_CSR_NCHNC | @@ -696,7 +691,7 @@ static dma_cookie_t txx9dmac_tx_submit(struct dma_async_tx_descriptor *tx) spin_lock_bh(&dc->lock); cookie = dma_cookie_assign(tx); - dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u %p\n", + dev_vdbg(dmaengine_chan_dev(tx->chan), "tx_submit: queued %u %p\n", desc->txd.cookie, desc); list_add_tail(&desc->desc_node, &dc->queue); @@ -717,11 +712,11 @@ txx9dmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, size_t xfer_count; size_t offset; - dev_vdbg(chan2dev(chan), "prep_dma_memcpy d%#llx s%#llx l%#zx f%#lx\n", + dev_vdbg(dmaengine_chan_dev(chan), "prep_dma_memcpy d%#llx s%#llx l%#zx f%#lx\n", (u64)dest, (u64)src, len, flags); if (unlikely(!len)) { - dev_dbg(chan2dev(chan), "prep_dma_memcpy: length is zero!\n"); + dev_dbg(dmaengine_chan_dev(chan), "prep_dma_memcpy: length is zero!\n"); return NULL; } @@ -812,7 +807,7 @@ txx9dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, unsigned int i; struct scatterlist *sg; - dev_vdbg(chan2dev(chan), "prep_dma_slave\n"); + dev_vdbg(dmaengine_chan_dev(chan), "prep_dma_slave\n"); BUG_ON(!ds || !ds->reg_width); if (ds->tx_reg) @@ -900,7 +895,7 @@ static int txx9dmac_terminate_all(struct dma_chan *chan) struct txx9dmac_desc *desc, *_desc; LIST_HEAD(list); - dev_vdbg(chan2dev(chan), "terminate_all\n"); + dev_vdbg(dmaengine_chan_dev(chan), "terminate_all\n"); spin_lock_bh(&dc->lock); txx9dmac_reset_chan(dc); @@ -988,11 +983,11 @@ static int txx9dmac_alloc_chan_resources(struct dma_chan *chan) struct txx9dmac_desc *desc; int i; - dev_vdbg(chan2dev(chan), "alloc_chan_resources\n"); + dev_vdbg(dmaengine_chan_dev(chan), "alloc_chan_resources\n"); /* ASSERT: channel is idle */ if (channel_readl(dc, CSR) & TXX9_DMA_CSR_XFACT) { - dev_dbg(chan2dev(chan), "DMA channel not idle?\n"); + dev_dbg(dmaengine_chan_dev(chan), "DMA channel not idle?\n"); return -EIO; } @@ -1022,7 +1017,7 @@ static int txx9dmac_alloc_chan_resources(struct dma_chan *chan) desc = txx9dmac_desc_alloc(dc, GFP_KERNEL); if (!desc) { - dev_info(chan2dev(chan), + dev_info(dmaengine_chan_dev(chan), "only allocated %d descriptors\n", i); spin_lock_bh(&dc->lock); break; @@ -1034,7 +1029,7 @@ static int txx9dmac_alloc_chan_resources(struct dma_chan *chan) } spin_unlock_bh(&dc->lock); - dev_dbg(chan2dev(chan), + dev_dbg(dmaengine_chan_dev(chan), "alloc_chan_resources allocated %d descriptors\n", i); return i; @@ -1047,7 +1042,7 @@ static void txx9dmac_free_chan_resources(struct dma_chan *chan) struct txx9dmac_desc *desc, *_desc; LIST_HEAD(list); - dev_dbg(chan2dev(chan), "free_chan_resources (descs allocated=%u)\n", + dev_dbg(dmaengine_chan_dev(chan), "free_chan_resources (descs allocated=%u)\n", dc->descs_allocated); /* ASSERT: channel is idle */ @@ -1061,13 +1056,13 @@ static void txx9dmac_free_chan_resources(struct dma_chan *chan) spin_unlock_bh(&dc->lock); list_for_each_entry_safe(desc, _desc, &list, desc_node) { - dev_vdbg(chan2dev(chan), " freeing descriptor %p\n", desc); + dev_vdbg(dmaengine_chan_dev(chan), " freeing descriptor %p\n", desc); dma_unmap_single(chan2parent(chan), desc->txd.phys, ddev->descsize, DMA_TO_DEVICE); kfree(desc); } - dev_vdbg(chan2dev(chan), "free_chan_resources done\n"); + dev_vdbg(dmaengine_chan_dev(chan), "free_chan_resources done\n"); } /*----------------------------------------------------------------------*/ @@ -1167,26 +1162,20 @@ static void txx9dmac_chan_remove(struct platform_device *pdev) static int __init txx9dmac_probe(struct platform_device *pdev) { struct txx9dmac_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct resource *io; struct txx9dmac_dev *ddev; + void __iomem *regs; u32 mcr; int err; - io = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!io) - return -EINVAL; + regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(regs)) + return PTR_ERR(regs); ddev = devm_kzalloc(&pdev->dev, sizeof(*ddev), GFP_KERNEL); if (!ddev) return -ENOMEM; - if (!devm_request_mem_region(&pdev->dev, io->start, resource_size(io), - dev_name(&pdev->dev))) - return -EBUSY; - - ddev->regs = devm_ioremap(&pdev->dev, io->start, resource_size(io)); - if (!ddev->regs) - return -ENOMEM; + ddev->regs = regs; ddev->have_64bit_regs = pdata->have_64bit_regs; if (__is_dmac64(ddev)) ddev->descsize = sizeof(struct txx9dmac_hwdesc); diff --git a/drivers/dma/virt-dma.h b/drivers/dma/virt-dma.h index 59d9eabc8b67..abf2ae737c30 100644 --- a/drivers/dma/virt-dma.h +++ b/drivers/dma/virt-dma.h @@ -41,6 +41,11 @@ static inline struct virt_dma_chan *to_virt_chan(struct dma_chan *chan) return container_of(chan, struct virt_dma_chan, chan); } +static inline struct device *vchan_chan_dev(struct virt_dma_chan *vc) +{ + return dmaengine_chan_dev(&vc->chan); +} + void vchan_dma_desc_free_list(struct virt_dma_chan *vc, struct list_head *head); void vchan_init(struct virt_dma_chan *vc, struct dma_device *dmadev); struct virt_dma_desc *vchan_find_desc(struct virt_dma_chan *, dma_cookie_t); @@ -210,6 +215,17 @@ static inline void vchan_free_chan_resources(struct virt_dma_chan *vc) } /** + * vchan_chan_name - Return vchan DMA channel device name + * @vc: virtual channel + * + * Return: The name of the DMA channel device + */ +static inline const char *vchan_chan_name(struct virt_dma_chan *vc) +{ + return dma_chan_name(&vc->chan); +} + +/** * vchan_synchronize() - synchronize callback execution to the current context * @vc: virtual channel to synchronize * diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index cffe7c6fa640..0336941d4095 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -223,6 +223,7 @@ #define XILINX_MCDMA_IRQ_ERR_MASK BIT(7) #define XILINX_MCDMA_BD_EOP BIT(30) #define XILINX_MCDMA_BD_SOP BIT(31) +#define XILINX_MCDMA_BD_HW_SIZE 64 /** * struct xilinx_vdma_desc_hw - Hardware Descriptor @@ -277,8 +278,10 @@ struct xilinx_axidma_desc_hw { * @buf_addr_msb: MSB of Buffer address @0x0C * @rsvd: Reserved field @0x10 * @control: Control Information field @0x14 - * @status: Status field @0x18 - * @sideband_status: Status of sideband signals @0x1C + * @mm2s_ctrl_sideband: Sideband control info for mm2s @0x18 + * @s2mm_status: Status field for s2mm @0x18 + * @mm2s_status: Status field for mm2s @0x1C + * @s2mm_sideband_status: Sideband status for s2mm @0x1C * @app: APP Fields @0x20 - 0x30 */ struct xilinx_aximcdma_desc_hw { @@ -288,10 +291,17 @@ struct xilinx_aximcdma_desc_hw { u32 buf_addr_msb; u32 rsvd; u32 control; - u32 status; - u32 sideband_status; + union { + u32 mm2s_ctrl_sideband; + u32 s2mm_status; + }; + union { + u32 mm2s_status; + u32 s2mm_sideband_status; + }; u32 app[XILINX_DMA_NUM_APP_WORDS]; } __aligned(64); +static_assert(sizeof(struct xilinx_aximcdma_desc_hw) == XILINX_MCDMA_BD_HW_SIZE); /** * struct xilinx_cdma_desc_hw - Hardware Descriptor @@ -641,17 +651,51 @@ static inline void xilinx_aximcdma_buf(struct xilinx_dma_chan *chan, * @tx: async transaction descriptor * @payload_len: metadata payload length * @max_len: metadata max length - * Return: The app field pointer. + * + * The metadata lives in the SOP descriptor for TX and the EOF descriptor for RX. + * Field order depends on dmatype and direction: + * + * AXI DMA: [0..] app + * AXI MCDMA (TX): [0] ctrl_sideband, [1] status, [2..] app + * AXI MCDMA (RX): [0] status, [1] sideband, [2..] app + * + * Return: Pointer to the first metadata word. */ static void *xilinx_dma_get_metadata_ptr(struct dma_async_tx_descriptor *tx, size_t *payload_len, size_t *max_len) { struct xilinx_dma_tx_descriptor *desc = to_dma_tx_descriptor(tx); + struct xilinx_dma_chan *chan = to_xilinx_chan(tx->chan); + + if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIMCDMA) { + struct xilinx_aximcdma_tx_segment *seg; + + if (chan->direction == DMA_DEV_TO_MEM) { + seg = list_last_entry(&desc->segments, + struct xilinx_aximcdma_tx_segment, node); + *max_len = *payload_len = sizeof(seg->hw.s2mm_status) + + sizeof(seg->hw.s2mm_sideband_status) + + sizeof(seg->hw.app); + return &seg->hw.s2mm_status; + } + seg = list_first_entry(&desc->segments, + struct xilinx_aximcdma_tx_segment, node); + *max_len = *payload_len = sizeof(seg->hw.mm2s_ctrl_sideband) + + sizeof(seg->hw.mm2s_status) + + sizeof(seg->hw.app); + return &seg->hw.mm2s_ctrl_sideband; + } + struct xilinx_axidma_tx_segment *seg; - *max_len = *payload_len = sizeof(u32) * XILINX_DMA_NUM_APP_WORDS; - seg = list_first_entry(&desc->segments, - struct xilinx_axidma_tx_segment, node); + if (chan->direction == DMA_DEV_TO_MEM) + seg = list_last_entry(&desc->segments, + struct xilinx_axidma_tx_segment, node); + else + seg = list_first_entry(&desc->segments, + struct xilinx_axidma_tx_segment, node); + + *max_len = *payload_len = sizeof(seg->hw.app); return seg->hw.app; } @@ -1025,9 +1069,11 @@ static u32 xilinx_dma_get_residue(struct xilinx_dma_chan *chan, struct xilinx_aximcdma_tx_segment, node); aximcdma_hw = &aximcdma_seg->hw; - residue += - (aximcdma_hw->control & chan->xdev->max_buffer_len) - - (aximcdma_hw->status & chan->xdev->max_buffer_len); + residue += aximcdma_hw->control & chan->xdev->max_buffer_len; + if (chan->direction == DMA_DEV_TO_MEM) + residue -= aximcdma_hw->s2mm_status & chan->xdev->max_buffer_len; + else + residue -= aximcdma_hw->mm2s_status & chan->xdev->max_buffer_len; } } @@ -1782,6 +1828,17 @@ static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan *chan) struct xilinx_axidma_tx_segment, node); if (!(seg->hw.status & XILINX_DMA_BD_COMP_MASK) && chan->has_sg) break; + } else if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIMCDMA) { + struct xilinx_aximcdma_tx_segment *seg; + u32 status; + + seg = list_last_entry(&desc->segments, + struct xilinx_aximcdma_tx_segment, + node); + status = (chan->direction == DMA_DEV_TO_MEM) ? + seg->hw.s2mm_status : seg->hw.mm2s_status; + if (!(status & XILINX_DMA_BD_COMP_MASK)) + break; } if (chan->has_sg && chan->xdev->dma_config->dmatype != XDMA_TYPE_VDMA) @@ -2626,6 +2683,9 @@ xilinx_mcdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, segment->hw.control |= XILINX_MCDMA_BD_EOP; } + if (chan->xdev->has_axistream_connected) + desc->async_tx.metadata_ops = &xilinx_dma_metadata_ops; + return &desc->async_tx; error: @@ -3274,7 +3334,8 @@ static int xilinx_dma_probe(struct platform_device *pdev) dma_set_max_seg_size(xdev->dev, xdev->max_buffer_len); - if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) { + if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA || + xdev->dma_config->dmatype == XDMA_TYPE_AXIMCDMA) { xdev->has_axistream_connected = of_property_read_bool(node, "xlnx,axistream-connected"); } diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c index 2b03584102ac..3b7dfa53f972 100644 --- a/drivers/dma/xilinx/zynqmp_dma.c +++ b/drivers/dma/xilinx/zynqmp_dma.c @@ -12,6 +12,7 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/of_address.h> #include <linux/of_dma.h> #include <linux/platform_device.h> #include <linux/slab.h> @@ -112,8 +113,7 @@ #define ZYNQMP_DMA_INT_DONE (ZYNQMP_DMA_DONE | ZYNQMP_DMA_DST_DSCR_DONE) #define ZYNQMP_DMA_INT_EN_DEFAULT_MASK (ZYNQMP_DMA_INT_DONE | \ ZYNQMP_DMA_INT_ERR | \ - ZYNQMP_DMA_INT_OVRFL | \ - ZYNQMP_DMA_DST_DSCR_DONE) + ZYNQMP_DMA_INT_OVRFL) /* Max number of descriptors per channel */ #define ZYNQMP_DMA_NUM_DESCS 32 @@ -128,8 +128,6 @@ /* Reset values for data attributes */ #define ZYNQMP_DMA_AXCACHE_VAL 0xF -#define ZYNQMP_DMA_SRC_ISSUE_RST_VAL 0x1F - #define ZYNQMP_DMA_IDS_DEFAULT_MASK 0xFFF /* Bus width in bits */ @@ -205,10 +203,10 @@ struct zynqmp_dma_desc_sw { * @desc_pool_p: Physical allocated descriptor base * @desc_free_cnt: Descriptor available count * @dev: The dma device - * @irq: Channel IRQ + * @irq: Linux IRQ number, or -1 when not registered * @is_dmacoherent: Tells whether dma operations are coherent or not * @tasklet: Cleanup work after irq - * @idle : Channel status; + * @idle: Channel status * @desc_size: Size of the low level descriptor * @err: Channel has errors * @bus_width: Bus width @@ -435,7 +433,7 @@ zynqmp_dma_get_descriptor(struct zynqmp_dma_chan *chan) } /** - * zynqmp_dma_free_descriptor - Issue pending transactions + * zynqmp_dma_free_descriptor - Return a descriptor to the free pool * @chan: ZynqMP DMA channel pointer * @sdesc: Transaction descriptor pointer */ @@ -483,8 +481,10 @@ static int zynqmp_dma_alloc_chan_resources(struct dma_chan *dchan) return ret; chan->sw_desc_pool = kzalloc_objs(*desc, ZYNQMP_DMA_NUM_DESCS); - if (!chan->sw_desc_pool) - return -ENOMEM; + if (!chan->sw_desc_pool) { + ret = -ENOMEM; + goto err_pm; + } chan->idle = true; chan->desc_free_cnt = ZYNQMP_DMA_NUM_DESCS; @@ -502,8 +502,10 @@ static int zynqmp_dma_alloc_chan_resources(struct dma_chan *dchan) (2 * ZYNQMP_DMA_DESC_SIZE(chan) * ZYNQMP_DMA_NUM_DESCS), &chan->desc_pool_p, GFP_KERNEL); - if (!chan->desc_pool_v) - return -ENOMEM; + if (!chan->desc_pool_v) { + ret = -ENOMEM; + goto err_free_sw_desc_pool; + } for (i = 0; i < ZYNQMP_DMA_NUM_DESCS; i++) { desc = chan->sw_desc_pool + i; @@ -516,6 +518,13 @@ static int zynqmp_dma_alloc_chan_resources(struct dma_chan *dchan) } return ZYNQMP_DMA_NUM_DESCS; + +err_free_sw_desc_pool: + kfree(chan->sw_desc_pool); + chan->sw_desc_pool = NULL; +err_pm: + pm_runtime_put_autosuspend(chan->dev); + return ret; } /** @@ -606,7 +615,6 @@ static void zynqmp_dma_start_transfer(struct zynqmp_dma_chan *chan) zynqmp_dma_start(chan); } - /** * zynqmp_dma_chan_desc_cleanup - Cleanup the completed descriptors * @chan: ZynqMP DMA channel @@ -826,7 +834,8 @@ static void zynqmp_dma_synchronize(struct dma_chan *dchan) * @len: Transfer length * @flags: transfer ack flags * - * Return: Async transaction descriptor on success and NULL on failure + * Return: Async transaction descriptor on success and NULL on failure or + * zero length transfer */ static struct dma_async_tx_descriptor *zynqmp_dma_prep_memcpy( struct dma_chan *dchan, dma_addr_t dma_dst, @@ -841,6 +850,9 @@ static struct dma_async_tx_descriptor *zynqmp_dma_prep_memcpy( chan = to_chan(dchan); + if (!len) + return NULL; + desc_cnt = DIV_ROUND_UP(len, ZYNQMP_DMA_MAX_TRANS_LEN); spin_lock_irqsave(&chan->lock, irqflags); @@ -885,10 +897,11 @@ static void zynqmp_dma_chan_remove(struct zynqmp_dma_chan *chan) if (!chan) return; - if (chan->irq) + if (chan->irq >= 0) devm_free_irq(chan->zdev->dev, chan->irq, chan); tasklet_kill(&chan->tasklet); - list_del(&chan->common.device_node); + if (!list_empty(&chan->common.device_node)) + list_del(&chan->common.device_node); } /** @@ -896,7 +909,7 @@ static void zynqmp_dma_chan_remove(struct zynqmp_dma_chan *chan) * @zdev: Driver specific device structure * @pdev: Pointer to the platform_device structure * - * Return: '0' on success and failure value on error + * Return: 0 on success and negative error code on failure */ static int zynqmp_dma_chan_probe(struct zynqmp_dma_device *zdev, struct platform_device *pdev) @@ -904,13 +917,14 @@ static int zynqmp_dma_chan_probe(struct zynqmp_dma_device *zdev, struct zynqmp_dma_chan *chan; struct device_node *node = pdev->dev.of_node; const struct zynqmp_dma_config *match_data; - int err; + int err, ret; chan = devm_kzalloc(zdev->dev, sizeof(*chan), GFP_KERNEL); if (!chan) return -ENOMEM; chan->dev = zdev->dev; chan->zdev = zdev; + chan->irq = -1; chan->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(chan->regs)) @@ -935,7 +949,7 @@ static int zynqmp_dma_chan_probe(struct zynqmp_dma_device *zdev, if (match_data) chan->irq_offset = match_data->offset; - chan->is_dmacoherent = of_property_read_bool(node, "dma-coherent"); + chan->is_dmacoherent = of_dma_is_coherent(node); zdev->chan = chan; tasklet_setup(&chan->tasklet, zynqmp_dma_do_tasklet); spin_lock_init(&chan->lock); @@ -943,22 +957,27 @@ static int zynqmp_dma_chan_probe(struct zynqmp_dma_device *zdev, INIT_LIST_HEAD(&chan->pending_list); INIT_LIST_HEAD(&chan->done_list); INIT_LIST_HEAD(&chan->free_list); + INIT_LIST_HEAD(&chan->common.device_node); dma_cookie_init(&chan->common); chan->common.device = &zdev->common; - list_add_tail(&chan->common.device_node, &zdev->common.channels); zynqmp_dma_init(chan); - chan->irq = platform_get_irq(pdev, 0); - if (chan->irq < 0) - return -ENXIO; - err = devm_request_irq(&pdev->dev, chan->irq, zynqmp_dma_irq_handler, 0, + ret = platform_get_irq(pdev, 0); + if (ret < 0) + return ret; + + err = devm_request_irq(&pdev->dev, ret, zynqmp_dma_irq_handler, 0, "zynqmp-dma", chan); if (err) return err; + chan->irq = ret; + chan->desc_size = sizeof(struct zynqmp_dma_desc_ll); chan->idle = true; + list_add_tail(&chan->common.device_node, &zdev->common.channels); + return 0; } @@ -1025,11 +1044,11 @@ static int __maybe_unused zynqmp_dma_runtime_suspend(struct device *dev) } /** - * zynqmp_dma_runtime_resume - Runtime suspend method for the driver + * zynqmp_dma_runtime_resume - Runtime resume method for the driver * @dev: Address of the device structure * - * Put the driver into low power mode. - * Return: 0 always + * Enable device clocks. + * Return: 0 on success and failure value on error */ static int __maybe_unused zynqmp_dma_runtime_resume(struct device *dev) { @@ -1123,7 +1142,7 @@ static int zynqmp_dma_probe(struct platform_device *pdev) ret = zynqmp_dma_chan_probe(zdev, pdev); if (ret) { dev_err_probe(&pdev->dev, ret, "Probing channel failed\n"); - goto err_disable_pm; + goto free_chan_resources; } p->dst_addr_widths = BIT(zdev->chan->bus_width / 8); @@ -1149,7 +1168,6 @@ static int zynqmp_dma_probe(struct platform_device *pdev) free_chan_resources: zynqmp_dma_chan_remove(zdev->chan); -err_disable_pm: if (!pm_runtime_enabled(zdev->dev)) zynqmp_dma_runtime_suspend(zdev->dev); pm_runtime_disable(zdev->dev); diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 855d2a54b3c6..c726aa71c830 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -1039,6 +1039,7 @@ static void dw_pcie_edma_init_data(struct dw_pcie *pci) pci->edma.ops = &dw_pcie_edma_ops; pci->edma.flags |= DW_EDMA_CHIP_LOCAL; + pci->edma.ch_space_sz = 256; } static int dw_pcie_edma_find_mf(struct dw_pcie *pci) |
