Skip to contentSkip to conversation

dw_dmac: don't exceed AHB master number in dwc_get_data_width

PATCH Superseded Andy Shevchenko 3 participants 7 messages Jan 14, 2013 – Jan 15, 2013 dmaengine

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 dw_dmac: don't exceed AHB master number in dwc_get_data_width

The driver's default assumes that hardware has two AHB masters which might be not true. In such rare cases we have not to exceed a number of the AHB masters present in the hardware. Thus, the AHB master with highest possible number will be used to retrieve the data witdh value.

The patch also changes the logic a bit when the master parameter of the dwc_get_data_width() is out of range. Now the function will return a value related to the first AHB master.

---
 drivers/dma/dw_dmac.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/dma/dw_dmac.c +4 -3
index 30ff2a4..b2d564a 100644
@@ -80,13 +80,14 @@ static inline unsigned int dwc_get_data_width(struct dma_chan *chan, int master)
 {
 	struct dw_dma *dw = to_dw_dma(chan->device);
 	struct dw_dma_slave *dws = chan->private;
+	unsigned int m = 0;
 
 	if (master == SRC_MASTER)
-		return dw->data_width[dwc_get_sms(dws)];
+		m = dwc_get_sms(dws);
 	else if (master == DST_MASTER)
-		return dw->data_width[dwc_get_dms(dws)];
+		m = dwc_get_dms(dws);
 
-	return 0;
+	return dw->data_width[min_t(unsigned int, dw->nr_masters - 1, m)];
 }
 
 /*----------------------------------------------------------------------*/
Signature · 1 line
1.7.10.4
#1 lore raw
Quoted 23 lines · Andy Shevchenko

The driver's default assumes that hardware has two AHB masters which might be not true. In such rare cases we have not to exceed a number of the AHB masters present in the hardware. Thus, the AHB master with highest possible number will be used to retrieve the data witdh value.

The patch also changes the logic a bit when the master parameter of the dwc_get_data_width() is out of range. Now the function will return a value related to the first AHB master.

---
 drivers/dma/dw_dmac.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/dma/dw_dmac.c +1 -0
index 30ff2a4..b2d564a 100644
@@ -80,13 +80,14 @@ static inline unsigned int dwc_get_data_width(struct dma_chan *chan, int master)
 {
        struct dw_dma *dw = to_dw_dma(chan->device);
        struct dw_dma_slave *dws = chan->private;
+       unsigned int m = 0;

drivers/dma/dw_dmac.c static inline unsigned int dwc_get_data_width(struct dma_chan *chan, int master) · line 90

Quoted 10 lines
drivers/dma/dw_dmac.c +3 -3
 
        if (master == SRC_MASTER)
-               return dw->data_width[dwc_get_sms(dws)];
+               m = dwc_get_sms(dws);
        else if (master == DST_MASTER)
-               return dw->data_width[dwc_get_dms(dws)];
+               m = dwc_get_dms(dws);
 
-       return 0;
+       return dw->data_width[min_t(unsigned int, dw->nr_masters - 1, m)];

The details of the patch are fine, but i didn't get how do you get master 1 selected
on a system where you have only 1 master?

#2 lore raw
Quoted 33 lines · Viresh Kumar
Quoted 31 lines · Andy Shevchenko

The driver's default assumes that hardware has two AHB masters which might be not true. In such rare cases we have not to exceed a number of the AHB masters present in the hardware. Thus, the AHB master with highest possible number will be used to retrieve the data witdh value.

The patch also changes the logic a bit when the master parameter of the dwc_get_data_width() is out of range. Now the function will return a value related to the first AHB master.

---
 drivers/dma/dw_dmac.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/dma/dw_dmac.c +3 -2
index 30ff2a4..b2d564a 100644
@@ -80,13 +80,14 @@ static inline unsigned int dwc_get_data_width(struct dma_chan *chan, int master)
 {
        struct dw_dma *dw = to_dw_dma(chan->device);
        struct dw_dma_slave *dws = chan->private;
+       unsigned int m = 0;
 
        if (master == SRC_MASTER)
-               return dw->data_width[dwc_get_sms(dws)];
+               m = dwc_get_sms(dws);
        else if (master == DST_MASTER)
-               return dw->data_width[dwc_get_dms(dws)];
+               m = dwc_get_dms(dws);
 
Quoted 6 lines

drivers/dma/dw_dmac.c static inline unsigned int dwc_get_data_width(struct dma_chan *chan, int master) · line 90

Quoted 2 lines
drivers/dma/dw_dmac.c +1 -1
-       return 0;
+       return dw->data_width[min_t(unsigned int, dw->nr_masters - 1, m)];

The details of the patch are fine, but i didn't get how do you get master 1 selected
on a system where you have only 1 master?

min_t(..., nr_masters - 1, m) defines this. m is returned value with default settings, let's say 1. In that case if nr_masters is also 1 the min_t(..., 1-1, 1) returns 0.

The value of nr_masters itself is come from autoconfig or platform data.

Quoted 5 lines

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Signature · 2 lines
With Best Regards,
Andy Shevchenko
#3 lore raw
Quoted 9 lines · Andy Shevchenko
Quoted 3 lines

The details of the patch are fine, but i didn't get how do you get master 1 selected
on a system where you have only 1 master?

min_t(..., nr_masters - 1, m) defines this. m is returned value with default settings, let's say 1. In that case if nr_masters is also 1 the min_t(..., 1-1, 1) returns 0.

The value of nr_masters itself is come from autoconfig or platform data.

:)
You didn't get me. How this code would work is pretty easy to understand. What i wanted to know is, the master information is coming from slave drivers and they must select master zero always. How would master 1 be selected ever in this driver.

#4 lore raw
Quoted 10 lines · Viresh Kumar
Quoted 8 lines · Andy Shevchenko
Quoted 3 lines

The details of the patch are fine, but i didn't get how do you get master 1 selected
on a system where you have only 1 master?

min_t(..., nr_masters - 1, m) defines this. m is returned value with default settings, let's say 1. In that case if nr_masters is also 1 the min_t(..., 1-1, 1) returns 0.

Quoted 7 lines
Quoted 1 line

The value of nr_masters itself is come from autoconfig or platform data.

:)
You didn't get me. How this code would work is pretty easy to understand. What i wanted to know is, the master information is coming from slave drivers and they must select master zero always. How would master 1 be selected ever in this driver.

You forgot the mem2mem type of transfers where we have no information about masters except default settings. Otherwise there is the case of custom slave config absence when we supply only request line via slave_id.

In the rest you are right.

Signature · 2 lines
With Best Regards,
Andy Shevchenko
#5 lore raw
Quoted 4 lines · Andy Shevchenko

You forgot the mem2mem type of transfers where we have no information about masters except default settings. Otherwise there is the case of custom slave config absence when we supply only request line via slave_id.

Okay, but even for mem2mem you have just got the right bus width by selecting same master. But are you programming same masters in control register? I can't see that :(

#6 lore raw
Quoted 9 lines · Viresh Kumar
Quoted 4 lines · Andy Shevchenko

You forgot the mem2mem type of transfers where we have no information about masters except default settings. Otherwise there is the case of custom slave config absence when we supply only request line via slave_id.

Okay, but even for mem2mem you have just got the right bus width by selecting same master. But are you programming same masters in control register? I can't see that :(

Oops. Seems this patch does not cover the CTL lo register value. Thank you for pointing this out. I will think how to make the fix better.

Signature · 2 lines
With Best Regards,
Andy Shevchenko