diff mbox

[RFC,v02,04/15] dmaengine: edma: Add support for DMA filter mapping to slave devices

Message ID 1448891145-10766-5-git-send-email-peter.ujfalusi@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Peter Ujfalusi Nov. 30, 2015, 1:45 p.m. UTC
Add support for providing device to filter_fn mapping so client drivers
can switch to use the dma_request_chan() API.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/edma.c                 | 24 ++++++++++++++++++++++++
 include/linux/platform_data/edma.h |  5 +++++
 2 files changed, 29 insertions(+)

Comments

Arnd Bergmann Nov. 30, 2015, 2:11 p.m. UTC | #1
On Monday 30 November 2015 15:45:34 Peter Ujfalusi wrote:
> @@ -2428,6 +2436,22 @@ bool edma_filter_fn(struct dma_chan *chan, void *param)
>  }
>  EXPORT_SYMBOL(edma_filter_fn);
>  
> +static bool edma_filter_for_map(struct dma_chan *chan, void *param)
> +{
> +       bool match = false;
> +
> +       if (chan->device->dev->driver == &edma_driver.driver) {
> +               struct edma_chan *echan = to_edma_chan(chan);
> +               unsigned ch_req = (unsigned)param;
> +               if (ch_req == echan->ch_num) {
> +                       /* The channel is going to be used as HW synchronized */
> +                       echan->hw_triggered = true;
> +                       match = true;
> +               }
> +       }
> +       return match;
> +}
> +
>  static int edma_init(void)
> 

I don't see the difference between edma_filter_fn and edma_filter_for_map.
Why do you need both?

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Peter Ujfalusi Dec. 1, 2015, 9:58 a.m. UTC | #2
On 11/30/2015 04:11 PM, Arnd Bergmann wrote:
> On Monday 30 November 2015 15:45:34 Peter Ujfalusi wrote:
>> @@ -2428,6 +2436,22 @@ bool edma_filter_fn(struct dma_chan *chan, void *param)
>>  }
>>  EXPORT_SYMBOL(edma_filter_fn);
>>  
>> +static bool edma_filter_for_map(struct dma_chan *chan, void *param)
>> +{
>> +       bool match = false;
>> +
>> +       if (chan->device->dev->driver == &edma_driver.driver) {
>> +               struct edma_chan *echan = to_edma_chan(chan);
>> +               unsigned ch_req = (unsigned)param;
>> +               if (ch_req == echan->ch_num) {
>> +                       /* The channel is going to be used as HW synchronized */
>> +                       echan->hw_triggered = true;
>> +                       match = true;
>> +               }
>> +       }
>> +       return match;
>> +}
>> +
>>  static int edma_init(void)
>>
> 
> I don't see the difference between edma_filter_fn and edma_filter_for_map.
> Why do you need both?

edma_filter_fn:
	unsigned ch_req = *(unsigned *)param;

edma_filter_for_map:
	unsigned ch_req = (unsigned)param;


If I want to reuse the edma_filter_fn, I would need an unsigned array for the
eDMA event numbers in the board files to be able to provide the pointer to
each of them.
Arnd Bergmann Dec. 1, 2015, 10:14 a.m. UTC | #3
On Tuesday 01 December 2015 11:58:53 Peter Ujfalusi wrote:
> On 11/30/2015 04:11 PM, Arnd Bergmann wrote:
> > On Monday 30 November 2015 15:45:34 Peter Ujfalusi wrote:
> >> @@ -2428,6 +2436,22 @@ bool edma_filter_fn(struct dma_chan *chan, void *param)
> >>  }
> >>  EXPORT_SYMBOL(edma_filter_fn);
> >>  
> >> +static bool edma_filter_for_map(struct dma_chan *chan, void *param)
> >> +{
> >> +       bool match = false;
> >> +
> >> +       if (chan->device->dev->driver == &edma_driver.driver) {
> >> +               struct edma_chan *echan = to_edma_chan(chan);
> >> +               unsigned ch_req = (unsigned)param;
> >> +               if (ch_req == echan->ch_num) {
> >> +                       /* The channel is going to be used as HW synchronized */
> >> +                       echan->hw_triggered = true;
> >> +                       match = true;
> >> +               }
> >> +       }
> >> +       return match;
> >> +}
> >> +
> >>  static int edma_init(void)
> >>
> > 
> > I don't see the difference between edma_filter_fn and edma_filter_for_map.
> > Why do you need both?
> 
> edma_filter_fn:
>         unsigned ch_req = *(unsigned *)param;
> 
> edma_filter_for_map:
>         unsigned ch_req = (unsigned)param;

