View | Details | Raw Unified | Return to bug 1043231
Collapse All | Expand All

(-)a/drivers/dma/dmaengine.c (-40 / +42 lines)
Lines 542-547 static struct dma_chan *private_candidate(const dma_cap_mask_t *mask, Link Here
542
	return NULL;
542
	return NULL;
543
}
543
}
544
544
545
static struct dma_chan *find_candidate(struct dma_device *device,
546
				       const dma_cap_mask_t *mask,
547
				       dma_filter_fn fn, void *fn_param)
548
{
549
	struct dma_chan *chan = private_candidate(mask, device, fn, fn_param);
550
	int err;
551
552
	if (chan) {
553
		/* Found a suitable channel, try to grab, prep, and return it.
554
		 * We first set DMA_PRIVATE to disable balance_ref_count as this
555
		 * channel will not be published in the general-purpose
556
		 * allocator
557
		 */
558
		dma_cap_set(DMA_PRIVATE, device->cap_mask);
559
		device->privatecnt++;
560
		err = dma_chan_get(chan);
561
562
		if (err) {
563
			if (err == -ENODEV) {
564
				pr_debug("%s: %s module removed\n", __func__,
565
					 dma_chan_name(chan));
566
				list_del_rcu(&device->global_node);
567
			} else
568
				pr_debug("%s: failed to get %s: (%d)\n",
569
					 __func__, dma_chan_name(chan), err);
570
571
			if (--device->privatecnt == 0)
572
				dma_cap_clear(DMA_PRIVATE, device->cap_mask);
573
574
			chan = ERR_PTR(err);
575
		}
576
	}
577
578
	return chan ? chan : ERR_PTR(-EPROBE_DEFER);
579
}
580
545
/**
581
/**
546
 * dma_get_slave_channel - try to get specific channel exclusively
582
 * dma_get_slave_channel - try to get specific channel exclusively
547
 * @chan: target channel
583
 * @chan: target channel
Lines 580-586 struct dma_chan *dma_get_any_slave_channel(struct dma_device *device) Link Here
580
{
616
{
581
	dma_cap_mask_t mask;
617
	dma_cap_mask_t mask;
582
	struct dma_chan *chan;
618
	struct dma_chan *chan;
583
	int err;
584
619
585
	dma_cap_zero(mask);
620
	dma_cap_zero(mask);
586
	dma_cap_set(DMA_SLAVE, mask);
621
	dma_cap_set(DMA_SLAVE, mask);
Lines 588-610 struct dma_chan *dma_get_any_slave_channel(struct dma_device *device) Link Here
588
	/* lock against __dma_request_channel */
623
	/* lock against __dma_request_channel */
589
	mutex_lock(&dma_list_mutex);
624
	mutex_lock(&dma_list_mutex);
590
625
591
	chan = private_candidate(&mask, device, NULL, NULL);
626
	chan = find_candidate(device, &mask, NULL, NULL);
592
	if (chan) {
593
		dma_cap_set(DMA_PRIVATE, device->cap_mask);
594
		device->privatecnt++;
595
		err = dma_chan_get(chan);
596
		if (err) {
597
			pr_debug("%s: failed to get %s: (%d)\n",
598
				__func__, dma_chan_name(chan), err);
599
			chan = NULL;
600
			if (--device->privatecnt == 0)
601
				dma_cap_clear(DMA_PRIVATE, device->cap_mask);
602
		}
603
	}
604
627
605
	mutex_unlock(&dma_list_mutex);
628
	mutex_unlock(&dma_list_mutex);
606
629
607
	return chan;
630
	return IS_ERR(chan) ? NULL : chan;
608
}
631
}
609
EXPORT_SYMBOL_GPL(dma_get_any_slave_channel);
632
EXPORT_SYMBOL_GPL(dma_get_any_slave_channel);
610
633
Lines 621-655 struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, Link Here
621
{
644
{
622
	struct dma_device *device, *_d;
645
	struct dma_device *device, *_d;
623
	struct dma_chan *chan = NULL;
646
	struct dma_chan *chan = NULL;
624
	int err;
625
647
626
	/* Find a channel */
648
	/* Find a channel */
627
	mutex_lock(&dma_list_mutex);
649
	mutex_lock(&dma_list_mutex);
628
	list_for_each_entry_safe(device, _d, &dma_device_list, global_node) {
650
	list_for_each_entry_safe(device, _d, &dma_device_list, global_node) {
629
		chan = private_candidate(mask, device, fn, fn_param);
651
		chan = find_candidate(device, mask, fn, fn_param);
630
		if (chan) {
652
		if (!IS_ERR(chan))
631
			/* Found a suitable channel, try to grab, prep, and
653
			break;
632
			 * return it.  We first set DMA_PRIVATE to disable
633
			 * balance_ref_count as this channel will not be
634
			 * published in the general-purpose allocator
635
			 */
636
			dma_cap_set(DMA_PRIVATE, device->cap_mask);
637
			device->privatecnt++;
638
			err = dma_chan_get(chan);
639
654
640
			if (err == -ENODEV) {
655
		chan = NULL;
641
				pr_debug("%s: %s module removed\n",
642
					 __func__, dma_chan_name(chan));
643
				list_del_rcu(&device->global_node);
644
			} else if (err)
645
				pr_debug("%s: failed to get %s: (%d)\n",
646
					 __func__, dma_chan_name(chan), err);
647
			else
648
				break;
649
			if (--device->privatecnt == 0)
650
				dma_cap_clear(DMA_PRIVATE, device->cap_mask);
651
			chan = NULL;
652
		}
653
	}
656
	}
654
	mutex_unlock(&dma_list_mutex);
657
	mutex_unlock(&dma_list_mutex);
655
658
656
- 

Return to bug 1043231