Patchwork dmaengine: pl330: introduce debugfs interface

login
register
mail settings
Submitter Katsuhiro Suzuki
Date March 14, 2019, 6:49 p.m.
Message ID <20190314184953.8129-1-katsuhiro@katsuster.net>
Download mbox | patch
Permalink /patch/748997/
State New
Headers show

Comments

Katsuhiro Suzuki - March 14, 2019, 6:49 p.m.
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 an 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>
---
 drivers/dma/pl330.c | 51 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
Vinod Koul - March 15, 2019, 5 p.m.
On 15-03-19, 03:49, Katsuhiro Suzuki wrote:
> 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 an user specify DMA channel ID in devicetree. This interface will

a user :)

> 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>
> ---
>  drivers/dma/pl330.c | 51 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 51 insertions(+)
> 
> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
> index eec79fdf27a5..aab71863757c 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, found;
> +
> +	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];
> +
> +		found = -1;

found can be uninitialized if we skip this for, which should not be an
issue as chans> 0!

> +		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 | S_IRUGO, NULL, pl330,

are we not supposed to use octal permissions?

> +			    &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,
> -- 
> 2.20.1
Katsuhiro Suzuki - March 17, 2019, 9:58 a.m.
Hello Vinod,

Thank you for your comment.
I fix it all and re-post v2 patch.


On 2019/03/16 2:00, Vinod Koul wrote:
> On 15-03-19, 03:49, Katsuhiro Suzuki wrote:
>> 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 an user specify DMA channel ID in devicetree. This interface will
> 
> a user :)
> 
>> 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>
>> ---
>>   drivers/dma/pl330.c | 51 +++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 51 insertions(+)
>>
>> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
>> index eec79fdf27a5..aab71863757c 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, found;
>> +
>> +	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];
>> +
>> +		found = -1;
> 
> found can be uninitialized if we skip this for, which should not be an
> issue as chans> 0!
> 

Exactly. Thanks, 'found' should be changed to for-loop local variable.


>> +		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 | S_IRUGO, NULL, pl330,
> 
> are we not supposed to use octal permissions?
> 
>> +			    &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,
>> -- 
>> 2.20.1
> 

Best Regards,
Katsuhiro Suzuki

Patch

diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index eec79fdf27a5..aab71863757c 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, found;
+
+	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];
+
+		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 | S_IRUGO, 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,