aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/dmaengine.c
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2013-11-26 12:04:22 -0500
committerVinod Koul <vinod.koul@intel.com>2013-12-10 07:16:48 -0500
commit0ad7c00057dc1640647c1dc81ccbd009de17a767 (patch)
treeb73891fc496ebb59a4fb531667d7f89d58698786 /drivers/dma/dmaengine.c
parent6ce4eac1f600b34f2f7f58f9cd8f0503d79e42ae (diff)
dma: add channel request API that supports deferred probe
dma_request_slave_channel() simply returns NULL whenever DMA channel lookup fails. Lookup could fail for two distinct reasons: a) No DMA specification exists for the channel name. This includes situations where no DMA specifications exist at all, or other general lookup problems. b) A DMA specification does exist, yet the driver for that channel is not yet registered. Case (b) should trigger deferred probe in client drivers. However, since they have no way to differentiate the two situations, it cannot. Implement new function dma_request_slave_channel_reason(), which performs identically to dma_request_slave_channel(), except that it returns an error-pointer rather than NULL, which allows callers to detect when deferred probe should occur. Eventually, all drivers should be converted to this new API, the old API removed, and the new API renamed to the more desirable name. This patch doesn't convert the existing API and all drivers in one go, since some drivers call dma_request_slave_channel() then dma_request_channel() if that fails. That would require either modifying dma_request_channel() in the same way, or adding extra error-handling code to all affected drivers, and there are close to 100 drivers using the other API, rather than just the 15-20 or so that use dma_request_slave_channel(), which might be tenable in a single patch. acpi_dma_request_slave_chan_by_name() doesn't currently implement deferred probe. It should, but this will be addressed later. Acked-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/dmaengine.c')
-rw-r--r--drivers/dma/dmaengine.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index ea806bdc12ef..e17e9b22d85e 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -540,6 +540,8 @@ EXPORT_SYMBOL_GPL(dma_get_slave_channel);
540 * @mask: capabilities that the channel must satisfy 540 * @mask: capabilities that the channel must satisfy
541 * @fn: optional callback to disposition available channels 541 * @fn: optional callback to disposition available channels
542 * @fn_param: opaque parameter to pass to dma_filter_fn 542 * @fn_param: opaque parameter to pass to dma_filter_fn
543 *
544 * Returns pointer to appropriate DMA channel on success or NULL.
543 */ 545 */
544struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, 546struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask,
545 dma_filter_fn fn, void *fn_param) 547 dma_filter_fn fn, void *fn_param)
@@ -591,18 +593,43 @@ EXPORT_SYMBOL_GPL(__dma_request_channel);
591 * dma_request_slave_channel - try to allocate an exclusive slave channel 593 * dma_request_slave_channel - try to allocate an exclusive slave channel
592 * @dev: pointer to client device structure 594 * @dev: pointer to client device structure
593 * @name: slave channel name 595 * @name: slave channel name
596 *
597 * Returns pointer to appropriate DMA channel on success or an error pointer.
594 */ 598 */
595struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name) 599struct dma_chan *dma_request_slave_channel_reason(struct device *dev,
600 const char *name)
596{ 601{
602 struct dma_chan *chan;
603
597 /* If device-tree is present get slave info from here */ 604 /* If device-tree is present get slave info from here */
598 if (dev->of_node) 605 if (dev->of_node)
599 return of_dma_request_slave_channel(dev->of_node, name); 606 return of_dma_request_slave_channel(dev->of_node, name);
600 607
601 /* If device was enumerated by ACPI get slave info from here */ 608 /* If device was enumerated by ACPI get slave info from here */
602 if (ACPI_HANDLE(dev)) 609 if (ACPI_HANDLE(dev)) {
603 return acpi_dma_request_slave_chan_by_name(dev, name); 610 chan = acpi_dma_request_slave_chan_by_name(dev, name);
611 if (chan)
612 return chan;
613 }
604 614
605 return NULL; 615 return ERR_PTR(-ENODEV);
616}
617EXPORT_SYMBOL_GPL(dma_request_slave_channel_reason);
618
619/**
620 * dma_request_slave_channel - try to allocate an exclusive slave channel
621 * @dev: pointer to client device structure
622 * @name: slave channel name
623 *
624 * Returns pointer to appropriate DMA channel on success or NULL.
625 */
626struct dma_chan *dma_request_slave_channel(struct device *dev,
627 const char *name)
628{
629 struct dma_chan *ch = dma_request_slave_channel_reason(dev, name);
630 if (IS_ERR(ch))
631 return NULL;
632 return ch;
606} 633}
607EXPORT_SYMBOL_GPL(dma_request_slave_channel); 634EXPORT_SYMBOL_GPL(dma_request_slave_channel);
608 635