Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Linux-御风守护者
linux
提交
2ce672e4
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,发现更多精彩内容 >>
提交
2ce672e4
编写于
11月 09, 2009
作者:
B
Ben Dooks
浏览文件
操作
浏览文件
下载
差异文件
ARM: S3C: Merge fixes-s3c64xx-dma
Merge branch 'fixes-s3c64xx-dma' into fixes-s3c-2632-rc6
上级
b3c5496f
336b1a31
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
52 addition
and
24 deletion
+52
-24
arch/arm/plat-s3c64xx/dma.c
arch/arm/plat-s3c64xx/dma.c
+52
-24
未找到文件。
arch/arm/plat-s3c64xx/dma.c
浏览文件 @
2ce672e4
...
...
@@ -151,8 +151,6 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
src
=
chan
->
dev_addr
;
dst
=
data
;
control0
=
PL080_CONTROL_SRC_AHB2
;
control0
|=
(
u32
)
chan
->
hw_width
<<
PL080_CONTROL_SWIDTH_SHIFT
;
control0
|=
2
<<
PL080_CONTROL_DWIDTH_SHIFT
;
control0
|=
PL080_CONTROL_DST_INCR
;
break
;
...
...
@@ -160,8 +158,6 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
src
=
data
;
dst
=
chan
->
dev_addr
;
control0
=
PL080_CONTROL_DST_AHB2
;
control0
|=
(
u32
)
chan
->
hw_width
<<
PL080_CONTROL_DWIDTH_SHIFT
;
control0
|=
2
<<
PL080_CONTROL_SWIDTH_SHIFT
;
control0
|=
PL080_CONTROL_SRC_INCR
;
break
;
default:
...
...
@@ -173,6 +169,8 @@ static void s3c64xx_dma_fill_lli(struct s3c2410_dma_chan *chan,
control1
=
size
>>
chan
->
hw_width
;
/* size in no of xfers */
control0
|=
PL080_CONTROL_PROT_SYS
;
/* always in priv. mode */
control0
|=
PL080_CONTROL_TC_IRQ_EN
;
/* always fire IRQ */
control0
|=
(
u32
)
chan
->
hw_width
<<
PL080_CONTROL_DWIDTH_SHIFT
;
control0
|=
(
u32
)
chan
->
hw_width
<<
PL080_CONTROL_SWIDTH_SHIFT
;
lli
->
src_addr
=
src
;
lli
->
dst_addr
=
dst
;
...
...
@@ -339,6 +337,7 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
struct
s3c64xx_dma_buff
*
next
;
struct
s3c64xx_dma_buff
*
buff
;
struct
pl080s_lli
*
lli
;
unsigned
long
flags
;
int
ret
;
WARN_ON
(
!
chan
);
...
...
@@ -366,6 +365,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
s3c64xx_dma_fill_lli
(
chan
,
lli
,
data
,
size
);
local_irq_save
(
flags
);
if
((
next
=
chan
->
next
)
!=
NULL
)
{
struct
s3c64xx_dma_buff
*
end
=
chan
->
end
;
struct
pl080s_lli
*
endlli
=
end
->
lli
;
...
...
@@ -397,6 +398,8 @@ int s3c2410_dma_enqueue(unsigned int channel, void *id,
s3c64xx_lli_to_regs
(
chan
,
lli
);
}
local_irq_restore
(
flags
);
show_lli
(
lli
);
dbg_showchan
(
chan
);
...
...
@@ -560,26 +563,11 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
EXPORT_SYMBOL
(
s3c2410_dma_free
);
static
void
s3c64xx_dma_tcirq
(
struct
s3c64xx_dmac
*
dmac
,
int
offs
)
{
struct
s3c2410_dma_chan
*
chan
=
dmac
->
channels
+
offs
;
/* note, we currently do not bother to work out which buffer
* or buffers have been completed since the last tc-irq. */
if
(
chan
->
callback_fn
)
(
chan
->
callback_fn
)(
chan
,
chan
->
curr
->
pw
,
0
,
S3C2410_RES_OK
);
}
static
void
s3c64xx_dma_errirq
(
struct
s3c64xx_dmac
*
dmac
,
int
offs
)
{
printk
(
KERN_DEBUG
"%s: offs %d
\n
"
,
__func__
,
offs
);
}
static
irqreturn_t
s3c64xx_dma_irq
(
int
irq
,
void
*
pw
)
{
struct
s3c64xx_dmac
*
dmac
=
pw
;
struct
s3c2410_dma_chan
*
chan
;
enum
s3c2410_dma_buffresult
res
;
u32
tcstat
,
errstat
;
u32
bit
;
int
offs
;
...
...
@@ -588,14 +576,54 @@ static irqreturn_t s3c64xx_dma_irq(int irq, void *pw)
errstat
=
readl
(
dmac
->
regs
+
PL080_ERR_STATUS
);
for
(
offs
=
0
,
bit
=
1
;
offs
<
8
;
offs
++
,
bit
<<=
1
)
{
struct
s3c64xx_dma_buff
*
buff
;
if
(
!
(
errstat
&
bit
)
&&
!
(
tcstat
&
bit
))
continue
;
chan
=
dmac
->
channels
+
offs
;
res
=
S3C2410_RES_ERR
;
if
(
tcstat
&
bit
)
{
writel
(
bit
,
dmac
->
regs
+
PL080_TC_CLEAR
);
s3c64xx_dma_tcirq
(
dmac
,
offs
)
;
res
=
S3C2410_RES_OK
;
}
if
(
errstat
&
bit
)
{
s3c64xx_dma_errirq
(
dmac
,
offs
);
if
(
errstat
&
bit
)
writel
(
bit
,
dmac
->
regs
+
PL080_ERR_CLEAR
);
/* 'next' points to the buffer that is next to the
* currently active buffer.
* For CIRCULAR queues, 'next' will be same as 'curr'
* when 'end' is the active buffer.
*/
buff
=
chan
->
curr
;
while
(
buff
&&
buff
!=
chan
->
next
&&
buff
->
next
!=
chan
->
next
)
buff
=
buff
->
next
;
if
(
!
buff
)
BUG
();
if
(
buff
==
chan
->
next
)
buff
=
chan
->
end
;
s3c64xx_dma_bufffdone
(
chan
,
buff
,
res
);
/* Free the node and update curr, if non-circular queue */
if
(
!
(
chan
->
flags
&
S3C2410_DMAF_CIRCULAR
))
{
chan
->
curr
=
buff
->
next
;
s3c64xx_dma_freebuff
(
buff
);
}
/* Update 'next' */
buff
=
chan
->
next
;
if
(
chan
->
next
==
chan
->
end
)
{
chan
->
next
=
chan
->
curr
;
if
(
!
(
chan
->
flags
&
S3C2410_DMAF_CIRCULAR
))
chan
->
end
=
NULL
;
}
else
{
chan
->
next
=
buff
->
next
;
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录