aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-23 21:36:55 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-23 21:36:55 -0500
commitf2c73464d7b399cf4e0c601c1c7d7b079080fa52 (patch)
tree902decd0c280757075bce5068fee679e0ccc261e /drivers/dma
parent93abdb7785503c269e73e811f3c7fd23a9243b14 (diff)
parent273c2279ca502267fac40bcaecb35942380c429c (diff)
Merge tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC cleanups from Olof Johansson: "This is the branch where we usually queue up cleanup efforts, moving drivers out of the architecture directory, header file restructuring, etc. Sometimes they tangle with new development so it's hard to keep it strictly to cleanups. Some of the things included in this branch are: * Atmel SAMA5 conversion to common clock * Reset framework conversion for tegra platforms - Some of this depends on tegra clock driver reworks that are shared with Mike Turquette's clk tree. * Tegra DMA refactoring, which are shared branches with the DMA tree. * Removal of some header files on exynos to prepare for multiplatform" * tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (169 commits) ARM: mvebu: move Armada 370/XP specific definitions to armada-370-xp.h ARM: mvebu: remove prototypes of non-existing functions from common.h ARM: mvebu: move ARMADA_XP_MAX_CPUS to armada-370-xp.h serial: sh-sci: Rework baud rate calculation serial: sh-sci: Compute overrun_bit without using baud rate algo serial: sh-sci: Remove unused GPIO request code serial: sh-sci: Move overrun_bit and error_mask fields out of pdata serial: sh-sci: Support resources passed through platform resources serial: sh-sci: Don't check IRQ in verify port operation serial: sh-sci: Set the UPF_FIXED_PORT flag serial: sh-sci: Remove duplicate interrupt check in verify port op serial: sh-sci: Simplify baud rate calculation algorithms serial: sh-sci: Remove baud rate calculation algorithm 5 serial: sh-sci: Sort headers alphabetically ARM: EXYNOS: Kill exynos_pm_late_initcall() ARM: EXYNOS: Consolidate selection of PM_GENERIC_DOMAINS for Exynos4 ARM: at91: switch Calao QIL-A9260 board to DT clk: at91: fix pmc_clk_ids data type attriubte PM / devfreq: use inclusion <mach/map.h> instead of <plat/map-s5p.h> ARM: EXYNOS: remove <mach/regs-clock.h> for exynos ...
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/Kconfig2
-rw-r--r--drivers/dma/dmaengine.c28
-rw-r--r--drivers/dma/mmp_pdma.c30
-rw-r--r--drivers/dma/tegra20-apb-dma.c52
4 files changed, 83 insertions, 29 deletions
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index c823daaf9043..c10eb89a3c1b 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -292,9 +292,11 @@ config MMP_TDMA
292 bool "MMP Two-Channel DMA support" 292 bool "MMP Two-Channel DMA support"
293 depends on ARCH_MMP 293 depends on ARCH_MMP
294 select DMA_ENGINE 294 select DMA_ENGINE
295 select MMP_SRAM
295 help 296 help
296 Support the MMP Two-Channel DMA engine. 297 Support the MMP Two-Channel DMA engine.
297 This engine used for MMP Audio DMA and pxa910 SQU. 298 This engine used for MMP Audio DMA and pxa910 SQU.
299 It needs sram driver under mach-mmp.
298 300
299 Say Y here if you enabled MMP ADMA, otherwise say N. 301 Say Y here if you enabled MMP ADMA, otherwise say N.
300 302
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 92caad629d99..ed610b497518 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -535,6 +535,34 @@ struct dma_chan *dma_get_slave_channel(struct dma_chan *chan)
535} 535}
536EXPORT_SYMBOL_GPL(dma_get_slave_channel); 536EXPORT_SYMBOL_GPL(dma_get_slave_channel);
537 537
538struct dma_chan *dma_get_any_slave_channel(struct dma_device *device)
539{
540 dma_cap_mask_t mask;
541 struct dma_chan *chan;
542 int err;
543
544 dma_cap_zero(mask);
545 dma_cap_set(DMA_SLAVE, mask);
546
547 /* lock against __dma_request_channel */
548 mutex_lock(&dma_list_mutex);
549
550 chan = private_candidate(&mask, device, NULL, NULL);
551 if (chan) {
552 err = dma_chan_get(chan);
553 if (err) {
554 pr_debug("%s: failed to get %s: (%d)\n",
555 __func__, dma_chan_name(chan), err);
556 chan = NULL;
557 }
558 }
559
560 mutex_unlock(&dma_list_mutex);
561
562 return chan;
563}
564EXPORT_SYMBOL_GPL(dma_get_any_slave_channel);
565
538/** 566/**
539 * __dma_request_channel - try to allocate an exclusive channel 567 * __dma_request_channel - try to allocate an exclusive channel
540 * @mask: capabilities that the channel must satisfy 568 * @mask: capabilities that the channel must satisfy
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index 8869500ab92b..c6a01ea8bc59 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -893,33 +893,17 @@ static struct dma_chan *mmp_pdma_dma_xlate(struct of_phandle_args *dma_spec,
893 struct of_dma *ofdma) 893 struct of_dma *ofdma)
894{ 894{
895 struct mmp_pdma_device *d = ofdma->of_dma_data; 895 struct mmp_pdma_device *d = ofdma->of_dma_data;
896 struct dma_chan *chan, *candidate; 896 struct dma_chan *chan;
897 struct mmp_pdma_chan *c;
897 898
898retry: 899 chan = dma_get_any_slave_channel(&d->device);
899 candidate = NULL; 900 if (!chan)
900
901 /* walk the list of channels registered with the current instance and
902 * find one that is currently unused */
903 list_for_each_entry(chan, &d->device.channels, device_node)
904 if (chan->client_count == 0) {
905 candidate = chan;
906 break;
907 }
908
909 if (!candidate)
910 return NULL; 901 return NULL;
911 902
912 /* dma_get_slave_channel will return NULL if we lost a race between 903 c = to_mmp_pdma_chan(chan);
913 * the lookup and the reservation */ 904 c->drcmr = dma_spec->args[0];
914 chan = dma_get_slave_channel(candidate);
915
916 if (chan) {
917 struct mmp_pdma_chan *c = to_mmp_pdma_chan(chan);
918 c->drcmr = dma_spec->args[0];
919 return chan;
920 }
921 905
922 goto retry; 906 return chan;
923} 907}
924 908
925static int mmp_pdma_probe(struct platform_device *op) 909static int mmp_pdma_probe(struct platform_device *op)
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index 73654e33f13b..d11bb3620f27 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * DMA driver for Nvidia's Tegra20 APB DMA controller. 2 * DMA driver for Nvidia's Tegra20 APB DMA controller.
3 * 3 *
4 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License, 7 * under the terms and conditions of the GNU General Public License,
@@ -29,11 +29,12 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/of.h> 30#include <linux/of.h>
31#include <linux/of_device.h> 31#include <linux/of_device.h>
32#include <linux/of_dma.h>
32#include <linux/platform_device.h> 33#include <linux/platform_device.h>
33#include <linux/pm.h> 34#include <linux/pm.h>
34#include <linux/pm_runtime.h> 35#include <linux/pm_runtime.h>
36#include <linux/reset.h>
35#include <linux/slab.h> 37#include <linux/slab.h>
36#include <linux/clk/tegra.h>
37 38
38#include "dmaengine.h" 39#include "dmaengine.h"
39 40
@@ -199,6 +200,7 @@ struct tegra_dma_channel {
199 void *callback_param; 200 void *callback_param;
200 201
201 /* Channel-slave specific configuration */ 202 /* Channel-slave specific configuration */
203 unsigned int slave_id;
202 struct dma_slave_config dma_sconfig; 204 struct dma_slave_config dma_sconfig;
203 struct tegra_dma_channel_regs channel_reg; 205 struct tegra_dma_channel_regs channel_reg;
204}; 206};
@@ -208,6 +210,7 @@ struct tegra_dma {
208 struct dma_device dma_dev; 210 struct dma_device dma_dev;
209 struct device *dev; 211 struct device *dev;
210 struct clk *dma_clk; 212 struct clk *dma_clk;
213 struct reset_control *rst;
211 spinlock_t global_lock; 214 spinlock_t global_lock;
212 void __iomem *base_addr; 215 void __iomem *base_addr;
213 const struct tegra_dma_chip_data *chip_data; 216 const struct tegra_dma_chip_data *chip_data;
@@ -339,6 +342,8 @@ static int tegra_dma_slave_config(struct dma_chan *dc,
339 } 342 }
340 343
341 memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig)); 344 memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig));
345 if (!tdc->slave_id)
346 tdc->slave_id = sconfig->slave_id;
342 tdc->config_init = true; 347 tdc->config_init = true;
343 return 0; 348 return 0;
344} 349}
@@ -941,7 +946,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg(
941 ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32; 946 ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32;
942 947
943 csr |= TEGRA_APBDMA_CSR_ONCE | TEGRA_APBDMA_CSR_FLOW; 948 csr |= TEGRA_APBDMA_CSR_ONCE | TEGRA_APBDMA_CSR_FLOW;
944 csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; 949 csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
945 if (flags & DMA_PREP_INTERRUPT) 950 if (flags & DMA_PREP_INTERRUPT)
946 csr |= TEGRA_APBDMA_CSR_IE_EOC; 951 csr |= TEGRA_APBDMA_CSR_IE_EOC;
947 952
@@ -1085,7 +1090,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic(
1085 csr |= TEGRA_APBDMA_CSR_FLOW; 1090 csr |= TEGRA_APBDMA_CSR_FLOW;
1086 if (flags & DMA_PREP_INTERRUPT) 1091 if (flags & DMA_PREP_INTERRUPT)
1087 csr |= TEGRA_APBDMA_CSR_IE_EOC; 1092 csr |= TEGRA_APBDMA_CSR_IE_EOC;
1088 csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT; 1093 csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
1089 1094
1090 apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1; 1095 apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1;
1091 1096
@@ -1205,6 +1210,25 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc)
1205 kfree(sg_req); 1210 kfree(sg_req);
1206 } 1211 }
1207 clk_disable_unprepare(tdma->dma_clk); 1212 clk_disable_unprepare(tdma->dma_clk);
1213
1214 tdc->slave_id = 0;
1215}
1216
1217static struct dma_chan *tegra_dma_of_xlate(struct of_phandle_args *dma_spec,
1218 struct of_dma *ofdma)
1219{
1220 struct tegra_dma *tdma = ofdma->of_dma_data;
1221 struct dma_chan *chan;
1222 struct tegra_dma_channel *tdc;
1223
1224 chan = dma_get_any_slave_channel(&tdma->dma_dev);
1225 if (!chan)
1226 return NULL;
1227
1228 tdc = to_tegra_dma_chan(chan);
1229 tdc->slave_id = dma_spec->args[0];
1230
1231 return chan;
1208} 1232}
1209 1233
1210/* Tegra20 specific DMA controller information */ 1234/* Tegra20 specific DMA controller information */
@@ -1282,6 +1306,12 @@ static int tegra_dma_probe(struct platform_device *pdev)
1282 return PTR_ERR(tdma->dma_clk); 1306 return PTR_ERR(tdma->dma_clk);
1283 } 1307 }
1284 1308
1309 tdma->rst = devm_reset_control_get(&pdev->dev, "dma");
1310 if (IS_ERR(tdma->rst)) {
1311 dev_err(&pdev->dev, "Error: Missing reset\n");
1312 return PTR_ERR(tdma->rst);
1313 }
1314
1285 spin_lock_init(&tdma->global_lock); 1315 spin_lock_init(&tdma->global_lock);
1286 1316
1287 pm_runtime_enable(&pdev->dev); 1317 pm_runtime_enable(&pdev->dev);
@@ -1302,9 +1332,9 @@ static int tegra_dma_probe(struct platform_device *pdev)
1302 } 1332 }
1303 1333
1304 /* Reset DMA controller */ 1334 /* Reset DMA controller */
1305 tegra_periph_reset_assert(tdma->dma_clk); 1335 reset_control_assert(tdma->rst);
1306 udelay(2); 1336 udelay(2);
1307 tegra_periph_reset_deassert(tdma->dma_clk); 1337 reset_control_deassert(tdma->rst);
1308 1338
1309 /* Enable global DMA registers */ 1339 /* Enable global DMA registers */
1310 tdma_write(tdma, TEGRA_APBDMA_GENERAL, TEGRA_APBDMA_GENERAL_ENABLE); 1340 tdma_write(tdma, TEGRA_APBDMA_GENERAL, TEGRA_APBDMA_GENERAL_ENABLE);
@@ -1376,10 +1406,20 @@ static int tegra_dma_probe(struct platform_device *pdev)
1376 goto err_irq; 1406 goto err_irq;
1377 } 1407 }
1378 1408
1409 ret = of_dma_controller_register(pdev->dev.of_node,
1410 tegra_dma_of_xlate, tdma);
1411 if (ret < 0) {
1412 dev_err(&pdev->dev,
1413 "Tegra20 APB DMA OF registration failed %d\n", ret);
1414 goto err_unregister_dma_dev;
1415 }
1416
1379 dev_info(&pdev->dev, "Tegra20 APB DMA driver register %d channels\n", 1417 dev_info(&pdev->dev, "Tegra20 APB DMA driver register %d channels\n",
1380 cdata->nr_channels); 1418 cdata->nr_channels);
1381 return 0; 1419 return 0;
1382 1420
1421err_unregister_dma_dev:
1422 dma_async_device_unregister(&tdma->dma_dev);
1383err_irq: 1423err_irq:
1384 while (--i >= 0) { 1424 while (--i >= 0) {
1385 struct tegra_dma_channel *tdc = &tdma->channels[i]; 1425 struct tegra_dma_channel *tdc = &tdma->channels[i];