diff mbox

dmaengine: maintain privatecnt in get_any_slave_channel

Message ID 1418036853-2889-1-git-send-email-julian@jusst.de (mailing list archive)
State Not Applicable
Headers show

Commit Message

Julian Scheel Dec. 8, 2014, 11:07 a.m. UTC
As dma_get_any_slave_channel is used to request a channel which will later on
be released through dma_release_channel it needs to maintain the privatecnt
just as __dma_request_channel does. Do this by refactoring the privatenct
handling into a helper function which is used from __dma_request_channel as
well as dma_get_any_slave_channel.

Signed-off-by: Julian Scheel <julian@jusst.de>
---
 drivers/dma/dmaengine.c | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

Comments

Julian Scheel Dec. 23, 2014, 11:27 a.m. UTC | #1
Am 08.12.2014 um 12:07 schrieb Julian Scheel:
> As dma_get_any_slave_channel is used to request a channel which will later on
> be released through dma_release_channel it needs to maintain the privatecnt
> just as __dma_request_channel does. Do this by refactoring the privatenct
> handling into a helper function which is used from __dma_request_channel as
> well as dma_get_any_slave_channel.
>
> Signed-off-by: Julian Scheel <julian@jusst.de>
> ---
>   drivers/dma/dmaengine.c | 30 +++++++++++++++++++++---------
>   1 file changed, 21 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> index 24bfaf0..0215db4 100644
> --- a/drivers/dma/dmaengine.c
> +++ b/drivers/dma/dmaengine.c
> @@ -535,6 +535,24 @@ struct dma_chan *dma_get_slave_channel(struct dma_chan *chan)
>   }
>   EXPORT_SYMBOL_GPL(dma_get_slave_channel);
>
> +
> +static int dma_get_channel_private(struct dma_device *device, struct dma_chan *chan)
> +{
> +	int err;
> +
> +	/* We first set DMA_PRIVATE to disable
> +	 * balance_ref_count as this channel will not be
> +	 * published in the general-purpose allocator
> +	 */
> +	dma_cap_set(DMA_PRIVATE, device->cap_mask);
> +	device->privatecnt++;
> +
> +	err = dma_chan_get(chan);
> +	if (err && --device->privatecnt == 0)
> +			dma_cap_clear(DMA_PRIVATE, device->cap_mask);
> +	return err;
> +}
> +
>   struct dma_chan *dma_get_any_slave_channel(struct dma_device *device)
>   {
>   	dma_cap_mask_t mask;
> @@ -549,7 +567,7 @@ struct dma_chan *dma_get_any_slave_channel(struct dma_device *device)
>
>   	chan = private_candidate(&mask, device, NULL, NULL);
>   	if (chan) {
> -		err = dma_chan_get(chan);
> +		err = dma_get_channel_private(device, chan);
>   		if (err) {
>   			pr_debug("%s: failed to get %s: (%d)\n",
>   				__func__, dma_chan_name(chan), err);
> @@ -584,13 +602,9 @@ struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
>   		chan = private_candidate(mask, device, fn, fn_param);
>   		if (chan) {
>   			/* Found a suitable channel, try to grab, prep, and
> -			 * return it.  We first set DMA_PRIVATE to disable
> -			 * balance_ref_count as this channel will not be
> -			 * published in the general-purpose allocator
> +			 * return it.
>   			 */
> -			dma_cap_set(DMA_PRIVATE, device->cap_mask);
> -			device->privatecnt++;
> -			err = dma_chan_get(chan);
> +			err = dma_get_channel_private(device, chan);
>
>   			if (err == -ENODEV) {
>   				pr_debug("%s: %s module removed\n",
> @@ -601,8 +615,6 @@ struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
>   					 __func__, dma_chan_name(chan), err);
>   			else
>   				break;
> -			if (--device->privatecnt == 0)
> -				dma_cap_clear(DMA_PRIVATE, device->cap_mask);
>   			chan = NULL;
>   		}
>   	}
>

Any objections on this patch?

-Julian

--
To unsubscribe from this list: send the line "unsubscribe dmaengine" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 24bfaf0..0215db4 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -535,6 +535,24 @@  struct dma_chan *dma_get_slave_channel(struct dma_chan *chan)
 }
 EXPORT_SYMBOL_GPL(dma_get_slave_channel);
 
+
+static int dma_get_channel_private(struct dma_device *device, struct dma_chan *chan)
+{
+	int err;
+
+	/* We first set DMA_PRIVATE to disable
+	 * balance_ref_count as this channel will not be
+	 * published in the general-purpose allocator
+	 */
+	dma_cap_set(DMA_PRIVATE, device->cap_mask);
+	device->privatecnt++;
+
+	err = dma_chan_get(chan);
+	if (err && --device->privatecnt == 0)
+			dma_cap_clear(DMA_PRIVATE, device->cap_mask);
+	return err;
+}
+
 struct dma_chan *dma_get_any_slave_channel(struct dma_device *device)
 {
 	dma_cap_mask_t mask;
@@ -549,7 +567,7 @@  struct dma_chan *dma_get_any_slave_channel(struct dma_device *device)
 
 	chan = private_candidate(&mask, device, NULL, NULL);
 	if (chan) {
-		err = dma_chan_get(chan);
+		err = dma_get_channel_private(device, chan);
 		if (err) {
 			pr_debug("%s: failed to get %s: (%d)\n",
 				__func__, dma_chan_name(chan), err);
@@ -584,13 +602,9 @@  struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
 		chan = private_candidate(mask, device, fn, fn_param);
 		if (chan) {
 			/* Found a suitable channel, try to grab, prep, and
-			 * return it.  We first set DMA_PRIVATE to disable
-			 * balance_ref_count as this channel will not be
-			 * published in the general-purpose allocator
+			 * return it.
 			 */
-			dma_cap_set(DMA_PRIVATE, device->cap_mask);
-			device->privatecnt++;
-			err = dma_chan_get(chan);
+			err = dma_get_channel_private(device, chan);
 
 			if (err == -ENODEV) {
 				pr_debug("%s: %s module removed\n",
@@ -601,8 +615,6 @@  struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
 					 __func__, dma_chan_name(chan), err);
 			else
 				break;
-			if (--device->privatecnt == 0)
-				dma_cap_clear(DMA_PRIVATE, device->cap_mask);
 			chan = NULL;
 		}
 	}