Skip to content

Commit 859bda4

Browse files
committed
dmaengine: add dma_request/release_chan_linked to manage device link
In order to enforce suspend/resume ordering, this patch adds a new API to request/release a DMA channel and create a device link between DMA controller (DMA channel provider) and DMA client (DMA channel consumer). This link avoids to suspend DMA before DMA clients. Clients who will use dma_request_chan_linked will have to unbalanced the device link by using dma_release_chan_linked. Change-Id: I37b69cf74b60091e2fff5447d6c623594d903737 Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com> Reviewed-on: https://gerrit.st.com/c/mpu/oe/st/linux-stm32/+/155327 Reviewed-by: CITOOLS <smet-aci-reviews@lists.codex.cro.st.com> Reviewed-by: Alexandre TORGUE <alexandre.torgue@st.com>
1 parent ed53604 commit 859bda4

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

drivers/dma/dmaengine.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,34 @@ struct dma_chan *dma_request_chan(struct device *dev, const char *name)
736736
}
737737
EXPORT_SYMBOL_GPL(dma_request_chan);
738738

739+
/**
740+
* dma_request_chan_linked - try to allocate an exclusive slave channel
741+
* @dev: pointer to client device structure
742+
* @name: slave channel name
743+
*
744+
* Returns pointer to appropriate DMA channel on success or an error pointer.
745+
* Create device link between DMA channel provider and client device consumer.
746+
*/
747+
struct dma_chan *dma_request_chan_linked(struct device *dev, const char *name)
748+
{
749+
struct dma_chan *ch = dma_request_chan(dev, name);
750+
struct device *provider_dev = ch->device->dev;
751+
struct device_link *link;
752+
753+
if (!IS_ERR_OR_NULL(ch)) {
754+
link = device_link_add(dev, provider_dev, DL_FLAG_STATELESS);
755+
if (!link) {
756+
dev_err(provider_dev,
757+
"failed to add dev link with %s\n",
758+
dev_name(dev));
759+
return ERR_PTR(-EINVAL);
760+
}
761+
}
762+
763+
return ch;
764+
}
765+
EXPORT_SYMBOL_GPL(dma_request_chan_linked);
766+
739767
/**
740768
* dma_request_slave_channel - try to allocate an exclusive slave channel
741769
* @dev: pointer to client device structure
@@ -794,6 +822,13 @@ void dma_release_channel(struct dma_chan *chan)
794822
}
795823
EXPORT_SYMBOL_GPL(dma_release_channel);
796824

825+
void dma_release_chan_linked(struct device *dev, struct dma_chan *chan)
826+
{
827+
device_link_remove(dev, chan->device->dev);
828+
dma_release_channel(chan);
829+
}
830+
EXPORT_SYMBOL_GPL(dma_release_chan_linked);
831+
797832
/**
798833
* dmaengine_get - register interest in dma_channels
799834
*/

include/linux/dmaengine.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,9 +1318,11 @@ struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
13181318
struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name);
13191319

13201320
struct dma_chan *dma_request_chan(struct device *dev, const char *name);
1321+
struct dma_chan *dma_request_chan_linked(struct device *dev, const char *name);
13211322
struct dma_chan *dma_request_chan_by_mask(const dma_cap_mask_t *mask);
13221323

13231324
void dma_release_channel(struct dma_chan *chan);
1325+
void dma_release_chan_linked(struct device *dev, struct dma_chan *chan);
13241326
int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps);
13251327
#else
13261328
static inline struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type)
@@ -1353,6 +1355,11 @@ static inline struct dma_chan *dma_request_chan(struct device *dev,
13531355
{
13541356
return ERR_PTR(-ENODEV);
13551357
}
1358+
static inline struct dma_chan *dma_request_chan_linked(struct device *dev,
1359+
const char *name)
1360+
{
1361+
return ERR_PTR(-ENODEV);
1362+
}
13561363
static inline struct dma_chan *dma_request_chan_by_mask(
13571364
const dma_cap_mask_t *mask)
13581365
{
@@ -1361,6 +1368,10 @@ static inline struct dma_chan *dma_request_chan_by_mask(
13611368
static inline void dma_release_channel(struct dma_chan *chan)
13621369
{
13631370
}
1371+
static inline void dma_release_chan_linked(struct device *dev,
1372+
struct dma_chan *chan)
1373+
{
1374+
}
13641375
static inline int dma_get_slave_caps(struct dma_chan *chan,
13651376
struct dma_slave_caps *caps)
13661377
{

0 commit comments

Comments
 (0)