Skip to content

Commit e81274c

Browse files
davejiangvinodkoul
authored andcommitted
dmaengine: add support to dynamic register/unregister of channels
With the channel registration routines broken out, now add support code to allow independent registering and unregistering of channels in a hotplug fashion. Signed-off-by: Dave Jiang <[email protected]> Link: https://lore.kernel.org/r/157965023364.73301.7821862091077299040.stgit@djiang5-desk3.ch.intel.com Signed-off-by: Vinod Koul <[email protected]>
1 parent d2fb0a0 commit e81274c

File tree

2 files changed

+30
-8
lines changed

2 files changed

+30
-8
lines changed

drivers/dma/dmaengine.c

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -986,19 +986,43 @@ static int __dma_async_device_channel_register(struct dma_device *device,
986986
return rc;
987987
}
988988

989+
int dma_async_device_channel_register(struct dma_device *device,
990+
struct dma_chan *chan)
991+
{
992+
int rc;
993+
994+
rc = __dma_async_device_channel_register(device, chan, -1);
995+
if (rc < 0)
996+
return rc;
997+
998+
dma_channel_rebalance();
999+
return 0;
1000+
}
1001+
EXPORT_SYMBOL_GPL(dma_async_device_channel_register);
1002+
9891003
static void __dma_async_device_channel_unregister(struct dma_device *device,
9901004
struct dma_chan *chan)
9911005
{
9921006
WARN_ONCE(!device->device_release && chan->client_count,
9931007
"%s called while %d clients hold a reference\n",
9941008
__func__, chan->client_count);
9951009
mutex_lock(&dma_list_mutex);
1010+
list_del(&chan->device_node);
1011+
device->chancnt--;
9961012
chan->dev->chan = NULL;
9971013
mutex_unlock(&dma_list_mutex);
9981014
device_unregister(&chan->dev->device);
9991015
free_percpu(chan->local);
10001016
}
10011017

1018+
void dma_async_device_channel_unregister(struct dma_device *device,
1019+
struct dma_chan *chan)
1020+
{
1021+
__dma_async_device_channel_unregister(device, chan);
1022+
dma_channel_rebalance();
1023+
}
1024+
EXPORT_SYMBOL_GPL(dma_async_device_channel_unregister);
1025+
10021026
/**
10031027
* dma_async_device_register - registers DMA devices found
10041028
* @device: &dma_device
@@ -1121,12 +1145,6 @@ int dma_async_device_register(struct dma_device *device)
11211145
goto err_out;
11221146
}
11231147

1124-
if (!device->chancnt) {
1125-
dev_err(device->dev, "%s: device has no channels!\n", __func__);
1126-
rc = -ENODEV;
1127-
goto err_out;
1128-
}
1129-
11301148
mutex_lock(&dma_list_mutex);
11311149
/* take references on public channels */
11321150
if (dmaengine_ref_count && !dma_has_cap(DMA_PRIVATE, device->cap_mask))
@@ -1181,9 +1199,9 @@ EXPORT_SYMBOL(dma_async_device_register);
11811199
*/
11821200
void dma_async_device_unregister(struct dma_device *device)
11831201
{
1184-
struct dma_chan *chan;
1202+
struct dma_chan *chan, *n;
11851203

1186-
list_for_each_entry(chan, &device->channels, device_node)
1204+
list_for_each_entry_safe(chan, n, &device->channels, device_node)
11871205
__dma_async_device_channel_unregister(device, chan);
11881206

11891207
mutex_lock(&dma_list_mutex);

include/linux/dmaengine.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,6 +1521,10 @@ static inline int dmaengine_desc_free(struct dma_async_tx_descriptor *desc)
15211521
int dma_async_device_register(struct dma_device *device);
15221522
int dmaenginem_async_device_register(struct dma_device *device);
15231523
void dma_async_device_unregister(struct dma_device *device);
1524+
int dma_async_device_channel_register(struct dma_device *device,
1525+
struct dma_chan *chan);
1526+
void dma_async_device_channel_unregister(struct dma_device *device,
1527+
struct dma_chan *chan);
15241528
void dma_run_dependencies(struct dma_async_tx_descriptor *tx);
15251529
#define dma_request_channel(mask, x, y) \
15261530
__dma_request_channel(&(mask), x, y, NULL)

0 commit comments

Comments
 (0)