Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Linux-御风守护者
linux
提交
dd58ffcf
L
linux
项目概览
Linux-御风守护者
/
linux
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
dd58ffcf
编写于
3月 03, 2010
作者:
D
Dan Williams
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'coh' into dmaengine
上级
aa4d72ae
56a5d3cf
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
116 addition
and
123 deletion
+116
-123
arch/arm/mach-u300/include/mach/coh901318.h
arch/arm/mach-u300/include/mach/coh901318.h
+1
-1
drivers/dma/coh901318.c
drivers/dma/coh901318.c
+96
-88
drivers/dma/coh901318_lli.c
drivers/dma/coh901318_lli.c
+9
-14
drivers/dma/dmaengine.c
drivers/dma/dmaengine.c
+1
-0
drivers/dma/dmatest.c
drivers/dma/dmatest.c
+1
-1
drivers/dma/ioat/dma_v2.c
drivers/dma/ioat/dma_v2.c
+1
-1
drivers/dma/ipu/ipu_idmac.c
drivers/dma/ipu/ipu_idmac.c
+7
-18
未找到文件。
arch/arm/mach-u300/include/mach/coh901318.h
浏览文件 @
dd58ffcf
...
@@ -53,7 +53,7 @@ struct coh901318_params {
...
@@ -53,7 +53,7 @@ struct coh901318_params {
* struct coh_dma_channel - dma channel base
* struct coh_dma_channel - dma channel base
* @name: ascii name of dma channel
* @name: ascii name of dma channel
* @number: channel id number
* @number: channel id number
* @desc_nbr_max: number of preallocated descriptor
tor
s
* @desc_nbr_max: number of preallocated descriptors
* @priority_high: prio of channel, 0 low otherwise high.
* @priority_high: prio of channel, 0 low otherwise high.
* @param: configuration parameters
* @param: configuration parameters
* @dev_addr: physical address of periphal connected to channel
* @dev_addr: physical address of periphal connected to channel
...
...
drivers/dma/coh901318.c
浏览文件 @
dd58ffcf
...
@@ -39,7 +39,6 @@ struct coh901318_desc {
...
@@ -39,7 +39,6 @@ struct coh901318_desc {
unsigned
int
sg_len
;
unsigned
int
sg_len
;
struct
coh901318_lli
*
data
;
struct
coh901318_lli
*
data
;
enum
dma_data_direction
dir
;
enum
dma_data_direction
dir
;
int
pending_irqs
;
unsigned
long
flags
;
unsigned
long
flags
;
};
};
...
@@ -72,7 +71,6 @@ struct coh901318_chan {
...
@@ -72,7 +71,6 @@ struct coh901318_chan {
unsigned
long
nbr_active_done
;
unsigned
long
nbr_active_done
;
unsigned
long
busy
;
unsigned
long
busy
;
int
pending_irqs
;
struct
coh901318_base
*
base
;
struct
coh901318_base
*
base
;
};
};
...
@@ -80,18 +78,16 @@ struct coh901318_chan {
...
@@ -80,18 +78,16 @@ struct coh901318_chan {
static
void
coh901318_list_print
(
struct
coh901318_chan
*
cohc
,
static
void
coh901318_list_print
(
struct
coh901318_chan
*
cohc
,
struct
coh901318_lli
*
lli
)
struct
coh901318_lli
*
lli
)
{
{
struct
coh901318_lli
*
l
;
struct
coh901318_lli
*
l
=
lli
;
dma_addr_t
addr
=
virt_to_phys
(
lli
);
int
i
=
0
;
int
i
=
0
;
while
(
addr
)
{
while
(
l
)
{
l
=
phys_to_virt
(
addr
);
dev_vdbg
(
COHC_2_DEV
(
cohc
),
"i %d, lli %p, ctrl 0x%x, src 0x%x"
dev_vdbg
(
COHC_2_DEV
(
cohc
),
"i %d, lli %p, ctrl 0x%x, src 0x%x"
", dst 0x%x, link 0x%x
link_virt
0x%p
\n
"
,
", dst 0x%x, link 0x%x
virt_link_addr
0x%p
\n
"
,
i
,
l
,
l
->
control
,
l
->
src_addr
,
l
->
dst_addr
,
i
,
l
,
l
->
control
,
l
->
src_addr
,
l
->
dst_addr
,
l
->
link_addr
,
phys_to_virt
(
l
->
link_addr
)
);
l
->
link_addr
,
l
->
virt_link_addr
);
i
++
;
i
++
;
addr
=
l
->
link_addr
;
l
=
l
->
virt_
link_addr
;
}
}
}
}
...
@@ -125,7 +121,7 @@ static int coh901318_debugfs_read(struct file *file, char __user *buf,
...
@@ -125,7 +121,7 @@ static int coh901318_debugfs_read(struct file *file, char __user *buf,
goto
err_kmalloc
;
goto
err_kmalloc
;
tmp
=
dev_buf
;
tmp
=
dev_buf
;
tmp
+=
sprintf
(
tmp
,
"DMA -- enable dma channels
\n
"
);
tmp
+=
sprintf
(
tmp
,
"DMA -- enable
d
dma channels
\n
"
);
for
(
i
=
0
;
i
<
debugfs_dma_base
->
platform
->
max_channels
;
i
++
)
for
(
i
=
0
;
i
<
debugfs_dma_base
->
platform
->
max_channels
;
i
++
)
if
(
started_channels
&
(
1
<<
i
))
if
(
started_channels
&
(
1
<<
i
))
...
@@ -337,16 +333,22 @@ coh901318_desc_get(struct coh901318_chan *cohc)
...
@@ -337,16 +333,22 @@ coh901318_desc_get(struct coh901318_chan *cohc)
* TODO: alloc a pile of descs instead of just one,
* TODO: alloc a pile of descs instead of just one,
* avoid many small allocations.
* avoid many small allocations.
*/
*/
desc
=
k
m
alloc
(
sizeof
(
struct
coh901318_desc
),
GFP_NOWAIT
);
desc
=
k
z
alloc
(
sizeof
(
struct
coh901318_desc
),
GFP_NOWAIT
);
if
(
desc
==
NULL
)
if
(
desc
==
NULL
)
goto
out
;
goto
out
;
INIT_LIST_HEAD
(
&
desc
->
node
);
INIT_LIST_HEAD
(
&
desc
->
node
);
dma_async_tx_descriptor_init
(
&
desc
->
desc
,
&
cohc
->
chan
);
}
else
{
}
else
{
/* Reuse an old desc. */
/* Reuse an old desc. */
desc
=
list_first_entry
(
&
cohc
->
free
,
desc
=
list_first_entry
(
&
cohc
->
free
,
struct
coh901318_desc
,
struct
coh901318_desc
,
node
);
node
);
list_del
(
&
desc
->
node
);
list_del
(
&
desc
->
node
);
/* Initialize it a bit so it's not insane */
desc
->
sg
=
NULL
;
desc
->
sg_len
=
0
;
desc
->
desc
.
callback
=
NULL
;
desc
->
desc
.
callback_param
=
NULL
;
}
}
out:
out:
...
@@ -364,10 +366,6 @@ static void
...
@@ -364,10 +366,6 @@ static void
coh901318_desc_submit
(
struct
coh901318_chan
*
cohc
,
struct
coh901318_desc
*
desc
)
coh901318_desc_submit
(
struct
coh901318_chan
*
cohc
,
struct
coh901318_desc
*
desc
)
{
{
list_add_tail
(
&
desc
->
node
,
&
cohc
->
active
);
list_add_tail
(
&
desc
->
node
,
&
cohc
->
active
);
BUG_ON
(
cohc
->
pending_irqs
!=
0
);
cohc
->
pending_irqs
=
desc
->
pending_irqs
;
}
}
static
struct
coh901318_desc
*
static
struct
coh901318_desc
*
...
@@ -592,6 +590,10 @@ static struct coh901318_desc *coh901318_queue_start(struct coh901318_chan *cohc)
...
@@ -592,6 +590,10 @@ static struct coh901318_desc *coh901318_queue_start(struct coh901318_chan *cohc)
return
cohd_que
;
return
cohd_que
;
}
}
/*
* This tasklet is called from the interrupt handler to
* handle each descriptor (DMA job) that is sent to a channel.
*/
static
void
dma_tasklet
(
unsigned
long
data
)
static
void
dma_tasklet
(
unsigned
long
data
)
{
{
struct
coh901318_chan
*
cohc
=
(
struct
coh901318_chan
*
)
data
;
struct
coh901318_chan
*
cohc
=
(
struct
coh901318_chan
*
)
data
;
...
@@ -600,57 +602,58 @@ static void dma_tasklet(unsigned long data)
...
@@ -600,57 +602,58 @@ static void dma_tasklet(unsigned long data)
dma_async_tx_callback
callback
;
dma_async_tx_callback
callback
;
void
*
callback_param
;
void
*
callback_param
;
dev_vdbg
(
COHC_2_DEV
(
cohc
),
"[%s] chan_id %d"
" nbr_active_done %ld
\n
"
,
__func__
,
cohc
->
id
,
cohc
->
nbr_active_done
);
spin_lock_irqsave
(
&
cohc
->
lock
,
flags
);
spin_lock_irqsave
(
&
cohc
->
lock
,
flags
);
/* get first active entry from list */
/* get first active
descriptor
entry from list */
cohd_fin
=
coh901318_first_active_get
(
cohc
);
cohd_fin
=
coh901318_first_active_get
(
cohc
);
BUG_ON
(
cohd_fin
->
pending_irqs
==
0
);
if
(
cohd_fin
==
NULL
)
if
(
cohd_fin
==
NULL
)
goto
err
;
goto
err
;
cohd_fin
->
pending_irqs
--
;
/* locate callback to client */
cohc
->
completed
=
cohd_fin
->
desc
.
cookie
;
callback
=
cohd_fin
->
desc
.
callback
;
callback_param
=
cohd_fin
->
desc
.
callback_param
;
BUG_ON
(
cohc
->
nbr_active_done
&&
cohd_fin
==
NULL
);
if
(
cohc
->
nbr_active_done
==
0
)
return
;
if
(
!
cohd_fin
->
pending_irqs
)
{
/* sign this job as completed on the channel */
/* release the lli allocation*/
cohc
->
completed
=
cohd_fin
->
desc
.
cookie
;
coh901318_lli_free
(
&
cohc
->
base
->
pool
,
&
cohd_fin
->
data
);
}
dev_vdbg
(
COHC_2_DEV
(
cohc
),
"[%s] chan_id %d pending_irqs %d"
/* release the lli allocation and remove the descriptor */
" nbr_active_done %ld
\n
"
,
__func__
,
coh901318_lli_free
(
&
cohc
->
base
->
pool
,
&
cohd_fin
->
data
);
cohc
->
id
,
cohc
->
pending_irqs
,
cohc
->
nbr_active_done
);
/*
callback to clien
t */
/*
return desc to free-lis
t */
c
allback
=
cohd_fin
->
desc
.
callback
;
c
oh901318_desc_remove
(
cohd_fin
)
;
c
allback_param
=
cohd_fin
->
desc
.
callback_param
;
c
oh901318_desc_free
(
cohc
,
cohd_fin
)
;
if
(
!
cohd_fin
->
pending_irqs
)
{
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flags
);
coh901318_desc_remove
(
cohd_fin
);
/* return desc to free-list
*/
/* Call the callback when we're done
*/
coh901318_desc_free
(
cohc
,
cohd_fin
);
if
(
callback
)
}
callback
(
callback_param
);
if
(
cohc
->
nbr_active_done
)
spin_lock_irqsave
(
&
cohc
->
lock
,
flags
);
cohc
->
nbr_active_done
--
;
/*
* If another interrupt fired while the tasklet was scheduling,
* we don't get called twice, so we have this number of active
* counter that keep track of the number of IRQs expected to
* be handled for this channel. If there happen to be more than
* one IRQ to be ack:ed, we simply schedule this tasklet again.
*/
cohc
->
nbr_active_done
--
;
if
(
cohc
->
nbr_active_done
)
{
if
(
cohc
->
nbr_active_done
)
{
dev_dbg
(
COHC_2_DEV
(
cohc
),
"scheduling tasklet again, new IRQs "
"came in while we were scheduling this tasklet
\n
"
);
if
(
cohc_chan_conf
(
cohc
)
->
priority_high
)
if
(
cohc_chan_conf
(
cohc
)
->
priority_high
)
tasklet_hi_schedule
(
&
cohc
->
tasklet
);
tasklet_hi_schedule
(
&
cohc
->
tasklet
);
else
else
tasklet_schedule
(
&
cohc
->
tasklet
);
tasklet_schedule
(
&
cohc
->
tasklet
);
}
}
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flags
);
if
(
callback
)
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flags
);
callback
(
callback_param
);
return
;
return
;
...
@@ -669,16 +672,17 @@ static void dma_tc_handle(struct coh901318_chan *cohc)
...
@@ -669,16 +672,17 @@ static void dma_tc_handle(struct coh901318_chan *cohc)
if
(
!
cohc
->
allocated
)
if
(
!
cohc
->
allocated
)
return
;
return
;
BUG_ON
(
cohc
->
pending_irqs
==
0
);
spin_lock
(
&
cohc
->
lock
);
cohc
->
pending_irqs
--
;
cohc
->
nbr_active_done
++
;
cohc
->
nbr_active_done
++
;
if
(
coh
c
->
pending_irqs
==
0
&&
coh
901318_queue_start
(
cohc
)
==
NULL
)
if
(
coh901318_queue_start
(
cohc
)
==
NULL
)
cohc
->
busy
=
0
;
cohc
->
busy
=
0
;
BUG_ON
(
list_empty
(
&
cohc
->
active
));
BUG_ON
(
list_empty
(
&
cohc
->
active
));
spin_unlock
(
&
cohc
->
lock
);
if
(
cohc_chan_conf
(
cohc
)
->
priority_high
)
if
(
cohc_chan_conf
(
cohc
)
->
priority_high
)
tasklet_hi_schedule
(
&
cohc
->
tasklet
);
tasklet_hi_schedule
(
&
cohc
->
tasklet
);
else
else
...
@@ -872,6 +876,7 @@ coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
...
@@ -872,6 +876,7 @@ coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
struct
coh901318_chan
*
cohc
=
to_coh901318_chan
(
chan
);
struct
coh901318_chan
*
cohc
=
to_coh901318_chan
(
chan
);
int
lli_len
;
int
lli_len
;
u32
ctrl_last
=
cohc_chan_param
(
cohc
)
->
ctrl_lli_last
;
u32
ctrl_last
=
cohc_chan_param
(
cohc
)
->
ctrl_lli_last
;
int
ret
;
spin_lock_irqsave
(
&
cohc
->
lock
,
flg
);
spin_lock_irqsave
(
&
cohc
->
lock
,
flg
);
...
@@ -892,22 +897,19 @@ coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
...
@@ -892,22 +897,19 @@ coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
if
(
data
==
NULL
)
if
(
data
==
NULL
)
goto
err
;
goto
err
;
cohd
=
coh901318_desc_get
(
cohc
);
ret
=
coh901318_lli_fill_memcpy
(
cohd
->
sg
=
NULL
;
&
cohc
->
base
->
pool
,
data
,
src
,
size
,
dest
,
cohd
->
sg_len
=
0
;
cohc_chan_param
(
cohc
)
->
ctrl_lli_chained
,
cohd
->
data
=
data
;
ctrl_last
);
if
(
ret
)
cohd
->
pending_irqs
=
goto
err
;
coh901318_lli_fill_memcpy
(
&
cohc
->
base
->
pool
,
data
,
src
,
size
,
dest
,
cohc_chan_param
(
cohc
)
->
ctrl_lli_chained
,
ctrl_last
);
cohd
->
flags
=
flags
;
COH_DBG
(
coh901318_list_print
(
cohc
,
data
));
COH_DBG
(
coh901318_list_print
(
cohc
,
data
));
dma_async_tx_descriptor_init
(
&
cohd
->
desc
,
chan
);
/* Pick a descriptor to handle this transfer */
cohd
=
coh901318_desc_get
(
cohc
);
cohd
->
data
=
data
;
cohd
->
flags
=
flags
;
cohd
->
desc
.
tx_submit
=
coh901318_tx_submit
;
cohd
->
desc
.
tx_submit
=
coh901318_tx_submit
;
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flg
);
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flg
);
...
@@ -926,6 +928,7 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
...
@@ -926,6 +928,7 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
struct
coh901318_chan
*
cohc
=
to_coh901318_chan
(
chan
);
struct
coh901318_chan
*
cohc
=
to_coh901318_chan
(
chan
);
struct
coh901318_lli
*
data
;
struct
coh901318_lli
*
data
;
struct
coh901318_desc
*
cohd
;
struct
coh901318_desc
*
cohd
;
const
struct
coh901318_params
*
params
;
struct
scatterlist
*
sg
;
struct
scatterlist
*
sg
;
int
len
=
0
;
int
len
=
0
;
int
size
;
int
size
;
...
@@ -933,7 +936,9 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
...
@@ -933,7 +936,9 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
u32
ctrl_chained
=
cohc_chan_param
(
cohc
)
->
ctrl_lli_chained
;
u32
ctrl_chained
=
cohc_chan_param
(
cohc
)
->
ctrl_lli_chained
;
u32
ctrl
=
cohc_chan_param
(
cohc
)
->
ctrl_lli
;
u32
ctrl
=
cohc_chan_param
(
cohc
)
->
ctrl_lli
;
u32
ctrl_last
=
cohc_chan_param
(
cohc
)
->
ctrl_lli_last
;
u32
ctrl_last
=
cohc_chan_param
(
cohc
)
->
ctrl_lli_last
;
u32
config
;
unsigned
long
flg
;
unsigned
long
flg
;
int
ret
;
if
(
!
sgl
)
if
(
!
sgl
)
goto
out
;
goto
out
;
...
@@ -949,15 +954,14 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
...
@@ -949,15 +954,14 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
/* Trigger interrupt after last lli */
/* Trigger interrupt after last lli */
ctrl_last
|=
COH901318_CX_CTRL_TC_IRQ_ENABLE
;
ctrl_last
|=
COH901318_CX_CTRL_TC_IRQ_ENABLE
;
cohd
=
coh901318_desc_get
(
cohc
);
params
=
cohc_chan_param
(
cohc
);
cohd
->
sg
=
NULL
;
config
=
params
->
config
;
cohd
->
sg_len
=
0
;
cohd
->
dir
=
direction
;
if
(
direction
==
DMA_TO_DEVICE
)
{
if
(
direction
==
DMA_TO_DEVICE
)
{
u32
tx_flags
=
COH901318_CX_CTRL_PRDD_SOURCE
|
u32
tx_flags
=
COH901318_CX_CTRL_PRDD_SOURCE
|
COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE
;
COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE
;
config
|=
COH901318_CX_CFG_RM_MEMORY_TO_PRIMARY
;
ctrl_chained
|=
tx_flags
;
ctrl_chained
|=
tx_flags
;
ctrl_last
|=
tx_flags
;
ctrl_last
|=
tx_flags
;
ctrl
|=
tx_flags
;
ctrl
|=
tx_flags
;
...
@@ -965,16 +969,14 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
...
@@ -965,16 +969,14 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
u32
rx_flags
=
COH901318_CX_CTRL_PRDD_DEST
|
u32
rx_flags
=
COH901318_CX_CTRL_PRDD_DEST
|
COH901318_CX_CTRL_DST_ADDR_INC_ENABLE
;
COH901318_CX_CTRL_DST_ADDR_INC_ENABLE
;
config
|=
COH901318_CX_CFG_RM_PRIMARY_TO_MEMORY
;
ctrl_chained
|=
rx_flags
;
ctrl_chained
|=
rx_flags
;
ctrl_last
|=
rx_flags
;
ctrl_last
|=
rx_flags
;
ctrl
|=
rx_flags
;
ctrl
|=
rx_flags
;
}
else
}
else
goto
err_direction
;
goto
err_direction
;
dma_async_tx_descriptor_init
(
&
cohd
->
desc
,
chan
);
coh901318_set_conf
(
cohc
,
config
);
cohd
->
desc
.
tx_submit
=
coh901318_tx_submit
;
/* The dma only supports transmitting packages up to
/* The dma only supports transmitting packages up to
* MAX_DMA_PACKET_SIZE. Calculate to total number of
* MAX_DMA_PACKET_SIZE. Calculate to total number of
...
@@ -996,32 +998,37 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
...
@@ -996,32 +998,37 @@ coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
len
+=
factor
;
len
+=
factor
;
}
}
pr_debug
(
"Allocate %d lli:s for this transfer
\n
"
,
len
);
data
=
coh901318_lli_alloc
(
&
cohc
->
base
->
pool
,
len
);
data
=
coh901318_lli_alloc
(
&
cohc
->
base
->
pool
,
len
);
if
(
data
==
NULL
)
if
(
data
==
NULL
)
goto
err_dma_alloc
;
goto
err_dma_alloc
;
/* initiate allocated data list */
/* initiate allocated data list */
cohd
->
pending_irqs
=
ret
=
coh901318_lli_fill_sg
(
&
cohc
->
base
->
pool
,
data
,
sgl
,
sg_len
,
coh901318_lli_fill_sg
(
&
cohc
->
base
->
pool
,
data
,
sgl
,
sg_len
,
cohc_dev_addr
(
cohc
),
cohc_dev_addr
(
cohc
),
ctrl_chained
,
ctrl_chained
,
ctrl
,
ctrl
,
ctrl_last
,
ctrl_last
,
direction
,
COH901318_CX_CTRL_TC_IRQ_ENABLE
);
direction
,
COH901318_CX_CTRL_TC_IRQ_ENABLE
);
if
(
ret
)
cohd
->
data
=
data
;
goto
err_lli_fill
;
cohd
->
flags
=
flags
;
COH_DBG
(
coh901318_list_print
(
cohc
,
data
));
COH_DBG
(
coh901318_list_print
(
cohc
,
data
));
/* Pick a descriptor to handle this transfer */
cohd
=
coh901318_desc_get
(
cohc
);
cohd
->
dir
=
direction
;
cohd
->
flags
=
flags
;
cohd
->
desc
.
tx_submit
=
coh901318_tx_submit
;
cohd
->
data
=
data
;
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flg
);
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flg
);
return
&
cohd
->
desc
;
return
&
cohd
->
desc
;
err_lli_fill:
err_dma_alloc:
err_dma_alloc:
err_direction:
err_direction:
coh901318_desc_remove
(
cohd
);
coh901318_desc_free
(
cohc
,
cohd
);
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flg
);
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flg
);
out:
out:
return
NULL
;
return
NULL
;
...
@@ -1094,9 +1101,8 @@ coh901318_terminate_all(struct dma_chan *chan)
...
@@ -1094,9 +1101,8 @@ coh901318_terminate_all(struct dma_chan *chan)
/* release the lli allocation*/
/* release the lli allocation*/
coh901318_lli_free
(
&
cohc
->
base
->
pool
,
&
cohd
->
data
);
coh901318_lli_free
(
&
cohc
->
base
->
pool
,
&
cohd
->
data
);
coh901318_desc_remove
(
cohd
);
/* return desc to free-list */
/* return desc to free-list */
coh901318_desc_remove
(
cohd
);
coh901318_desc_free
(
cohc
,
cohd
);
coh901318_desc_free
(
cohc
,
cohd
);
}
}
...
@@ -1104,16 +1110,14 @@ coh901318_terminate_all(struct dma_chan *chan)
...
@@ -1104,16 +1110,14 @@ coh901318_terminate_all(struct dma_chan *chan)
/* release the lli allocation*/
/* release the lli allocation*/
coh901318_lli_free
(
&
cohc
->
base
->
pool
,
&
cohd
->
data
);
coh901318_lli_free
(
&
cohc
->
base
->
pool
,
&
cohd
->
data
);
coh901318_desc_remove
(
cohd
);
/* return desc to free-list */
/* return desc to free-list */
coh901318_desc_remove
(
cohd
);
coh901318_desc_free
(
cohc
,
cohd
);
coh901318_desc_free
(
cohc
,
cohd
);
}
}
cohc
->
nbr_active_done
=
0
;
cohc
->
nbr_active_done
=
0
;
cohc
->
busy
=
0
;
cohc
->
busy
=
0
;
cohc
->
pending_irqs
=
0
;
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
cohc
->
lock
,
flags
);
}
}
...
@@ -1140,7 +1144,6 @@ void coh901318_base_init(struct dma_device *dma, const int *pick_chans,
...
@@ -1140,7 +1144,6 @@ void coh901318_base_init(struct dma_device *dma, const int *pick_chans,
spin_lock_init
(
&
cohc
->
lock
);
spin_lock_init
(
&
cohc
->
lock
);
cohc
->
pending_irqs
=
0
;
cohc
->
nbr_active_done
=
0
;
cohc
->
nbr_active_done
=
0
;
cohc
->
busy
=
0
;
cohc
->
busy
=
0
;
INIT_LIST_HEAD
(
&
cohc
->
free
);
INIT_LIST_HEAD
(
&
cohc
->
free
);
...
@@ -1256,12 +1259,17 @@ static int __init coh901318_probe(struct platform_device *pdev)
...
@@ -1256,12 +1259,17 @@ static int __init coh901318_probe(struct platform_device *pdev)
base
->
dma_memcpy
.
device_issue_pending
=
coh901318_issue_pending
;
base
->
dma_memcpy
.
device_issue_pending
=
coh901318_issue_pending
;
base
->
dma_memcpy
.
device_terminate_all
=
coh901318_terminate_all
;
base
->
dma_memcpy
.
device_terminate_all
=
coh901318_terminate_all
;
base
->
dma_memcpy
.
dev
=
&
pdev
->
dev
;
base
->
dma_memcpy
.
dev
=
&
pdev
->
dev
;
/*
* This controller can only access address at even 32bit boundaries,
* i.e. 2^2
*/
base
->
dma_memcpy
.
copy_align
=
2
;
err
=
dma_async_device_register
(
&
base
->
dma_memcpy
);
err
=
dma_async_device_register
(
&
base
->
dma_memcpy
);
if
(
err
)
if
(
err
)
goto
err_register_memcpy
;
goto
err_register_memcpy
;
dev_
dbg
(
&
pdev
->
dev
,
"Initialized COH901318 DMA on virtual base 0x%08x
\n
"
,
dev_
info
(
&
pdev
->
dev
,
"Initialized COH901318 DMA on virtual base 0x%08x
\n
"
,
(
u32
)
base
->
virtbase
);
(
u32
)
base
->
virtbase
);
return
err
;
return
err
;
...
...
drivers/dma/coh901318_lli.c
浏览文件 @
dd58ffcf
...
@@ -74,6 +74,8 @@ coh901318_lli_alloc(struct coh901318_pool *pool, unsigned int len)
...
@@ -74,6 +74,8 @@ coh901318_lli_alloc(struct coh901318_pool *pool, unsigned int len)
lli
=
head
;
lli
=
head
;
lli
->
phy_this
=
phy
;
lli
->
phy_this
=
phy
;
lli
->
link_addr
=
0x00000000
;
lli
->
virt_link_addr
=
0x00000000U
;
for
(
i
=
1
;
i
<
len
;
i
++
)
{
for
(
i
=
1
;
i
<
len
;
i
++
)
{
lli_prev
=
lli
;
lli_prev
=
lli
;
...
@@ -85,13 +87,13 @@ coh901318_lli_alloc(struct coh901318_pool *pool, unsigned int len)
...
@@ -85,13 +87,13 @@ coh901318_lli_alloc(struct coh901318_pool *pool, unsigned int len)
DEBUGFS_POOL_COUNTER_ADD
(
pool
,
1
);
DEBUGFS_POOL_COUNTER_ADD
(
pool
,
1
);
lli
->
phy_this
=
phy
;
lli
->
phy_this
=
phy
;
lli
->
link_addr
=
0x00000000
;
lli
->
virt_link_addr
=
0x00000000U
;
lli_prev
->
link_addr
=
phy
;
lli_prev
->
link_addr
=
phy
;
lli_prev
->
virt_link_addr
=
lli
;
lli_prev
->
virt_link_addr
=
lli
;
}
}
lli
->
link_addr
=
0x00000000U
;
spin_unlock
(
&
pool
->
lock
);
spin_unlock
(
&
pool
->
lock
);
return
head
;
return
head
;
...
@@ -166,8 +168,7 @@ coh901318_lli_fill_memcpy(struct coh901318_pool *pool,
...
@@ -166,8 +168,7 @@ coh901318_lli_fill_memcpy(struct coh901318_pool *pool,
lli
->
src_addr
=
src
;
lli
->
src_addr
=
src
;
lli
->
dst_addr
=
dst
;
lli
->
dst_addr
=
dst
;
/* One irq per single transfer */
return
0
;
return
1
;
}
}
int
int
...
@@ -223,8 +224,7 @@ coh901318_lli_fill_single(struct coh901318_pool *pool,
...
@@ -223,8 +224,7 @@ coh901318_lli_fill_single(struct coh901318_pool *pool,
lli
->
src_addr
=
src
;
lli
->
src_addr
=
src
;
lli
->
dst_addr
=
dst
;
lli
->
dst_addr
=
dst
;
/* One irq per single transfer */
return
0
;
return
1
;
}
}
int
int
...
@@ -240,7 +240,6 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
...
@@ -240,7 +240,6 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
u32
ctrl_sg
;
u32
ctrl_sg
;
dma_addr_t
src
=
0
;
dma_addr_t
src
=
0
;
dma_addr_t
dst
=
0
;
dma_addr_t
dst
=
0
;
int
nbr_of_irq
=
0
;
u32
bytes_to_transfer
;
u32
bytes_to_transfer
;
u32
elem_size
;
u32
elem_size
;
...
@@ -269,15 +268,12 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
...
@@ -269,15 +268,12 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
ctrl_sg
=
ctrl
?
ctrl
:
ctrl_last
;
ctrl_sg
=
ctrl
?
ctrl
:
ctrl_last
;
if
((
ctrl_sg
&
ctrl_irq_mask
))
nbr_of_irq
++
;
if
(
dir
==
DMA_TO_DEVICE
)
if
(
dir
==
DMA_TO_DEVICE
)
/* increment source address */
/* increment source address */
src
=
sg_
dma_addres
s
(
sg
);
src
=
sg_
phy
s
(
sg
);
else
else
/* increment destination address */
/* increment destination address */
dst
=
sg_
dma_addres
s
(
sg
);
dst
=
sg_
phy
s
(
sg
);
bytes_to_transfer
=
sg_dma_len
(
sg
);
bytes_to_transfer
=
sg_dma_len
(
sg
);
...
@@ -310,8 +306,7 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
...
@@ -310,8 +306,7 @@ coh901318_lli_fill_sg(struct coh901318_pool *pool,
}
}
spin_unlock
(
&
pool
->
lock
);
spin_unlock
(
&
pool
->
lock
);
/* There can be many IRQs per sg transfer */
return
0
;
return
nbr_of_irq
;
err:
err:
spin_unlock
(
&
pool
->
lock
);
spin_unlock
(
&
pool
->
lock
);
return
-
EINVAL
;
return
-
EINVAL
;
...
...
drivers/dma/dmaengine.c
浏览文件 @
dd58ffcf
...
@@ -826,6 +826,7 @@ void dma_async_device_unregister(struct dma_device *device)
...
@@ -826,6 +826,7 @@ void dma_async_device_unregister(struct dma_device *device)
chan
->
dev
->
chan
=
NULL
;
chan
->
dev
->
chan
=
NULL
;
mutex_unlock
(
&
dma_list_mutex
);
mutex_unlock
(
&
dma_list_mutex
);
device_unregister
(
&
chan
->
dev
->
device
);
device_unregister
(
&
chan
->
dev
->
device
);
free_percpu
(
chan
->
local
);
}
}
}
}
EXPORT_SYMBOL
(
dma_async_device_unregister
);
EXPORT_SYMBOL
(
dma_async_device_unregister
);
...
...
drivers/dma/dmatest.c
浏览文件 @
dd58ffcf
...
@@ -467,7 +467,7 @@ static int dmatest_func(void *data)
...
@@ -467,7 +467,7 @@ static int dmatest_func(void *data)
if
(
iterations
>
0
)
if
(
iterations
>
0
)
while
(
!
kthread_should_stop
())
{
while
(
!
kthread_should_stop
())
{
DECLARE_WAIT_QUEUE_HEAD
(
wait_dmatest_exit
);
DECLARE_WAIT_QUEUE_HEAD
_ONSTACK
(
wait_dmatest_exit
);
interruptible_sleep_on
(
&
wait_dmatest_exit
);
interruptible_sleep_on
(
&
wait_dmatest_exit
);
}
}
...
...
drivers/dma/ioat/dma_v2.c
浏览文件 @
dd58ffcf
...
@@ -241,7 +241,7 @@ int ioat2_quiesce(struct ioat_chan_common *chan, unsigned long tmo)
...
@@ -241,7 +241,7 @@ int ioat2_quiesce(struct ioat_chan_common *chan, unsigned long tmo)
if
(
is_ioat_active
(
status
)
||
is_ioat_idle
(
status
))
if
(
is_ioat_active
(
status
)
||
is_ioat_idle
(
status
))
ioat_suspend
(
chan
);
ioat_suspend
(
chan
);
while
(
is_ioat_active
(
status
)
||
is_ioat_idle
(
status
))
{
while
(
is_ioat_active
(
status
)
||
is_ioat_idle
(
status
))
{
if
(
end
&&
time_after
(
jiffies
,
end
))
{
if
(
tmo
&&
time_after
(
jiffies
,
end
))
{
err
=
-
ETIMEDOUT
;
err
=
-
ETIMEDOUT
;
break
;
break
;
}
}
...
...
drivers/dma/ipu/ipu_idmac.c
浏览文件 @
dd58ffcf
...
@@ -748,12 +748,10 @@ static void ipu_select_buffer(enum ipu_channel channel, int buffer_n)
...
@@ -748,12 +748,10 @@ static void ipu_select_buffer(enum ipu_channel channel, int buffer_n)
* @buffer_n: buffer number to update.
* @buffer_n: buffer number to update.
* 0 or 1 are the only valid values.
* 0 or 1 are the only valid values.
* @phyaddr: buffer physical address.
* @phyaddr: buffer physical address.
* @return: Returns 0 on success or negative error code on failure. This
* function will fail if the buffer is set to ready.
*/
*/
/* Called under spin_lock(_irqsave)(&ichan->lock) */
/* Called under spin_lock(_irqsave)(&ichan->lock) */
static
int
ipu_update_channel_buffer
(
struct
idmac_channel
*
ichan
,
static
void
ipu_update_channel_buffer
(
struct
idmac_channel
*
ichan
,
int
buffer_n
,
dma_addr_t
phyaddr
)
int
buffer_n
,
dma_addr_t
phyaddr
)
{
{
enum
ipu_channel
channel
=
ichan
->
dma_chan
.
chan_id
;
enum
ipu_channel
channel
=
ichan
->
dma_chan
.
chan_id
;
uint32_t
reg
;
uint32_t
reg
;
...
@@ -793,8 +791,6 @@ static int ipu_update_channel_buffer(struct idmac_channel *ichan,
...
@@ -793,8 +791,6 @@ static int ipu_update_channel_buffer(struct idmac_channel *ichan,
}
}
spin_unlock_irqrestore
(
&
ipu_data
.
lock
,
flags
);
spin_unlock_irqrestore
(
&
ipu_data
.
lock
,
flags
);
return
0
;
}
}
/* Called under spin_lock_irqsave(&ichan->lock) */
/* Called under spin_lock_irqsave(&ichan->lock) */
...
@@ -803,7 +799,6 @@ static int ipu_submit_buffer(struct idmac_channel *ichan,
...
@@ -803,7 +799,6 @@ static int ipu_submit_buffer(struct idmac_channel *ichan,
{
{
unsigned
int
chan_id
=
ichan
->
dma_chan
.
chan_id
;
unsigned
int
chan_id
=
ichan
->
dma_chan
.
chan_id
;
struct
device
*
dev
=
&
ichan
->
dma_chan
.
dev
->
device
;
struct
device
*
dev
=
&
ichan
->
dma_chan
.
dev
->
device
;
int
ret
;
if
(
async_tx_test_ack
(
&
desc
->
txd
))
if
(
async_tx_test_ack
(
&
desc
->
txd
))
return
-
EINTR
;
return
-
EINTR
;
...
@@ -814,14 +809,7 @@ static int ipu_submit_buffer(struct idmac_channel *ichan,
...
@@ -814,14 +809,7 @@ static int ipu_submit_buffer(struct idmac_channel *ichan,
* could make it conditional on status >= IPU_CHANNEL_ENABLED, but
* could make it conditional on status >= IPU_CHANNEL_ENABLED, but
* doing it again shouldn't hurt either.
* doing it again shouldn't hurt either.
*/
*/
ret
=
ipu_update_channel_buffer
(
ichan
,
buf_idx
,
ipu_update_channel_buffer
(
ichan
,
buf_idx
,
sg_dma_address
(
sg
));
sg_dma_address
(
sg
));
if
(
ret
<
0
)
{
dev_err
(
dev
,
"Updating sg %p on channel 0x%x buffer %d failed!
\n
"
,
sg
,
chan_id
,
buf_idx
);
return
ret
;
}
ipu_select_buffer
(
chan_id
,
buf_idx
);
ipu_select_buffer
(
chan_id
,
buf_idx
);
dev_dbg
(
dev
,
"Updated sg %p on channel 0x%x buffer %d
\n
"
,
dev_dbg
(
dev
,
"Updated sg %p on channel 0x%x buffer %d
\n
"
,
...
@@ -1366,10 +1354,11 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
...
@@ -1366,10 +1354,11 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
if
(
likely
(
sgnew
)
&&
if
(
likely
(
sgnew
)
&&
ipu_submit_buffer
(
ichan
,
descnew
,
sgnew
,
ichan
->
active_buffer
)
<
0
)
{
ipu_submit_buffer
(
ichan
,
descnew
,
sgnew
,
ichan
->
active_buffer
)
<
0
)
{
callback
=
desc
->
txd
.
callback
;
callback
=
desc
new
->
txd
.
callback
;
callback_param
=
desc
->
txd
.
callback_param
;
callback_param
=
desc
new
->
txd
.
callback_param
;
spin_unlock
(
&
ichan
->
lock
);
spin_unlock
(
&
ichan
->
lock
);
callback
(
callback_param
);
if
(
callback
)
callback
(
callback_param
);
spin_lock
(
&
ichan
->
lock
);
spin_lock
(
&
ichan
->
lock
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录