diff options
-rw-r--r-- | drivers/dma/at_hdmac.c | 9 | ||||
-rw-r--r-- | drivers/dma/at_xdmac.c | 1 | ||||
-rw-r--r-- | drivers/dma/coh901318.c | 20 | ||||
-rw-r--r-- | drivers/dma/dmaengine.c | 33 | ||||
-rw-r--r-- | drivers/dma/dw/core.c | 16 | ||||
-rw-r--r-- | drivers/dma/fsldma.c | 6 | ||||
-rw-r--r-- | drivers/dma/fsldma.h | 4 | ||||
-rw-r--r-- | drivers/dma/imx-dma.c | 5 | ||||
-rw-r--r-- | drivers/dma/imx-sdma.c | 84 | ||||
-rw-r--r-- | drivers/dma/ioat/dma_v3.c | 11 | ||||
-rw-r--r-- | drivers/dma/k3dma.c | 14 | ||||
-rw-r--r-- | drivers/dma/mmp_tdma.c | 3 | ||||
-rw-r--r-- | drivers/dma/mxs-dma.c | 4 | ||||
-rw-r--r-- | drivers/dma/of-dma.c | 4 | ||||
-rw-r--r-- | drivers/dma/s3c24xx-dma.c | 2 | ||||
-rw-r--r-- | drivers/dma/sa11x0-dma.c | 21 | ||||
-rw-r--r-- | drivers/dma/sh/rcar-hpbdma.c | 6 | ||||
-rw-r--r-- | drivers/dma/sh/shdmac.c | 9 | ||||
-rw-r--r-- | drivers/dma/tegra20-apb-dma.c | 15 | ||||
-rw-r--r-- | include/linux/dmaengine.h | 38 |
20 files changed, 181 insertions, 124 deletions
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 86450b3442f2..1e1a4c567542 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -42,6 +42,11 @@ #define ATC_DEFAULT_CFG (ATC_FIFOCFG_HALFFIFO) #define ATC_DEFAULT_CTRLB (ATC_SIF(AT_DMA_MEM_IF) \ |ATC_DIF(AT_DMA_MEM_IF)) +#define ATC_DMA_BUSWIDTHS\ + (BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) |\ + BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |\ + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |\ + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES)) /* * Initial number of descriptors to allocate for each channel. This could @@ -1531,6 +1536,10 @@ static int __init at_dma_probe(struct platform_device *pdev) atdma->dma_common.device_pause = atc_pause; atdma->dma_common.device_resume = atc_resume; atdma->dma_common.device_terminate_all = atc_terminate_all; + atdma->dma_common.src_addr_widths = ATC_DMA_BUSWIDTHS; + atdma->dma_common.dst_addr_widths = ATC_DMA_BUSWIDTHS; + atdma->dma_common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); + atdma->dma_common.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; } dma_writel(atdma, EN, AT_DMA_ENABLE); diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 8c799f66a6dc..c39000b9980a 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -1516,7 +1516,6 @@ static struct platform_driver at_xdmac_driver = { .remove = at_xdmac_remove, .driver = { .name = "at_xdmac", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_xdmac_dt_ids), .pm = &atmel_xdmac_dev_pm_ops, } diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index 418e4e4fb7ba..fd22dd36985f 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -1690,7 +1690,7 @@ static u32 coh901318_get_bytes_left(struct dma_chan *chan) * Pauses a transfer without losing data. Enables power save. * Use this function in conjunction with coh901318_resume. */ -static void coh901318_pause(struct dma_chan *chan) +static int coh901318_pause(struct dma_chan *chan) { u32 val; unsigned long flags; @@ -1730,12 +1730,13 @@ static void coh901318_pause(struct dma_chan *chan) enable_powersave(cohc); spin_unlock_irqrestore(&cohc->lock, flags); + return 0; } /* Resumes a transfer that has been stopped via 300_dma_stop(..). Power save is handled. */ -static void coh901318_resume(struct dma_chan *chan) +static int coh901318_resume(struct dma_chan *chan) { u32 val; unsigned long flags; @@ -1760,6 +1761,7 @@ static void coh901318_resume(struct dma_chan *chan) } spin_unlock_irqrestore(&cohc->lock, flags); + return 0; } bool coh901318_filter_id(struct dma_chan *chan, void *chan_id) @@ -2512,8 +2514,8 @@ static const struct burst_table burst_sizes[] = { }, }; -static void coh901318_dma_set_runtimeconfig(struct dma_chan *chan, - struct dma_slave_config *config) +static int coh901318_dma_set_runtimeconfig(struct dma_chan *chan, + struct dma_slave_config *config) { struct coh901318_chan *cohc = to_coh901318_chan(chan); dma_addr_t addr; @@ -2533,7 +2535,7 @@ static void coh901318_dma_set_runtimeconfig(struct dma_chan *chan, maxburst = config->dst_maxburst; } else { dev_err(COHC_2_DEV(cohc), "illegal channel mode\n"); - return; + return -EINVAL; } dev_dbg(COHC_2_DEV(cohc), "configure channel for %d byte transfers\n", @@ -2579,7 +2581,7 @@ static void coh901318_dma_set_runtimeconfig(struct dma_chan *chan, default: dev_err(COHC_2_DEV(cohc), "bad runtimeconfig: alien address width\n"); - return; + return -EINVAL; } ctrl |= burst_sizes[i].reg; @@ -2589,10 +2591,12 @@ static void coh901318_dma_set_runtimeconfig(struct dma_chan *chan, cohc->addr = addr; cohc->ctrl = ctrl; + + return 0; } -void coh901318_base_init(struct dma_device *dma, const int *pick_chans, - struct coh901318_base *base) +static void coh901318_base_init(struct dma_device *dma, const int *pick_chans, + struct coh901318_base *base) { int chans_i; int i = 0; diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 30211f9791b7..f15712f2fec6 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -479,6 +479,39 @@ static void dma_channel_rebalance(void) } } +int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps) +{ + struct dma_device *device; + + if (!chan || !caps) + return -EINVAL; + + device = chan->device; + + /* check if the channel supports slave transactions */ + if (!test_bit(DMA_SLAVE, device->cap_mask.bits)) + return -ENXIO; + + /* + * Check whether it reports it uses the generic slave + * capabilities, if not, that means it doesn't support any + * kind of slave capabilities reporting. + */ + if (!device->directions) + return -ENXIO; + + caps->src_addr_widths = device->src_addr_widths; + caps->dst_addr_widths = device->dst_addr_widths; + caps->directions = device->directions; + caps->residue_granularity = device->residue_granularity; + + caps->cmd_pause = !!device->device_pause; + caps->cmd_terminate = !!device->device_terminate_all; + + return 0; +} +EXPORT_SYMBOL_GPL(dma_get_slave_caps); + static struct dma_chan *private_candidate(const dma_cap_mask_t *mask, struct dma_device *dev, dma_filter_fn fn, void *fn_param) diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index 4bc307745ef1..fcb9a916e6f6 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c @@ -61,6 +61,13 @@ */ #define NR_DESCS_PER_CHANNEL 64 +/* The set of bus widths supported by the DMA controller */ +#define DW_DMA_BUSWIDTHS \ + BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \ + BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) + /*----------------------------------------------------------------------*/ static struct device *chan2dev(struct dma_chan *chan) @@ -1660,8 +1667,8 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) dw->dma.device_free_chan_resources = dwc_free_chan_resources; dw->dma.device_prep_dma_memcpy = dwc_prep_dma_memcpy; - dw->dma.device_prep_slave_sg = dwc_prep_slave_sg; + dw->dma.device_config = dwc_config; dw->dma.device_pause = dwc_pause; dw->dma.device_resume = dwc_resume; @@ -1670,6 +1677,13 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) dw->dma.device_tx_status = dwc_tx_status; dw->dma.device_issue_pending = dwc_issue_pending; + /* DMA capabilities */ + dw->dma.src_addr_widths = DW_DMA_BUSWIDTHS; + dw->dma.dst_addr_widths = DW_DMA_BUSWIDTHS; + dw->dma.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV) | + BIT(DMA_MEM_TO_MEM); + dw->dma.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; + err = dma_async_device_register(&dw->dma); if (err) goto err_dma_register; diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index b891079a166d..300f821f1890 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -944,7 +944,6 @@ fail: static int fsl_dma_device_terminate_all(struct dma_chan *dchan) { struct fsldma_chan *chan; - int size; if (!dchan) return -EINVAL; @@ -1372,6 +1371,11 @@ static int fsldma_of_probe(struct platform_device *op) fdev->common.device_terminate_all = fsl_dma_device_terminate_all; fdev->common.dev = &op->dev; + fdev->common.src_addr_widths = FSL_DMA_BUSWIDTHS; + fdev->common.dst_addr_widths = FSL_DMA_BUSWIDTHS; + fdev->common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); + fdev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; + dma_set_mask(&(op->dev), DMA_BIT_MASK(36)); platform_set_drvdata(op, fdev); diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h index 239c20c84382..31bffccdcc75 100644 --- a/drivers/dma/fsldma.h +++ b/drivers/dma/fsldma.h @@ -83,6 +83,10 @@ #define FSL_DMA_DGSR_EOSI 0x02 #define FSL_DMA_DGSR_EOLSI 0x01 +#define FSL_DMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \ + BIT(DMA_SLAVE_BUSWIDTH_8_BYTES)) typedef u64 __bitwise v64; typedef u32 __bitwise v32; diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index 02d1f73bd12b..eed405976ea9 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -230,11 +230,6 @@ static inline int is_imx1_dma(struct imxdma_engine *imxdma) return imxdma->devtype == IMX1_DMA; } -static inline int is_imx21_dma(struct imxdma_engine *imxdma) -{ - return imxdma->devtype == IMX21_DMA; -} - static inline int is_imx27_dma(struct imxdma_engine *imxdma) { return imxdma->devtype == IMX27_DMA; diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 1748a4bd475f..18c0a131e4e4 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1296,15 +1296,15 @@ static void sdma_load_firmware(const struct firmware *fw, void *context) if (header->ram_code_start + header->ram_code_size > fw->size) goto err_firmware; switch (header->version_major) { - case 1: - sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; - break; - case 2: - sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2; - break; - default: - dev_err(sdma->dev, "unknown firmware version\n"); - goto err_firmware; + case 1: + sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; + break; + case 2: + sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2; + break; + default: + dev_err(sdma->dev, "unknown firmware version\n"); + goto err_firmware; } addr = (void *)header + header->script_addrs_start; @@ -1472,7 +1472,7 @@ static int sdma_probe(struct platform_device *pdev) if (ret) return ret; - sdma = kzalloc(sizeof(*sdma), GFP_KERNEL); + sdma = devm_kzalloc(&pdev->dev, sizeof(*sdma), GFP_KERNEL); if (!sdma) return -ENOMEM; @@ -1481,48 +1481,34 @@ static int sdma_probe(struct platform_device *pdev) sdma->dev = &pdev->dev; sdma->drvdata = drvdata; - iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); - if (!iores || irq < 0) { - ret = -EINVAL; - goto err_irq; - } + if (irq < 0) + return irq; - if (!request_mem_region(iores->start, resource_size(iores), pdev->name)) { - ret = -EBUSY; - goto err_request_region; - } + iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); + sdma->regs = devm_ioremap_resource(&pdev->dev, iores); + if (IS_ERR(sdma->regs)) + return PTR_ERR(sdma->regs); sdma->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); - if (IS_ERR(sdma->clk_ipg)) { - ret = PTR_ERR(sdma->clk_ipg); - goto err_clk; - } + if (IS_ERR(sdma->clk_ipg)) + return PTR_ERR(sdma->clk_ipg); sdma->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); - if (IS_ERR(sdma->clk_ahb)) { - ret = PTR_ERR(sdma->clk_ahb); - goto err_clk; - } + if (IS_ERR(sdma->clk_ahb)) + return PTR_ERR(sdma->clk_ahb); clk_prepare(sdma->clk_ipg); clk_prepare(sdma->clk_ahb); - sdma->regs = ioremap(iores->start, resource_size(iores)); - if (!sdma->regs) { - ret = -ENOMEM; - goto err_ioremap; - } - - ret = request_irq(irq, sdma_int_handler, 0, "sdma", sdma); + ret = devm_request_irq(&pdev->dev, irq, sdma_int_handler, 0, "sdma", + sdma); if (ret) - goto err_request_irq; + return ret; sdma->script_addrs = kzalloc(sizeof(*sdma->script_addrs), GFP_KERNEL); - if (!sdma->script_addrs) { - ret = -ENOMEM; - goto err_alloc; - } + if (!sdma->script_addrs) + return -ENOMEM; /* initially no scripts available */ saddr_arr = (s32 *)sdma->script_addrs; @@ -1595,6 +1581,10 @@ static int sdma_probe(struct platform_device *pdev) sdma->dma_device.device_prep_dma_cyclic = sdma_prep_dma_cyclic; sdma->dma_device.device_config = sdma_config; sdma->dma_device.device_terminate_all = sdma_disable_channel; + sdma->dma_device.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + sdma->dma_device.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + sdma->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); + sdma->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; sdma->dma_device.device_issue_pending = sdma_issue_pending; sdma->dma_device.dev->dma_parms = &sdma->dma_parms; dma_set_max_seg_size(sdma->dma_device.dev, 65535); @@ -1623,38 +1613,22 @@ err_register: dma_async_device_unregister(&sdma->dma_device); err_init: kfree(sdma->script_addrs); -err_alloc: - free_irq(irq, sdma); -err_request_irq: - iounmap(sdma->regs); -err_ioremap: -err_clk: - release_mem_region(iores->start, resource_size(iores)); -err_request_region: -err_irq: - kfree(sdma); return ret; } static int sdma_remove(struct platform_device *pdev) { struct sdma_engine *sdma = platform_get_drvdata(pdev); - struct resource *iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); - int irq = platform_get_irq(pdev, 0); int i; dma_async_device_unregister(&sdma->dma_device); kfree(sdma->script_addrs); - free_irq(irq, sdma); - iounmap(sdma->regs); - release_mem_region(iores->start, resource_size(iores)); /* Kill the tasklet */ for (i = 0; i < MAX_DMA_CHANNELS; i++) { struct sdma_channel *sdmac = &sdma->channel[i]; tasklet_kill(&sdmac->tasklet); } - kfree(sdma); platform_set_drvdata(pdev, NULL); dev_info(&pdev->dev, "Removed...\n"); diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 32eae38291e5..be307182231e 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -489,6 +489,7 @@ static void ioat3_eh(struct ioat2_dma_chan *ioat) struct ioat_chan_common *chan = &ioat->base; struct pci_dev *pdev = to_pdev(chan); struct ioat_dma_descriptor *hw; + struct dma_async_tx_descriptor *tx; u64 phys_complete; struct ioat_ring_ent *desc; u32 err_handled = 0; @@ -534,6 +535,16 @@ static void ioat3_eh(struct ioat2_dma_chan *ioat) dev_err(to_dev(chan), "%s: fatal error (%x:%x)\n", __func__, chanerr, err_handled); BUG(); + } else { /* cleanup the faulty descriptor */ + tx = &desc->txd; + if (tx->cookie) { + dma_cookie_complete(tx); + dma_descriptor_unmap(tx); + if (tx->callback) { + tx->callback(tx->callback_param); + tx->callback = NULL; + } + } } writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET); diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index 49be7f687c4c..6f7f43529ccb 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -601,7 +601,7 @@ static int k3_dma_terminate_all(struct dma_chan *chan) return 0; } -static int k3_dma_pause(struct dma_chan *chan) +static int k3_dma_transfer_pause(struct dma_chan *chan) { struct k3_dma_chan *c = to_k3_chan(chan); struct k3_dma_dev *d = to_k3_dma(chan->device); @@ -622,7 +622,7 @@ static int k3_dma_pause(struct dma_chan *chan) return 0; } -static int k3_dma_resume(struct dma_chan *chan) +static int k3_dma_transfer_resume(struct dma_chan *chan) { struct k3_dma_chan *c = to_k3_chan(chan); struct k3_dma_dev *d = to_k3_dma(chan->device); @@ -735,8 +735,8 @@ static int k3_dma_probe(struct platform_device *op) d->slave.device_prep_slave_sg = k3_dma_prep_slave_sg; d->slave.device_issue_pending = k3_dma_issue_pending; d->slave.device_config = k3_dma_config; - d->slave.device_pause = k3_dma_pause; - d->slave.device_resume = k3_dma_resume; + d->slave.device_pause = k3_dma_transfer_pause; + d->slave.device_resume = k3_dma_transfer_resume; d->slave.device_terminate_all = k3_dma_terminate_all; d->slave.copy_align = DMA_ALIGN; @@ -804,7 +804,7 @@ static int k3_dma_remove(struct platform_device *op) } #ifdef CONFIG_PM_SLEEP -static int k3_dma_suspend(struct device *dev) +static int k3_dma_suspend_dev(struct device *dev) { struct k3_dma_dev *d = dev_get_drvdata(dev); u32 stat = 0; @@ -820,7 +820,7 @@ static int k3_dma_suspend(struct device *dev) return 0; } -static int k3_dma_resume(struct device *dev) +static int k3_dma_resume_dev(struct device *dev) { struct k3_dma_dev *d = dev_get_drvdata(dev); int ret = 0; @@ -835,7 +835,7 @@ static int k3_dma_resume(struct device *dev) } #endif -static SIMPLE_DEV_PM_OPS(k3_dma_pmops, k3_dma_suspend, k3_dma_resume); +static SIMPLE_DEV_PM_OPS(k3_dma_pmops, k3_dma_suspend_dev, k3_dma_resume_dev); static struct platform_driver k3_pdma_driver = { .driver = { diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c index a8a79b1763d5..70c2fa9963cd 100644 --- a/drivers/dma/mmp_tdma.c +++ b/drivers/dma/mmp_tdma.c @@ -19,7 +19,6 @@ #include <linux/dmaengine.h> #include <linux/platform_device.h> #include <linux/device.h> -#include <mach/regs-icu.h> #include <linux/platform_data/dma-mmp_tdma.h> #include <linux/of_device.h> #include <linux/of_dma.h> @@ -472,6 +471,8 @@ static int mmp_tdma_terminate_all(struct dma_chan *chan) mmp_tdma_disable_chan(chan); /* disable interrupt */ mmp_tdma_enable_irq(tdmac, false); + + return 0; } static int mmp_tdma_config(struct dma_chan *chan, diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c index 599ffb5b7848..829ec686dac3 100644 --- a/drivers/dma/mxs-dma.c +++ b/drivers/dma/mxs-dma.c @@ -848,6 +848,10 @@ static int __init mxs_dma_probe(struct platform_device *pdev) mxs_dma->dma_device.device_pause = mxs_dma_pause_chan; mxs_dma->dma_device.device_resume = mxs_dma_resume_chan; mxs_dma->dma_device.device_terminate_all = mxs_dma_terminate_all; + mxs_dma->dma_device.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + mxs_dma->dma_device.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES); + mxs_dma->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); + mxs_dma->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; mxs_dma->dma_device.device_issue_pending = mxs_dma_enable_chan; ret = dma_async_device_register(&mxs_dma->dma_device); diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c index d5fbeaa1e7ba..ca31f1b45366 100644 --- a/drivers/dma/of-dma.c +++ b/drivers/dma/of-dma.c @@ -159,6 +159,10 @@ struct dma_chan *of_dma_request_slave_channel(struct device_node *np, return ERR_PTR(-ENODEV); } + /* Silently fail if there is not even the "dmas" property */ + if (!of_find_property(np, "dmas", NULL)) + return ERR_PTR(-ENODEV); + count = of_property_count_strings(np, "dma-names"); if (count < 0) { pr_err("%s: dma-names property of node '%s' missing or empty\n", diff --git a/drivers/dma/s3c24xx-dma.c b/drivers/dma/s3c24xx-dma.c index 231f76acebde..4d5a84815ba7 100644 --- a/drivers/dma/s3c24xx-dma.c +++ b/drivers/dma/s3c24xx-dma.c @@ -406,7 +406,7 @@ static int s3c24xx_dma_set_runtime_config(struct dma_chan *chan, s3cchan->cfg = *config; out: - spin_lock_irqrestore(&s3cchan->vc.lock, flags); + spin_unlock_irqrestore(&s3cchan->vc.lock, flags); return ret; } diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c index e229c62d7bad..5adf5407a8cb 100644 --- a/drivers/dma/sa11x0-dma.c +++ b/drivers/dma/sa11x0-dma.c @@ -669,8 +669,8 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic( return vchan_tx_prep(&c->vc, &txd->vd, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); } -static int sa11x0_dma_slave_config(struct dma_chan *chan, - struct dma_slave_config *cfg) +static int sa11x0_dma_device_config(struct dma_chan *chan, + struct dma_slave_config *cfg) { struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); u32 ddar = c->ddar & ((0xf << 4) | DDAR_RW); @@ -706,14 +706,13 @@ static int sa11x0_dma_slave_config(struct dma_chan *chan, return 0; } -static int sa11x0_dma_pause(struct dma_chan *chan) +static int sa11x0_dma_device_pause(struct dma_chan *chan) { struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device); struct sa11x0_dma_phy *p; LIST_HEAD(head); unsigned long flags; - int ret; dev_dbg(d->slave.dev, "vchan %p: pause\n", &c->vc); spin_lock_irqsave(&c->vc.lock, flags); @@ -734,14 +733,13 @@ static int sa11x0_dma_pause(struct dma_chan *chan) return 0; } -static int sa11x0_dma_resume(struct dma_chan *chan) +static int sa11x0_dma_device_resume(struct dma_chan *chan) { struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device); struct sa11x0_dma_phy *p; LIST_HEAD(head); unsigned long flags; - int ret; dev_dbg(d->slave.dev, "vchan %p: resume\n", &c->vc); spin_lock_irqsave(&c->vc.lock, flags); @@ -762,14 +760,13 @@ static int sa11x0_dma_resume(struct dma_chan *chan) return 0; } -static int sa11x0_dma_terminate_all(struct dma_chan *chan) +static int sa11x0_dma_device_terminate_all(struct dma_chan *chan) { struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device); struct sa11x0_dma_phy *p; LIST_HEAD(head); unsigned long flags; - int ret; dev_dbg(d->slave.dev, "vchan %p: terminate all\n", &c->vc); /* Clear the tx descriptor lists */ @@ -840,10 +837,10 @@ static int sa11x0_dma_init_dmadev(struct dma_device *dmadev, dmadev->dev = dev; dmadev->device_alloc_chan_resources = sa11x0_dma_alloc_chan_resources; dmadev->device_free_chan_resources = sa11x0_dma_free_chan_resources; - dmadev->device_config = sa11x0_dma_slave_config; - dmadev->device_pause = sa11x0_dma_pause; - dmadev->device_resume = sa11x0_dma_resume; - dmadev->device_terminate_all = sa11x0_dma_terminate_all; + dmadev->device_config = sa11x0_dma_device_config; + dmadev->device_pause = sa11x0_dma_device_pause; + dmadev->device_resume = sa11x0_dma_device_resume; + dmadev->device_terminate_all = sa11x0_dma_device_terminate_all; dmadev->device_tx_status = sa11x0_dma_tx_status; dmadev->device_issue_pending = sa11x0_dma_issue_pending; diff --git a/drivers/dma/sh/rcar-hpbdma.c b/drivers/dma/sh/rcar-hpbdma.c index 20a6f6f2a018..749f26ecd3b3 100644 --- a/drivers/dma/sh/rcar-hpbdma.c +++ b/drivers/dma/sh/rcar-hpbdma.c @@ -534,6 +534,8 @@ static int hpb_dmae_chan_probe(struct hpb_dmae_device *hpbdev, int id) static int hpb_dmae_probe(struct platform_device *pdev) { + const enum dma_slave_buswidth widths = DMA_SLAVE_BUSWIDTH_1_BYTE | + DMA_SLAVE_BUSWIDTH_2_BYTES | DMA_SLAVE_BUSWIDTH_4_BYTES; struct hpb_dmae_pdata *pdata = pdev->dev.platform_data; struct hpb_dmae_device *hpbdev; struct dma_device *dma_dev; @@ -595,6 +597,10 @@ static int hpb_dmae_probe(struct platform_device *pdev) dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask); dma_cap_set(DMA_SLAVE, dma_dev->cap_mask); + dma_dev->src_addr_widths = widths; + dma_dev->dst_addr_widths = widths; + dma_dev->directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM); + dma_dev->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; hpbdev->shdma_dev.ops = &hpb_dmae_ops; hpbdev->shdma_dev.desc_size = sizeof(struct hpb_desc); diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c index aec8a84784a4..ce4cd6be07cf 100644 --- a/drivers/dma/sh/shdmac.c +++ b/drivers/dma/sh/shdmac.c @@ -684,6 +684,10 @@ MODULE_DEVICE_TABLE(of, sh_dmae_of_match); static int sh_dmae_probe(struct platform_device *pdev) { + const enum dma_slave_buswidth widths = + DMA_SLAVE_BUSWIDTH_1_BYTE | DMA_SLAVE_BUSWIDTH_2_BYTES | + DMA_SLAVE_BUSWIDTH_4_BYTES | DMA_SLAVE_BUSWIDTH_8_BYTES | + DMA_SLAVE_BUSWIDTH_16_BYTES | DMA_SLAVE_BUSWIDTH_32_BYTES; const struct sh_dmae_pdata *pdata; unsigned long chan_flag[SH_DMAE_MAX_CHANNELS] = {}; int chan_irq[SH_DMAE_MAX_CHANNELS]; @@ -746,6 +750,11 @@ static int sh_dmae_probe(struct platform_device *pdev) return PTR_ERR(shdev->dmars); } + dma_dev->src_addr_widths = widths; + dma_dev->dst_addr_widths = widths; + dma_dev->directions = BIT(DMA_MEM_TO_DEV) | BIT(DMA_DEV_TO_MEM); + dma_dev->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; + if (!pdata->slave_only) dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask); if (pdata->slave && pdata->slave_num) diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 5695fb8a7a24..eaf585e8286b 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1425,6 +1425,21 @@ static int tegra_dma_probe(struct platform_device *pdev) tegra_dma_free_chan_resources; tdma->dma_dev.device_prep_slave_sg = tegra_dma_prep_slave_sg; tdma->dma_dev.device_prep_dma_cyclic = tegra_dma_prep_dma_cyclic; + tdma->dma_dev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | + BIT(DMA_SLAVE_BUSWIDTH_8_BYTES); + tdma->dma_dev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | + BIT(DMA_SLAVE_BUSWIDTH_8_BYTES); + tdma->dma_dev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); + /* + * XXX The hardware appears to support + * DMA_RESIDUE_GRANULARITY_BURST-level reporting, but it's + * only used by this driver during tegra_dma_terminate_all() + */ + tdma->dma_dev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; tdma->dma_dev.device_config = tegra_dma_slave_config; tdma->dma_dev.device_terminate_all = tegra_dma_terminate_all; tdma->dma_dev.device_tx_status = tegra_dma_tx_status; diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index b7724a5d4661..b6997a0cb528 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -761,38 +761,6 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_sg( src_sg, src_nents, flags); } -static inline int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps) -{ - struct dma_device *device; - - if (!chan || !caps) - return -EINVAL; - - device = chan->device; - - /* check if the channel supports slave transactions */ - if (!test_bit(DMA_SLAVE, device->cap_mask.bits)) - return -ENXIO; - - /* - * Check whether it reports it uses the generic slave - * capabilities, if not, that means it doesn't support any - * kind of slave capabilities reporting. - */ - if (!device->directions) - return -ENXIO; - - caps->src_addr_widths = device->src_addr_widths; - caps->dst_addr_widths = device->dst_addr_widths; - caps->directions = device->directions; - caps->residue_granularity = device->residue_granularity; - - caps->cmd_pause = !!device->device_pause; - caps->cmd_terminate = !!device->device_terminate_all; - - return 0; -} - static inline int dmaengine_terminate_all(struct dma_chan *chan) { if (chan->device->device_terminate_all) @@ -1081,6 +1049,7 @@ struct dma_chan *dma_request_slave_channel_reason(struct device *dev, const char *name); struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name); void dma_release_channel(struct dma_chan *chan); +int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps); #else static inline struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type) { @@ -1115,6 +1084,11 @@ static inline struct dma_chan *dma_request_slave_channel(struct device *dev, static inline void dma_release_channel(struct dma_chan *chan) { } +static inline int dma_get_slave_caps(struct dma_chan *chan, + struct dma_slave_caps *caps) +{ + return -ENXIO; +} #endif /* --- DMA device --- */ |