diff options
Diffstat (limited to 'drivers/dma/dmaengine.c')
-rw-r--r-- | drivers/dma/dmaengine.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 322ee2984e3d..828310d8be80 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -316,7 +316,7 @@ EXPORT_SYMBOL(dma_async_client_chan_request); | |||
316 | int dma_async_device_register(struct dma_device *device) | 316 | int dma_async_device_register(struct dma_device *device) |
317 | { | 317 | { |
318 | static int id; | 318 | static int id; |
319 | int chancnt = 0; | 319 | int chancnt = 0, rc; |
320 | struct dma_chan* chan; | 320 | struct dma_chan* chan; |
321 | 321 | ||
322 | if (!device) | 322 | if (!device) |
@@ -338,8 +338,15 @@ int dma_async_device_register(struct dma_device *device) | |||
338 | snprintf(chan->class_dev.class_id, BUS_ID_SIZE, "dma%dchan%d", | 338 | snprintf(chan->class_dev.class_id, BUS_ID_SIZE, "dma%dchan%d", |
339 | device->dev_id, chan->chan_id); | 339 | device->dev_id, chan->chan_id); |
340 | 340 | ||
341 | rc = class_device_register(&chan->class_dev); | ||
342 | if (rc) { | ||
343 | chancnt--; | ||
344 | free_percpu(chan->local); | ||
345 | chan->local = NULL; | ||
346 | goto err_out; | ||
347 | } | ||
348 | |||
341 | kref_get(&device->refcount); | 349 | kref_get(&device->refcount); |
342 | class_device_register(&chan->class_dev); | ||
343 | } | 350 | } |
344 | 351 | ||
345 | mutex_lock(&dma_list_mutex); | 352 | mutex_lock(&dma_list_mutex); |
@@ -349,6 +356,17 @@ int dma_async_device_register(struct dma_device *device) | |||
349 | dma_chans_rebalance(); | 356 | dma_chans_rebalance(); |
350 | 357 | ||
351 | return 0; | 358 | return 0; |
359 | |||
360 | err_out: | ||
361 | list_for_each_entry(chan, &device->channels, device_node) { | ||
362 | if (chan->local == NULL) | ||
363 | continue; | ||
364 | kref_put(&device->refcount, dma_async_device_cleanup); | ||
365 | class_device_unregister(&chan->class_dev); | ||
366 | chancnt--; | ||
367 | free_percpu(chan->local); | ||
368 | } | ||
369 | return rc; | ||
352 | } | 370 | } |
353 | EXPORT_SYMBOL(dma_async_device_register); | 371 | EXPORT_SYMBOL(dma_async_device_register); |
354 | 372 | ||