Re: [PATCH] dmaengine: maintain privatecnt in get_any_slave_channel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxx>
---
  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@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux