diff options
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/Kconfig | 5 | ||||
-rw-r--r-- | drivers/dma/acpi-dma.c | 2 | ||||
-rw-r--r-- | drivers/dma/dw/regs.h | 2 | ||||
-rw-r--r-- | drivers/dma/edma.c | 63 | ||||
-rw-r--r-- | drivers/dma/ep93xx_dma.c | 28 | ||||
-rw-r--r-- | drivers/dma/ioat/prep.c | 2 | ||||
-rw-r--r-- | drivers/dma/mic_x100_dma.c | 2 | ||||
-rw-r--r-- | drivers/dma/sirf-dma.c | 10 | ||||
-rw-r--r-- | drivers/dma/sun4i-dma.c | 1 | ||||
-rw-r--r-- | drivers/dma/tegra20-apb-dma.c | 47 |
10 files changed, 85 insertions, 77 deletions
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 79b1390f2016..c77f214c9466 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -341,12 +341,13 @@ config MV_XOR config MXS_DMA bool "MXS DMA support" - depends on SOC_IMX23 || SOC_IMX28 || SOC_IMX6Q + depends on SOC_IMX23 || SOC_IMX28 || SOC_IMX6Q || SOC_IMX6UL select STMP_DEVICE select DMA_ENGINE help Support the MXS DMA engine. This engine including APBH-DMA - and APBX-DMA is integrated into Freescale i.MX23/28/MX6Q/MX6DL chips. + and APBX-DMA is integrated into Freescale + i.MX23/28/MX6Q/MX6DL/MX6UL chips. config MX3_IPU bool "MX3x Image Processing Unit support" diff --git a/drivers/dma/acpi-dma.c b/drivers/dma/acpi-dma.c index eed6bda01790..4a748c3435d7 100644 --- a/drivers/dma/acpi-dma.c +++ b/drivers/dma/acpi-dma.c @@ -438,7 +438,7 @@ struct dma_chan *acpi_dma_request_slave_chan_by_name(struct device *dev, return ERR_PTR(-ENODEV); } - dev_dbg(dev, "found DMA channel \"%s\" at index %d\n", name, index); + dev_dbg(dev, "Looking for DMA channel \"%s\" at index %d...\n", name, index); return acpi_dma_request_slave_chan_by_index(dev, index); } EXPORT_SYMBOL_GPL(acpi_dma_request_slave_chan_by_name); diff --git a/drivers/dma/dw/regs.h b/drivers/dma/dw/regs.h index 241ff2b1402b..0a50c18d85b8 100644 --- a/drivers/dma/dw/regs.h +++ b/drivers/dma/dw/regs.h @@ -150,7 +150,7 @@ enum dw_dma_msize { #define DWC_CTLL_DST_INC (0<<7) /* DAR update/not */ #define DWC_CTLL_DST_DEC (1<<7) #define DWC_CTLL_DST_FIX (2<<7) -#define DWC_CTLL_SRC_INC (0<<7) /* SAR update/not */ +#define DWC_CTLL_SRC_INC (0<<9) /* SAR update/not */ #define DWC_CTLL_SRC_DEC (1<<9) #define DWC_CTLL_SRC_FIX (2<<9) #define DWC_CTLL_DST_MSIZE(n) ((n)<<11) /* burst, #elements */ diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index d92d65549406..29a7723918d9 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -866,6 +866,13 @@ static int edma_terminate_all(struct dma_chan *chan) return 0; } +static void edma_synchronize(struct dma_chan *chan) +{ + struct edma_chan *echan = to_edma_chan(chan); + + vchan_synchronize(&echan->vchan); +} + static int edma_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg) { @@ -1362,36 +1369,36 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( static void edma_completion_handler(struct edma_chan *echan) { struct device *dev = echan->vchan.chan.device->dev; - struct edma_desc *edesc = echan->edesc; - - if (!edesc) - return; + struct edma_desc *edesc; spin_lock(&echan->vchan.lock); - if (edesc->cyclic) { - vchan_cyclic_callback(&edesc->vdesc); - spin_unlock(&echan->vchan.lock); - return; - } else if (edesc->processed == edesc->pset_nr) { - edesc->residue = 0; - edma_stop(echan); - vchan_cookie_complete(&edesc->vdesc); - echan->edesc = NULL; - - dev_dbg(dev, "Transfer completed on channel %d\n", - echan->ch_num); - } else { - dev_dbg(dev, "Sub transfer completed on channel %d\n", - echan->ch_num); - - edma_pause(echan); - - /* Update statistics for tx_status */ - edesc->residue -= edesc->sg_len; - edesc->residue_stat = edesc->residue; - edesc->processed_stat = edesc->processed; + edesc = echan->edesc; + if (edesc) { + if (edesc->cyclic) { + vchan_cyclic_callback(&edesc->vdesc); + spin_unlock(&echan->vchan.lock); + return; + } else if (edesc->processed == edesc->pset_nr) { + edesc->residue = 0; + edma_stop(echan); + vchan_cookie_complete(&edesc->vdesc); + echan->edesc = NULL; + + dev_dbg(dev, "Transfer completed on channel %d\n", + echan->ch_num); + } else { + dev_dbg(dev, "Sub transfer completed on channel %d\n", + echan->ch_num); + + edma_pause(echan); + + /* Update statistics for tx_status */ + edesc->residue -= edesc->sg_len; + edesc->residue_stat = edesc->residue; + edesc->processed_stat = edesc->processed; + } + edma_execute(echan); } - edma_execute(echan); spin_unlock(&echan->vchan.lock); } @@ -1798,6 +1805,7 @@ static void edma_dma_init(struct edma_cc *ecc, bool legacy_mode) s_ddev->device_pause = edma_dma_pause; s_ddev->device_resume = edma_dma_resume; s_ddev->device_terminate_all = edma_terminate_all; + s_ddev->device_synchronize = edma_synchronize; s_ddev->src_addr_widths = EDMA_DMA_BUSWIDTHS; s_ddev->dst_addr_widths = EDMA_DMA_BUSWIDTHS; @@ -1823,6 +1831,7 @@ static void edma_dma_init(struct edma_cc *ecc, bool legacy_mode) m_ddev->device_pause = edma_dma_pause; m_ddev->device_resume = edma_dma_resume; m_ddev->device_terminate_all = edma_terminate_all; + m_ddev->device_synchronize = edma_synchronize; m_ddev->src_addr_widths = EDMA_DMA_BUSWIDTHS; m_ddev->dst_addr_widths = EDMA_DMA_BUSWIDTHS; diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c index 57ff46284f15..21f08cc3352b 100644 --- a/drivers/dma/ep93xx_dma.c +++ b/drivers/dma/ep93xx_dma.c @@ -421,23 +421,25 @@ static int m2p_hw_interrupt(struct ep93xx_dma_chan *edmac) desc->size); } - switch (irq_status & (M2P_INTERRUPT_STALL | M2P_INTERRUPT_NFB)) { - case M2P_INTERRUPT_STALL: - /* Disable interrupts */ - control = readl(edmac->regs + M2P_CONTROL); - control &= ~(M2P_CONTROL_STALLINT | M2P_CONTROL_NFBINT); - m2p_set_control(edmac, control); - - return INTERRUPT_DONE; - - case M2P_INTERRUPT_NFB: - if (ep93xx_dma_advance_active(edmac)) - m2p_fill_desc(edmac); + /* + * Even latest E2 silicon revision sometimes assert STALL interrupt + * instead of NFB. Therefore we treat them equally, basing on the + * amount of data we still have to transfer. + */ + if (!(irq_status & (M2P_INTERRUPT_STALL | M2P_INTERRUPT_NFB))) + return INTERRUPT_UNKNOWN; + if (ep93xx_dma_advance_active(edmac)) { + m2p_fill_desc(edmac); return INTERRUPT_NEXT_BUFFER; } - return INTERRUPT_UNKNOWN; + /* Disable interrupts */ + control = readl(edmac->regs + M2P_CONTROL); + control &= ~(M2P_CONTROL_STALLINT | M2P_CONTROL_NFBINT); + m2p_set_control(edmac, control); + + return INTERRUPT_DONE; } /* diff --git a/drivers/dma/ioat/prep.c b/drivers/dma/ioat/prep.c index 6bb4a13a8fbd..243421af888f 100644 --- a/drivers/dma/ioat/prep.c +++ b/drivers/dma/ioat/prep.c @@ -26,7 +26,7 @@ #include "hw.h" #include "dma.h" -#define MAX_SCF 1024 +#define MAX_SCF 256 /* provide a lookup table for setting the source address in the base or * extended descriptor of an xor or pq descriptor diff --git a/drivers/dma/mic_x100_dma.c b/drivers/dma/mic_x100_dma.c index 068e920ecb68..1502b24b7c7d 100644 --- a/drivers/dma/mic_x100_dma.c +++ b/drivers/dma/mic_x100_dma.c @@ -483,7 +483,7 @@ static int mic_dma_setup_irq(struct mic_dma_chan *ch) mic_dma_intr_handler, mic_dma_thread_fn, "mic dma_channel", ch, ch->ch_num); if (IS_ERR(ch->cookie)) - return IS_ERR(ch->cookie); + return PTR_ERR(ch->cookie); return 0; } diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c index 22ea2419ee56..e48350e65089 100644 --- a/drivers/dma/sirf-dma.c +++ b/drivers/dma/sirf-dma.c @@ -989,7 +989,7 @@ static int sirfsoc_dma_remove(struct platform_device *op) return 0; } -static int sirfsoc_dma_runtime_suspend(struct device *dev) +static int __maybe_unused sirfsoc_dma_runtime_suspend(struct device *dev) { struct sirfsoc_dma *sdma = dev_get_drvdata(dev); @@ -997,7 +997,7 @@ static int sirfsoc_dma_runtime_suspend(struct device *dev) return 0; } -static int sirfsoc_dma_runtime_resume(struct device *dev) +static int __maybe_unused sirfsoc_dma_runtime_resume(struct device *dev) { struct sirfsoc_dma *sdma = dev_get_drvdata(dev); int ret; @@ -1010,8 +1010,7 @@ static int sirfsoc_dma_runtime_resume(struct device *dev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int sirfsoc_dma_pm_suspend(struct device *dev) +static int __maybe_unused sirfsoc_dma_pm_suspend(struct device *dev) { struct sirfsoc_dma *sdma = dev_get_drvdata(dev); struct sirfsoc_dma_regs *save = &sdma->regs_save; @@ -1062,7 +1061,7 @@ static int sirfsoc_dma_pm_suspend(struct device *dev) return 0; } -static int sirfsoc_dma_pm_resume(struct device *dev) +static int __maybe_unused sirfsoc_dma_pm_resume(struct device *dev) { struct sirfsoc_dma *sdma = dev_get_drvdata(dev); struct sirfsoc_dma_regs *save = &sdma->regs_save; @@ -1121,7 +1120,6 @@ static int sirfsoc_dma_pm_resume(struct device *dev) return 0; } -#endif static const struct dev_pm_ops sirfsoc_dma_pm_ops = { SET_RUNTIME_PM_OPS(sirfsoc_dma_runtime_suspend, sirfsoc_dma_runtime_resume, NULL) diff --git a/drivers/dma/sun4i-dma.c b/drivers/dma/sun4i-dma.c index 1661d518224a..e0df233dde92 100644 --- a/drivers/dma/sun4i-dma.c +++ b/drivers/dma/sun4i-dma.c @@ -1271,6 +1271,7 @@ static const struct of_device_id sun4i_dma_match[] = { { .compatible = "allwinner,sun4i-a10-dma" }, { /* sentinel */ }, }; +MODULE_DEVICE_TABLE(of, sun4i_dma_match); static struct platform_driver sun4i_dma_driver = { .probe = sun4i_dma_probe, diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 935da8192f59..3871f29e523d 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -1292,40 +1292,19 @@ static const struct tegra_dma_chip_data tegra148_dma_chip_data = { .support_separate_wcount_reg = true, }; - -static const struct of_device_id tegra_dma_of_match[] = { - { - .compatible = "nvidia,tegra148-apbdma", - .data = &tegra148_dma_chip_data, - }, { - .compatible = "nvidia,tegra114-apbdma", - .data = &tegra114_dma_chip_data, - }, { - .compatible = "nvidia,tegra30-apbdma", - .data = &tegra30_dma_chip_data, - }, { - .compatible = "nvidia,tegra20-apbdma", - .data = &tegra20_dma_chip_data, - }, { - }, -}; -MODULE_DEVICE_TABLE(of, tegra_dma_of_match); - static int tegra_dma_probe(struct platform_device *pdev) { struct resource *res; struct tegra_dma *tdma; int ret; int i; - const struct tegra_dma_chip_data *cdata = NULL; - const struct of_device_id *match; + const struct tegra_dma_chip_data *cdata; - match = of_match_device(tegra_dma_of_match, &pdev->dev); - if (!match) { - dev_err(&pdev->dev, "Error: No device match found\n"); + cdata = of_device_get_match_data(&pdev->dev); + if (!cdata) { + dev_err(&pdev->dev, "Error: No device match data found\n"); return -ENODEV; } - cdata = match->data; tdma = devm_kzalloc(&pdev->dev, sizeof(*tdma) + cdata->nr_channels * sizeof(struct tegra_dma_channel), GFP_KERNEL); @@ -1612,6 +1591,24 @@ static const struct dev_pm_ops tegra_dma_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(tegra_dma_pm_suspend, tegra_dma_pm_resume) }; +static const struct of_device_id tegra_dma_of_match[] = { + { + .compatible = "nvidia,tegra148-apbdma", + .data = &tegra148_dma_chip_data, + }, { + .compatible = "nvidia,tegra114-apbdma", + .data = &tegra114_dma_chip_data, + }, { + .compatible = "nvidia,tegra30-apbdma", + .data = &tegra30_dma_chip_data, + }, { + .compatible = "nvidia,tegra20-apbdma", + .data = &tegra20_dma_chip_data, + }, { + }, +}; +MODULE_DEVICE_TABLE(of, tegra_dma_of_match); + static struct platform_driver tegra_dmac_driver = { .driver = { .name = "tegra-apbdma", |