summaryrefslogtreecommitdiffstats
path: root/drivers/dma/pl330.c
diff options
context:
space:
mode:
authorKatsuhiro Suzuki <katsuhiro@katsuster.net>2019-03-17 11:03:06 +0100
committerVinod Koul <vkoul@kernel.org>2019-03-25 17:22:28 +0100
commitb45aef3aef63610e75fa67c7ae8b838304bdad3e (patch)
treef0ae2343d96391012fc9196203cf6514a8819a52 /drivers/dma/pl330.c
parentdmaengine: tegra210-adma: update system sleep callbacks (diff)
downloadlinux-b45aef3aef63610e75fa67c7ae8b838304bdad3e.tar.xz
linux-b45aef3aef63610e75fa67c7ae8b838304bdad3e.zip
dmaengine: pl330: introduce debugfs interface
This patch adds debugfs interface to show the relationship between DMA threads (hardware resource for transferring data) and DMA channel ID of DMA slave. Typically, PL330 has many slaves than number of DMA threads. So sometimes PL330 cannot allocate DMA threads for all slaves even if a user specify DMA channel ID in devicetree. This interface will be useful for checking that DMA threads are allocated or not. Below is an output sample: $ sudo cat /sys/kernel/debug/ff1f0000.dmac PL330 physical channels: THREAD: CHANNEL: -------- ----- 0 8 1 9 2 11 3 12 4 14 5 15 6 10 7 -- Signed-off-by: Katsuhiro Suzuki <katsuhiro@katsuster.net> Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/dma/pl330.c')
-rw-r--r--drivers/dma/pl330.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index eec79fdf27a5..c72f6fd79c43 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -11,6 +11,7 @@
* (at your option) any later version.
*/
+#include <linux/debugfs.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/init.h>
@@ -2896,6 +2897,55 @@ static irqreturn_t pl330_irq_handler(int irq, void *data)
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
BIT(DMA_SLAVE_BUSWIDTH_8_BYTES)
+#ifdef CONFIG_DEBUG_FS
+static int pl330_debugfs_show(struct seq_file *s, void *data)
+{
+ struct pl330_dmac *pl330 = s->private;
+ int chans, pchs, ch, pr;
+
+ chans = pl330->pcfg.num_chan;
+ pchs = pl330->num_peripherals;
+
+ seq_puts(s, "PL330 physical channels:\n");
+ seq_puts(s, "THREAD:\t\tCHANNEL:\n");
+ seq_puts(s, "--------\t-----\n");
+ for (ch = 0; ch < chans; ch++) {
+ struct pl330_thread *thrd = &pl330->channels[ch];
+ int found = -1;
+
+ for (pr = 0; pr < pchs; pr++) {
+ struct dma_pl330_chan *pch = &pl330->peripherals[pr];
+
+ if (!pch->thread || thrd->id != pch->thread->id)
+ continue;
+
+ found = pr;
+ }
+
+ seq_printf(s, "%d\t\t", thrd->id);
+ if (found == -1)
+ seq_puts(s, "--\n");
+ else
+ seq_printf(s, "%d\n", found);
+ }
+
+ return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(pl330_debugfs);
+
+static inline void init_pl330_debugfs(struct pl330_dmac *pl330)
+{
+ debugfs_create_file(dev_name(pl330->ddma.dev),
+ S_IFREG | 0444, NULL, pl330,
+ &pl330_debugfs_fops);
+}
+#else
+static inline void init_pl330_debugfs(struct pl330_dmac *pl330)
+{
+}
+#endif
+
/*
* Runtime PM callbacks are provided by amba/bus.c driver.
*
@@ -3082,6 +3132,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
dev_err(&adev->dev, "unable to set the seg size\n");
+ init_pl330_debugfs(pl330);
dev_info(&adev->dev,
"Loaded driver for PL330 DMAC-%x\n", adev->periphid);
dev_info(&adev->dev,