aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/bcm2835-dma.c
diff options
context:
space:
mode:
authorMartin Sperl <kernel@martin.sperl.org>2016-04-11 09:29:08 -0400
committerVinod Koul <vinod.koul@intel.com>2016-04-19 11:32:48 -0400
commite2eca6389b031cdbbc4172eee89ce271c00cb672 (patch)
tree8d04e37288b8d3b47c6972794d629fb8eee21f0d /drivers/dma/bcm2835-dma.c
parente7679db714c356f8e27df2dc3ff721c0d3775448 (diff)
dmaengine: bcm2835: use platform_get_irq_byname
Use platform_get_irq_byname to allow for correct mapping of interrupts to dma channels. The currently implemented device tree is unfortunately implemented with the wrong assumption, that each dma-channel has its own dma channel, but dma-irq 11 is handling dma-channel 11-14 and dma-irq 12 is actually a "catch all" interrupt. So here we use the byname variant and require that interrupts are explicitly named via the interrupts-name property in the device tree. The use of shared interrupts is also implemented. As a side-effect this means we can now use dma channels 12, 13 and 14 in a correct manner - also testing shows that onl using channels 11 to 14 for spi and i2s works perfectly (when playing some video) Signed-off-by: Martin Sperl <kernel@martin.sperl.org> Acked-by: Eric Anholt <eric@anholt.net> Acked-by: Mark Rutland <mark.rutland@arm.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/bcm2835-dma.c')
-rw-r--r--drivers/dma/bcm2835-dma.c77
1 files changed, 63 insertions, 14 deletions
diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c
index cc771cd35dd0..974015193b93 100644
--- a/drivers/dma/bcm2835-dma.c
+++ b/drivers/dma/bcm2835-dma.c
@@ -46,6 +46,9 @@
46 46
47#include "virt-dma.h" 47#include "virt-dma.h"
48 48
49#define BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED 14
50#define BCM2835_DMA_CHAN_NAME_SIZE 8
51
49struct bcm2835_dmadev { 52struct bcm2835_dmadev {
50 struct dma_device ddev; 53 struct dma_device ddev;
51 spinlock_t lock; 54 spinlock_t lock;
@@ -81,6 +84,7 @@ struct bcm2835_chan {
81 84
82 void __iomem *chan_base; 85 void __iomem *chan_base;
83 int irq_number; 86 int irq_number;
87 unsigned int irq_flags;
84 88
85 bool is_lite_channel; 89 bool is_lite_channel;
86}; 90};
@@ -466,6 +470,15 @@ static irqreturn_t bcm2835_dma_callback(int irq, void *data)
466 struct bcm2835_desc *d; 470 struct bcm2835_desc *d;
467 unsigned long flags; 471 unsigned long flags;
468 472
473 /* check the shared interrupt */
474 if (c->irq_flags & IRQF_SHARED) {
475 /* check if the interrupt is enabled */
476 flags = readl(c->chan_base + BCM2835_DMA_CS);
477 /* if not set then we are not the reason for the irq */
478 if (!(flags & BCM2835_DMA_INT))
479 return IRQ_NONE;
480 }
481
469 spin_lock_irqsave(&c->vc.lock, flags); 482 spin_lock_irqsave(&c->vc.lock, flags);
470 483
471 /* Acknowledge interrupt */ 484 /* Acknowledge interrupt */
@@ -506,8 +519,8 @@ static int bcm2835_dma_alloc_chan_resources(struct dma_chan *chan)
506 return -ENOMEM; 519 return -ENOMEM;
507 } 520 }
508 521
509 return request_irq(c->irq_number, 522 return request_irq(c->irq_number, bcm2835_dma_callback,
510 bcm2835_dma_callback, 0, "DMA IRQ", c); 523 c->irq_flags, "DMA IRQ", c);
511} 524}
512 525
513static void bcm2835_dma_free_chan_resources(struct dma_chan *chan) 526static void bcm2835_dma_free_chan_resources(struct dma_chan *chan)
@@ -819,7 +832,8 @@ static int bcm2835_dma_terminate_all(struct dma_chan *chan)
819 return 0; 832 return 0;
820} 833}
821 834
822static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id, int irq) 835static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id,
836 int irq, unsigned int irq_flags)
823{ 837{
824 struct bcm2835_chan *c; 838 struct bcm2835_chan *c;
825 839
@@ -834,6 +848,7 @@ static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id, int irq)
834 c->chan_base = BCM2835_DMA_CHANIO(d->base, chan_id); 848 c->chan_base = BCM2835_DMA_CHANIO(d->base, chan_id);
835 c->ch = chan_id; 849 c->ch = chan_id;
836 c->irq_number = irq; 850 c->irq_number = irq;
851 c->irq_flags = irq_flags;
837 852
838 /* check in DEBUG register if this is a LITE channel */ 853 /* check in DEBUG register if this is a LITE channel */
839 if (readl(c->chan_base + BCM2835_DMA_DEBUG) & 854 if (readl(c->chan_base + BCM2835_DMA_DEBUG) &
@@ -882,9 +897,11 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
882 struct resource *res; 897 struct resource *res;
883 void __iomem *base; 898 void __iomem *base;
884 int rc; 899 int rc;
885 int i; 900 int i, j;
886 int irq; 901 int irq[BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED + 1];
902 int irq_flags;
887 uint32_t chans_available; 903 uint32_t chans_available;
904 char chan_name[BCM2835_DMA_CHAN_NAME_SIZE];
888 905
889 if (!pdev->dev.dma_mask) 906 if (!pdev->dev.dma_mask)
890 pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; 907 pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
@@ -941,16 +958,48 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
941 goto err_no_dma; 958 goto err_no_dma;
942 } 959 }
943 960
944 for (i = 0; i < pdev->num_resources; i++) { 961 /* get irqs for each channel that we support */
945 irq = platform_get_irq(pdev, i); 962 for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) {
946 if (irq < 0) 963 /* skip masked out channels */
947 break; 964 if (!(chans_available & (1 << i))) {
948 965 irq[i] = -1;
949 if (chans_available & (1 << i)) { 966 continue;
950 rc = bcm2835_dma_chan_init(od, i, irq);
951 if (rc)
952 goto err_no_dma;
953 } 967 }
968
969 /* get the named irq */
970 snprintf(chan_name, sizeof(chan_name), "dma%i", i);
971 irq[i] = platform_get_irq_byname(pdev, chan_name);
972 if (irq[i] >= 0)
973 continue;
974
975 /* legacy device tree case handling */
976 dev_warn_once(&pdev->dev,
977 "missing interrupts-names property in device tree - legacy interpretation is used");
978 /*
979 * in case of channel >= 11
980 * use the 11th interrupt and that is shared
981 */
982 irq[i] = platform_get_irq(pdev, i < 11 ? i : 11);
983 }
984
985 /* get irqs for each channel */
986 for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) {
987 /* skip channels without irq */
988 if (irq[i] < 0)
989 continue;
990
991 /* check if there are other channels that also use this irq */
992 irq_flags = 0;
993 for (j = 0; j <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; j++)
994 if ((i != j) && (irq[j] == irq[i])) {
995 irq_flags = IRQF_SHARED;
996 break;
997 }
998
999 /* initialize the channel */
1000 rc = bcm2835_dma_chan_init(od, i, irq[i], irq_flags);
1001 if (rc)
1002 goto err_no_dma;
954 } 1003 }
955 1004
956 dev_dbg(&pdev->dev, "Initialized %i DMA channels\n", i); 1005 dev_dbg(&pdev->dev, "Initialized %i DMA channels\n", i);