aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/include/asm/async_tx.h
blob: 6b49cf1f702b31a87c8220017b1fdad2c05b1e1c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
 * Copyright(c) 2008 DENX Engineering. All rights reserved.
 *
 * Author: Yuri Tikhonov <yur@emcraft.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * The full GNU General Public License is included in this distribution in the
 * file called COPYING.
 */
#ifndef _PPC_ASYNC_TX_H_
#define _PPC_ASYNC_TX_H_

#if defined(CONFIG_440SPe) || defined(CONFIG_440SP) 
extern int ppc440spe_adma_estimate (struct dma_chan *chan,
	enum dma_transaction_type cap, struct page **src_lst,
	int src_cnt, size_t src_sz);
#define ppc_adma_estimate(chan, cap, src_lst, src_cnt, src_sz) \
	ppc440spe_adma_estimate(chan, cap, src_lst, src_cnt, src_sz)
#elif  defined(CONFIG_460EX) || defined(CONFIG_460GT)
extern int ppc460ex_adma_estimate (struct dma_chan *chan,
	enum dma_transaction_type cap, struct page **src_lst,
	int src_cnt, size_t src_sz);
#define ppc_adma_estimate(chan, cap, src_lst, src_cnt, src_sz) \
	ppc460ex_adma_estimate(chan, cap, src_lst, src_cnt, src_sz)
#elif defined(CONFIG_APM82181)
extern int apm82181_adma_estimate (struct dma_chan *chan,
        enum dma_transaction_type cap, struct page **src_lst,
        int src_cnt, size_t src_sz);
#define ppc_adma_estimate(chan, cap, src_lst, src_cnt, src_sz) \
        apm82181_adma_estimate(chan, cap, src_lst, src_cnt, src_sz)
#endif

struct ppc_dma_chan_ref {
	struct dma_chan *chan;
	struct list_head node;
};

extern struct list_head ppc_adma_chan_list;

/**
 * ppc_async_tx_find_best_channel - find a channel with the maximum rank for the
 *	transaction type given (the rank of the operation is the value
 *	returned by the device_estimate method).
 * @cap: transaction type
 * @src_lst: array of pointers to sources for the transaction
 * @src_cnt: number of arguments (size of the srcs array)
 * @src_sz: length of the each argument pointed by srcs
 */
static inline struct dma_chan *
ppc_async_tx_find_best_channel (enum dma_transaction_type cap,
	struct page **src_lst, int src_cnt, size_t src_sz)
{
	struct dma_chan *best_chan = NULL;
	struct ppc_dma_chan_ref *ref;
	int best_rank = -1;

	list_for_each_entry(ref, &ppc_adma_chan_list, node)
		if (dma_has_cap(cap, ref->chan->device->cap_mask)) {
			int rank;

			rank = ppc_adma_estimate (ref->chan,
				cap, src_lst, src_cnt, src_sz);
			if (rank > best_rank) {
				best_rank = rank;
				best_chan = ref->chan;
			}
		}

	return best_chan;
}

#define async_tx_find_channel(dep, type, dst, dst_count, src, src_count, len) \
	ppc_async_tx_find_best_channel(type, src, src_count, len)

#endif