I see.

> If I want to reuse the edma_filter_fn, I would need an unsigned array for the
> eDMA event numbers in the board files to be able to provide the pointer to
> each of them.

How about this:

#define EDMA_CTLR_CHANP(ctlr, chan)      ((const int[]){ [0] = ((ctlr) << 16) | (chan)})

static struct dma_filter_map da830_edma_map[] = {
         { "davinci-mcasp.0", "rx", EDMA_CTLR_CHANP(0, 0)},
         { "davinci-mcasp.0", "tx", EDMA_CTLR_CHANP(0, 1)},
         { "davinci-mcasp.1", "rx", EDMA_CTLR_CHANP(0, 2)},
         ...
};

That way, you create an anonymous constant integer expression and the data
points to that.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Vinod Koul Dec. 1, 2015, 5:22 p.m. UTC | #4
On Mon, Nov 30, 2015 at 03:45:34PM +0200, Peter Ujfalusi wrote:
> Add support for providing device to filter_fn mapping so client drivers
> can switch to use the dma_request_chan() API.

Any reason why we dont want to go with DT based only for edma here?

> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
>  drivers/dma/edma.c                 | 24 ++++++++++++++++++++++++
>  include/linux/platform_data/edma.h |  5 +++++
>  2 files changed, 29 insertions(+)
> 
> diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
> index 0675e268d577..386f8c9bd606 100644
> --- a/drivers/dma/edma.c
> +++ b/drivers/dma/edma.c
> @@ -2098,6 +2098,8 @@ static struct dma_chan *of_edma_xlate(struct of_phandle_args *dma_spec,
>  }
>  #endif
>  
> +static bool edma_filter_for_map(struct dma_chan *chan, void *param);
> +
>  static int edma_probe(struct platform_device *pdev)
>  {
>  	struct edma_soc_info	*info = pdev->dev.platform_data;
> @@ -2297,6 +2299,12 @@ static int edma_probe(struct platform_device *pdev)
>  		edma_set_chmap(&ecc->slave_chans[i], ecc->dummy_slot);
>  	}
>  
> +	if (info->filter_map) {
> +		ecc->dma_slave.filter_map.map = info->filter_map;
> +		ecc->dma_slave.filter_map.mapcnt = info->filtercnt;
> +		ecc->dma_slave.filter_map.filter_fn = edma_filter_for_map;
> +	}
> +
>  	ret = dma_async_device_register(&ecc->dma_slave);
>  	if (ret) {
>  		dev_err(dev, "slave ddev registration failed (%d)\n", ret);
> @@ -2428,6 +2436,22 @@ bool edma_filter_fn(struct dma_chan *chan, void *param)
>  }
>  EXPORT_SYMBOL(edma_filter_fn);
>  
> +static bool edma_filter_for_map(struct dma_chan *chan, void *param)
> +{
> +	bool match = false;
> +
> +	if (chan->device->dev->driver == &edma_driver.driver) {
> +		struct edma_chan *echan = to_edma_chan(chan);
> +		unsigned ch_req = (unsigned)param;
> +		if (ch_req == echan->ch_num) {
> +			/* The channel is going to be used as HW synchronized */
> +			echan->hw_triggered = true;
> +			match = true;
> +		}
> +	}
> +	return match;
> +}
> +
>  static int edma_init(void)
>  {
>  	int ret;
> diff --git a/include/linux/platform_data/edma.h b/include/linux/platform_data/edma.h
> index e2878baeb90e..117a36d63840 100644
> --- a/include/linux/platform_data/edma.h
> +++ b/include/linux/platform_data/edma.h
> @@ -59,6 +59,8 @@ struct edma_rsv_info {
>  	const s16	(*rsv_slots)[2];
>  };
>  
> +struct dma_filter_map;
> +
>  /* platform_data for EDMA driver */
>  struct edma_soc_info {
>  	/*
> @@ -76,6 +78,9 @@ struct edma_soc_info {
>  
>  	s8	(*queue_priority_mapping)[2];
>  	const s16	(*xbar_chans)[2];
> +
> +	struct dma_filter_map *filter_map;
> +	int filtercnt;
>  };
>  
>  #endif
> -- 
> 2.6.3
>
Arnd Bergmann Dec. 1, 2015, 8:20 p.m. UTC | #5
On Tuesday 01 December 2015 22:52:12 Vinod Koul wrote:
> On Mon, Nov 30, 2015 at 03:45:34PM +0200, Peter Ujfalusi wrote:
> > Add support for providing device to filter_fn mapping so client drivers
> > can switch to use the dma_request_chan() API.
> 
> Any reason why we dont want to go with DT based only for edma here?

I think the OMAP2 based platforms using edma are all DT-only, but mach-davinci
would need a lot of work for that.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Vinod Koul Dec. 2, 2015, 4:37 a.m. UTC | #6
On Tue, Dec 01, 2015 at 09:20:28PM +0100, Arnd Bergmann wrote:
> On Tuesday 01 December 2015 22:52:12 Vinod Koul wrote:
> > On Mon, Nov 30, 2015 at 03:45:34PM +0200, Peter Ujfalusi wrote:
> > > Add support for providing device to filter_fn mapping so client drivers
> > > can switch to use the dma_request_chan() API.
> > 
> > Any reason why we dont want to go with DT based only for edma here?
> 
> I think the OMAP2 based platforms using edma are all DT-only, but mach-davinci
> would need a lot of work for that.

Okay sound fine then
Peter Ujfalusi Dec. 2, 2015, 10:02 a.m. UTC | #7
On 12/02/2015 06:37 AM, Vinod Koul wrote:
> On Tue, Dec 01, 2015 at 09:20:28PM +0100, Arnd Bergmann wrote:
>> On Tuesday 01 December 2015 22:52:12 Vinod Koul wrote:
>>> On Mon, Nov 30, 2015 at 03:45:34PM +0200, Peter Ujfalusi wrote:
>>>> Add support for providing device to filter_fn mapping so client drivers
>>>> can switch to use the dma_request_chan() API.
>>>
>>> Any reason why we dont want to go with DT based only for edma here?
>>
>> I think the OMAP2 based platforms using edma are all DT-only, but mach-davinci
>> would need a lot of work for that.
> 
> Okay sound fine then

Yes, daVinci is mostly board file based and the problem is that those devices
are hard to find to do the conversion to DT.
diff mbox

Patch

diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
index 0675e268d577..386f8c9bd606 100644
--- a/drivers/dma/edma.c
+++ b/drivers/dma/edma.c
@@ -2098,6 +2098,8 @@  static struct dma_chan *of_edma_xlate(struct of_phandle_args *dma_spec,
 }
 #endif
 
+static bool edma_filter_for_map(struct dma_chan *chan, void *param);
+
 static int edma_probe(struct platform_device *pdev)
 {
 	struct edma_soc_info	*info = pdev->dev.platform_data;
@@ -2297,6 +2299,12 @@  static int edma_probe(struct platform_device *pdev)
 		edma_set_chmap(&ecc->slave_chans[i], ecc->dummy_slot);
 	}
 
+	if (info->filter_map) {
+		ecc->dma_slave.filter_map.map = info->filter_map;
+		ecc->dma_slave.filter_map.mapcnt = info->filtercnt;
+		ecc->dma_slave.filter_map.filter_fn = edma_filter_for_map;
+	}
+
 	ret = dma_async_device_register(&ecc->dma_slave);
 	if (ret) {
 		dev_err(dev, "slave ddev registration failed (%d)\n", ret);
@@ -2428,6 +2436,22 @@  bool edma_filter_fn(struct dma_chan *chan, void *param)
 }
 EXPORT_SYMBOL(edma_filter_fn);
 
+static bool edma_filter_for_map(struct dma_chan *chan, void *param)
+{
+	bool match = false;
+
+	if (chan->device->dev->driver == &edma_driver.driver) {
+		struct edma_chan *echan = to_edma_chan(chan);
+		unsigned ch_req = (unsigned)param;
+		if (ch_req == echan->ch_num) {
+			/* The channel is going to be used as HW synchronized */
+			echan->hw_triggered = true;
+			match = true;
+		}
+	}
+	return match;
+}
+
 static int edma_init(void)
 {
 	int ret;
diff --git a/include/linux/platform_data/edma.h b/include/linux/platform_data/edma.h
index e2878baeb90e..117a36d63840 100644
--- a/include/linux/platform_data/edma.h
+++ b/include/linux/platform_data/edma.h
@@ -59,6 +59,8 @@  struct edma_rsv_info {
 	const s16	(*rsv_slots)[2];
 };
 
+struct dma_filter_map;
+
 /* platform_data for EDMA driver */
 struct edma_soc_info {
 	/*
@@ -76,6 +78,9 @@  struct edma_soc_info {
 
 	s8	(*queue_priority_mapping)[2];
 	const s16	(*xbar_chans)[2];
+
+	struct dma_filter_map *filter_map;
+	int filtercnt;
 };
 
 #endif