diff options
-rw-r--r-- | drivers/dma/amba-pl08x.c | 14 | ||||
-rw-r--r-- | drivers/dma/bcm2835-dma.c | 13 | ||||
-rw-r--r-- | drivers/dma/coh901318.c | 5 | ||||
-rw-r--r-- | drivers/dma/imx-sdma.c | 56 | ||||
-rw-r--r-- | drivers/dma/mic_x100_dma.c | 22 | ||||
-rw-r--r-- | drivers/dma/mmp_pdma.c | 28 | ||||
-rw-r--r-- | drivers/dma/pl330.c | 28 | ||||
-rw-r--r-- | drivers/dma/pxa_dma.c | 36 | ||||
-rw-r--r-- | drivers/dma/qcom/hidma_dbg.c | 33 | ||||
-rw-r--r-- | drivers/dma/ste_dma40.c | 31 | ||||
-rw-r--r-- | drivers/dma/xilinx/zynqmp_dma.c | 37 |
11 files changed, 158 insertions, 145 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 97483df1f82e..fc8c2bab563c 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -2505,24 +2505,14 @@ static int pl08x_debugfs_show(struct seq_file *s, void *data) return 0; } -static int pl08x_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, pl08x_debugfs_show, inode->i_private); -} - -static const struct file_operations pl08x_debugfs_operations = { - .open = pl08x_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(pl08x_debugfs); static void init_pl08x_debugfs(struct pl08x_driver_data *pl08x) { /* Expose a simple debugfs interface to view all clocks */ (void) debugfs_create_file(dev_name(&pl08x->adev->dev), S_IFREG | S_IRUGO, NULL, pl08x, - &pl08x_debugfs_operations); + &pl08x_debugfs_fops); } #else diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c index cad55ab80d41..1a44c8086d77 100644 --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * BCM2835 DMA engine support * @@ -18,16 +19,6 @@ * * MARVELL MMP Peripheral DMA Driver * Copyright 2012 Marvell International Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/dmaengine.h> #include <linux/dma-mapping.h> @@ -1056,4 +1047,4 @@ module_platform_driver(bcm2835_dma_driver); MODULE_ALIAS("platform:bcm2835-dma"); MODULE_DESCRIPTION("BCM2835 DMA engine driver"); MODULE_AUTHOR("Florian Meier <[email protected]>"); -MODULE_LICENSE("GPL v2"); +MODULE_LICENSE("GPL"); diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index eebaba3d9e78..b69d66e44052 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -1802,13 +1802,10 @@ static struct dma_chan *coh901318_xlate(struct of_phandle_args *dma_spec, static int coh901318_config(struct coh901318_chan *cohc, struct coh901318_params *param) { - unsigned long flags; const struct coh901318_params *p; int channel = cohc->id; void __iomem *virtbase = cohc->base->virtbase; - spin_lock_irqsave(&cohc->lock, flags); - if (param) p = param; else @@ -1828,8 +1825,6 @@ static int coh901318_config(struct coh901318_chan *cohc, coh901318_set_conf(cohc, p->config); coh901318_set_ctrl(cohc, p->ctrl_lli_last); - spin_unlock_irqrestore(&cohc->lock, flags); - return 0; } diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index b4ec2d20e661..d6a5d6ddfdad 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -335,6 +335,7 @@ struct sdma_desc { * @sdma: pointer to the SDMA engine for this channel * @channel: the channel number, matches dmaengine chan_id + 1 * @direction: transfer type. Needed for setting SDMA script + * @slave_config Slave configuration * @peripheral_type: Peripheral type. Needed for setting SDMA script * @event_id0: aka dma request line * @event_id1: for channels that use 2 events @@ -362,6 +363,7 @@ struct sdma_channel { struct sdma_engine *sdma; unsigned int channel; enum dma_transfer_direction direction; + struct dma_slave_config slave_config; enum sdma_peripheral_type peripheral_type; unsigned int event_id0; unsigned int event_id1; @@ -440,6 +442,10 @@ struct sdma_engine { struct sdma_buffer_descriptor *bd0; }; +static int sdma_config_write(struct dma_chan *chan, + struct dma_slave_config *dmaengine_cfg, + enum dma_transfer_direction direction); + static struct sdma_driver_data sdma_imx31 = { .chnenbl0 = SDMA_CHNENBL0_IMX31, .num_events = 32, @@ -1104,18 +1110,6 @@ static int sdma_config_channel(struct dma_chan *chan) sdmac->shp_addr = 0; sdmac->per_addr = 0; - if (sdmac->event_id0) { - if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events) - return -EINVAL; - sdma_event_enable(sdmac, sdmac->event_id0); - } - - if (sdmac->event_id1) { - if (sdmac->event_id1 >= sdmac->sdma->drvdata->num_events) - return -EINVAL; - sdma_event_enable(sdmac, sdmac->event_id1); - } - switch (sdmac->peripheral_type) { case IMX_DMATYPE_DSP: sdma_config_ownership(sdmac, false, true, true); @@ -1415,6 +1409,8 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( struct scatterlist *sg; struct sdma_desc *desc; + sdma_config_write(chan, &sdmac->slave_config, direction); + desc = sdma_transfer_init(sdmac, direction, sg_len); if (!desc) goto err_out; @@ -1499,6 +1495,8 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel); + sdma_config_write(chan, &sdmac->slave_config, direction); + desc = sdma_transfer_init(sdmac, direction, num_periods); if (!desc) goto err_out; @@ -1554,17 +1552,18 @@ err_out: return NULL; } -static int sdma_config(struct dma_chan *chan, - struct dma_slave_config *dmaengine_cfg) +static int sdma_config_write(struct dma_chan *chan, + struct dma_slave_config *dmaengine_cfg, + enum dma_transfer_direction direction) { struct sdma_channel *sdmac = to_sdma_chan(chan); - if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) { + if (direction == DMA_DEV_TO_MEM) { sdmac->per_address = dmaengine_cfg->src_addr; sdmac->watermark_level = dmaengine_cfg->src_maxburst * dmaengine_cfg->src_addr_width; sdmac->word_size = dmaengine_cfg->src_addr_width; - } else if (dmaengine_cfg->direction == DMA_DEV_TO_DEV) { + } else if (direction == DMA_DEV_TO_DEV) { sdmac->per_address2 = dmaengine_cfg->src_addr; sdmac->per_address = dmaengine_cfg->dst_addr; sdmac->watermark_level = dmaengine_cfg->src_maxburst & @@ -1578,10 +1577,33 @@ static int sdma_config(struct dma_chan *chan, dmaengine_cfg->dst_addr_width; sdmac->word_size = dmaengine_cfg->dst_addr_width; } - sdmac->direction = dmaengine_cfg->direction; + sdmac->direction = direction; return sdma_config_channel(chan); } +static int sdma_config(struct dma_chan *chan, + struct dma_slave_config *dmaengine_cfg) +{ + struct sdma_channel *sdmac = to_sdma_chan(chan); + + memcpy(&sdmac->slave_config, dmaengine_cfg, sizeof(*dmaengine_cfg)); + + /* Set ENBLn earlier to make sure dma request triggered after that */ + if (sdmac->event_id0) { + if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events) + return -EINVAL; + sdma_event_enable(sdmac, sdmac->event_id0); + } + + if (sdmac->event_id1) { + if (sdmac->event_id1 >= sdmac->sdma->drvdata->num_events) + return -EINVAL; + sdma_event_enable(sdmac, sdmac->event_id1); + } + + return 0; +} + static enum dma_status sdma_tx_status(struct dma_chan *chan, dma_cookie_t cookie, struct dma_tx_state *txstate) diff --git a/drivers/dma/mic_x100_dma.c b/drivers/dma/mic_x100_dma.c index adfd316db1a8..6a91e28d537d 100644 --- a/drivers/dma/mic_x100_dma.c +++ b/drivers/dma/mic_x100_dma.c @@ -676,7 +676,7 @@ static void mic_dma_dev_unreg(struct mic_dma_device *mic_dma_dev) } /* DEBUGFS CODE */ -static int mic_dma_reg_seq_show(struct seq_file *s, void *pos) +static int mic_dma_reg_show(struct seq_file *s, void *pos) { struct mic_dma_device *mic_dma_dev = s->private; int i, chan_num, first_chan = mic_dma_dev->start_ch; @@ -707,23 +707,7 @@ static int mic_dma_reg_seq_show(struct seq_file *s, void *pos) return 0; } -static int mic_dma_reg_debug_open(struct inode *inode, struct file *file) -{ - return single_open(file, mic_dma_reg_seq_show, inode->i_private); -} - -static int mic_dma_reg_debug_release(struct inode *inode, struct file *file) -{ - return single_release(inode, file); -} - -static const struct file_operations mic_dma_reg_ops = { - .owner = THIS_MODULE, - .open = mic_dma_reg_debug_open, - .read = seq_read, - .llseek = seq_lseek, - .release = mic_dma_reg_debug_release -}; +DEFINE_SHOW_ATTRIBUTE(mic_dma_reg); /* Debugfs parent dir */ static struct dentry *mic_dma_dbg; @@ -747,7 +731,7 @@ static int mic_dma_driver_probe(struct mbus_device *mbdev) if (mic_dma_dev->dbg_dir) debugfs_create_file("mic_dma_reg", 0444, mic_dma_dev->dbg_dir, mic_dma_dev, - &mic_dma_reg_ops); + &mic_dma_reg_fops); } return 0; } diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c index eb3a1f42ab06..334bab92d26d 100644 --- a/drivers/dma/mmp_pdma.c +++ b/drivers/dma/mmp_pdma.c @@ -96,6 +96,7 @@ struct mmp_pdma_chan { struct dma_async_tx_descriptor desc; struct mmp_pdma_phy *phy; enum dma_transfer_direction dir; + struct dma_slave_config slave_config; struct mmp_pdma_desc_sw *cyclic_first; /* first desc_sw if channel * is in cyclic mode */ @@ -140,6 +141,10 @@ struct mmp_pdma_device { #define to_mmp_pdma_dev(dmadev) \ container_of(dmadev, struct mmp_pdma_device, device) +static int mmp_pdma_config_write(struct dma_chan *dchan, + struct dma_slave_config *cfg, + enum dma_transfer_direction direction); + static void set_desc(struct mmp_pdma_phy *phy, dma_addr_t addr) { u32 reg = (phy->idx << 4) + DDADR; @@ -537,6 +542,8 @@ mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, chan->byte_align = false; + mmp_pdma_config_write(dchan, &chan->slave_config, dir); + for_each_sg(sgl, sg, sg_len, i) { addr = sg_dma_address(sg); avail = sg_dma_len(sgl); @@ -619,6 +626,7 @@ mmp_pdma_prep_dma_cyclic(struct dma_chan *dchan, return NULL; chan = to_mmp_pdma_chan(dchan); + mmp_pdma_config_write(dchan, &chan->slave_config, direction); switch (direction) { case DMA_MEM_TO_DEV: @@ -684,8 +692,9 @@ fail: return NULL; } -static int mmp_pdma_config(struct dma_chan *dchan, - struct dma_slave_config *cfg) +static int mmp_pdma_config_write(struct dma_chan *dchan, + struct dma_slave_config *cfg, + enum dma_transfer_direction direction) { struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan); u32 maxburst = 0, addr = 0; @@ -694,12 +703,12 @@ static int mmp_pdma_config(struct dma_chan *dchan, if (!dchan) return -EINVAL; - if (cfg->direction == DMA_DEV_TO_MEM) { + if (direction == DMA_DEV_TO_MEM) { chan->dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC; maxburst = cfg->src_maxburst; width = cfg->src_addr_width; addr = cfg->src_addr; - } else if (cfg->direction == DMA_MEM_TO_DEV) { + } else if (direction == DMA_MEM_TO_DEV) { chan->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG; maxburst = cfg->dst_maxburst; width = cfg->dst_addr_width; @@ -720,7 +729,7 @@ static int mmp_pdma_config(struct dma_chan *dchan, else if (maxburst == 32) chan->dcmd |= DCMD_BURST32; - chan->dir = cfg->direction; + chan->dir = direction; chan->dev_addr = addr; /* FIXME: drivers should be ported over to use the filter * function. Once that's done, the following two lines can @@ -732,6 +741,15 @@ static int mmp_pdma_config(struct dma_chan *dchan, return 0; } +static int mmp_pdma_config(struct dma_chan *dchan, + struct dma_slave_config *cfg) +{ + struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan); + + memcpy(&chan->slave_config, cfg, sizeof(*cfg)); + return 0; +} + static int mmp_pdma_terminate_all(struct dma_chan *dchan) { struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan); diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 88750a34e859..cff1b143fff5 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -448,6 +448,7 @@ struct dma_pl330_chan { /* DMA-mapped view of the FIFO; may differ if an IOMMU is present */ dma_addr_t fifo_dma; enum dma_data_direction dir; + struct dma_slave_config slave_config; /* for cyclic capability */ bool cyclic; @@ -542,6 +543,10 @@ struct _xfer_spec { struct dma_pl330_desc *desc; }; +static int pl330_config_write(struct dma_chan *chan, + struct dma_slave_config *slave_config, + enum dma_transfer_direction direction); + static inline bool _queue_full(struct pl330_thread *thrd) { return thrd->req[0].desc != NULL && thrd->req[1].desc != NULL; @@ -2220,20 +2225,21 @@ static int fixup_burst_len(int max_burst_len, int quirks) return max_burst_len; } -static int pl330_config(struct dma_chan *chan, - struct dma_slave_config *slave_config) +static int pl330_config_write(struct dma_chan *chan, + struct dma_slave_config *slave_config, + enum dma_transfer_direction direction) { struct dma_pl330_chan *pch = to_pchan(chan); pl330_unprep_slave_fifo(pch); - if (slave_config->direction == DMA_MEM_TO_DEV) { + if (direction == DMA_MEM_TO_DEV) { if (slave_config->dst_addr) pch->fifo_addr = slave_config->dst_addr; if (slave_config->dst_addr_width) pch->burst_sz = __ffs(slave_config->dst_addr_width); pch->burst_len = fixup_burst_len(slave_config->dst_maxburst, pch->dmac->quirks); - } else if (slave_config->direction == DMA_DEV_TO_MEM) { + } else if (direction == DMA_DEV_TO_MEM) { if (slave_config->src_addr) pch->fifo_addr = slave_config->src_addr; if (slave_config->src_addr_width) @@ -2245,6 +2251,16 @@ static int pl330_config(struct dma_chan *chan, return 0; } +static int pl330_config(struct dma_chan *chan, + struct dma_slave_config *slave_config) +{ + struct dma_pl330_chan *pch = to_pchan(chan); + + memcpy(&pch->slave_config, slave_config, sizeof(*slave_config)); + + return 0; +} + static int pl330_terminate_all(struct dma_chan *chan) { struct dma_pl330_chan *pch = to_pchan(chan); @@ -2661,6 +2677,8 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( return NULL; } + pl330_config_write(chan, &pch->slave_config, direction); + if (!pl330_prep_slave_fifo(pch, direction)) return NULL; @@ -2815,6 +2833,8 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (unlikely(!pch || !sgl || !sg_len)) return NULL; + pl330_config_write(chan, &pch->slave_config, direction); + if (!pl330_prep_slave_fifo(pch, direction)) return NULL; diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c index 825725057e00..e78fe98b5cf1 100644 --- a/drivers/dma/pxa_dma.c +++ b/drivers/dma/pxa_dma.c @@ -189,7 +189,7 @@ bool pxad_filter_fn(struct dma_chan *chan, void *param); #include <linux/uaccess.h> #include <linux/seq_file.h> -static int dbg_show_requester_chan(struct seq_file *s, void *p) +static int requester_chan_show(struct seq_file *s, void *p) { struct pxad_phy *phy = s->private; int i; @@ -220,7 +220,7 @@ static int is_phys_valid(unsigned long addr) #define PXA_DCSR_STR(flag) (dcsr & PXA_DCSR_##flag ? #flag" " : "") #define PXA_DCMD_STR(flag) (dcmd & PXA_DCMD_##flag ? #flag" " : "") -static int dbg_show_descriptors(struct seq_file *s, void *p) +static int descriptors_show(struct seq_file *s, void *p) { struct pxad_phy *phy = s->private; int i, max_show = 20, burst, width; @@ -263,7 +263,7 @@ static int dbg_show_descriptors(struct seq_file *s, void *p) return 0; } -static int dbg_show_chan_state(struct seq_file *s, void *p) +static int chan_state_show(struct seq_file *s, void *p) { struct pxad_phy *phy = s->private; u32 dcsr, dcmd; @@ -306,7 +306,7 @@ static int dbg_show_chan_state(struct seq_file *s, void *p) return 0; } -static int dbg_show_state(struct seq_file *s, void *p) +static int state_show(struct seq_file *s, void *p) { struct pxad_device *pdev = s->private; @@ -317,22 +317,10 @@ static int dbg_show_state(struct seq_file *s, void *p) return 0; } -#define DBGFS_FUNC_DECL(name) \ -static int dbg_open_##name(struct inode *inode, struct file *file) \ -{ \ - return single_open(file, dbg_show_##name, inode->i_private); \ -} \ -static const struct file_operations dbg_fops_##name = { \ - .open = dbg_open_##name, \ - .llseek = seq_lseek, \ - .read = seq_read, \ - .release = single_release, \ -} - -DBGFS_FUNC_DECL(state); -DBGFS_FUNC_DECL(chan_state); -DBGFS_FUNC_DECL(descriptors); -DBGFS_FUNC_DECL(requester_chan); +DEFINE_SHOW_ATTRIBUTE(state); +DEFINE_SHOW_ATTRIBUTE(chan_state); +DEFINE_SHOW_ATTRIBUTE(descriptors); +DEFINE_SHOW_ATTRIBUTE(requester_chan); static struct dentry *pxad_dbg_alloc_chan(struct pxad_device *pdev, int ch, struct dentry *chandir) @@ -348,13 +336,13 @@ static struct dentry *pxad_dbg_alloc_chan(struct pxad_device *pdev, if (chan) chan_state = debugfs_create_file("state", 0400, chan, dt, - &dbg_fops_chan_state); + &chan_state_fops); if (chan_state) chan_descr = debugfs_create_file("descriptors", 0400, chan, dt, - &dbg_fops_descriptors); + &descriptors_fops); if (chan_descr) chan_reqs = debugfs_create_file("requesters", 0400, chan, dt, - &dbg_fops_requester_chan); + &requester_chan_fops); if (!chan_reqs) goto err_state; @@ -375,7 +363,7 @@ static void pxad_init_debugfs(struct pxad_device *pdev) goto err_root; pdev->dbgfs_state = debugfs_create_file("state", 0400, pdev->dbgfs_root, - pdev, &dbg_fops_state); + pdev, &state_fops); if (!pdev->dbgfs_state) goto err_state; diff --git a/drivers/dma/qcom/hidma_dbg.c b/drivers/dma/qcom/hidma_dbg.c index 3bdcb8056a36..9523faf7acdc 100644 --- a/drivers/dma/qcom/hidma_dbg.c +++ b/drivers/dma/qcom/hidma_dbg.c @@ -85,11 +85,11 @@ static void hidma_ll_devstats(struct seq_file *s, void *llhndl) } /* - * hidma_chan_stats: display HIDMA channel statistics + * hidma_chan_show: display HIDMA channel statistics * * Display the statistics for the current HIDMA virtual channel device. */ -static int hidma_chan_stats(struct seq_file *s, void *unused) +static int hidma_chan_show(struct seq_file *s, void *unused) { struct hidma_chan *mchan = s->private; struct hidma_desc *mdesc; @@ -117,11 +117,11 @@ static int hidma_chan_stats(struct seq_file *s, void *unused) } /* - * hidma_dma_info: display HIDMA device info + * hidma_dma_show: display HIDMA device info * * Display the info for the current HIDMA device. */ -static int hidma_dma_info(struct seq_file *s, void *unused) +static int hidma_dma_show(struct seq_file *s, void *unused) { struct hidma_dev *dmadev = s->private; resource_size_t sz; @@ -138,29 +138,8 @@ static int hidma_dma_info(struct seq_file *s, void *unused) return 0; } -static int hidma_chan_stats_open(struct inode *inode, struct file *file) -{ - return single_open(file, hidma_chan_stats, inode->i_private); -} - -static int hidma_dma_info_open(struct inode *inode, struct file *file) -{ - return single_open(file, hidma_dma_info, inode->i_private); -} - -static const struct file_operations hidma_chan_fops = { - .open = hidma_chan_stats_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations hidma_dma_fops = { - .open = hidma_dma_info_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(hidma_chan); +DEFINE_SHOW_ATTRIBUTE(hidma_dma); void hidma_debug_uninit(struct hidma_dev *dmadev) { diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 5e328bd10c27..907ae97a3ef4 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -442,6 +442,7 @@ struct d40_base; * @queue: Queued jobs. * @prepare_queue: Prepared jobs. * @dma_cfg: The client configuration of this dma channel. + * @slave_config: DMA slave configuration. * @configured: whether the dma_cfg configuration is valid * @base: Pointer to the device instance struct. * @src_def_cfg: Default cfg register setting for src. @@ -468,6 +469,7 @@ struct d40_chan { struct list_head queue; struct list_head prepare_queue; struct stedma40_chan_cfg dma_cfg; + struct dma_slave_config slave_config; bool configured; struct d40_base *base; /* Default register configurations */ @@ -625,6 +627,10 @@ static void __iomem *chan_base(struct d40_chan *chan) #define chan_err(d40c, format, arg...) \ d40_err(chan2dev(d40c), format, ## arg) +static int d40_set_runtime_config_write(struct dma_chan *chan, + struct dma_slave_config *config, + enum dma_transfer_direction direction); + static int d40_pool_lli_alloc(struct d40_chan *d40c, struct d40_desc *d40d, int lli_len) { @@ -2216,6 +2222,8 @@ d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src, return NULL; } + d40_set_runtime_config_write(dchan, &chan->slave_config, direction); + spin_lock_irqsave(&chan->lock, flags); desc = d40_prep_desc(chan, sg_src, sg_len, dma_flags); @@ -2634,11 +2642,22 @@ dma40_config_to_halfchannel(struct d40_chan *d40c, return 0; } -/* Runtime reconfiguration extension */ static int d40_set_runtime_config(struct dma_chan *chan, struct dma_slave_config *config) { struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); + + memcpy(&d40c->slave_config, config, sizeof(*config)); + + return 0; +} + +/* Runtime reconfiguration extension */ +static int d40_set_runtime_config_write(struct dma_chan *chan, + struct dma_slave_config *config, + enum dma_transfer_direction direction) +{ + struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); struct stedma40_chan_cfg *cfg = &d40c->dma_cfg; enum dma_slave_buswidth src_addr_width, dst_addr_width; dma_addr_t config_addr; @@ -2655,7 +2674,7 @@ static int d40_set_runtime_config(struct dma_chan *chan, dst_addr_width = config->dst_addr_width; dst_maxburst = config->dst_maxburst; - if (config->direction == DMA_DEV_TO_MEM) { + if (direction == DMA_DEV_TO_MEM) { config_addr = config->src_addr; if (cfg->dir != DMA_DEV_TO_MEM) @@ -2671,7 +2690,7 @@ static int d40_set_runtime_config(struct dma_chan *chan, if (dst_maxburst == 0) dst_maxburst = src_maxburst; - } else if (config->direction == DMA_MEM_TO_DEV) { + } else if (direction == DMA_MEM_TO_DEV) { config_addr = config->dst_addr; if (cfg->dir != DMA_MEM_TO_DEV) @@ -2689,7 +2708,7 @@ static int d40_set_runtime_config(struct dma_chan *chan, } else { dev_err(d40c->base->dev, "unrecognized channel direction %d\n", - config->direction); + direction); return -EINVAL; } @@ -2746,12 +2765,12 @@ static int d40_set_runtime_config(struct dma_chan *chan, /* These settings will take precedence later */ d40c->runtime_addr = config_addr; - d40c->runtime_direction = config->direction; + d40c->runtime_direction = direction; dev_dbg(d40c->base->dev, "configured channel %s for %s, data width %d/%d, " "maxburst %d/%d elements, LE, no flow control\n", dma_chan_name(chan), - (config->direction == DMA_DEV_TO_MEM) ? "RX" : "TX", + (direction == DMA_DEV_TO_MEM) ? "RX" : "TX", src_addr_width, dst_addr_width, src_maxburst, dst_maxburst); diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c index c74a88b65039..6f26b59a7216 100644 --- a/drivers/dma/xilinx/zynqmp_dma.c +++ b/drivers/dma/xilinx/zynqmp_dma.c @@ -375,9 +375,10 @@ static dma_cookie_t zynqmp_dma_tx_submit(struct dma_async_tx_descriptor *tx) struct zynqmp_dma_chan *chan = to_chan(tx->chan); struct zynqmp_dma_desc_sw *desc, *new; dma_cookie_t cookie; + unsigned long irqflags; new = tx_to_desc(tx); - spin_lock_bh(&chan->lock); + spin_lock_irqsave(&chan->lock, irqflags); cookie = dma_cookie_assign(tx); if (!list_empty(&chan->pending_list)) { @@ -393,7 +394,7 @@ static dma_cookie_t zynqmp_dma_tx_submit(struct dma_async_tx_descriptor *tx) } list_add_tail(&new->node, &chan->pending_list); - spin_unlock_bh(&chan->lock); + spin_unlock_irqrestore(&chan->lock, irqflags); return cookie; } @@ -408,12 +409,13 @@ static struct zynqmp_dma_desc_sw * zynqmp_dma_get_descriptor(struct zynqmp_dma_chan *chan) { struct zynqmp_dma_desc_sw *desc; + unsigned long irqflags; - spin_lock_bh(&chan->lock); + spin_lock_irqsave(&chan->lock, irqflags); desc = list_first_entry(&chan->free_list, struct zynqmp_dma_desc_sw, node); list_del(&desc->node); - spin_unlock_bh(&chan->lock); + spin_unlock_irqrestore(&chan->lock, irqflags); INIT_LIST_HEAD(&desc->tx_list); /* Clear the src and dst descriptor memory */ @@ -643,10 +645,11 @@ static void zynqmp_dma_complete_descriptor(struct zynqmp_dma_chan *chan) static void zynqmp_dma_issue_pending(struct dma_chan *dchan) { struct zynqmp_dma_chan *chan = to_chan(dchan); + unsigned long irqflags; - spin_lock_bh(&chan->lock); + spin_lock_irqsave(&chan->lock, irqflags); zynqmp_dma_start_transfer(chan); - spin_unlock_bh(&chan->lock); + spin_unlock_irqrestore(&chan->lock, irqflags); } /** @@ -667,10 +670,11 @@ static void zynqmp_dma_free_descriptors(struct zynqmp_dma_chan *chan) static void zynqmp_dma_free_chan_resources(struct dma_chan *dchan) { struct zynqmp_dma_chan *chan = to_chan(dchan); + unsigned long irqflags; - spin_lock_bh(&chan->lock); + spin_lock_irqsave(&chan->lock, irqflags); zynqmp_dma_free_descriptors(chan); - spin_unlock_bh(&chan->lock); + spin_unlock_irqrestore(&chan->lock, irqflags); dma_free_coherent(chan->dev, (2 * ZYNQMP_DMA_DESC_SIZE(chan) * ZYNQMP_DMA_NUM_DESCS), chan->desc_pool_v, chan->desc_pool_p); @@ -743,8 +747,9 @@ static void zynqmp_dma_do_tasklet(unsigned long data) { struct zynqmp_dma_chan *chan = (struct zynqmp_dma_chan *)data; u32 count; + unsigned long irqflags; - spin_lock(&chan->lock); + spin_lock_irqsave(&chan->lock, irqflags); if (chan->err) { zynqmp_dma_reset(chan); @@ -764,7 +769,7 @@ static void zynqmp_dma_do_tasklet(unsigned long data) zynqmp_dma_start_transfer(chan); unlock: - spin_unlock(&chan->lock); + spin_unlock_irqrestore(&chan->lock, irqflags); } /** @@ -776,11 +781,12 @@ unlock: static int zynqmp_dma_device_terminate_all(struct dma_chan *dchan) { struct zynqmp_dma_chan *chan = to_chan(dchan); + unsigned long irqflags; - spin_lock_bh(&chan->lock); + spin_lock_irqsave(&chan->lock, irqflags); writel(ZYNQMP_DMA_IDS_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IDS); zynqmp_dma_free_descriptors(chan); - spin_unlock_bh(&chan->lock); + spin_unlock_irqrestore(&chan->lock, irqflags); return 0; } @@ -804,19 +810,20 @@ static struct dma_async_tx_descriptor *zynqmp_dma_prep_memcpy( void *desc = NULL, *prev = NULL; size_t copy; u32 desc_cnt; + unsigned long irqflags; chan = to_chan(dchan); desc_cnt = DIV_ROUND_UP(len, ZYNQMP_DMA_MAX_TRANS_LEN); - spin_lock_bh(&chan->lock); + spin_lock_irqsave(&chan->lock, irqflags); if (desc_cnt > chan->desc_free_cnt) { - spin_unlock_bh(&chan->lock); + spin_unlock_irqrestore(&chan->lock, irqflags); dev_dbg(chan->dev, "chan %p descs are not available\n", chan); return NULL; } chan->desc_free_cnt = chan->desc_free_cnt - desc_cnt; - spin_unlock_bh(&chan->lock); + spin_unlock_irqrestore(&chan->lock, irqflags); do { /* Allocate and populate the descriptor */ |