Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
22b61a11
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
22b61a11
编写于
2月 21, 2009
作者:
R
Russell King
提交者:
Russell King
2月 21, 2009
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'dma' into devel
Conflicts: arch/arm/plat-mxc/dma-mx1-mx2.c
上级
423145a5
fa4e9989
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
292 addition
and
238 deletion
+292
-238
arch/arm/include/asm/dma.h
arch/arm/include/asm/dma.h
+21
-25
arch/arm/include/asm/mach/dma.h
arch/arm/include/asm/mach/dma.h
+16
-19
arch/arm/kernel/dma-isa.c
arch/arm/kernel/dma-isa.c
+34
-33
arch/arm/kernel/dma.c
arch/arm/kernel/dma.c
+67
-52
arch/arm/mach-footbridge/dma.c
arch/arm/mach-footbridge/dma.c
+7
-5
arch/arm/mach-rpc/dma.c
arch/arm/mach-rpc/dma.c
+131
-82
arch/arm/mach-rpc/include/mach/isa-dma.h
arch/arm/mach-rpc/include/mach/isa-dma.h
+2
-0
arch/arm/mach-shark/dma.c
arch/arm/mach-shark/dma.c
+4
-2
arch/arm/plat-mxc/dma-mx1-mx2.c
arch/arm/plat-mxc/dma-mx1-mx2.c
+1
-1
drivers/ata/pata_icside.c
drivers/ata/pata_icside.c
+3
-16
drivers/scsi/arm/cumana_2.c
drivers/scsi/arm/cumana_2.c
+2
-1
drivers/scsi/arm/eesox.c
drivers/scsi/arm/eesox.c
+2
-1
drivers/scsi/arm/powertec.c
drivers/scsi/arm/powertec.c
+2
-1
未找到文件。
arch/arm/include/asm/dma.h
浏览文件 @
22b61a11
...
@@ -19,21 +19,17 @@
...
@@ -19,21 +19,17 @@
#include <asm/system.h>
#include <asm/system.h>
#include <asm/scatterlist.h>
#include <asm/scatterlist.h>
typedef
unsigned
int
dmach_t
;
#include <mach/isa-dma.h>
#include <mach/isa-dma.h>
/*
/*
*
DMA modes
*
The DMA modes reflect the settings for the ISA DMA controller
*/
*/
typedef
unsigned
int
dmamode_t
;
#define DMA_MODE_MASK 0xcc
#define DMA_MODE_MASK 3
#define DMA_MODE_READ 0
#define DMA_MODE_READ 0
x44
#define DMA_MODE_WRITE
1
#define DMA_MODE_WRITE
0x48
#define DMA_MODE_CASCADE
2
#define DMA_MODE_CASCADE
0xc0
#define DMA_AUTOINIT
4
#define DMA_AUTOINIT
0x10
extern
spinlock_t
dma_spin_lock
;
extern
spinlock_t
dma_spin_lock
;
...
@@ -52,44 +48,44 @@ static inline void release_dma_lock(unsigned long flags)
...
@@ -52,44 +48,44 @@ static inline void release_dma_lock(unsigned long flags)
/* Clear the 'DMA Pointer Flip Flop'.
/* Clear the 'DMA Pointer Flip Flop'.
* Write 0 for LSB/MSB, 1 for MSB/LSB access.
* Write 0 for LSB/MSB, 1 for MSB/LSB access.
*/
*/
#define clear_dma_ff(chan
nel
)
#define clear_dma_ff(chan)
/* Set only the page register bits of the transfer address.
/* Set only the page register bits of the transfer address.
*
*
* NOTE: This is an architecture specific function, and should
* NOTE: This is an architecture specific function, and should
* be hidden from the drivers
* be hidden from the drivers
*/
*/
extern
void
set_dma_page
(
dmach_t
channel
,
char
pagenr
);
extern
void
set_dma_page
(
unsigned
int
chan
,
char
pagenr
);
/* Request a DMA channel
/* Request a DMA channel
*
*
* Some architectures may need to do allocate an interrupt
* Some architectures may need to do allocate an interrupt
*/
*/
extern
int
request_dma
(
dmach_t
channel
,
const
char
*
device_id
);
extern
int
request_dma
(
unsigned
int
chan
,
const
char
*
device_id
);
/* Free a DMA channel
/* Free a DMA channel
*
*
* Some architectures may need to do free an interrupt
* Some architectures may need to do free an interrupt
*/
*/
extern
void
free_dma
(
dmach_t
channel
);
extern
void
free_dma
(
unsigned
int
chan
);
/* Enable DMA for this channel
/* Enable DMA for this channel
*
*
* On some architectures, this may have other side effects like
* On some architectures, this may have other side effects like
* enabling an interrupt and setting the DMA registers.
* enabling an interrupt and setting the DMA registers.
*/
*/
extern
void
enable_dma
(
dmach_t
channel
);
extern
void
enable_dma
(
unsigned
int
chan
);
/* Disable DMA for this channel
/* Disable DMA for this channel
*
*
* On some architectures, this may have other side effects like
* On some architectures, this may have other side effects like
* disabling an interrupt or whatever.
* disabling an interrupt or whatever.
*/
*/
extern
void
disable_dma
(
dmach_t
channel
);
extern
void
disable_dma
(
unsigned
int
chan
);
/* Test whether the specified channel has an active DMA transfer
/* Test whether the specified channel has an active DMA transfer
*/
*/
extern
int
dma_channel_active
(
dmach_t
channel
);
extern
int
dma_channel_active
(
unsigned
int
chan
);
/* Set the DMA scatter gather list for this channel
/* Set the DMA scatter gather list for this channel
*
*
...
@@ -97,7 +93,7 @@ extern int dma_channel_active(dmach_t channel);
...
@@ -97,7 +93,7 @@ extern int dma_channel_active(dmach_t channel);
* especially since some DMA architectures don't update the
* especially since some DMA architectures don't update the
* DMA address immediately, but defer it to the enable_dma().
* DMA address immediately, but defer it to the enable_dma().
*/
*/
extern
void
set_dma_sg
(
dmach_t
channel
,
struct
scatterlist
*
sg
,
int
nr_sg
);
extern
void
set_dma_sg
(
unsigned
int
chan
,
struct
scatterlist
*
sg
,
int
nr_sg
);
/* Set the DMA address for this channel
/* Set the DMA address for this channel
*
*
...
@@ -105,9 +101,9 @@ extern void set_dma_sg(dmach_t channel, struct scatterlist *sg, int nr_sg);
...
@@ -105,9 +101,9 @@ extern void set_dma_sg(dmach_t channel, struct scatterlist *sg, int nr_sg);
* especially since some DMA architectures don't update the
* especially since some DMA architectures don't update the
* DMA address immediately, but defer it to the enable_dma().
* DMA address immediately, but defer it to the enable_dma().
*/
*/
extern
void
__set_dma_addr
(
dmach_t
channel
,
void
*
addr
);
extern
void
__set_dma_addr
(
unsigned
int
chan
,
void
*
addr
);
#define set_dma_addr(chan
nel
, addr) \
#define set_dma_addr(chan, addr) \
__set_dma_addr(chan
nel
, bus_to_virt(addr))
__set_dma_addr(chan, bus_to_virt(addr))
/* Set the DMA byte count for this channel
/* Set the DMA byte count for this channel
*
*
...
@@ -115,7 +111,7 @@ extern void __set_dma_addr(dmach_t channel, void *addr);
...
@@ -115,7 +111,7 @@ extern void __set_dma_addr(dmach_t channel, void *addr);
* especially since some DMA architectures don't update the
* especially since some DMA architectures don't update the
* DMA count immediately, but defer it to the enable_dma().
* DMA count immediately, but defer it to the enable_dma().
*/
*/
extern
void
set_dma_count
(
dmach_t
channel
,
unsigned
long
count
);
extern
void
set_dma_count
(
unsigned
int
chan
,
unsigned
long
count
);
/* Set the transfer direction for this channel
/* Set the transfer direction for this channel
*
*
...
@@ -124,11 +120,11 @@ extern void set_dma_count(dmach_t channel, unsigned long count);
...
@@ -124,11 +120,11 @@ extern void set_dma_count(dmach_t channel, unsigned long count);
* DMA transfer direction immediately, but defer it to the
* DMA transfer direction immediately, but defer it to the
* enable_dma().
* enable_dma().
*/
*/
extern
void
set_dma_mode
(
dmach_t
channel
,
dmamode_
t
mode
);
extern
void
set_dma_mode
(
unsigned
int
chan
,
unsigned
in
t
mode
);
/* Set the transfer speed for this channel
/* Set the transfer speed for this channel
*/
*/
extern
void
set_dma_speed
(
dmach_t
channel
,
int
cycle_ns
);
extern
void
set_dma_speed
(
unsigned
int
chan
,
int
cycle_ns
);
/* Get DMA residue count. After a DMA transfer, this
/* Get DMA residue count. After a DMA transfer, this
* should return zero. Reading this while a DMA transfer is
* should return zero. Reading this while a DMA transfer is
...
@@ -136,7 +132,7 @@ extern void set_dma_speed(dmach_t channel, int cycle_ns);
...
@@ -136,7 +132,7 @@ extern void set_dma_speed(dmach_t channel, int cycle_ns);
* If called before the channel has been used, it may return 1.
* If called before the channel has been used, it may return 1.
* Otherwise, it returns the number of _bytes_ left to transfer.
* Otherwise, it returns the number of _bytes_ left to transfer.
*/
*/
extern
int
get_dma_residue
(
dmach_t
channel
);
extern
int
get_dma_residue
(
unsigned
int
chan
);
#ifndef NO_DMA
#ifndef NO_DMA
#define NO_DMA 255
#define NO_DMA 255
...
...
arch/arm/include/asm/mach/dma.h
浏览文件 @
22b61a11
...
@@ -15,13 +15,13 @@ struct dma_struct;
...
@@ -15,13 +15,13 @@ struct dma_struct;
typedef
struct
dma_struct
dma_t
;
typedef
struct
dma_struct
dma_t
;
struct
dma_ops
{
struct
dma_ops
{
int
(
*
request
)(
dmach_
t
,
dma_t
*
);
/* optional */
int
(
*
request
)(
unsigned
in
t
,
dma_t
*
);
/* optional */
void
(
*
free
)(
dmach_t
,
dma_t
*
);
/* optional */
void
(
*
free
)(
unsigned
int
,
dma_t
*
);
/* optional */
void
(
*
enable
)(
dmach_
t
,
dma_t
*
);
/* mandatory */
void
(
*
enable
)(
unsigned
in
t
,
dma_t
*
);
/* mandatory */
void
(
*
disable
)(
dmach_
t
,
dma_t
*
);
/* mandatory */
void
(
*
disable
)(
unsigned
in
t
,
dma_t
*
);
/* mandatory */
int
(
*
residue
)(
dmach_
t
,
dma_t
*
);
/* optional */
int
(
*
residue
)(
unsigned
in
t
,
dma_t
*
);
/* optional */
int
(
*
setspeed
)(
dmach_
t
,
dma_t
*
,
int
);
/* optional */
int
(
*
setspeed
)(
unsigned
in
t
,
dma_t
*
,
int
);
/* optional */
c
har
*
type
;
c
onst
char
*
type
;
};
};
struct
dma_struct
{
struct
dma_struct
{
...
@@ -34,24 +34,21 @@ struct dma_struct {
...
@@ -34,24 +34,21 @@ struct dma_struct {
unsigned
int
active
:
1
;
/* Transfer active */
unsigned
int
active
:
1
;
/* Transfer active */
unsigned
int
invalid
:
1
;
/* Address/Count changed */
unsigned
int
invalid
:
1
;
/* Address/Count changed */
dmamode_
t
dma_mode
;
/* DMA mode */
unsigned
in
t
dma_mode
;
/* DMA mode */
int
speed
;
/* DMA speed */
int
speed
;
/* DMA speed */
unsigned
int
lock
;
/* Device is allocated */
unsigned
int
lock
;
/* Device is allocated */
const
char
*
device_id
;
/* Device name */
const
char
*
device_id
;
/* Device name */
unsigned
int
dma_base
;
/* Controller base address */
const
struct
dma_ops
*
d_ops
;
int
dma_irq
;
/* Controller IRQ */
struct
scatterlist
cur_sg
;
/* Current controller buffer */
unsigned
int
state
;
struct
dma_ops
*
d_ops
;
};
};
/* Prototype: void arch_dma_init(dma)
/*
* Purpose : Initialise architecture specific DMA
* isa_dma_add - add an ISA-style DMA channel
* Params : dma - pointer to array of DMA structures
*/
*/
extern
void
arch_dma_init
(
dma_t
*
dma
);
extern
int
isa_dma_add
(
unsigned
int
,
dma_t
*
dma
);
extern
void
isa_init_dma
(
dma_t
*
dma
);
/*
* Add the ISA DMA controller. Always takes channels 0-7.
*/
extern
void
isa_init_dma
(
void
);
arch/arm/kernel/dma-isa.c
浏览文件 @
22b61a11
...
@@ -24,11 +24,6 @@
...
@@ -24,11 +24,6 @@
#include <asm/dma.h>
#include <asm/dma.h>
#include <asm/mach/dma.h>
#include <asm/mach/dma.h>
#define ISA_DMA_MODE_READ 0x44
#define ISA_DMA_MODE_WRITE 0x48
#define ISA_DMA_MODE_CASCADE 0xc0
#define ISA_DMA_AUTOINIT 0x10
#define ISA_DMA_MASK 0
#define ISA_DMA_MASK 0
#define ISA_DMA_MODE 1
#define ISA_DMA_MODE 1
#define ISA_DMA_CLRFF 2
#define ISA_DMA_CLRFF 2
...
@@ -49,38 +44,35 @@ static unsigned int isa_dma_port[8][7] = {
...
@@ -49,38 +44,35 @@ static unsigned int isa_dma_port[8][7] = {
{
0xd4
,
0xd6
,
0xd8
,
0x48a
,
0x08a
,
0xcc
,
0xce
}
{
0xd4
,
0xd6
,
0xd8
,
0x48a
,
0x08a
,
0xcc
,
0xce
}
};
};
static
int
isa_get_dma_residue
(
dmach_t
channel
,
dma_t
*
dma
)
static
int
isa_get_dma_residue
(
unsigned
int
chan
,
dma_t
*
dma
)
{
{
unsigned
int
io_port
=
isa_dma_port
[
chan
nel
][
ISA_DMA_COUNT
];
unsigned
int
io_port
=
isa_dma_port
[
chan
][
ISA_DMA_COUNT
];
int
count
;
int
count
;
count
=
1
+
inb
(
io_port
);
count
=
1
+
inb
(
io_port
);
count
|=
inb
(
io_port
)
<<
8
;
count
|=
inb
(
io_port
)
<<
8
;
return
chan
nel
<
4
?
count
:
(
count
<<
1
);
return
chan
<
4
?
count
:
(
count
<<
1
);
}
}
static
void
isa_enable_dma
(
dmach_t
channel
,
dma_t
*
dma
)
static
void
isa_enable_dma
(
unsigned
int
chan
,
dma_t
*
dma
)
{
{
if
(
dma
->
invalid
)
{
if
(
dma
->
invalid
)
{
unsigned
long
address
,
length
;
unsigned
long
address
,
length
;
unsigned
int
mode
;
unsigned
int
mode
;
enum
dma_data_direction
direction
;
enum
dma_data_direction
direction
;
mode
=
channel
&
3
;
mode
=
(
chan
&
3
)
|
dma
->
dma_mode
;
switch
(
dma
->
dma_mode
&
DMA_MODE_MASK
)
{
switch
(
dma
->
dma_mode
&
DMA_MODE_MASK
)
{
case
DMA_MODE_READ
:
case
DMA_MODE_READ
:
mode
|=
ISA_DMA_MODE_READ
;
direction
=
DMA_FROM_DEVICE
;
direction
=
DMA_FROM_DEVICE
;
break
;
break
;
case
DMA_MODE_WRITE
:
case
DMA_MODE_WRITE
:
mode
|=
ISA_DMA_MODE_WRITE
;
direction
=
DMA_TO_DEVICE
;
direction
=
DMA_TO_DEVICE
;
break
;
break
;
case
DMA_MODE_CASCADE
:
case
DMA_MODE_CASCADE
:
mode
|=
ISA_DMA_MODE_CASCADE
;
direction
=
DMA_BIDIRECTIONAL
;
direction
=
DMA_BIDIRECTIONAL
;
break
;
break
;
...
@@ -105,34 +97,31 @@ static void isa_enable_dma(dmach_t channel, dma_t *dma)
...
@@ -105,34 +97,31 @@ static void isa_enable_dma(dmach_t channel, dma_t *dma)
address
=
dma
->
buf
.
dma_address
;
address
=
dma
->
buf
.
dma_address
;
length
=
dma
->
buf
.
length
-
1
;
length
=
dma
->
buf
.
length
-
1
;
outb
(
address
>>
16
,
isa_dma_port
[
chan
nel
][
ISA_DMA_PGLO
]);
outb
(
address
>>
16
,
isa_dma_port
[
chan
][
ISA_DMA_PGLO
]);
outb
(
address
>>
24
,
isa_dma_port
[
chan
nel
][
ISA_DMA_PGHI
]);
outb
(
address
>>
24
,
isa_dma_port
[
chan
][
ISA_DMA_PGHI
]);
if
(
chan
nel
>=
4
)
{
if
(
chan
>=
4
)
{
address
>>=
1
;
address
>>=
1
;
length
>>=
1
;
length
>>=
1
;
}
}
outb
(
0
,
isa_dma_port
[
channel
][
ISA_DMA_CLRFF
]);
outb
(
0
,
isa_dma_port
[
chan
][
ISA_DMA_CLRFF
]);
outb
(
address
,
isa_dma_port
[
channel
][
ISA_DMA_ADDR
]);
outb
(
address
>>
8
,
isa_dma_port
[
channel
][
ISA_DMA_ADDR
]);
outb
(
length
,
isa_dma_port
[
channel
][
ISA_DMA_COUNT
]);
outb
(
address
,
isa_dma_port
[
chan
][
ISA_DMA_ADDR
]);
outb
(
length
>>
8
,
isa_dma_port
[
channel
][
ISA_DMA_COUNT
]);
outb
(
address
>>
8
,
isa_dma_port
[
chan
][
ISA_DMA_ADDR
]);
if
(
dma
->
dma_mode
&
DMA_AUTOINIT
)
outb
(
length
,
isa_dma_port
[
chan
][
ISA_DMA_COUNT
]);
mode
|=
ISA_DMA_AUTOINIT
;
outb
(
length
>>
8
,
isa_dma_port
[
chan
][
ISA_DMA_COUNT
])
;
outb
(
mode
,
isa_dma_port
[
chan
nel
][
ISA_DMA_MODE
]);
outb
(
mode
,
isa_dma_port
[
chan
][
ISA_DMA_MODE
]);
dma
->
invalid
=
0
;
dma
->
invalid
=
0
;
}
}
outb
(
chan
nel
&
3
,
isa_dma_port
[
channel
][
ISA_DMA_MASK
]);
outb
(
chan
&
3
,
isa_dma_port
[
chan
][
ISA_DMA_MASK
]);
}
}
static
void
isa_disable_dma
(
dmach_t
channel
,
dma_t
*
dma
)
static
void
isa_disable_dma
(
unsigned
int
chan
,
dma_t
*
dma
)
{
{
outb
(
chan
nel
|
4
,
isa_dma_port
[
channel
][
ISA_DMA_MASK
]);
outb
(
chan
|
4
,
isa_dma_port
[
chan
][
ISA_DMA_MASK
]);
}
}
static
struct
dma_ops
isa_dma_ops
=
{
static
struct
dma_ops
isa_dma_ops
=
{
...
@@ -160,7 +149,12 @@ static struct resource dma_resources[] = { {
...
@@ -160,7 +149,12 @@ static struct resource dma_resources[] = { {
.
end
=
0x048f
.
end
=
0x048f
}
};
}
};
void
__init
isa_init_dma
(
dma_t
*
dma
)
static
dma_t
isa_dma
[
8
];
/*
* ISA DMA always starts at channel 0
*/
void
__init
isa_init_dma
(
void
)
{
{
/*
/*
* Try to autodetect presence of an ISA DMA controller.
* Try to autodetect presence of an ISA DMA controller.
...
@@ -178,11 +172,11 @@ void __init isa_init_dma(dma_t *dma)
...
@@ -178,11 +172,11 @@ void __init isa_init_dma(dma_t *dma)
outb
(
0xaa
,
0x00
);
outb
(
0xaa
,
0x00
);
if
(
inb
(
0
)
==
0x55
&&
inb
(
0
)
==
0xaa
)
{
if
(
inb
(
0
)
==
0x55
&&
inb
(
0
)
==
0xaa
)
{
int
channel
,
i
;
unsigned
int
chan
,
i
;
for
(
chan
nel
=
0
;
channel
<
8
;
channel
++
)
{
for
(
chan
=
0
;
chan
<
8
;
chan
++
)
{
dma
[
channel
].
d_ops
=
&
isa_dma_ops
;
isa_dma
[
chan
].
d_ops
=
&
isa_dma_ops
;
isa_disable_dma
(
chan
nel
,
NULL
);
isa_disable_dma
(
chan
,
NULL
);
}
}
outb
(
0x40
,
0x0b
);
outb
(
0x40
,
0x0b
);
...
@@ -217,5 +211,12 @@ void __init isa_init_dma(dma_t *dma)
...
@@ -217,5 +211,12 @@ void __init isa_init_dma(dma_t *dma)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
dma_resources
);
i
++
)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
dma_resources
);
i
++
)
request_resource
(
&
ioport_resource
,
dma_resources
+
i
);
request_resource
(
&
ioport_resource
,
dma_resources
+
i
);
for
(
chan
=
0
;
chan
<
8
;
chan
++
)
{
int
ret
=
isa_dma_add
(
chan
,
&
isa_dma
[
chan
]);
if
(
ret
)
printk
(
KERN_ERR
"ISADMA%u: unable to register: %d
\n
"
,
chan
,
ret
);
}
}
}
}
}
arch/arm/kernel/dma.c
浏览文件 @
22b61a11
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/scatterlist.h>
#include <asm/dma.h>
#include <asm/dma.h>
...
@@ -23,19 +24,40 @@
...
@@ -23,19 +24,40 @@
DEFINE_SPINLOCK
(
dma_spin_lock
);
DEFINE_SPINLOCK
(
dma_spin_lock
);
EXPORT_SYMBOL
(
dma_spin_lock
);
EXPORT_SYMBOL
(
dma_spin_lock
);
static
dma_t
dma_chan
[
MAX_DMA_CHANNELS
];
static
dma_t
*
dma_chan
[
MAX_DMA_CHANNELS
];
static
inline
dma_t
*
dma_channel
(
unsigned
int
chan
)
{
if
(
chan
>=
MAX_DMA_CHANNELS
)
return
NULL
;
return
dma_chan
[
chan
];
}
int
__init
isa_dma_add
(
unsigned
int
chan
,
dma_t
*
dma
)
{
if
(
!
dma
->
d_ops
)
return
-
EINVAL
;
sg_init_table
(
&
dma
->
buf
,
1
);
if
(
dma_chan
[
chan
])
return
-
EBUSY
;
dma_chan
[
chan
]
=
dma
;
return
0
;
}
/*
/*
* Request DMA channel
* Request DMA channel
*
*
* On certain platforms, we have to allocate an interrupt as well...
* On certain platforms, we have to allocate an interrupt as well...
*/
*/
int
request_dma
(
dmach_t
channel
,
const
char
*
device_id
)
int
request_dma
(
unsigned
int
chan
,
const
char
*
device_id
)
{
{
dma_t
*
dma
=
dma_chan
+
channel
;
dma_t
*
dma
=
dma_chan
nel
(
chan
)
;
int
ret
;
int
ret
;
if
(
channel
>=
MAX_DMA_CHANNELS
||
!
dma
->
d_ops
)
if
(
!
dma
)
goto
bad_dma
;
goto
bad_dma
;
if
(
xchg
(
&
dma
->
lock
,
1
)
!=
0
)
if
(
xchg
(
&
dma
->
lock
,
1
)
!=
0
)
...
@@ -47,7 +69,7 @@ int request_dma(dmach_t channel, const char *device_id)
...
@@ -47,7 +69,7 @@ int request_dma(dmach_t channel, const char *device_id)
ret
=
0
;
ret
=
0
;
if
(
dma
->
d_ops
->
request
)
if
(
dma
->
d_ops
->
request
)
ret
=
dma
->
d_ops
->
request
(
chan
nel
,
dma
);
ret
=
dma
->
d_ops
->
request
(
chan
,
dma
);
if
(
ret
)
if
(
ret
)
xchg
(
&
dma
->
lock
,
0
);
xchg
(
&
dma
->
lock
,
0
);
...
@@ -55,7 +77,7 @@ int request_dma(dmach_t channel, const char *device_id)
...
@@ -55,7 +77,7 @@ int request_dma(dmach_t channel, const char *device_id)
return
ret
;
return
ret
;
bad_dma:
bad_dma:
printk
(
KERN_ERR
"dma: trying to allocate DMA%d
\n
"
,
chan
nel
);
printk
(
KERN_ERR
"dma: trying to allocate DMA%d
\n
"
,
chan
);
return
-
EINVAL
;
return
-
EINVAL
;
busy:
busy:
...
@@ -68,42 +90,42 @@ EXPORT_SYMBOL(request_dma);
...
@@ -68,42 +90,42 @@ EXPORT_SYMBOL(request_dma);
*
*
* On certain platforms, we have to free interrupt as well...
* On certain platforms, we have to free interrupt as well...
*/
*/
void
free_dma
(
dmach_t
channel
)
void
free_dma
(
unsigned
int
chan
)
{
{
dma_t
*
dma
=
dma_chan
+
channel
;
dma_t
*
dma
=
dma_chan
nel
(
chan
)
;
if
(
channel
>=
MAX_DMA_CHANNELS
||
!
dma
->
d_ops
)
if
(
!
dma
)
goto
bad_dma
;
goto
bad_dma
;
if
(
dma
->
active
)
{
if
(
dma
->
active
)
{
printk
(
KERN_ERR
"dma%d: freeing active DMA
\n
"
,
chan
nel
);
printk
(
KERN_ERR
"dma%d: freeing active DMA
\n
"
,
chan
);
dma
->
d_ops
->
disable
(
chan
nel
,
dma
);
dma
->
d_ops
->
disable
(
chan
,
dma
);
dma
->
active
=
0
;
dma
->
active
=
0
;
}
}
if
(
xchg
(
&
dma
->
lock
,
0
)
!=
0
)
{
if
(
xchg
(
&
dma
->
lock
,
0
)
!=
0
)
{
if
(
dma
->
d_ops
->
free
)
if
(
dma
->
d_ops
->
free
)
dma
->
d_ops
->
free
(
chan
nel
,
dma
);
dma
->
d_ops
->
free
(
chan
,
dma
);
return
;
return
;
}
}
printk
(
KERN_ERR
"dma%d: trying to free free DMA
\n
"
,
chan
nel
);
printk
(
KERN_ERR
"dma%d: trying to free free DMA
\n
"
,
chan
);
return
;
return
;
bad_dma:
bad_dma:
printk
(
KERN_ERR
"dma: trying to free DMA%d
\n
"
,
chan
nel
);
printk
(
KERN_ERR
"dma: trying to free DMA%d
\n
"
,
chan
);
}
}
EXPORT_SYMBOL
(
free_dma
);
EXPORT_SYMBOL
(
free_dma
);
/* Set DMA Scatter-Gather list
/* Set DMA Scatter-Gather list
*/
*/
void
set_dma_sg
(
dmach_t
channel
,
struct
scatterlist
*
sg
,
int
nr_sg
)
void
set_dma_sg
(
unsigned
int
chan
,
struct
scatterlist
*
sg
,
int
nr_sg
)
{
{
dma_t
*
dma
=
dma_chan
+
channel
;
dma_t
*
dma
=
dma_chan
nel
(
chan
)
;
if
(
dma
->
active
)
if
(
dma
->
active
)
printk
(
KERN_ERR
"dma%d: altering DMA SG while "
printk
(
KERN_ERR
"dma%d: altering DMA SG while "
"DMA active
\n
"
,
chan
nel
);
"DMA active
\n
"
,
chan
);
dma
->
sg
=
sg
;
dma
->
sg
=
sg
;
dma
->
sgcount
=
nr_sg
;
dma
->
sgcount
=
nr_sg
;
...
@@ -115,13 +137,13 @@ EXPORT_SYMBOL(set_dma_sg);
...
@@ -115,13 +137,13 @@ EXPORT_SYMBOL(set_dma_sg);
*
*
* Copy address to the structure, and set the invalid bit
* Copy address to the structure, and set the invalid bit
*/
*/
void
__set_dma_addr
(
dmach_t
channel
,
void
*
addr
)
void
__set_dma_addr
(
unsigned
int
chan
,
void
*
addr
)
{
{
dma_t
*
dma
=
dma_chan
+
channel
;
dma_t
*
dma
=
dma_chan
nel
(
chan
)
;
if
(
dma
->
active
)
if
(
dma
->
active
)
printk
(
KERN_ERR
"dma%d: altering DMA address while "
printk
(
KERN_ERR
"dma%d: altering DMA address while "
"DMA active
\n
"
,
chan
nel
);
"DMA active
\n
"
,
chan
);
dma
->
sg
=
NULL
;
dma
->
sg
=
NULL
;
dma
->
addr
=
addr
;
dma
->
addr
=
addr
;
...
@@ -133,13 +155,13 @@ EXPORT_SYMBOL(__set_dma_addr);
...
@@ -133,13 +155,13 @@ EXPORT_SYMBOL(__set_dma_addr);
*
*
* Copy address to the structure, and set the invalid bit
* Copy address to the structure, and set the invalid bit
*/
*/
void
set_dma_count
(
dmach_t
channel
,
unsigned
long
count
)
void
set_dma_count
(
unsigned
int
chan
,
unsigned
long
count
)
{
{
dma_t
*
dma
=
dma_chan
+
channel
;
dma_t
*
dma
=
dma_chan
nel
(
chan
)
;
if
(
dma
->
active
)
if
(
dma
->
active
)
printk
(
KERN_ERR
"dma%d: altering DMA count while "
printk
(
KERN_ERR
"dma%d: altering DMA count while "
"DMA active
\n
"
,
chan
nel
);
"DMA active
\n
"
,
chan
);
dma
->
sg
=
NULL
;
dma
->
sg
=
NULL
;
dma
->
count
=
count
;
dma
->
count
=
count
;
...
@@ -149,13 +171,13 @@ EXPORT_SYMBOL(set_dma_count);
...
@@ -149,13 +171,13 @@ EXPORT_SYMBOL(set_dma_count);
/* Set DMA direction mode
/* Set DMA direction mode
*/
*/
void
set_dma_mode
(
dmach_t
channel
,
dmamode_
t
mode
)
void
set_dma_mode
(
unsigned
int
chan
,
unsigned
in
t
mode
)
{
{
dma_t
*
dma
=
dma_chan
+
channel
;
dma_t
*
dma
=
dma_chan
nel
(
chan
)
;
if
(
dma
->
active
)
if
(
dma
->
active
)
printk
(
KERN_ERR
"dma%d: altering DMA mode while "
printk
(
KERN_ERR
"dma%d: altering DMA mode while "
"DMA active
\n
"
,
chan
nel
);
"DMA active
\n
"
,
chan
);
dma
->
dma_mode
=
mode
;
dma
->
dma_mode
=
mode
;
dma
->
invalid
=
1
;
dma
->
invalid
=
1
;
...
@@ -164,42 +186,42 @@ EXPORT_SYMBOL(set_dma_mode);
...
@@ -164,42 +186,42 @@ EXPORT_SYMBOL(set_dma_mode);
/* Enable DMA channel
/* Enable DMA channel
*/
*/
void
enable_dma
(
dmach_t
channel
)
void
enable_dma
(
unsigned
int
chan
)
{
{
dma_t
*
dma
=
dma_chan
+
channel
;
dma_t
*
dma
=
dma_chan
nel
(
chan
)
;
if
(
!
dma
->
lock
)
if
(
!
dma
->
lock
)
goto
free_dma
;
goto
free_dma
;
if
(
dma
->
active
==
0
)
{
if
(
dma
->
active
==
0
)
{
dma
->
active
=
1
;
dma
->
active
=
1
;
dma
->
d_ops
->
enable
(
chan
nel
,
dma
);
dma
->
d_ops
->
enable
(
chan
,
dma
);
}
}
return
;
return
;
free_dma:
free_dma:
printk
(
KERN_ERR
"dma%d: trying to enable free DMA
\n
"
,
chan
nel
);
printk
(
KERN_ERR
"dma%d: trying to enable free DMA
\n
"
,
chan
);
BUG
();
BUG
();
}
}
EXPORT_SYMBOL
(
enable_dma
);
EXPORT_SYMBOL
(
enable_dma
);
/* Disable DMA channel
/* Disable DMA channel
*/
*/
void
disable_dma
(
dmach_t
channel
)
void
disable_dma
(
unsigned
int
chan
)
{
{
dma_t
*
dma
=
dma_chan
+
channel
;
dma_t
*
dma
=
dma_chan
nel
(
chan
)
;
if
(
!
dma
->
lock
)
if
(
!
dma
->
lock
)
goto
free_dma
;
goto
free_dma
;
if
(
dma
->
active
==
1
)
{
if
(
dma
->
active
==
1
)
{
dma
->
active
=
0
;
dma
->
active
=
0
;
dma
->
d_ops
->
disable
(
chan
nel
,
dma
);
dma
->
d_ops
->
disable
(
chan
,
dma
);
}
}
return
;
return
;
free_dma:
free_dma:
printk
(
KERN_ERR
"dma%d: trying to disable free DMA
\n
"
,
chan
nel
);
printk
(
KERN_ERR
"dma%d: trying to disable free DMA
\n
"
,
chan
);
BUG
();
BUG
();
}
}
EXPORT_SYMBOL
(
disable_dma
);
EXPORT_SYMBOL
(
disable_dma
);
...
@@ -207,45 +229,38 @@ EXPORT_SYMBOL(disable_dma);
...
@@ -207,45 +229,38 @@ EXPORT_SYMBOL(disable_dma);
/*
/*
* Is the specified DMA channel active?
* Is the specified DMA channel active?
*/
*/
int
dma_channel_active
(
dmach_t
channel
)
int
dma_channel_active
(
unsigned
int
chan
)
{
{
return
dma_chan
[
channel
].
active
;
dma_t
*
dma
=
dma_channel
(
chan
);
return
dma
->
active
;
}
}
EXPORT_SYMBOL
(
dma_channel_active
);
EXPORT_SYMBOL
(
dma_channel_active
);
void
set_dma_page
(
dmach_t
channel
,
char
pagenr
)
void
set_dma_page
(
unsigned
int
chan
,
char
pagenr
)
{
{
printk
(
KERN_ERR
"dma%d: trying to set_dma_page
\n
"
,
chan
nel
);
printk
(
KERN_ERR
"dma%d: trying to set_dma_page
\n
"
,
chan
);
}
}
EXPORT_SYMBOL
(
set_dma_page
);
EXPORT_SYMBOL
(
set_dma_page
);
void
set_dma_speed
(
dmach_t
channel
,
int
cycle_ns
)
void
set_dma_speed
(
unsigned
int
chan
,
int
cycle_ns
)
{
{
dma_t
*
dma
=
dma_chan
+
channel
;
dma_t
*
dma
=
dma_chan
nel
(
chan
)
;
int
ret
=
0
;
int
ret
=
0
;
if
(
dma
->
d_ops
->
setspeed
)
if
(
dma
->
d_ops
->
setspeed
)
ret
=
dma
->
d_ops
->
setspeed
(
chan
nel
,
dma
,
cycle_ns
);
ret
=
dma
->
d_ops
->
setspeed
(
chan
,
dma
,
cycle_ns
);
dma
->
speed
=
ret
;
dma
->
speed
=
ret
;
}
}
EXPORT_SYMBOL
(
set_dma_speed
);
EXPORT_SYMBOL
(
set_dma_speed
);
int
get_dma_residue
(
dmach_t
channel
)
int
get_dma_residue
(
unsigned
int
chan
)
{
{
dma_t
*
dma
=
dma_chan
+
channel
;
dma_t
*
dma
=
dma_chan
nel
(
chan
)
;
int
ret
=
0
;
int
ret
=
0
;
if
(
dma
->
d_ops
->
residue
)
if
(
dma
->
d_ops
->
residue
)
ret
=
dma
->
d_ops
->
residue
(
chan
nel
,
dma
);
ret
=
dma
->
d_ops
->
residue
(
chan
,
dma
);
return
ret
;
return
ret
;
}
}
EXPORT_SYMBOL
(
get_dma_residue
);
EXPORT_SYMBOL
(
get_dma_residue
);
static
int
__init
init_dma
(
void
)
{
arch_dma_init
(
dma_chan
);
return
0
;
}
core_initcall
(
init_dma
);
arch/arm/mach-footbridge/dma.c
浏览文件 @
22b61a11
...
@@ -21,16 +21,16 @@
...
@@ -21,16 +21,16 @@
#include <asm/hardware/dec21285.h>
#include <asm/hardware/dec21285.h>
#if 0
#if 0
static int fb_dma_request(
dmach_t channel
, dma_t *dma)
static int fb_dma_request(
unsigned int chan
, dma_t *dma)
{
{
return -EINVAL;
return -EINVAL;
}
}
static void fb_dma_enable(
dmach_t channel
, dma_t *dma)
static void fb_dma_enable(
unsigned int chan
, dma_t *dma)
{
{
}
}
static void fb_dma_disable(
dmach_t channel
, dma_t *dma)
static void fb_dma_disable(
unsigned int chan
, dma_t *dma)
{
{
}
}
...
@@ -42,7 +42,7 @@ static struct dma_ops fb_dma_ops = {
...
@@ -42,7 +42,7 @@ static struct dma_ops fb_dma_ops = {
};
};
#endif
#endif
void
__init
arch_dma_init
(
dma_t
*
dma
)
static
int
__init
fb_dma_init
(
void
)
{
{
#if 0
#if 0
dma[_DC21285_DMA(0)].d_ops = &fb_dma_ops;
dma[_DC21285_DMA(0)].d_ops = &fb_dma_ops;
...
@@ -50,6 +50,8 @@ void __init arch_dma_init(dma_t *dma)
...
@@ -50,6 +50,8 @@ void __init arch_dma_init(dma_t *dma)
#endif
#endif
#ifdef CONFIG_ISA_DMA
#ifdef CONFIG_ISA_DMA
if
(
footbridge_cfn_mode
())
if
(
footbridge_cfn_mode
())
isa_init_dma
(
dma
+
_ISA_DMA
(
0
)
);
isa_init_dma
();
#endif
#endif
return
0
;
}
}
core_initcall
(
fb_dma_init
);
arch/arm/mach-rpc/dma.c
浏览文件 @
22b61a11
...
@@ -26,6 +26,16 @@
...
@@ -26,6 +26,16 @@
#include <asm/mach/dma.h>
#include <asm/mach/dma.h>
#include <asm/hardware/iomd.h>
#include <asm/hardware/iomd.h>
struct
iomd_dma
{
struct
dma_struct
dma
;
unsigned
int
state
;
unsigned
long
base
;
/* Controller base address */
int
irq
;
/* Controller IRQ */
struct
scatterlist
cur_sg
;
/* Current controller buffer */
dma_addr_t
dma_addr
;
unsigned
int
dma_len
;
};
#if 0
#if 0
typedef enum {
typedef enum {
dma_size_8 = 1,
dma_size_8 = 1,
...
@@ -44,15 +54,15 @@ typedef enum {
...
@@ -44,15 +54,15 @@ typedef enum {
#define CR (IOMD_IO0CR - IOMD_IO0CURA)
#define CR (IOMD_IO0CR - IOMD_IO0CURA)
#define ST (IOMD_IO0ST - IOMD_IO0CURA)
#define ST (IOMD_IO0ST - IOMD_IO0CURA)
static
void
iomd_get_next_sg
(
struct
scatterlist
*
sg
,
dma_t
*
dma
)
static
void
iomd_get_next_sg
(
struct
scatterlist
*
sg
,
struct
iomd_dma
*
i
dma
)
{
{
unsigned
long
end
,
offset
,
flags
=
0
;
unsigned
long
end
,
offset
,
flags
=
0
;
if
(
dma
->
sg
)
{
if
(
idma
->
dma
.
sg
)
{
sg
->
dma_address
=
dma
->
sg
->
dma_address
;
sg
->
dma_address
=
idma
->
dma_addr
;
offset
=
sg
->
dma_address
&
~
PAGE_MASK
;
offset
=
sg
->
dma_address
&
~
PAGE_MASK
;
end
=
offset
+
dma
->
sg
->
length
;
end
=
offset
+
idma
->
dma_len
;
if
(
end
>
PAGE_SIZE
)
if
(
end
>
PAGE_SIZE
)
end
=
PAGE_SIZE
;
end
=
PAGE_SIZE
;
...
@@ -62,15 +72,17 @@ static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma)
...
@@ -62,15 +72,17 @@ static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma)
sg
->
length
=
end
-
TRANSFER_SIZE
;
sg
->
length
=
end
-
TRANSFER_SIZE
;
dma
->
sg
->
length
-=
end
-
offset
;
idma
->
dma_len
-=
end
-
offset
;
dma
->
sg
->
dma_address
+=
end
-
offset
;
idma
->
dma_addr
+=
end
-
offset
;
if
(
dma
->
sg
->
length
==
0
)
{
if
(
idma
->
dma_len
==
0
)
{
if
(
dma
->
sgcount
>
1
)
{
if
(
idma
->
dma
.
sgcount
>
1
)
{
dma
->
sg
++
;
idma
->
dma
.
sg
=
sg_next
(
idma
->
dma
.
sg
);
dma
->
sgcount
--
;
idma
->
dma_addr
=
idma
->
dma
.
sg
->
dma_address
;
idma
->
dma_len
=
idma
->
dma
.
sg
->
length
;
idma
->
dma
.
sgcount
--
;
}
else
{
}
else
{
dma
->
sg
=
NULL
;
idma
->
dma
.
sg
=
NULL
;
flags
|=
DMA_END_S
;
flags
|=
DMA_END_S
;
}
}
}
}
...
@@ -85,8 +97,8 @@ static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma)
...
@@ -85,8 +97,8 @@ static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma)
static
irqreturn_t
iomd_dma_handle
(
int
irq
,
void
*
dev_id
)
static
irqreturn_t
iomd_dma_handle
(
int
irq
,
void
*
dev_id
)
{
{
dma_t
*
dma
=
(
dma_t
*
)
dev_id
;
struct
iomd_dma
*
idma
=
dev_id
;
unsigned
long
base
=
dma
->
dma_
base
;
unsigned
long
base
=
idma
->
base
;
do
{
do
{
unsigned
int
status
;
unsigned
int
status
;
...
@@ -95,93 +107,99 @@ static irqreturn_t iomd_dma_handle(int irq, void *dev_id)
...
@@ -95,93 +107,99 @@ static irqreturn_t iomd_dma_handle(int irq, void *dev_id)
if
(
!
(
status
&
DMA_ST_INT
))
if
(
!
(
status
&
DMA_ST_INT
))
return
IRQ_HANDLED
;
return
IRQ_HANDLED
;
if
((
dma
->
state
^
status
)
&
DMA_ST_AB
)
if
((
i
dma
->
state
^
status
)
&
DMA_ST_AB
)
iomd_get_next_sg
(
&
dma
->
cur_sg
,
dma
);
iomd_get_next_sg
(
&
idma
->
cur_sg
,
i
dma
);
switch
(
status
&
(
DMA_ST_OFL
|
DMA_ST_AB
))
{
switch
(
status
&
(
DMA_ST_OFL
|
DMA_ST_AB
))
{
case
DMA_ST_OFL
:
/* OIA */
case
DMA_ST_OFL
:
/* OIA */
case
DMA_ST_AB
:
/* .IB */
case
DMA_ST_AB
:
/* .IB */
iomd_writel
(
dma
->
cur_sg
.
dma_address
,
base
+
CURA
);
iomd_writel
(
i
dma
->
cur_sg
.
dma_address
,
base
+
CURA
);
iomd_writel
(
dma
->
cur_sg
.
length
,
base
+
ENDA
);
iomd_writel
(
i
dma
->
cur_sg
.
length
,
base
+
ENDA
);
dma
->
state
=
DMA_ST_AB
;
i
dma
->
state
=
DMA_ST_AB
;
break
;
break
;
case
DMA_ST_OFL
|
DMA_ST_AB
:
/* OIB */
case
DMA_ST_OFL
|
DMA_ST_AB
:
/* OIB */
case
0
:
/* .IA */
case
0
:
/* .IA */
iomd_writel
(
dma
->
cur_sg
.
dma_address
,
base
+
CURB
);
iomd_writel
(
i
dma
->
cur_sg
.
dma_address
,
base
+
CURB
);
iomd_writel
(
dma
->
cur_sg
.
length
,
base
+
ENDB
);
iomd_writel
(
i
dma
->
cur_sg
.
length
,
base
+
ENDB
);
dma
->
state
=
0
;
i
dma
->
state
=
0
;
break
;
break
;
}
}
if
(
status
&
DMA_ST_OFL
&&
if
(
status
&
DMA_ST_OFL
&&
dma
->
cur_sg
.
length
==
(
DMA_END_S
|
DMA_END_L
))
i
dma
->
cur_sg
.
length
==
(
DMA_END_S
|
DMA_END_L
))
break
;
break
;
}
while
(
1
);
}
while
(
1
);
dma
->
state
=
~
DMA_ST_AB
;
i
dma
->
state
=
~
DMA_ST_AB
;
disable_irq
(
irq
);
disable_irq
(
irq
);
return
IRQ_HANDLED
;
return
IRQ_HANDLED
;
}
}
static
int
iomd_request_dma
(
dmach_t
channel
,
dma_t
*
dma
)
static
int
iomd_request_dma
(
unsigned
int
chan
,
dma_t
*
dma
)
{
{
return
request_irq
(
dma
->
dma_irq
,
iomd_dma_handle
,
struct
iomd_dma
*
idma
=
container_of
(
dma
,
struct
iomd_dma
,
dma
);
IRQF_DISABLED
,
dma
->
device_id
,
dma
);
return
request_irq
(
idma
->
irq
,
iomd_dma_handle
,
IRQF_DISABLED
,
idma
->
dma
.
device_id
,
idma
);
}
}
static
void
iomd_free_dma
(
dmach_t
channel
,
dma_t
*
dma
)
static
void
iomd_free_dma
(
unsigned
int
chan
,
dma_t
*
dma
)
{
{
free_irq
(
dma
->
dma_irq
,
dma
);
struct
iomd_dma
*
idma
=
container_of
(
dma
,
struct
iomd_dma
,
dma
);
free_irq
(
idma
->
irq
,
idma
);
}
}
static
void
iomd_enable_dma
(
dmach_t
channel
,
dma_t
*
dma
)
static
void
iomd_enable_dma
(
unsigned
int
chan
,
dma_t
*
dma
)
{
{
unsigned
long
dma_base
=
dma
->
dma_base
;
struct
iomd_dma
*
idma
=
container_of
(
dma
,
struct
iomd_dma
,
dma
);
unsigned
long
dma_base
=
idma
->
base
;
unsigned
int
ctrl
=
TRANSFER_SIZE
|
DMA_CR_E
;
unsigned
int
ctrl
=
TRANSFER_SIZE
|
DMA_CR_E
;
if
(
dma
->
invalid
)
{
if
(
idma
->
dma
.
invalid
)
{
dma
->
invalid
=
0
;
idma
->
dma
.
invalid
=
0
;
/*
/*
* Cope with ISA-style drivers which expect cache
* Cope with ISA-style drivers which expect cache
* coherence.
* coherence.
*/
*/
if
(
!
dma
->
sg
)
{
if
(
!
idma
->
dma
.
sg
)
{
dma
->
sg
=
&
dma
->
buf
;
idma
->
dma
.
sg
=
&
idma
->
dma
.
buf
;
dma
->
sgcount
=
1
;
idma
->
dma
.
sgcount
=
1
;
dma
->
buf
.
length
=
dma
->
count
;
idma
->
dma
.
buf
.
length
=
idma
->
dma
.
count
;
dma
->
buf
.
dma_address
=
dma_map_single
(
NULL
,
idma
->
dma
.
buf
.
dma_address
=
dma_map_single
(
NULL
,
dma
->
addr
,
dma
->
count
,
idma
->
dma
.
addr
,
idma
->
dma
.
count
,
dma
->
dma_mode
==
DMA_MODE_READ
?
idma
->
dma
.
dma_mode
==
DMA_MODE_READ
?
DMA_FROM_DEVICE
:
DMA_TO_DEVICE
);
DMA_FROM_DEVICE
:
DMA_TO_DEVICE
);
}
}
iomd_writeb
(
DMA_CR_C
,
dma_base
+
CR
);
iomd_writeb
(
DMA_CR_C
,
dma_base
+
CR
);
dma
->
state
=
DMA_ST_AB
;
i
dma
->
state
=
DMA_ST_AB
;
}
}
if
(
dma
->
dma_mode
==
DMA_MODE_READ
)
if
(
idma
->
dma
.
dma_mode
==
DMA_MODE_READ
)
ctrl
|=
DMA_CR_D
;
ctrl
|=
DMA_CR_D
;
iomd_writeb
(
ctrl
,
dma_base
+
CR
);
iomd_writeb
(
ctrl
,
dma_base
+
CR
);
enable_irq
(
dma
->
dma_
irq
);
enable_irq
(
idma
->
irq
);
}
}
static
void
iomd_disable_dma
(
dmach_t
channel
,
dma_t
*
dma
)
static
void
iomd_disable_dma
(
unsigned
int
chan
,
dma_t
*
dma
)
{
{
unsigned
long
dma_base
=
dma
->
dma_base
;
struct
iomd_dma
*
idma
=
container_of
(
dma
,
struct
iomd_dma
,
dma
);
unsigned
long
dma_base
=
idma
->
base
;
unsigned
long
flags
;
unsigned
long
flags
;
local_irq_save
(
flags
);
local_irq_save
(
flags
);
if
(
dma
->
state
!=
~
DMA_ST_AB
)
if
(
i
dma
->
state
!=
~
DMA_ST_AB
)
disable_irq
(
dma
->
dma_
irq
);
disable_irq
(
idma
->
irq
);
iomd_writeb
(
0
,
dma_base
+
CR
);
iomd_writeb
(
0
,
dma_base
+
CR
);
local_irq_restore
(
flags
);
local_irq_restore
(
flags
);
}
}
static
int
iomd_set_dma_speed
(
dmach_t
channel
,
dma_t
*
dma
,
int
cycle
)
static
int
iomd_set_dma_speed
(
unsigned
int
chan
,
dma_t
*
dma
,
int
cycle
)
{
{
int
tcr
,
speed
;
int
tcr
,
speed
;
...
@@ -197,7 +215,7 @@ static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
...
@@ -197,7 +215,7 @@ static int iomd_set_dma_speed(dmach_t channel, dma_t *dma, int cycle)
tcr
=
iomd_readb
(
IOMD_DMATCR
);
tcr
=
iomd_readb
(
IOMD_DMATCR
);
speed
&=
3
;
speed
&=
3
;
switch
(
chan
nel
)
{
switch
(
chan
)
{
case
DMA_0
:
case
DMA_0
:
tcr
=
(
tcr
&
~
0x03
)
|
speed
;
tcr
=
(
tcr
&
~
0x03
)
|
speed
;
break
;
break
;
...
@@ -236,16 +254,22 @@ static struct fiq_handler fh = {
...
@@ -236,16 +254,22 @@ static struct fiq_handler fh = {
.
name
=
"floppydma"
.
name
=
"floppydma"
};
};
static
void
floppy_enable_dma
(
dmach_t
channel
,
dma_t
*
dma
)
struct
floppy_dma
{
struct
dma_struct
dma
;
unsigned
int
fiq
;
};
static
void
floppy_enable_dma
(
unsigned
int
chan
,
dma_t
*
dma
)
{
{
struct
floppy_dma
*
fdma
=
container_of
(
dma
,
struct
floppy_dma
,
dma
);
void
*
fiqhandler_start
;
void
*
fiqhandler_start
;
unsigned
int
fiqhandler_length
;
unsigned
int
fiqhandler_length
;
struct
pt_regs
regs
;
struct
pt_regs
regs
;
if
(
dma
->
sg
)
if
(
fdma
->
dma
.
sg
)
BUG
();
BUG
();
if
(
dma
->
dma_mode
==
DMA_MODE_READ
)
{
if
(
fdma
->
dma
.
dma_mode
==
DMA_MODE_READ
)
{
extern
unsigned
char
floppy_fiqin_start
,
floppy_fiqin_end
;
extern
unsigned
char
floppy_fiqin_start
,
floppy_fiqin_end
;
fiqhandler_start
=
&
floppy_fiqin_start
;
fiqhandler_start
=
&
floppy_fiqin_start
;
fiqhandler_length
=
&
floppy_fiqin_end
-
&
floppy_fiqin_start
;
fiqhandler_length
=
&
floppy_fiqin_end
-
&
floppy_fiqin_start
;
...
@@ -255,8 +279,8 @@ static void floppy_enable_dma(dmach_t channel, dma_t *dma)
...
@@ -255,8 +279,8 @@ static void floppy_enable_dma(dmach_t channel, dma_t *dma)
fiqhandler_length
=
&
floppy_fiqout_end
-
&
floppy_fiqout_start
;
fiqhandler_length
=
&
floppy_fiqout_end
-
&
floppy_fiqout_start
;
}
}
regs
.
ARM_r9
=
dma
->
count
;
regs
.
ARM_r9
=
fdma
->
dma
.
count
;
regs
.
ARM_r10
=
(
unsigned
long
)
dma
->
addr
;
regs
.
ARM_r10
=
(
unsigned
long
)
fdma
->
dma
.
addr
;
regs
.
ARM_fp
=
(
unsigned
long
)
FLOPPYDMA_BASE
;
regs
.
ARM_fp
=
(
unsigned
long
)
FLOPPYDMA_BASE
;
if
(
claim_fiq
(
&
fh
))
{
if
(
claim_fiq
(
&
fh
))
{
...
@@ -266,16 +290,17 @@ static void floppy_enable_dma(dmach_t channel, dma_t *dma)
...
@@ -266,16 +290,17 @@ static void floppy_enable_dma(dmach_t channel, dma_t *dma)
set_fiq_handler
(
fiqhandler_start
,
fiqhandler_length
);
set_fiq_handler
(
fiqhandler_start
,
fiqhandler_length
);
set_fiq_regs
(
&
regs
);
set_fiq_regs
(
&
regs
);
enable_fiq
(
dma
->
dma_ir
q
);
enable_fiq
(
fdma
->
fi
q
);
}
}
static
void
floppy_disable_dma
(
dmach_t
channel
,
dma_t
*
dma
)
static
void
floppy_disable_dma
(
unsigned
int
chan
,
dma_t
*
dma
)
{
{
disable_fiq
(
dma
->
dma_irq
);
struct
floppy_dma
*
fdma
=
container_of
(
dma
,
struct
floppy_dma
,
dma
);
disable_fiq
(
fdma
->
fiq
);
release_fiq
(
&
fh
);
release_fiq
(
&
fh
);
}
}
static
int
floppy_get_residue
(
dmach_t
channel
,
dma_t
*
dma
)
static
int
floppy_get_residue
(
unsigned
int
chan
,
dma_t
*
dma
)
{
{
struct
pt_regs
regs
;
struct
pt_regs
regs
;
get_fiq_regs
(
&
regs
);
get_fiq_regs
(
&
regs
);
...
@@ -292,7 +317,7 @@ static struct dma_ops floppy_dma_ops = {
...
@@ -292,7 +317,7 @@ static struct dma_ops floppy_dma_ops = {
/*
/*
* This is virtual DMA - we don't need anything here.
* This is virtual DMA - we don't need anything here.
*/
*/
static
void
sound_enable_disable_dma
(
dmach_t
channel
,
dma_t
*
dma
)
static
void
sound_enable_disable_dma
(
unsigned
int
chan
,
dma_t
*
dma
)
{
{
}
}
...
@@ -302,8 +327,24 @@ static struct dma_ops sound_dma_ops = {
...
@@ -302,8 +327,24 @@ static struct dma_ops sound_dma_ops = {
.
disable
=
sound_enable_disable_dma
,
.
disable
=
sound_enable_disable_dma
,
};
};
void
__init
arch_dma_init
(
dma_t
*
dma
)
static
struct
iomd_dma
iomd_dma
[
6
];
static
struct
floppy_dma
floppy_dma
=
{
.
dma
=
{
.
d_ops
=
&
floppy_dma_ops
,
},
.
fiq
=
FIQ_FLOPPYDATA
,
};
static
dma_t
sound_dma
=
{
.
d_ops
=
&
sound_dma_ops
,
};
static
int
__init
rpc_dma_init
(
void
)
{
{
unsigned
int
i
;
int
ret
;
iomd_writeb
(
0
,
IOMD_IO0CR
);
iomd_writeb
(
0
,
IOMD_IO0CR
);
iomd_writeb
(
0
,
IOMD_IO1CR
);
iomd_writeb
(
0
,
IOMD_IO1CR
);
iomd_writeb
(
0
,
IOMD_IO2CR
);
iomd_writeb
(
0
,
IOMD_IO2CR
);
...
@@ -311,31 +352,39 @@ void __init arch_dma_init(dma_t *dma)
...
@@ -311,31 +352,39 @@ void __init arch_dma_init(dma_t *dma)
iomd_writeb
(
0xa0
,
IOMD_DMATCR
);
iomd_writeb
(
0xa0
,
IOMD_DMATCR
);
dma
[
DMA_0
].
dma_base
=
IOMD_IO0CURA
;
dma
[
DMA_0
].
dma_irq
=
IRQ_DMA0
;
dma
[
DMA_0
].
d_ops
=
&
iomd_dma_ops
;
dma
[
DMA_1
].
dma_base
=
IOMD_IO1CURA
;
dma
[
DMA_1
].
dma_irq
=
IRQ_DMA1
;
dma
[
DMA_1
].
d_ops
=
&
iomd_dma_ops
;
dma
[
DMA_2
].
dma_base
=
IOMD_IO2CURA
;
dma
[
DMA_2
].
dma_irq
=
IRQ_DMA2
;
dma
[
DMA_2
].
d_ops
=
&
iomd_dma_ops
;
dma
[
DMA_3
].
dma_base
=
IOMD_IO3CURA
;
dma
[
DMA_3
].
dma_irq
=
IRQ_DMA3
;
dma
[
DMA_3
].
d_ops
=
&
iomd_dma_ops
;
dma
[
DMA_S0
].
dma_base
=
IOMD_SD0CURA
;
dma
[
DMA_S0
].
dma_irq
=
IRQ_DMAS0
;
dma
[
DMA_S0
].
d_ops
=
&
iomd_dma_ops
;
dma
[
DMA_S1
].
dma_base
=
IOMD_SD1CURA
;
dma
[
DMA_S1
].
dma_irq
=
IRQ_DMAS1
;
dma
[
DMA_S1
].
d_ops
=
&
iomd_dma_ops
;
dma
[
DMA_VIRTUAL_FLOPPY
].
dma_irq
=
FIQ_FLOPPYDATA
;
dma
[
DMA_VIRTUAL_FLOPPY
].
d_ops
=
&
floppy_dma_ops
;
dma
[
DMA_VIRTUAL_SOUND
].
d_ops
=
&
sound_dma_ops
;
/*
/*
* Setup DMA channels 2,3 to be for podules
* Setup DMA channels 2,3 to be for podules
* and channels 0,1 for internal devices
* and channels 0,1 for internal devices
*/
*/
iomd_writeb
(
DMA_EXT_IO3
|
DMA_EXT_IO2
,
IOMD_DMAEXT
);
iomd_writeb
(
DMA_EXT_IO3
|
DMA_EXT_IO2
,
IOMD_DMAEXT
);
iomd_dma
[
DMA_0
].
base
=
IOMD_IO0CURA
;
iomd_dma
[
DMA_0
].
irq
=
IRQ_DMA0
;
iomd_dma
[
DMA_1
].
base
=
IOMD_IO1CURA
;
iomd_dma
[
DMA_1
].
irq
=
IRQ_DMA1
;
iomd_dma
[
DMA_2
].
base
=
IOMD_IO2CURA
;
iomd_dma
[
DMA_2
].
irq
=
IRQ_DMA2
;
iomd_dma
[
DMA_3
].
base
=
IOMD_IO3CURA
;
iomd_dma
[
DMA_3
].
irq
=
IRQ_DMA3
;
iomd_dma
[
DMA_S0
].
base
=
IOMD_SD0CURA
;
iomd_dma
[
DMA_S0
].
irq
=
IRQ_DMAS0
;
iomd_dma
[
DMA_S1
].
base
=
IOMD_SD1CURA
;
iomd_dma
[
DMA_S1
].
irq
=
IRQ_DMAS1
;
for
(
i
=
DMA_0
;
i
<=
DMA_S1
;
i
++
)
{
iomd_dma
[
i
].
dma
.
d_ops
=
&
iomd_dma_ops
;
ret
=
isa_dma_add
(
i
,
&
iomd_dma
[
i
].
dma
);
if
(
ret
)
printk
(
"IOMDDMA%u: unable to register: %d
\n
"
,
i
,
ret
);
}
ret
=
isa_dma_add
(
DMA_VIRTUAL_FLOPPY
,
&
floppy_dma
.
dma
);
if
(
ret
)
printk
(
"IOMDFLOPPY: unable to register: %d
\n
"
,
ret
);
ret
=
isa_dma_add
(
DMA_VIRTUAL_SOUND
,
&
sound_dma
);
if
(
ret
)
printk
(
"IOMDSOUND: unable to register: %d
\n
"
,
ret
);
return
0
;
}
}
core_initcall
(
rpc_dma_init
);
arch/arm/mach-rpc/include/mach/isa-dma.h
浏览文件 @
22b61a11
...
@@ -23,5 +23,7 @@
...
@@ -23,5 +23,7 @@
#define DMA_FLOPPY DMA_VIRTUAL_FLOPPY
#define DMA_FLOPPY DMA_VIRTUAL_FLOPPY
#define IOMD_DMA_BOUNDARY (PAGE_SIZE - 1)
#endif
/* _ASM_ARCH_DMA_H */
#endif
/* _ASM_ARCH_DMA_H */
arch/arm/mach-shark/dma.c
浏览文件 @
22b61a11
...
@@ -13,9 +13,11 @@
...
@@ -13,9 +13,11 @@
#include <asm/dma.h>
#include <asm/dma.h>
#include <asm/mach/dma.h>
#include <asm/mach/dma.h>
void
__init
arch_dma_init
(
dma_t
*
dma
)
static
int
__init
shark_dma_init
(
void
)
{
{
#ifdef CONFIG_ISA_DMA
#ifdef CONFIG_ISA_DMA
isa_init_dma
(
dma
);
isa_init_dma
();
#endif
#endif
return
0
;
}
}
core_initcall
(
shark_dma_init
);
arch/arm/plat-mxc/dma-mx1-mx2.c
浏览文件 @
22b61a11
...
@@ -113,7 +113,7 @@ struct imx_dma_channel {
...
@@ -113,7 +113,7 @@ struct imx_dma_channel {
void
(
*
err_handler
)
(
int
,
void
*
,
int
errcode
);
void
(
*
err_handler
)
(
int
,
void
*
,
int
errcode
);
void
(
*
prog_handler
)
(
int
,
void
*
,
struct
scatterlist
*
);
void
(
*
prog_handler
)
(
int
,
void
*
,
struct
scatterlist
*
);
void
*
data
;
void
*
data
;
unsigned
int
dma_mode
;
unsigned
int
dma_mode
;
struct
scatterlist
*
sg
;
struct
scatterlist
*
sg
;
unsigned
int
resbytes
;
unsigned
int
resbytes
;
int
dma_num
;
int
dma_num
;
...
...
drivers/ata/pata_icside.c
浏览文件 @
22b61a11
...
@@ -45,8 +45,6 @@ static const struct portinfo pata_icside_portinfo_v6_2 = {
...
@@ -45,8 +45,6 @@ static const struct portinfo pata_icside_portinfo_v6_2 = {
.
stepping
=
6
,
.
stepping
=
6
,
};
};
#define PATA_ICSIDE_MAX_SG 128
struct
pata_icside_state
{
struct
pata_icside_state
{
void
__iomem
*
irq_port
;
void
__iomem
*
irq_port
;
void
__iomem
*
ioc_base
;
void
__iomem
*
ioc_base
;
...
@@ -57,7 +55,6 @@ struct pata_icside_state {
...
@@ -57,7 +55,6 @@ struct pata_icside_state {
u8
disabled
;
u8
disabled
;
unsigned
int
speed
[
ATA_MAX_DEVICES
];
unsigned
int
speed
[
ATA_MAX_DEVICES
];
}
port
[
2
];
}
port
[
2
];
struct
scatterlist
sg
[
PATA_ICSIDE_MAX_SG
];
};
};
struct
pata_icside_info
{
struct
pata_icside_info
{
...
@@ -222,9 +219,7 @@ static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc)
...
@@ -222,9 +219,7 @@ static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc)
{
{
struct
ata_port
*
ap
=
qc
->
ap
;
struct
ata_port
*
ap
=
qc
->
ap
;
struct
pata_icside_state
*
state
=
ap
->
host
->
private_data
;
struct
pata_icside_state
*
state
=
ap
->
host
->
private_data
;
struct
scatterlist
*
sg
,
*
rsg
=
state
->
sg
;
unsigned
int
write
=
qc
->
tf
.
flags
&
ATA_TFLAG_WRITE
;
unsigned
int
write
=
qc
->
tf
.
flags
&
ATA_TFLAG_WRITE
;
unsigned
int
si
;
/*
/*
* We are simplex; BUG if we try to fiddle with DMA
* We are simplex; BUG if we try to fiddle with DMA
...
@@ -232,21 +227,13 @@ static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc)
...
@@ -232,21 +227,13 @@ static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc)
*/
*/
BUG_ON
(
dma_channel_active
(
state
->
dma
));
BUG_ON
(
dma_channel_active
(
state
->
dma
));
/*
* Copy ATAs scattered sg list into a contiguous array of sg
*/
for_each_sg
(
qc
->
sg
,
sg
,
qc
->
n_elem
,
si
)
{
memcpy
(
rsg
,
sg
,
sizeof
(
*
sg
));
rsg
++
;
}
/*
/*
* Route the DMA signals to the correct interface
* Route the DMA signals to the correct interface
*/
*/
writeb
(
state
->
port
[
ap
->
port_no
].
port_sel
,
state
->
ioc_base
);
writeb
(
state
->
port
[
ap
->
port_no
].
port_sel
,
state
->
ioc_base
);
set_dma_speed
(
state
->
dma
,
state
->
port
[
ap
->
port_no
].
speed
[
qc
->
dev
->
devno
]);
set_dma_speed
(
state
->
dma
,
state
->
port
[
ap
->
port_no
].
speed
[
qc
->
dev
->
devno
]);
set_dma_sg
(
state
->
dma
,
state
->
sg
,
rsg
-
state
->
sg
);
set_dma_sg
(
state
->
dma
,
qc
->
sg
,
qc
->
n_elem
);
set_dma_mode
(
state
->
dma
,
write
?
DMA_MODE_WRITE
:
DMA_MODE_READ
);
set_dma_mode
(
state
->
dma
,
write
?
DMA_MODE_WRITE
:
DMA_MODE_READ
);
/* issue r/w command */
/* issue r/w command */
...
@@ -306,8 +293,8 @@ static int icside_dma_init(struct pata_icside_info *info)
...
@@ -306,8 +293,8 @@ static int icside_dma_init(struct pata_icside_info *info)
static
struct
scsi_host_template
pata_icside_sht
=
{
static
struct
scsi_host_template
pata_icside_sht
=
{
ATA_BASE_SHT
(
DRV_NAME
),
ATA_BASE_SHT
(
DRV_NAME
),
.
sg_tablesize
=
PATA_ICSIDE_MAX_SG
,
.
sg_tablesize
=
SCSI_MAX_SG_CHAIN_SEGMENTS
,
.
dma_boundary
=
~
0
,
/* no dma boundaries */
.
dma_boundary
=
IOMD_DMA_BOUNDARY
,
};
};
static
void
pata_icside_postreset
(
struct
ata_link
*
link
,
unsigned
int
*
classes
)
static
void
pata_icside_postreset
(
struct
ata_link
*
link
,
unsigned
int
*
classes
)
...
...
drivers/scsi/arm/cumana_2.c
浏览文件 @
22b61a11
...
@@ -390,7 +390,8 @@ static struct scsi_host_template cumanascsi2_template = {
...
@@ -390,7 +390,8 @@ static struct scsi_host_template cumanascsi2_template = {
.
eh_abort_handler
=
fas216_eh_abort
,
.
eh_abort_handler
=
fas216_eh_abort
,
.
can_queue
=
1
,
.
can_queue
=
1
,
.
this_id
=
7
,
.
this_id
=
7
,
.
sg_tablesize
=
SG_ALL
,
.
sg_tablesize
=
SCSI_MAX_SG_CHAIN_SEGMENTS
,
.
dma_boundary
=
IOMD_DMA_BOUNDARY
,
.
cmd_per_lun
=
1
,
.
cmd_per_lun
=
1
,
.
use_clustering
=
DISABLE_CLUSTERING
,
.
use_clustering
=
DISABLE_CLUSTERING
,
.
proc_name
=
"cumanascsi2"
,
.
proc_name
=
"cumanascsi2"
,
...
...
drivers/scsi/arm/eesox.c
浏览文件 @
22b61a11
...
@@ -508,7 +508,8 @@ static struct scsi_host_template eesox_template = {
...
@@ -508,7 +508,8 @@ static struct scsi_host_template eesox_template = {
.
eh_abort_handler
=
fas216_eh_abort
,
.
eh_abort_handler
=
fas216_eh_abort
,
.
can_queue
=
1
,
.
can_queue
=
1
,
.
this_id
=
7
,
.
this_id
=
7
,
.
sg_tablesize
=
SG_ALL
,
.
sg_tablesize
=
SCSI_MAX_SG_CHAIN_SEGMENTS
,
.
dma_boundary
=
IOMD_DMA_BOUNDARY
,
.
cmd_per_lun
=
1
,
.
cmd_per_lun
=
1
,
.
use_clustering
=
DISABLE_CLUSTERING
,
.
use_clustering
=
DISABLE_CLUSTERING
,
.
proc_name
=
"eesox"
,
.
proc_name
=
"eesox"
,
...
...
drivers/scsi/arm/powertec.c
浏览文件 @
22b61a11
...
@@ -302,7 +302,8 @@ static struct scsi_host_template powertecscsi_template = {
...
@@ -302,7 +302,8 @@ static struct scsi_host_template powertecscsi_template = {
.
can_queue
=
8
,
.
can_queue
=
8
,
.
this_id
=
7
,
.
this_id
=
7
,
.
sg_tablesize
=
SG_ALL
,
.
sg_tablesize
=
SCSI_MAX_SG_CHAIN_SEGMENTS
,
.
dma_boundary
=
IOMD_DMA_BOUNDARY
,
.
cmd_per_lun
=
2
,
.
cmd_per_lun
=
2
,
.
use_clustering
=
ENABLE_CLUSTERING
,
.
use_clustering
=
ENABLE_CLUSTERING
,
.
proc_name
=
"powertec"
,
.
proc_name
=
"powertec"
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录