Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
e11c910b
K
Kernel
项目概览
openeuler
/
Kernel
12 个月 前同步成功
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
e11c910b
编写于
6月 24, 2006
作者:
R
Russell King
提交者:
Russell King
6月 24, 2006
浏览文件
操作
浏览文件
下载
差异文件
Merge S3C24xx branch
上级
c1e08adc
c9b949a7
变更
27
隐藏空白更改
内联
并排
Showing
27 changed file
with
1530 addition
and
77 deletion
+1530
-77
arch/arm/mach-s3c2410/Kconfig
arch/arm/mach-s3c2410/Kconfig
+20
-0
arch/arm/mach-s3c2410/Makefile
arch/arm/mach-s3c2410/Makefile
+6
-0
arch/arm/mach-s3c2410/clock.c
arch/arm/mach-s3c2410/clock.c
+15
-6
arch/arm/mach-s3c2410/clock.h
arch/arm/mach-s3c2410/clock.h
+2
-0
arch/arm/mach-s3c2410/cpu.c
arch/arm/mach-s3c2410/cpu.c
+34
-3
arch/arm/mach-s3c2410/cpu.h
arch/arm/mach-s3c2410/cpu.h
+1
-0
arch/arm/mach-s3c2410/irq.c
arch/arm/mach-s3c2410/irq.c
+37
-20
arch/arm/mach-s3c2410/mach-smdk2413.c
arch/arm/mach-s3c2410/mach-smdk2413.c
+126
-0
arch/arm/mach-s3c2410/pm-simtec.c
arch/arm/mach-s3c2410/pm-simtec.c
+2
-1
arch/arm/mach-s3c2410/s3c2410-clock.c
arch/arm/mach-s3c2410/s3c2410-clock.c
+9
-1
arch/arm/mach-s3c2410/s3c2410-gpio.c
arch/arm/mach-s3c2410/s3c2410-gpio.c
+5
-8
arch/arm/mach-s3c2410/s3c2412-clock.c
arch/arm/mach-s3c2410/s3c2412-clock.c
+711
-0
arch/arm/mach-s3c2410/s3c2412.c
arch/arm/mach-s3c2410/s3c2412.c
+195
-0
arch/arm/mach-s3c2410/s3c2412.h
arch/arm/mach-s3c2410/s3c2412.h
+29
-0
arch/arm/mm/Kconfig
arch/arm/mm/Kconfig
+5
-5
drivers/serial/Kconfig
drivers/serial/Kconfig
+6
-3
drivers/serial/s3c2410.c
drivers/serial/s3c2410.c
+142
-1
include/asm-arm/arch-s3c2410/debug-macro.S
include/asm-arm/arch-s3c2410/debug-macro.S
+8
-2
include/asm-arm/arch-s3c2410/entry-macro.S
include/asm-arm/arch-s3c2410/entry-macro.S
+7
-23
include/asm-arm/arch-s3c2410/map.h
include/asm-arm/arch-s3c2410/map.h
+16
-0
include/asm-arm/arch-s3c2410/regs-clock.h
include/asm-arm/arch-s3c2410/regs-clock.h
+62
-1
include/asm-arm/arch-s3c2410/regs-dsc.h
include/asm-arm/arch-s3c2410/regs-dsc.h
+3
-0
include/asm-arm/arch-s3c2410/regs-gpio.h
include/asm-arm/arch-s3c2410/regs-gpio.h
+60
-3
include/asm-arm/arch-s3c2410/regs-gpioj.h
include/asm-arm/arch-s3c2410/regs-gpioj.h
+5
-0
include/asm-arm/arch-s3c2410/regs-irq.h
include/asm-arm/arch-s3c2410/regs-irq.h
+6
-0
include/asm-arm/arch-s3c2410/regs-serial.h
include/asm-arm/arch-s3c2410/regs-serial.h
+15
-0
include/linux/serial_core.h
include/linux/serial_core.h
+3
-0
未找到文件。
arch/arm/mach-s3c2410/Kconfig
浏览文件 @
e11c910b
...
...
@@ -81,6 +81,12 @@ config SMDK2440_CPU2442
depends on ARCH_S3C2440
select CPU_S3C2442
config MACH_SMDK2413
bool "SMDK2413"
select CPU_S3C2412
select MACH_SMDK
help
Say Y here if you are using an SMDK2413
config MACH_VR1000
bool "Thorcom VR1000"
...
...
@@ -127,6 +133,20 @@ config CPU_S3C2410
Support for S3C2410 and S3C2410A family from the S3C24XX line
of Samsung Mobile CPUs.
# internal node to signify if we are only dealing with an S3C2412
config CPU_S3C2412_ONLY
bool
depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
!CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412
default y if CPU_S3C2412
config CPU_S3C2412
bool
depends on ARCH_S3C2410
help
Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
config CPU_S3C244X
bool
depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
...
...
arch/arm/mach-s3c2410/Makefile
浏览文件 @
e11c910b
...
...
@@ -24,6 +24,11 @@ obj-$(CONFIG_S3C2410_DMA) += dma.o
obj-$(CONFIG_PM)
+=
pm.o sleep.o
obj-$(CONFIG_PM_SIMTEC)
+=
pm-simtec.o
# S3C2412 support
obj-$(CONFIG_CPU_S3C2412)
+=
s3c2412.o
obj-$(CONFIG_CPU_S3C2412)
+=
s3c2412-clock.o
#
# S3C244X support
obj-$(CONFIG_CPU_S3C244X)
+=
s3c244x.o
...
...
@@ -57,6 +62,7 @@ obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o
obj-$(CONFIG_ARCH_H1940)
+=
mach-h1940.o
obj-$(CONFIG_MACH_N30)
+=
mach-n30.o
obj-$(CONFIG_ARCH_SMDK2410)
+=
mach-smdk2410.o
obj-$(CONFIG_MACH_SMDK2413)
+=
mach-smdk2413.o
obj-$(CONFIG_ARCH_S3C2440)
+=
mach-smdk2440.o
obj-$(CONFIG_MACH_VR1000)
+=
mach-vr1000.o usb-simtec.o
obj-$(CONFIG_MACH_RX3715)
+=
mach-rx3715.o
...
...
arch/arm/mach-s3c2410/clock.c
浏览文件 @
e11c910b
...
...
@@ -213,7 +213,7 @@ EXPORT_SYMBOL(clk_set_parent);
/* base clocks */
st
atic
st
ruct
clk
clk_xtal
=
{
struct
clk
clk_xtal
=
{
.
name
=
"xtal"
,
.
id
=
-
1
,
.
rate
=
0
,
...
...
@@ -221,6 +221,11 @@ static struct clk clk_xtal = {
.
ctrlbit
=
0
,
};
struct
clk
clk_mpll
=
{
.
name
=
"mpll"
,
.
id
=
-
1
,
};
struct
clk
clk_upll
=
{
.
name
=
"upll"
,
.
id
=
-
1
,
...
...
@@ -232,7 +237,7 @@ struct clk clk_f = {
.
name
=
"fclk"
,
.
id
=
-
1
,
.
rate
=
0
,
.
parent
=
NULL
,
.
parent
=
&
clk_mpll
,
.
ctrlbit
=
0
,
};
...
...
@@ -263,14 +268,14 @@ struct clk clk_usb_bus = {
static
int
s3c24xx_dclk_enable
(
struct
clk
*
clk
,
int
enable
)
{
unsigned
long
dclkcon
=
__raw_readl
(
S3C24
10
_DCLKCON
);
unsigned
long
dclkcon
=
__raw_readl
(
S3C24
XX
_DCLKCON
);
if
(
enable
)
dclkcon
|=
clk
->
ctrlbit
;
else
dclkcon
&=
~
clk
->
ctrlbit
;
__raw_writel
(
dclkcon
,
S3C24
10
_DCLKCON
);
__raw_writel
(
dclkcon
,
S3C24
XX
_DCLKCON
);
return
0
;
}
...
...
@@ -289,7 +294,7 @@ static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
clk
->
parent
=
parent
;
dclkcon
=
__raw_readl
(
S3C24
10
_DCLKCON
);
dclkcon
=
__raw_readl
(
S3C24
XX
_DCLKCON
);
if
(
clk
->
ctrlbit
==
S3C2410_DCLKCON_DCLK0EN
)
{
if
(
uclk
)
...
...
@@ -303,7 +308,7 @@ static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
dclkcon
&=
~
S3C2410_DCLKCON_DCLK1_UCLK
;
}
__raw_writel
(
dclkcon
,
S3C24
10
_DCLKCON
);
__raw_writel
(
dclkcon
,
S3C24
XX
_DCLKCON
);
return
0
;
}
...
...
@@ -413,6 +418,7 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
clk_xtal
.
rate
=
xtal
;
clk_upll
.
rate
=
s3c2410_get_pll
(
__raw_readl
(
S3C2410_UPLLCON
),
xtal
);
clk_mpll
.
rate
=
fclk
;
clk_h
.
rate
=
hclk
;
clk_p
.
rate
=
pclk
;
clk_f
.
rate
=
fclk
;
...
...
@@ -424,6 +430,9 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
if
(
s3c24xx_register_clock
(
&
clk_xtal
)
<
0
)
printk
(
KERN_ERR
"failed to register master xtal
\n
"
);
if
(
s3c24xx_register_clock
(
&
clk_mpll
)
<
0
)
printk
(
KERN_ERR
"failed to register mpll clock
\n
"
);
if
(
s3c24xx_register_clock
(
&
clk_upll
)
<
0
)
printk
(
KERN_ERR
"failed to register upll clock
\n
"
);
...
...
arch/arm/mach-s3c2410/clock.h
浏览文件 @
e11c910b
...
...
@@ -42,7 +42,9 @@ extern struct clk clk_usb_bus;
extern
struct
clk
clk_f
;
extern
struct
clk
clk_h
;
extern
struct
clk
clk_p
;
extern
struct
clk
clk_mpll
;
extern
struct
clk
clk_upll
;
extern
struct
clk
clk_xtal
;
/* exports for arch/arm/mach-s3c2410
*
...
...
arch/arm/mach-s3c2410/cpu.c
浏览文件 @
e11c910b
...
...
@@ -44,6 +44,7 @@
#include "clock.h"
#include "s3c2400.h"
#include "s3c2410.h"
#include "s3c2412.h"
#include "s3c244x.h"
#include "s3c2440.h"
#include "s3c2442.h"
...
...
@@ -62,6 +63,7 @@ struct cpu_table {
static
const
char
name_s3c2400
[]
=
"S3C2400"
;
static
const
char
name_s3c2410
[]
=
"S3C2410"
;
static
const
char
name_s3c2412
[]
=
"S3C2412"
;
static
const
char
name_s3c2440
[]
=
"S3C2440"
;
static
const
char
name_s3c2442
[]
=
"S3C2442"
;
static
const
char
name_s3c2410a
[]
=
"S3C2410A"
;
...
...
@@ -113,6 +115,15 @@ static struct cpu_table cpu_ids[] __initdata = {
.
init
=
s3c2442_init
,
.
name
=
name_s3c2442
},
{
.
idcode
=
0x32412001
,
.
idmask
=
0xffffffff
,
.
map_io
=
s3c2412_map_io
,
.
init_clocks
=
s3c2412_init_clocks
,
.
init_uarts
=
s3c2412_init_uarts
,
.
init
=
s3c2412_init
,
.
name
=
name_s3c2412
,
},
{
.
idcode
=
0x0
,
/* S3C2400 doesn't have an idcode */
.
idmask
=
0xffffffff
,
...
...
@@ -171,6 +182,24 @@ void s3c24xx_set_board(struct s3c24xx_board *b)
static
struct
cpu_table
*
cpu
;
static
unsigned
long
s3c24xx_read_idcode_v5
(
void
)
{
#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
return
__raw_readl
(
S3C2412_GSTATUS1
);
#else
return
1UL
;
/* don't look like an 2400 */
#endif
}
static
unsigned
long
s3c24xx_read_idcode_v4
(
void
)
{
#ifndef CONFIG_CPU_S3C2400
return
__raw_readl
(
S3C2410_GSTATUS1
);
#else
return
0UL
;
#endif
}
void
__init
s3c24xx_init_io
(
struct
map_desc
*
mach_desc
,
int
size
)
{
unsigned
long
idcode
=
0x0
;
...
...
@@ -178,9 +207,11 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
/* initialise the io descriptors we need for initialisation */
iotable_init
(
s3c_iodesc
,
ARRAY_SIZE
(
s3c_iodesc
));
#ifndef CONFIG_CPU_S3C2400
idcode
=
__raw_readl
(
S3C2410_GSTATUS1
);
#endif
if
(
cpu_architecture
()
>=
CPU_ARCH_ARMv5
)
{
idcode
=
s3c24xx_read_idcode_v5
();
}
else
{
idcode
=
s3c24xx_read_idcode_v4
();
}
cpu
=
s3c_lookup_cpu
(
idcode
);
...
...
arch/arm/mach-s3c2410/cpu.h
浏览文件 @
e11c910b
...
...
@@ -74,5 +74,6 @@ extern struct sys_timer s3c24xx_timer;
/* system device classes */
extern
struct
sysdev_class
s3c2410_sysclass
;
extern
struct
sysdev_class
s3c2412_sysclass
;
extern
struct
sysdev_class
s3c2440_sysclass
;
extern
struct
sysdev_class
s3c2442_sysclass
;
arch/arm/mach-s3c2410/irq.c
浏览文件 @
e11c910b
...
...
@@ -191,13 +191,9 @@ static struct irqchip s3c_irq_chip = {
.
ack
=
s3c_irq_ack
,
.
mask
=
s3c_irq_mask
,
.
unmask
=
s3c_irq_unmask
,
.
set_wake
=
s3c_irq_wake
.
set_wake
=
s3c_irq_wake
};
/* S3C2410_EINTMASK
* S3C2410_EINTPEND
*/
static
void
s3c_irqext_mask
(
unsigned
int
irqno
)
{
...
...
@@ -205,9 +201,9 @@ s3c_irqext_mask(unsigned int irqno)
irqno
-=
EXTINT_OFF
;
mask
=
__raw_readl
(
S3C24
10
_EINTMASK
);
mask
=
__raw_readl
(
S3C24
XX
_EINTMASK
);
mask
|=
(
1UL
<<
irqno
);
__raw_writel
(
mask
,
S3C24
10
_EINTMASK
);
__raw_writel
(
mask
,
S3C24
XX
_EINTMASK
);
if
(
irqno
<=
(
IRQ_EINT7
-
EXTINT_OFF
))
{
/* check to see if all need masking */
...
...
@@ -232,11 +228,11 @@ s3c_irqext_ack(unsigned int irqno)
bit
=
1UL
<<
(
irqno
-
EXTINT_OFF
);
mask
=
__raw_readl
(
S3C24
10
_EINTMASK
);
mask
=
__raw_readl
(
S3C24
XX
_EINTMASK
);
__raw_writel
(
bit
,
S3C24
10
_EINTPEND
);
__raw_writel
(
bit
,
S3C24
XX
_EINTPEND
);
req
=
__raw_readl
(
S3C24
10
_EINTPEND
);
req
=
__raw_readl
(
S3C24
XX
_EINTPEND
);
req
&=
~
mask
;
/* not sure if we should be acking the parent irq... */
...
...
@@ -257,9 +253,9 @@ s3c_irqext_unmask(unsigned int irqno)
irqno
-=
EXTINT_OFF
;
mask
=
__raw_readl
(
S3C24
10
_EINTMASK
);
mask
=
__raw_readl
(
S3C24
XX
_EINTMASK
);
mask
&=
~
(
1UL
<<
irqno
);
__raw_writel
(
mask
,
S3C24
10
_EINTMASK
);
__raw_writel
(
mask
,
S3C24
XX
_EINTMASK
);
s3c_irq_unmask
((
irqno
<=
(
IRQ_EINT7
-
EXTINT_OFF
))
?
IRQ_EINT4t7
:
IRQ_EINT8t23
);
}
...
...
@@ -275,28 +271,28 @@ s3c_irqext_type(unsigned int irq, unsigned int type)
if
((
irq
>=
IRQ_EINT0
)
&&
(
irq
<=
IRQ_EINT3
))
{
gpcon_reg
=
S3C2410_GPFCON
;
extint_reg
=
S3C24
10
_EXTINT0
;
extint_reg
=
S3C24
XX
_EXTINT0
;
gpcon_offset
=
(
irq
-
IRQ_EINT0
)
*
2
;
extint_offset
=
(
irq
-
IRQ_EINT0
)
*
4
;
}
else
if
((
irq
>=
IRQ_EINT4
)
&&
(
irq
<=
IRQ_EINT7
))
{
gpcon_reg
=
S3C2410_GPFCON
;
extint_reg
=
S3C24
10
_EXTINT0
;
extint_reg
=
S3C24
XX
_EXTINT0
;
gpcon_offset
=
(
irq
-
(
EXTINT_OFF
))
*
2
;
extint_offset
=
(
irq
-
(
EXTINT_OFF
))
*
4
;
}
else
if
((
irq
>=
IRQ_EINT8
)
&&
(
irq
<=
IRQ_EINT15
))
{
gpcon_reg
=
S3C2410_GPGCON
;
extint_reg
=
S3C24
10
_EXTINT1
;
extint_reg
=
S3C24
XX
_EXTINT1
;
gpcon_offset
=
(
irq
-
IRQ_EINT8
)
*
2
;
extint_offset
=
(
irq
-
IRQ_EINT8
)
*
4
;
}
else
if
((
irq
>=
IRQ_EINT16
)
&&
(
irq
<=
IRQ_EINT23
))
{
gpcon_reg
=
S3C2410_GPGCON
;
extint_reg
=
S3C24
10
_EXTINT2
;
extint_reg
=
S3C24
XX
_EXTINT2
;
gpcon_offset
=
(
irq
-
IRQ_EINT8
)
*
2
;
extint_offset
=
(
irq
-
IRQ_EINT16
)
*
4
;
}
else
...
...
@@ -572,6 +568,23 @@ s3c_irq_demux_uart2(unsigned int irq,
s3c_irq_demux_uart
(
IRQ_S3CUART_RX2
,
regs
);
}
static
void
s3c_irq_demux_extint
(
unsigned
int
irq
,
struct
irqdesc
*
desc
,
struct
pt_regs
*
regs
)
{
unsigned
long
eintpnd
=
__raw_readl
(
S3C24XX_EINTPEND
);
unsigned
long
eintmsk
=
__raw_readl
(
S3C24XX_EINTMASK
);
eintpnd
&=
~
eintmsk
;
if
(
eintpnd
)
{
irq
=
fls
(
eintpnd
);
irq
+=
(
IRQ_EINT4
-
(
4
+
1
));
desc_handle_irq
(
irq
,
irq_desc
+
irq
,
regs
);
}
}
/* s3c24xx_init_irq
*
...
...
@@ -591,12 +604,12 @@ void __init s3c24xx_init_irq(void)
last
=
0
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
pend
=
__raw_readl
(
S3C24
10
_EINTPEND
);
pend
=
__raw_readl
(
S3C24
XX
_EINTPEND
);
if
(
pend
==
0
||
pend
==
last
)
break
;
__raw_writel
(
pend
,
S3C24
10
_EINTPEND
);
__raw_writel
(
pend
,
S3C24
XX
_EINTPEND
);
printk
(
"irq: clearing pending ext status %08x
\n
"
,
(
int
)
pend
);
last
=
pend
;
}
...
...
@@ -630,12 +643,14 @@ void __init s3c24xx_init_irq(void)
irqdbf
(
"s3c2410_init_irq: registering s3c2410 interrupt handlers
\n
"
);
for
(
irqno
=
IRQ_
BATT_FLT
;
irqno
<=
IRQ_ADCPARENT
;
irqno
++
)
{
for
(
irqno
=
IRQ_
EINT4t7
;
irqno
<=
IRQ_ADCPARENT
;
irqno
++
)
{
/* set all the s3c2410 internal irqs */
switch
(
irqno
)
{
/* deal with the special IRQs (cascaded) */
case
IRQ_EINT4t7
:
case
IRQ_EINT8t23
:
case
IRQ_UART0
:
case
IRQ_UART1
:
case
IRQ_UART2
:
...
...
@@ -659,12 +674,14 @@ void __init s3c24xx_init_irq(void)
/* setup the cascade irq handlers */
set_irq_chained_handler
(
IRQ_EINT4t7
,
s3c_irq_demux_extint
);
set_irq_chained_handler
(
IRQ_EINT8t23
,
s3c_irq_demux_extint
);
set_irq_chained_handler
(
IRQ_UART0
,
s3c_irq_demux_uart0
);
set_irq_chained_handler
(
IRQ_UART1
,
s3c_irq_demux_uart1
);
set_irq_chained_handler
(
IRQ_UART2
,
s3c_irq_demux_uart2
);
set_irq_chained_handler
(
IRQ_ADCPARENT
,
s3c_irq_demux_adc
);
/* external interrupts */
for
(
irqno
=
IRQ_EINT0
;
irqno
<=
IRQ_EINT3
;
irqno
++
)
{
...
...
arch/arm/mach-s3c2410/mach-smdk2413.c
0 → 100644
浏览文件 @
e11c910b
/* linux/arch/arm/mach-s3c2410/mach-smdk2413.c
*
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Thanks to Dimity Andric (TomTom) and Steven Ryu (Samsung) for the
* loans of SMDK2413 to work with.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/hardware.h>
#include <asm/hardware/iomd.h>
#include <asm/setup.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
//#include <asm/debug-ll.h>
#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-lcd.h>
#include <asm/arch/idle.h>
#include <asm/arch/fb.h>
#include "s3c2410.h"
#include "s3c2412.h"
#include "clock.h"
#include "devs.h"
#include "cpu.h"
#include "common-smdk.h"
static
struct
map_desc
smdk2413_iodesc
[]
__initdata
=
{
};
static
struct
s3c2410_uartcfg
smdk2413_uartcfgs
[]
__initdata
=
{
[
0
]
=
{
.
hwport
=
0
,
.
flags
=
0
,
.
ucon
=
0x3c5
,
.
ulcon
=
0x03
,
.
ufcon
=
0x51
,
},
[
1
]
=
{
.
hwport
=
1
,
.
flags
=
0
,
.
ucon
=
0x3c5
,
.
ulcon
=
0x03
,
.
ufcon
=
0x51
,
},
/* IR port */
[
2
]
=
{
.
hwport
=
2
,
.
flags
=
0
,
.
ucon
=
0x3c5
,
.
ulcon
=
0x43
,
.
ufcon
=
0x51
,
}
};
static
struct
platform_device
*
smdk2413_devices
[]
__initdata
=
{
&
s3c_device_usb
,
//&s3c_device_lcd,
&
s3c_device_wdt
,
&
s3c_device_i2c
,
&
s3c_device_iis
,
};
static
struct
s3c24xx_board
smdk2413_board
__initdata
=
{
.
devices
=
smdk2413_devices
,
.
devices_count
=
ARRAY_SIZE
(
smdk2413_devices
)
};
static
void
__init
smdk2413_fixup
(
struct
machine_desc
*
desc
,
struct
tag
*
tags
,
char
**
cmdline
,
struct
meminfo
*
mi
)
{
if
(
tags
!=
phys_to_virt
(
S3C2410_SDRAM_PA
+
0x100
))
{
mi
->
nr_banks
=
1
;
mi
->
bank
[
0
].
start
=
0x30000000
;
mi
->
bank
[
0
].
size
=
SZ_64M
;
mi
->
bank
[
0
].
node
=
0
;
}
}
static
void
__init
smdk2413_map_io
(
void
)
{
s3c24xx_init_io
(
smdk2413_iodesc
,
ARRAY_SIZE
(
smdk2413_iodesc
));
s3c24xx_init_clocks
(
12000000
);
s3c24xx_init_uarts
(
smdk2413_uartcfgs
,
ARRAY_SIZE
(
smdk2413_uartcfgs
));
s3c24xx_set_board
(
&
smdk2413_board
);
}
static
void
__init
smdk2413_machine_init
(
void
)
{
smdk_machine_init
();
}
MACHINE_START
(
S3C2413
,
"SMDK2413"
)
/* Maintainer: Ben Dooks <ben@fluff.org> */
.
phys_io
=
S3C2410_PA_UART
,
.
io_pg_offst
=
(((
u32
)
S3C24XX_VA_UART
)
>>
18
)
&
0xfffc
,
.
boot_params
=
S3C2410_SDRAM_PA
+
0x100
,
.
fixup
=
smdk2413_fixup
,
.
init_irq
=
s3c24xx_init_irq
,
.
map_io
=
smdk2413_map_io
,
.
init_machine
=
smdk2413_machine_init
,
.
timer
=
&
s3c24xx_timer
,
MACHINE_END
arch/arm/mach-s3c2410/pm-simtec.c
浏览文件 @
e11c910b
...
...
@@ -48,7 +48,8 @@ static __init int pm_simtec_init(void)
/* check which machine we are running on */
if
(
!
machine_is_bast
()
&&
!
machine_is_vr1000
()
&&
!
machine_is_anubis
())
if
(
!
machine_is_bast
()
&&
!
machine_is_vr1000
()
&&
!
machine_is_anubis
()
&&
!
machine_is_osiris
())
return
0
;
printk
(
KERN_INFO
"Simtec Board Power Manangement"
COPYRIGHT
"
\n
"
);
...
...
arch/arm/mach-s3c2410/s3c2410-clock.c
浏览文件 @
e11c910b
...
...
@@ -182,7 +182,15 @@ static struct clk init_clocks[] = {
.
id
=
-
1
,
.
parent
=
&
clk_p
,
.
ctrlbit
=
0
,
}
},
{
.
name
=
"usb-bus-host"
,
.
id
=
-
1
,
.
parent
=
&
clk_usb_bus
,
},
{
.
name
=
"usb-bus-gadget"
,
.
id
=
-
1
,
.
parent
=
&
clk_usb_bus
,
},
};
/* s3c2410_baseclk_add()
...
...
arch/arm/mach-s3c2410/s3c2410-gpio.c
浏览文件 @
e11c910b
...
...
@@ -18,9 +18,6 @@
* 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
*
* Changelog
* 15-Jan-2006 LCVR Splitted from gpio.c
*/
#include <linux/kernel.h>
...
...
@@ -38,7 +35,7 @@
int
s3c2410_gpio_irqfilter
(
unsigned
int
pin
,
unsigned
int
on
,
unsigned
int
config
)
{
void
__iomem
*
reg
=
S3C24
10
_EINFLT0
;
void
__iomem
*
reg
=
S3C24
XX
_EINFLT0
;
unsigned
long
flags
;
unsigned
long
val
;
...
...
@@ -47,7 +44,7 @@ int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
config
&=
0xff
;
pin
-=
S3C2410_GPG8
_EINT16
;
pin
-=
S3C2410_GPG8
;
reg
+=
pin
&
~
3
;
local_irq_save
(
flags
);
...
...
@@ -61,10 +58,10 @@ int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
/* update filter enable */
val
=
__raw_readl
(
S3C24
10
_EXTINT2
);
val
=
__raw_readl
(
S3C24
XX
_EXTINT2
);
val
&=
~
(
1
<<
((
pin
*
4
)
+
3
));
val
|=
on
<<
((
pin
*
4
)
+
3
);
__raw_writel
(
val
,
S3C24
10
_EXTINT2
);
__raw_writel
(
val
,
S3C24
XX
_EXTINT2
);
local_irq_restore
(
flags
);
...
...
@@ -75,7 +72,7 @@ EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
int
s3c2410_gpio_getirq
(
unsigned
int
pin
)
{
if
(
pin
<
S3C2410_GPF0
||
pin
>
S3C2410_GPG15
_EINT23
)
if
(
pin
<
S3C2410_GPF0
||
pin
>
S3C2410_GPG15
)
return
-
1
;
/* not valid interrupts */
if
(
pin
<
S3C2410_GPG0
&&
pin
>
S3C2410_GPF7
)
...
...
arch/arm/mach-s3c2410/s3c2412-clock.c
0 → 100644
浏览文件 @
e11c910b
/* linux/arch/arm/mach-s3c2410/s3c2412-clock.c
*
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2412,S3C2413 Clock control support
*
* 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
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/sysdev.h>
#include <linux/clk.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/arch/regs-clock.h>
#include <asm/arch/regs-gpio.h>
#include "clock.h"
#include "cpu.h"
/* We currently have to assume that the system is running
* from the XTPll input, and that all ***REFCLKs are being
* fed from it, as we cannot read the state of OM[4] from
* software.
*
* It would be possible for each board initialisation to
* set the correct muxing at initialisation
*/
int
s3c2412_clkcon_enable
(
struct
clk
*
clk
,
int
enable
)
{
unsigned
int
clocks
=
clk
->
ctrlbit
;
unsigned
long
clkcon
;
clkcon
=
__raw_readl
(
S3C2410_CLKCON
);
if
(
enable
)
clkcon
|=
clocks
;
else
clkcon
&=
~
clocks
;
__raw_writel
(
clkcon
,
S3C2410_CLKCON
);
return
0
;
}
static
int
s3c2412_upll_enable
(
struct
clk
*
clk
,
int
enable
)
{
unsigned
long
upllcon
=
__raw_readl
(
S3C2410_UPLLCON
);
unsigned
long
orig
=
upllcon
;
if
(
!
enable
)
upllcon
|=
S3C2412_PLLCON_OFF
;
else
upllcon
&=
~
S3C2412_PLLCON_OFF
;
__raw_writel
(
upllcon
,
S3C2410_UPLLCON
);
/* allow ~150uS for the PLL to settle and lock */
if
(
enable
&&
(
orig
&
S3C2412_PLLCON_OFF
))
udelay
(
150
);
return
0
;
}
/* clock selections */
/* CPU EXTCLK input */
static
struct
clk
clk_ext
=
{
.
name
=
"extclk"
,
.
id
=
-
1
,
};
static
struct
clk
clk_erefclk
=
{
.
name
=
"erefclk"
,
.
id
=
-
1
,
};
static
struct
clk
clk_urefclk
=
{
.
name
=
"urefclk"
,
.
id
=
-
1
,
};
static
int
s3c2412_setparent_usysclk
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2412_CLKSRC
);
if
(
parent
==
&
clk_urefclk
)
clksrc
&=
~
S3C2412_CLKSRC_USYSCLK_UPLL
;
else
if
(
parent
==
&
clk_upll
)
clksrc
|=
S3C2412_CLKSRC_USYSCLK_UPLL
;
else
return
-
EINVAL
;
clk
->
parent
=
parent
;
__raw_writel
(
clksrc
,
S3C2412_CLKSRC
);
return
0
;
}
static
struct
clk
clk_usysclk
=
{
.
name
=
"usysclk"
,
.
id
=
-
1
,
.
parent
=
&
clk_xtal
,
.
set_parent
=
s3c2412_setparent_usysclk
,
};
static
struct
clk
clk_mrefclk
=
{
.
name
=
"mrefclk"
,
.
parent
=
&
clk_xtal
,
.
id
=
-
1
,
};
static
struct
clk
clk_mdivclk
=
{
.
name
=
"mdivclk"
,
.
parent
=
&
clk_xtal
,
.
id
=
-
1
,
};
static
int
s3c2412_setparent_usbsrc
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2412_CLKSRC
);
if
(
parent
==
&
clk_usysclk
)
clksrc
&=
~
S3C2412_CLKSRC_USBCLK_HCLK
;
else
if
(
parent
==
&
clk_h
)
clksrc
|=
S3C2412_CLKSRC_USBCLK_HCLK
;
else
return
-
EINVAL
;
clk
->
parent
=
parent
;
__raw_writel
(
clksrc
,
S3C2412_CLKSRC
);
return
0
;
}
static
unsigned
long
s3c2412_roundrate_usbsrc
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
int
div
;
if
(
rate
>
parent_rate
)
return
parent_rate
;
div
=
parent_rate
/
rate
;
if
(
div
>
2
)
div
=
2
;
return
parent_rate
/
div
;
}
static
unsigned
long
s3c2412_getrate_usbsrc
(
struct
clk
*
clk
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
div
=
__raw_readl
(
S3C2410_CLKDIVN
);
return
parent_rate
/
((
div
&
S3C2412_CLKDIVN_USB48DIV
)
?
2
:
1
);
}
static
int
s3c2412_setrate_usbsrc
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
clkdivn
=
__raw_readl
(
S3C2410_CLKDIVN
);
rate
=
s3c2412_roundrate_usbsrc
(
clk
,
rate
);
if
((
parent_rate
/
rate
)
==
2
)
clkdivn
|=
S3C2412_CLKDIVN_USB48DIV
;
else
clkdivn
&=
~
S3C2412_CLKDIVN_USB48DIV
;
__raw_writel
(
clkdivn
,
S3C2410_CLKDIVN
);
return
0
;
}
static
struct
clk
clk_usbsrc
=
{
.
name
=
"usbsrc"
,
.
id
=
-
1
,
.
get_rate
=
s3c2412_getrate_usbsrc
,
.
set_rate
=
s3c2412_setrate_usbsrc
,
.
round_rate
=
s3c2412_roundrate_usbsrc
,
.
set_parent
=
s3c2412_setparent_usbsrc
,
};
static
int
s3c2412_setparent_msysclk
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2412_CLKSRC
);
if
(
parent
==
&
clk_mdivclk
)
clksrc
&=
~
S3C2412_CLKSRC_MSYSCLK_MPLL
;
else
if
(
parent
==
&
clk_upll
)
clksrc
|=
S3C2412_CLKSRC_MSYSCLK_MPLL
;
else
return
-
EINVAL
;
clk
->
parent
=
parent
;
__raw_writel
(
clksrc
,
S3C2412_CLKSRC
);
return
0
;
}
static
struct
clk
clk_msysclk
=
{
.
name
=
"msysclk"
,
.
id
=
-
1
,
.
set_parent
=
s3c2412_setparent_msysclk
,
};
/* these next clocks have an divider immediately after them,
* so we can register them with their divider and leave out the
* intermediate clock stage
*/
static
unsigned
long
s3c2412_roundrate_clksrc
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
int
div
;
if
(
rate
>
parent_rate
)
return
parent_rate
;
/* note, we remove the +/- 1 calculations as they cancel out */
div
=
(
rate
/
parent_rate
);
if
(
div
<
1
)
div
=
1
;
else
if
(
div
>
16
)
div
=
16
;
return
parent_rate
/
div
;
}
static
int
s3c2412_setparent_uart
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2412_CLKSRC
);
if
(
parent
==
&
clk_erefclk
)
clksrc
&=
~
S3C2412_CLKSRC_UARTCLK_MPLL
;
else
if
(
parent
==
&
clk_mpll
)
clksrc
|=
S3C2412_CLKSRC_UARTCLK_MPLL
;
else
return
-
EINVAL
;
clk
->
parent
=
parent
;
__raw_writel
(
clksrc
,
S3C2412_CLKSRC
);
return
0
;
}
static
unsigned
long
s3c2412_getrate_uart
(
struct
clk
*
clk
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
div
=
__raw_readl
(
S3C2410_CLKDIVN
);
div
&=
S3C2412_CLKDIVN_UARTDIV_MASK
;
div
>>=
S3C2412_CLKDIVN_UARTDIV_SHIFT
;
return
parent_rate
/
(
div
+
1
);
}
static
int
s3c2412_setrate_uart
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
clkdivn
=
__raw_readl
(
S3C2410_CLKDIVN
);
rate
=
s3c2412_roundrate_clksrc
(
clk
,
rate
);
clkdivn
&=
~
S3C2412_CLKDIVN_UARTDIV_MASK
;
clkdivn
|=
((
parent_rate
/
rate
)
-
1
)
<<
S3C2412_CLKDIVN_UARTDIV_SHIFT
;
__raw_writel
(
clkdivn
,
S3C2410_CLKDIVN
);
return
0
;
}
static
struct
clk
clk_uart
=
{
.
name
=
"uartclk"
,
.
id
=
-
1
,
.
get_rate
=
s3c2412_getrate_uart
,
.
set_rate
=
s3c2412_setrate_uart
,
.
set_parent
=
s3c2412_setparent_uart
,
.
round_rate
=
s3c2412_roundrate_clksrc
,
};
static
int
s3c2412_setparent_i2s
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2412_CLKSRC
);
if
(
parent
==
&
clk_erefclk
)
clksrc
&=
~
S3C2412_CLKSRC_I2SCLK_MPLL
;
else
if
(
parent
==
&
clk_mpll
)
clksrc
|=
S3C2412_CLKSRC_I2SCLK_MPLL
;
else
return
-
EINVAL
;
clk
->
parent
=
parent
;
__raw_writel
(
clksrc
,
S3C2412_CLKSRC
);
return
0
;
}
static
unsigned
long
s3c2412_getrate_i2s
(
struct
clk
*
clk
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
div
=
__raw_readl
(
S3C2410_CLKDIVN
);
div
&=
S3C2412_CLKDIVN_I2SDIV_MASK
;
div
>>=
S3C2412_CLKDIVN_I2SDIV_SHIFT
;
return
parent_rate
/
(
div
+
1
);
}
static
int
s3c2412_setrate_i2s
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
clkdivn
=
__raw_readl
(
S3C2410_CLKDIVN
);
rate
=
s3c2412_roundrate_clksrc
(
clk
,
rate
);
clkdivn
&=
~
S3C2412_CLKDIVN_I2SDIV_MASK
;
clkdivn
|=
((
parent_rate
/
rate
)
-
1
)
<<
S3C2412_CLKDIVN_I2SDIV_SHIFT
;
__raw_writel
(
clkdivn
,
S3C2410_CLKDIVN
);
return
0
;
}
static
struct
clk
clk_i2s
=
{
.
name
=
"i2sclk"
,
.
id
=
-
1
,
.
get_rate
=
s3c2412_getrate_i2s
,
.
set_rate
=
s3c2412_setrate_i2s
,
.
set_parent
=
s3c2412_setparent_i2s
,
.
round_rate
=
s3c2412_roundrate_clksrc
,
};
static
int
s3c2412_setparent_cam
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2412_CLKSRC
);
if
(
parent
==
&
clk_usysclk
)
clksrc
&=
~
S3C2412_CLKSRC_CAMCLK_HCLK
;
else
if
(
parent
==
&
clk_h
)
clksrc
|=
S3C2412_CLKSRC_CAMCLK_HCLK
;
else
return
-
EINVAL
;
clk
->
parent
=
parent
;
__raw_writel
(
clksrc
,
S3C2412_CLKSRC
);
return
0
;
}
static
unsigned
long
s3c2412_getrate_cam
(
struct
clk
*
clk
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
div
=
__raw_readl
(
S3C2410_CLKDIVN
);
div
&=
S3C2412_CLKDIVN_CAMDIV_MASK
;
div
>>=
S3C2412_CLKDIVN_CAMDIV_SHIFT
;
return
parent_rate
/
(
div
+
1
);
}
static
int
s3c2412_setrate_cam
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
clkdivn
=
__raw_readl
(
S3C2410_CLKDIVN
);
rate
=
s3c2412_roundrate_clksrc
(
clk
,
rate
);
clkdivn
&=
~
S3C2412_CLKDIVN_CAMDIV_MASK
;
clkdivn
|=
((
parent_rate
/
rate
)
-
1
)
<<
S3C2412_CLKDIVN_CAMDIV_SHIFT
;
__raw_writel
(
clkdivn
,
S3C2410_CLKDIVN
);
return
0
;
}
static
struct
clk
clk_cam
=
{
.
name
=
"camif-upll"
,
/* same as 2440 name */
.
id
=
-
1
,
.
get_rate
=
s3c2412_getrate_cam
,
.
set_rate
=
s3c2412_setrate_cam
,
.
set_parent
=
s3c2412_setparent_cam
,
.
round_rate
=
s3c2412_roundrate_clksrc
,
};
/* standard clock definitions */
static
struct
clk
init_clocks_disable
[]
=
{
{
.
name
=
"nand"
,
.
id
=
-
1
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_NAND
,
},
{
.
name
=
"sdi"
,
.
id
=
-
1
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_SDI
,
},
{
.
name
=
"adc"
,
.
id
=
-
1
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_ADC
,
},
{
.
name
=
"i2c"
,
.
id
=
-
1
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_IIC
,
},
{
.
name
=
"iis"
,
.
id
=
-
1
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_IIS
,
},
{
.
name
=
"spi"
,
.
id
=
-
1
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_SPI
,
}
};
static
struct
clk
init_clocks
[]
=
{
{
.
name
=
"dma"
,
.
id
=
0
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_DMA0
,
},
{
.
name
=
"dma"
,
.
id
=
1
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_DMA1
,
},
{
.
name
=
"dma"
,
.
id
=
2
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_DMA2
,
},
{
.
name
=
"dma"
,
.
id
=
3
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_DMA3
,
},
{
.
name
=
"lcd"
,
.
id
=
-
1
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_LCDC
,
},
{
.
name
=
"gpio"
,
.
id
=
-
1
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_GPIO
,
},
{
.
name
=
"usb-host"
,
.
id
=
-
1
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_USBH
,
},
{
.
name
=
"usb-device"
,
.
id
=
-
1
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_USBD
,
},
{
.
name
=
"timers"
,
.
id
=
-
1
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_PWMT
,
},
{
.
name
=
"uart"
,
.
id
=
0
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_UART0
,
},
{
.
name
=
"uart"
,
.
id
=
1
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_UART1
,
},
{
.
name
=
"uart"
,
.
id
=
2
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_UART2
,
},
{
.
name
=
"rtc"
,
.
id
=
-
1
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_RTC
,
},
{
.
name
=
"watchdog"
,
.
id
=
-
1
,
.
parent
=
&
clk_p
,
.
ctrlbit
=
0
,
},
{
.
name
=
"usb-bus-gadget"
,
.
id
=
-
1
,
.
parent
=
&
clk_usb_bus
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_USB_DEV48
,
},
{
.
name
=
"usb-bus-host"
,
.
id
=
-
1
,
.
parent
=
&
clk_usb_bus
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_USB_HOST48
,
}
};
/* clocks to add where we need to check their parentage */
struct
clk_init
{
struct
clk
*
clk
;
unsigned
int
bit
;
struct
clk
*
src_0
;
struct
clk
*
src_1
;
};
struct
clk_init
clks_src
[]
__initdata
=
{
{
.
clk
=
&
clk_usysclk
,
.
bit
=
S3C2412_CLKSRC_USBCLK_HCLK
,
.
src_0
=
&
clk_urefclk
,
.
src_1
=
&
clk_upll
,
},
{
.
clk
=
&
clk_i2s
,
.
bit
=
S3C2412_CLKSRC_I2SCLK_MPLL
,
.
src_0
=
&
clk_erefclk
,
.
src_1
=
&
clk_mpll
,
},
{
.
clk
=
&
clk_cam
,
.
bit
=
S3C2412_CLKSRC_CAMCLK_HCLK
,
.
src_0
=
&
clk_usysclk
,
.
src_1
=
&
clk_h
,
},
{
.
clk
=
&
clk_msysclk
,
.
bit
=
S3C2412_CLKSRC_MSYSCLK_MPLL
,
.
src_0
=
&
clk_mdivclk
,
.
src_1
=
&
clk_mpll
,
},
{
.
clk
=
&
clk_uart
,
.
bit
=
S3C2412_CLKSRC_UARTCLK_MPLL
,
.
src_0
=
&
clk_erefclk
,
.
src_1
=
&
clk_mpll
,
},
{
.
clk
=
&
clk_usbsrc
,
.
bit
=
S3C2412_CLKSRC_USBCLK_HCLK
,
.
src_0
=
&
clk_usysclk
,
.
src_1
=
&
clk_h
,
},
};
/* s3c2412_clk_initparents
*
* Initialise the parents for the clocks that we get at start-time
*/
static
void
__init
s3c2412_clk_initparents
(
void
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2412_CLKSRC
);
struct
clk_init
*
cip
=
clks_src
;
struct
clk
*
src
;
int
ptr
;
int
ret
;
for
(
ptr
=
0
;
ptr
<
ARRAY_SIZE
(
clks_src
);
ptr
++
,
cip
++
)
{
ret
=
s3c24xx_register_clock
(
cip
->
clk
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"Failed to register clock %s (%d)
\n
"
,
cip
->
clk
->
name
,
ret
);
}
src
=
(
clksrc
&
cip
->
bit
)
?
cip
->
src_1
:
cip
->
src_0
;
printk
(
KERN_INFO
"%s: parent %s
\n
"
,
cip
->
clk
->
name
,
src
->
name
);
clk_set_parent
(
cip
->
clk
,
src
);
}
}
/* clocks to add straight away */
struct
clk
*
clks
[]
__initdata
=
{
&
clk_ext
,
&
clk_usb_bus
,
&
clk_erefclk
,
&
clk_urefclk
,
&
clk_mrefclk
,
};
int
__init
s3c2412_baseclk_add
(
void
)
{
unsigned
long
clkcon
=
__raw_readl
(
S3C2410_CLKCON
);
struct
clk
*
clkp
;
int
ret
;
int
ptr
;
clk_upll
.
enable
=
s3c2412_upll_enable
;
clk_usb_bus
.
parent
=
&
clk_usbsrc
;
clk_usb_bus
.
rate
=
0x0
;
s3c2412_clk_initparents
();
for
(
ptr
=
0
;
ptr
<
ARRAY_SIZE
(
clks
);
ptr
++
)
{
clkp
=
clks
[
ptr
];
ret
=
s3c24xx_register_clock
(
clkp
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"Failed to register clock %s (%d)
\n
"
,
clkp
->
name
,
ret
);
}
}
/* ensure usb bus clock is within correct rate of 48MHz */
if
(
clk_get_rate
(
&
clk_usb_bus
)
!=
(
48
*
1000
*
1000
))
{
printk
(
KERN_INFO
"Warning: USB bus clock not at 48MHz
\n
"
);
/* for the moment, let's use the UPLL, and see if we can
* get 48MHz */
clk_set_parent
(
&
clk_usysclk
,
&
clk_upll
);
clk_set_parent
(
&
clk_usbsrc
,
&
clk_usysclk
);
clk_set_rate
(
&
clk_usbsrc
,
48
*
1000
*
1000
);
}
printk
(
"S3C2412: upll %s, %ld.%03ld MHz, usb-bus %ld.%03ld MHz
\n
"
,
(
__raw_readl
(
S3C2410_UPLLCON
)
&
S3C2412_PLLCON_OFF
)
?
"off"
:
"on"
,
print_mhz
(
clk_get_rate
(
&
clk_upll
)),
print_mhz
(
clk_get_rate
(
&
clk_usb_bus
)));
/* register clocks from clock array */
clkp
=
init_clocks
;
for
(
ptr
=
0
;
ptr
<
ARRAY_SIZE
(
init_clocks
);
ptr
++
,
clkp
++
)
{
/* ensure that we note the clock state */
clkp
->
usage
=
clkcon
&
clkp
->
ctrlbit
?
1
:
0
;
ret
=
s3c24xx_register_clock
(
clkp
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"Failed to register clock %s (%d)
\n
"
,
clkp
->
name
,
ret
);
}
}
/* We must be careful disabling the clocks we are not intending to
* be using at boot time, as subsytems such as the LCD which do
* their own DMA requests to the bus can cause the system to lockup
* if they where in the middle of requesting bus access.
*
* Disabling the LCD clock if the LCD is active is very dangerous,
* and therefore the bootloader should be careful to not enable
* the LCD clock if it is not needed.
*/
/* install (and disable) the clocks we do not need immediately */
clkp
=
init_clocks_disable
;
for
(
ptr
=
0
;
ptr
<
ARRAY_SIZE
(
init_clocks_disable
);
ptr
++
,
clkp
++
)
{
ret
=
s3c24xx_register_clock
(
clkp
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"Failed to register clock %s (%d)
\n
"
,
clkp
->
name
,
ret
);
}
s3c2412_clkcon_enable
(
clkp
,
0
);
}
return
0
;
}
arch/arm/mach-s3c2410/s3c2412.c
0 → 100644
浏览文件 @
e11c910b
/* linux/arch/arm/mach-s3c2410/s3c2412.c
*
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* http://armlinux.simtec.co.uk/.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Modifications:
* 16-May-2003 BJD Created initial version
* 16-Aug-2003 BJD Fixed header files and copyright, added URL
* 05-Sep-2003 BJD Moved to kernel v2.6
* 18-Jan-2004 BJD Added serial port configuration
* 21-Aug-2004 BJD Added new struct s3c2410_board handler
* 28-Sep-2004 BJD Updates for new serial port bits
* 04-Nov-2004 BJD Updated UART configuration process
* 10-Jan-2005 BJD Removed s3c2410_clock_tick_rate
* 13-Aug-2005 DA Removed UART from initial I/O mappings
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/sysdev.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/arch/regs-clock.h>
#include <asm/arch/regs-serial.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-gpioj.h>
#include <asm/arch/regs-dsc.h>
#include "s3c2412.h"
#include "cpu.h"
#include "devs.h"
#include "clock.h"
#include "pm.h"
#ifndef CONFIG_CPU_S3C2412_ONLY
void
__iomem
*
s3c24xx_va_gpio2
=
S3C24XX_VA_GPIO
;
#endif
/* Initial IO mappings */
static
struct
map_desc
s3c2412_iodesc
[]
__initdata
=
{
IODESC_ENT
(
CLKPWR
),
IODESC_ENT
(
LCD
),
IODESC_ENT
(
TIMER
),
IODESC_ENT
(
ADC
),
IODESC_ENT
(
WATCHDOG
),
};
/* uart registration process */
void
__init
s3c2412_init_uarts
(
struct
s3c2410_uartcfg
*
cfg
,
int
no
)
{
s3c24xx_init_uartdevs
(
"s3c2412-uart"
,
s3c2410_uart_resources
,
cfg
,
no
);
/* rename devices that are s3c2412/s3c2413 specific */
s3c_device_sdi
.
name
=
"s3c2412-sdi"
;
s3c_device_nand
.
name
=
"s3c2412-nand"
;
}
/* s3c2412_map_io
*
* register the standard cpu IO areas, and any passed in from the
* machine specific initialisation.
*/
void
__init
s3c2412_map_io
(
struct
map_desc
*
mach_desc
,
int
mach_size
)
{
/* move base of IO */
s3c24xx_va_gpio2
=
S3C24XX_VA_GPIO
+
0x10
;
/* register our io-tables */
iotable_init
(
s3c2412_iodesc
,
ARRAY_SIZE
(
s3c2412_iodesc
));
iotable_init
(
mach_desc
,
mach_size
);
}
void
__init
s3c2412_init_clocks
(
int
xtal
)
{
unsigned
long
tmp
;
unsigned
long
fclk
;
unsigned
long
hclk
;
unsigned
long
pclk
;
/* now we've got our machine bits initialised, work out what
* clocks we've got */
fclk
=
s3c2410_get_pll
(
__raw_readl
(
S3C2410_MPLLCON
),
xtal
*
2
);
tmp
=
__raw_readl
(
S3C2410_CLKDIVN
);
/* work out clock scalings */
hclk
=
fclk
/
((
tmp
&
S3C2412_CLKDIVN_HDIVN_MASK
)
+
1
);
hclk
/=
((
tmp
&
S3C2421_CLKDIVN_ARMDIVN
)
?
2
:
1
);
pclk
=
hclk
/
((
tmp
&
S3C2412_CLKDIVN_PDIVN
)
?
2
:
1
);
/* print brieft summary of clocks, etc */
printk
(
"S3C2412: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz
\n
"
,
print_mhz
(
fclk
),
print_mhz
(
hclk
),
print_mhz
(
pclk
));
/* initialise the clocks here, to allow other things like the
* console to use them
*/
s3c24xx_setup_clocks
(
xtal
,
fclk
,
hclk
,
pclk
);
s3c2412_baseclk_add
();
}
/* need to register class before we actually register the device, and
* we also need to ensure that it has been initialised before any of the
* drivers even try to use it (even if not on an s3c2412 based system)
* as a driver which may support both 2410 and 2440 may try and use it.
*/
#ifdef CONFIG_PM
static
struct
sleep_save
s3c2412_sleep
[]
=
{
SAVE_ITEM
(
S3C2412_DSC0
),
SAVE_ITEM
(
S3C2412_DSC1
),
SAVE_ITEM
(
S3C2413_GPJDAT
),
SAVE_ITEM
(
S3C2413_GPJCON
),
SAVE_ITEM
(
S3C2413_GPJUP
),
/* save the sleep configuration anyway, just in case these
* get damaged during wakeup */
SAVE_ITEM
(
S3C2412_GPBSLPCON
),
SAVE_ITEM
(
S3C2412_GPCSLPCON
),
SAVE_ITEM
(
S3C2412_GPDSLPCON
),
SAVE_ITEM
(
S3C2412_GPESLPCON
),
SAVE_ITEM
(
S3C2412_GPFSLPCON
),
SAVE_ITEM
(
S3C2412_GPGSLPCON
),
SAVE_ITEM
(
S3C2412_GPHSLPCON
),
SAVE_ITEM
(
S3C2413_GPJSLPCON
),
};
static
int
s3c2412_suspend
(
struct
sys_device
*
dev
,
pm_message_t
state
)
{
s3c2410_pm_do_save
(
s3c2412_sleep
,
ARRAY_SIZE
(
s3c2412_sleep
));
return
0
;
}
static
int
s3c2412_resume
(
struct
sys_device
*
dev
)
{
s3c2410_pm_do_restore
(
s3c2412_sleep
,
ARRAY_SIZE
(
s3c2412_sleep
));
return
0
;
}
#else
#define s3c2412_suspend NULL
#define s3c2412_resume NULL
#endif
struct
sysdev_class
s3c2412_sysclass
=
{
set_kset_name
(
"s3c2412-core"
),
.
suspend
=
s3c2412_suspend
,
.
resume
=
s3c2412_resume
};
static
int
__init
s3c2412_core_init
(
void
)
{
return
sysdev_class_register
(
&
s3c2412_sysclass
);
}
core_initcall
(
s3c2412_core_init
);
static
struct
sys_device
s3c2412_sysdev
=
{
.
cls
=
&
s3c2412_sysclass
,
};
int
__init
s3c2412_init
(
void
)
{
printk
(
"S3C2412: Initialising architecture
\n
"
);
return
sysdev_register
(
&
s3c2412_sysdev
);
}
arch/arm/mach-s3c2410/s3c2412.h
0 → 100644
浏览文件 @
e11c910b
/* arch/arm/mach-s3c2410/s3c2412.h
*
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Header file for s3c2412 cpu support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifdef CONFIG_CPU_S3C2412
extern
int
s3c2412_init
(
void
);
extern
void
s3c2412_map_io
(
struct
map_desc
*
mach_desc
,
int
size
);
extern
void
s3c2412_init_uarts
(
struct
s3c2410_uartcfg
*
cfg
,
int
no
);
extern
void
s3c2412_init_clocks
(
int
xtal
);
extern
int
s3c2412_baseclk_add
(
void
);
#else
#define s3c2412_init_clocks NULL
#define s3c2412_init_uarts NULL
#define s3c2412_map_io NULL
#define s3c2412_init NULL
#endif
arch/arm/mm/Kconfig
浏览文件 @
e11c910b
...
...
@@ -61,9 +61,9 @@ config CPU_ARM720T
# ARM920T
config CPU_ARM920T
bool "Support ARM920T processor"
if !ARCH_S3C2410
depends on ARCH_EP93XX || ARCH_INTEGRATOR ||
ARCH_S3C2410
|| ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200
default y if
ARCH_S3C2410
|| ARCH_AT91RM9200
bool "Support ARM920T processor"
depends on ARCH_EP93XX || ARCH_INTEGRATOR ||
CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442
|| ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200
default y if
CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442
|| ARCH_AT91RM9200
select CPU_32v4
select CPU_ABRT_EV4T
select CPU_CACHE_V4WT
...
...
@@ -121,8 +121,8 @@ config CPU_ARM925T
# ARM926T
config CPU_ARM926T
bool "Support ARM926T processor"
depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX
default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX
depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX
|| CPU_S3C2412
default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX
|| CPU_S3C2412
select CPU_32v5
select CPU_ABRT_EV5TJ
select CPU_CACHE_VIVT
...
...
drivers/serial/Kconfig
浏览文件 @
e11c910b
...
...
@@ -354,21 +354,24 @@ config SERIAL_CLPS711X_CONSOLE
kernel at boot time.)
config SERIAL_S3C2410
tristate "Samsung S3C2410 Serial port support"
tristate "Samsung S3C2410
/S3C2440/S3C2442/S3C2412
Serial port support"
depends on ARM && ARCH_S3C2410
select SERIAL_CORE
help
Support for the on-chip UARTs on the Samsung S3C24
10X CPU
,
Support for the on-chip UARTs on the Samsung S3C24
XX series CPUs
,
providing /dev/ttySAC0, 1 and 2 (note, some machines may not
provide all of these ports, depending on how the serial port
pins are configured.
Currently this driver supports the UARTS on the S3C2410, S3C2440,
S3C2442, S3C2412 and S3C2413 CPUs.
config SERIAL_S3C2410_CONSOLE
bool "Support for console on S3C2410 serial port"
depends on SERIAL_S3C2410=y
select SERIAL_CORE_CONSOLE
help
Allow selection of the S3C24
10
on-board serial ports for use as
Allow selection of the S3C24
XX
on-board serial ports for use as
an virtual console.
Even if you say Y here, the currently visible virtual console
...
...
drivers/serial/s3c2410.c
浏览文件 @
e11c910b
...
...
@@ -872,6 +872,8 @@ static const char *s3c24xx_serial_type(struct uart_port *port)
return
"S3C2410"
;
case
PORT_S3C2440
:
return
"S3C2440"
;
case
PORT_S3C2412
:
return
"S3C2412"
;
default:
return
NULL
;
}
...
...
@@ -1528,6 +1530,141 @@ static inline void s3c2440_serial_exit(void)
#define s3c2440_uart_inf_at NULL
#endif
/* CONFIG_CPU_S3C2440 */
#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
static
int
s3c2412_serial_setsource
(
struct
uart_port
*
port
,
struct
s3c24xx_uart_clksrc
*
clk
)
{
unsigned
long
ucon
=
rd_regl
(
port
,
S3C2410_UCON
);
ucon
&=
~
S3C2412_UCON_CLKMASK
;
if
(
strcmp
(
clk
->
name
,
"uclk"
)
==
0
)
ucon
|=
S3C2440_UCON_UCLK
;
else
if
(
strcmp
(
clk
->
name
,
"pclk"
)
==
0
)
ucon
|=
S3C2440_UCON_PCLK
;
else
if
(
strcmp
(
clk
->
name
,
"usysclk"
)
==
0
)
ucon
|=
S3C2412_UCON_USYSCLK
;
else
{
printk
(
KERN_ERR
"unknown clock source %s
\n
"
,
clk
->
name
);
return
-
EINVAL
;
}
wr_regl
(
port
,
S3C2410_UCON
,
ucon
);
return
0
;
}
static
int
s3c2412_serial_getsource
(
struct
uart_port
*
port
,
struct
s3c24xx_uart_clksrc
*
clk
)
{
unsigned
long
ucon
=
rd_regl
(
port
,
S3C2410_UCON
);
switch
(
ucon
&
S3C2412_UCON_CLKMASK
)
{
case
S3C2412_UCON_UCLK
:
clk
->
divisor
=
1
;
clk
->
name
=
"uclk"
;
break
;
case
S3C2412_UCON_PCLK
:
case
S3C2412_UCON_PCLK2
:
clk
->
divisor
=
1
;
clk
->
name
=
"pclk"
;
break
;
case
S3C2412_UCON_USYSCLK
:
clk
->
divisor
=
1
;
clk
->
name
=
"usysclk"
;
break
;
}
return
0
;
}
static
int
s3c2412_serial_resetport
(
struct
uart_port
*
port
,
struct
s3c2410_uartcfg
*
cfg
)
{
unsigned
long
ucon
=
rd_regl
(
port
,
S3C2410_UCON
);
dbg
(
"%s: port=%p (%08lx), cfg=%p
\n
"
,
__FUNCTION__
,
port
,
port
->
mapbase
,
cfg
);
/* ensure we don't change the clock settings... */
ucon
&=
S3C2412_UCON_CLKMASK
;
wr_regl
(
port
,
S3C2410_UCON
,
ucon
|
cfg
->
ucon
);
wr_regl
(
port
,
S3C2410_ULCON
,
cfg
->
ulcon
);
/* reset both fifos */
wr_regl
(
port
,
S3C2410_UFCON
,
cfg
->
ufcon
|
S3C2410_UFCON_RESETBOTH
);
wr_regl
(
port
,
S3C2410_UFCON
,
cfg
->
ufcon
);
return
0
;
}
static
struct
s3c24xx_uart_info
s3c2412_uart_inf
=
{
.
name
=
"Samsung S3C2412 UART"
,
.
type
=
PORT_S3C2412
,
.
fifosize
=
64
,
.
rx_fifomask
=
S3C2440_UFSTAT_RXMASK
,
.
rx_fifoshift
=
S3C2440_UFSTAT_RXSHIFT
,
.
rx_fifofull
=
S3C2440_UFSTAT_RXFULL
,
.
tx_fifofull
=
S3C2440_UFSTAT_TXFULL
,
.
tx_fifomask
=
S3C2440_UFSTAT_TXMASK
,
.
tx_fifoshift
=
S3C2440_UFSTAT_TXSHIFT
,
.
get_clksrc
=
s3c2412_serial_getsource
,
.
set_clksrc
=
s3c2412_serial_setsource
,
.
reset_port
=
s3c2412_serial_resetport
,
};
/* device management */
static
int
s3c2412_serial_probe
(
struct
platform_device
*
dev
)
{
dbg
(
"s3c2440_serial_probe: dev=%p
\n
"
,
dev
);
return
s3c24xx_serial_probe
(
dev
,
&
s3c2440_uart_inf
);
}
static
struct
platform_driver
s3c2412_serial_drv
=
{
.
probe
=
s3c2412_serial_probe
,
.
remove
=
s3c24xx_serial_remove
,
.
suspend
=
s3c24xx_serial_suspend
,
.
resume
=
s3c24xx_serial_resume
,
.
driver
=
{
.
name
=
"s3c2412-uart"
,
.
owner
=
THIS_MODULE
,
},
};
static
inline
int
s3c2412_serial_init
(
void
)
{
return
s3c24xx_serial_init
(
&
s3c2412_serial_drv
,
&
s3c2412_uart_inf
);
}
static
inline
void
s3c2412_serial_exit
(
void
)
{
platform_driver_unregister
(
&
s3c2412_serial_drv
);
}
#define s3c2412_uart_inf_at &s3c2412_uart_inf
#else
static
inline
int
s3c2412_serial_init
(
void
)
{
return
0
;
}
static
inline
void
s3c2412_serial_exit
(
void
)
{
}
#define s3c2412_uart_inf_at NULL
#endif
/* CONFIG_CPU_S3C2440 */
/* module initialisation code */
static
int
__init
s3c24xx_serial_modinit
(
void
)
...
...
@@ -1542,6 +1679,7 @@ static int __init s3c24xx_serial_modinit(void)
s3c2400_serial_init
();
s3c2410_serial_init
();
s3c2412_serial_init
();
s3c2440_serial_init
();
return
0
;
...
...
@@ -1551,6 +1689,7 @@ static void __exit s3c24xx_serial_modexit(void)
{
s3c2400_serial_exit
();
s3c2410_serial_exit
();
s3c2412_serial_exit
();
s3c2440_serial_exit
();
uart_unregister_driver
(
&
s3c24xx_uart_drv
);
...
...
@@ -1773,6 +1912,8 @@ static int s3c24xx_serial_initconsole(void)
info
=
s3c2410_uart_inf_at
;
}
else
if
(
strcmp
(
dev
->
name
,
"s3c2440-uart"
)
==
0
)
{
info
=
s3c2440_uart_inf_at
;
}
else
if
(
strcmp
(
dev
->
name
,
"s3c2412-uart"
)
==
0
)
{
info
=
s3c2412_uart_inf_at
;
}
else
{
printk
(
KERN_ERR
"s3c24xx: no driver for %s
\n
"
,
dev
->
name
);
return
0
;
...
...
@@ -1796,4 +1937,4 @@ console_initcall(s3c24xx_serial_initconsole);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Ben Dooks <ben@simtec.co.uk>"
);
MODULE_DESCRIPTION
(
"Samsung S3C2410/S3C2440 Serial port driver"
);
MODULE_DESCRIPTION
(
"Samsung S3C2410/S3C2440
/S3C2412
Serial port driver"
);
include/asm-arm/arch-s3c2410/debug-macro.S
浏览文件 @
e11c910b
...
...
@@ -33,7 +33,7 @@
.
endm
.
macro
senduart
,
rd
,
rx
str
\
rd
,
[
\
rx
,
#
S3C2410_UTXH
]
str
b
\
rd
,
[
\
rx
,
#
S3C2410_UTXH
]
.
endm
.
macro
busyuart
,
rd
,
rx
...
...
@@ -42,6 +42,12 @@
beq
1001
f
@
@
FIFO
enabled
...
1003
:
@
check
for
arm920
vs
arm926
.
currently
assume
all
arm926
@
devices
have
an
64
byte
FIFO
identical
to
the
s3c2440
mrc
p15
,
0
,
\
rd
,
c0
,
c0
and
\
rd
,
\
rd
,
#
0xff0
teq
\
rd
,
#
0x260
beq
1004
f
mrc
p15
,
0
,
\
rd
,
c1
,
c0
tst
\
rd
,
#
1
addeq
\
rd
,
\
rx
,
#(
S3C24XX_PA_GPIO
-
S3C24XX_PA_UART
)
...
...
@@ -50,7 +56,7 @@
ldr
\
rd
,
[
\
rd
,
#
S3C2410_GSTATUS1
-
S3C2410_GPIOREG
(
0
)
]
and
\
rd
,
\
rd
,
#
0x00ff0000
teq
\
rd
,
#
0x00440000
@
is
it
2440
?
1004
:
ldr
\
rd
,
[
\
rx
,
#
S3C2410_UFSTAT
]
moveq
\
rd
,
\
rd
,
lsr
#
SHIFT_2440TXF
tst
\
rd
,
#
S3C2410_UFSTAT_TXFULL
...
...
include/asm-arm/arch-s3c2410/entry-macro.S
浏览文件 @
e11c910b
...
...
@@ -18,8 +18,6 @@
#define INTPND (0x10)
#define INTOFFSET (0x14)
#define EXTINTPEND (0xa8)
#define EXTINTMASK (0xa4)
#include <asm/hardware.h>
#include <asm/arch/irqs.h>
...
...
@@ -28,37 +26,23 @@
mov
\
base
,
#
S3C24XX_VA_IRQ
ldr
\
irqstat
,
[
\
base
,
#
INTPND
]
bics
\
irqnr
,
\
irqstat
,
#
3
<<
4
@@
only
an
GPIO
IRQ
beq
2000
f
@@
try
the
interrupt
offset
register
,
since
it
is
there
ldr
\
irqstat
,
[
\
base
,
#
INTPND
]
teq
\
irqstat
,
#
0
beq
1002
f
ldr
\
irqnr
,
[
\
base
,
#
INTOFFSET
]
mov
\
tmp
,
#
1
tst
\
irqstat
,
\
tmp
,
lsl
\
irqnr
addne
\
irqnr
,
\
irqnr
,
#
IRQ_EINT0
bne
1001
f
@@
the
number
specified
is
not
a
valid
irq
,
so
try
@@
and
work
it
out
for
ourselves
mov
\
irqnr
,
#
IRQ_EINT0
@@
start
here
b
3000
f
2000
:
@@
load
the
GPIO
interrupt
register
,
and
check
it
add
\
tmp
,
\
base
,
#
S3C24XX_VA_GPIO
-
S3C24XX_VA_IRQ
ldr
\
irqstat
,
[
\
tmp
,
#
EXTINTPEND
]
ldr
\
irqnr
,
[
\
tmp
,
#
EXTINTMASK
]
bics
\
irqstat
,
\
irqstat
,
\
irqnr
beq
1001
f
mov
\
irqnr
,
#(
IRQ_EINT4
-
4
)
mov
\
irqnr
,
#
0
@@
start
here
@@
work
out
which
irq
(
if
any
)
we
got
3000
:
movs
\
tmp
,
\
irqstat
,
lsl
#
16
addeq
\
irqnr
,
\
irqnr
,
#
16
moveq
\
irqstat
,
\
irqstat
,
lsr
#
16
...
...
@@ -75,9 +59,9 @@
addeq
\
irqnr
,
\
irqnr
,
#
1
@@
we
have
the
value
movs
\
irqnr
,
\
irqnr
1001
:
adds
\
irqnr
,
\
irqnr
,
#
IRQ_EINT0
1002
:
@@
exit
here
,
Z
flag
unset
if
IRQ
.
endm
...
...
include/asm-arm/arch-s3c2410/map.h
浏览文件 @
e11c910b
...
...
@@ -236,4 +236,20 @@
#define S3C24XX_PA_SPI S3C2410_PA_SPI
#endif
/* deal with the registers that move under the 2412/2413 */
#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
#ifndef __ASSEMBLY__
extern
void
__iomem
*
s3c24xx_va_gpio2
;
#endif
#ifdef CONFIG_CPU_S3C2412_ONLY
#define S3C24XX_VA_GPIO2 (S3C24XX_VA_GPIO + 0x10)
#else
#define S3C24XX_VA_GPIO2 s3c24xx_va_gpio2
#endif
#else
#define s3c24xx_va_gpio2 S3C24XX_VA_GPIO
#define S3C24XX_VA_GPIO2 S3C24XX_VA_GPIO
#endif
#endif
/* __ASM_ARCH_MAP_H */
include/asm-arm/arch-s3c2410/regs-clock.h
浏览文件 @
e11c910b
/* linux/include/asm/arch-s3c2410/regs-clock.h
*
* Copyright (c) 2003,2004,2005 Simtec Electronics <linux@simtec.co.uk>
* Copyright (c) 2003,2004,2005
,2006
Simtec Electronics <linux@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* This program is free software; you can redistribute it and/or modify
...
...
@@ -140,5 +140,66 @@ s3c2410_get_pll(unsigned int pllval, unsigned int baseclk)
#endif
/* CONFIG_CPU_S3C2440 or CONFIG_CPU_S3C2442 */
#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
#define S3C2412_OSCSET S3C2410_CLKREG(0x18)
#define S3C2412_CLKSRC S3C2410_CLKREG(0x1C)
#define S3C2412_PLLCON_OFF (1<<20)
#define S3C2412_CLKDIVN_PDIVN (1<<2)
#define S3C2412_CLKDIVN_HDIVN_MASK (3<<0)
#define S3C2421_CLKDIVN_ARMDIVN (1<<3)
#define S3C2412_CLKDIVN_USB48DIV (1<<6)
#define S3C2412_CLKDIVN_UARTDIV_MASK (15<<8)
#define S3C2412_CLKDIVN_UARTDIV_SHIFT (8)
#define S3C2412_CLKDIVN_I2SDIV_MASK (15<<12)
#define S3C2412_CLKDIVN_I2SDIV_SHIFT (12)
#define S3C2412_CLKDIVN_CAMDIV_MASK (15<<16)
#define S3C2412_CLKDIVN_CAMDIV_SHIFT (16)
#define S3C2412_CLKCON_WDT (1<<28)
#define S3C2412_CLKCON_SPI (1<<27)
#define S3C2412_CLKCON_IIS (1<<26)
#define S3C2412_CLKCON_IIC (1<<25)
#define S3C2412_CLKCON_ADC (1<<24)
#define S3C2412_CLKCON_RTC (1<<23)
#define S3C2412_CLKCON_GPIO (1<<22)
#define S3C2412_CLKCON_UART2 (1<<21)
#define S3C2412_CLKCON_UART1 (1<<20)
#define S3C2412_CLKCON_UART0 (1<<19)
#define S3C2412_CLKCON_SDI (1<<18)
#define S3C2412_CLKCON_PWMT (1<<17)
#define S3C2412_CLKCON_USBD (1<<16)
#define S3C2412_CLKCON_CAMCLK (1<<15)
#define S3C2412_CLKCON_UARTCLK (1<<14)
/* missing 13 */
#define S3C2412_CLKCON_USB_HOST48 (1<<12)
#define S3C2412_CLKCON_USB_DEV48 (1<<11)
#define S3C2412_CLKCON_HCLKdiv2 (1<<10)
#define S3C2412_CLKCON_HCLKx2 (1<<9)
#define S3C2412_CLKCON_SDRAM (1<<8)
/* missing 7 */
#define S3C2412_CLKCON_USBH S3C2410_CLKCON_USBH
#define S3C2412_CLKCON_LCDC S3C2410_CLKCON_LCDC
#define S3C2412_CLKCON_NAND S3C2410_CLKCON_NAND
#define S3C2412_CLKCON_DMA3 (1<<3)
#define S3C2412_CLKCON_DMA2 (1<<2)
#define S3C2412_CLKCON_DMA1 (1<<1)
#define S3C2412_CLKCON_DMA0 (1<<0)
/* clock sourec controls */
#define S3C2412_CLKSRC_EXTCLKDIV_MASK (7 << 0)
#define S3C2412_CLKSRC_EXTCLKDIV_SHIFT (0)
#define S3C2412_CLKSRC_MDIVCLK_EXTCLKDIV (1<<3)
#define S3C2412_CLKSRC_MSYSCLK_MPLL (1<<4)
#define S3C2412_CLKSRC_USYSCLK_UPLL (1<<5)
#define S3C2412_CLKSRC_UARTCLK_MPLL (1<<8)
#define S3C2412_CLKSRC_I2SCLK_MPLL (1<<9)
#define S3C2412_CLKSRC_USBCLK_HCLK (1<<10)
#define S3C2412_CLKSRC_CAMCLK_HCLK (1<<11)
#endif
/* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */
#endif
/* __ASM_ARM_REGS_CLOCK */
include/asm-arm/arch-s3c2410/regs-dsc.h
浏览文件 @
e11c910b
...
...
@@ -23,6 +23,9 @@
#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4)
#define S3C2440_DSC1 S3C2410_GPIOREG(0xc8)
#define S3C2412_DSC0 S3C2410_GPIOREG(0xdc)
#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0)
#define S3C2440_SELECT_DSC0 (0)
#define S3C2440_SELECT_DSC1 (1<<31)
...
...
include/asm-arm/arch-s3c2410/regs-gpio.h
浏览文件 @
e11c910b
...
...
@@ -45,7 +45,7 @@
#define S3C24XX_MISCCR S3C2400_MISCCR
#else
#define S3C24XX_GPIO_BASE(x) S3C2410_GPIO_BASE(x)
#define S3C24XX_MISCCR
S3C2410_MISCCR
#define S3C24XX_MISCCR
S3C24XX_GPIOREG2(0x80)
#endif
/* CONFIG_CPU_S3C2400 */
...
...
@@ -73,9 +73,15 @@
#define S3C2410_GPIO_SFN2 (0xFFFFFFF2)
/* not available on A */
#define S3C2410_GPIO_SFN3 (0xFFFFFFF3)
/* not available on A */
/* configure GPIO ports A..G */
/* register address for the GPIO registers.
* S3C24XX_GPIOREG2 is for the second set of registers in the
* GPIO which move between s3c2410 and s3c2412 type systems */
#define S3C2410_GPIOREG(x) ((x) + S3C24XX_VA_GPIO)
#define S3C24XX_GPIOREG2(x) ((x) + S3C24XX_VA_GPIO2)
/* configure GPIO ports A..G */
/* port A - S3C2410: 22bits, zero in bit X makes pin X output
* S3C2400: 18bits, zero in bit X makes pin X output
...
...
@@ -953,11 +959,18 @@
#define S3C2410_GPH10_OUTP (0x01 << 20)
#define S3C2410_GPH10_CLKOUT1 (0x02 << 20)
/* The S3C2412 and S3C2413 move the GPJ register set to after
* GPH, which means all registers after 0x80 are now offset by 0x10
* for the 2412/2413 from the 2410/2440/2442
*/
/* miscellaneous control */
#define S3C2400_MISCCR S3C2410_GPIOREG(0x54)
#define S3C2410_MISCCR S3C2410_GPIOREG(0x80)
#define S3C2410_DCLKCON S3C2410_GPIOREG(0x84)
#define S3C24XX_DCLKCON S3C24XX_GPIOREG2(0x84)
/* see clock.h for dclk definitions */
/* pullup control on databus */
...
...
@@ -985,6 +998,8 @@
#define S3C2410_MISCCR_CLK0_DCLK0 (5<<4)
#define S3C2410_MISCCR_CLK0_MASK (7<<4)
#define S3C2412_MISCCR_CLK0_RTC (2<<4)
#define S3C2410_MISCCR_CLK1_MPLL (0<<8)
#define S3C2410_MISCCR_CLK1_UPLL (1<<8)
#define S3C2410_MISCCR_CLK1_FCLK (2<<8)
...
...
@@ -993,6 +1008,8 @@
#define S3C2410_MISCCR_CLK1_DCLK1 (5<<8)
#define S3C2410_MISCCR_CLK1_MASK (7<<8)
#define S3C2412_MISCCR_CLK1_CLKsrc (0<<8)
#define S3C2410_MISCCR_USBSUSPND0 (1<<12)
#define S3C2410_MISCCR_USBSUSPND1 (1<<13)
...
...
@@ -1000,7 +1017,7 @@
#define S3C2410_MISCCR_nEN_SCLK0 (1<<17)
#define S3C2410_MISCCR_nEN_SCLK1 (1<<18)
#define S3C2410_MISCCR_nEN_SCLKE (1<<19)
#define S3C2410_MISCCR_nEN_SCLKE (1<<19)
/* not 2412 */
#define S3C2410_MISCCR_SDSLEEP (7<<17)
/* external interrupt control... */
...
...
@@ -1017,6 +1034,10 @@
#define S3C2410_EXTINT1 S3C2410_GPIOREG(0x8C)
#define S3C2410_EXTINT2 S3C2410_GPIOREG(0x90)
#define S3C24XX_EXTINT0 S3C24XX_GPIOREG2(0x88)
#define S3C24XX_EXTINT1 S3C24XX_GPIOREG2(0x8C)
#define S3C24XX_EXTINT2 S3C24XX_GPIOREG2(0x90)
/* values for S3C2410_EXTINT0/1/2 */
#define S3C2410_EXTINT_LOWLEV (0x00)
#define S3C2410_EXTINT_HILEV (0x01)
...
...
@@ -1030,6 +1051,11 @@
#define S3C2410_EINFLT2 S3C2410_GPIOREG(0x9C)
#define S3C2410_EINFLT3 S3C2410_GPIOREG(0xA0)
#define S3C24XX_EINFLT0 S3C24XX_GPIOREG2(0x94)
#define S3C24XX_EINFLT1 S3C24XX_GPIOREG2(0x98)
#define S3C24XX_EINFLT2 S3C24XX_GPIOREG2(0x9C)
#define S3C24XX_EINFLT3 S3C24XX_GPIOREG2(0xA0)
/* values for interrupt filtering */
#define S3C2410_EINTFLT_PCLK (0x00)
#define S3C2410_EINTFLT_EXTCLK (1<<7)
...
...
@@ -1039,6 +1065,7 @@
/* GSTATUS have miscellaneous information in them
*
* These move between s3c2410 and s3c2412 style systems.
*/
#define S3C2410_GSTATUS0 S3C2410_GPIOREG(0x0AC)
...
...
@@ -1047,6 +1074,18 @@
#define S3C2410_GSTATUS3 S3C2410_GPIOREG(0x0B8)
#define S3C2410_GSTATUS4 S3C2410_GPIOREG(0x0BC)
#define S3C2412_GSTATUS0 S3C2410_GPIOREG(0x0BC)
#define S3C2412_GSTATUS1 S3C2410_GPIOREG(0x0C0)
#define S3C2412_GSTATUS2 S3C2410_GPIOREG(0x0C4)
#define S3C2412_GSTATUS3 S3C2410_GPIOREG(0x0C8)
#define S3C2412_GSTATUS4 S3C2410_GPIOREG(0x0CC)
#define S3C24XX_GSTATUS0 S3C24XX_GPIOREG2(0x0AC)
#define S3C24XX_GSTATUS1 S3C24XX_GPIOREG2(0x0B0)
#define S3C24XX_GSTATUS2 S3C24XX_GPIOREG2(0x0B4)
#define S3C24XX_GSTATUS3 S3C24XX_GPIOREG2(0x0B8)
#define S3C24XX_GSTATUS4 S3C24XX_GPIOREG2(0x0BC)
#define S3C2410_GSTATUS0_nWAIT (1<<3)
#define S3C2410_GSTATUS0_NCON (1<<2)
#define S3C2410_GSTATUS0_RnB (1<<1)
...
...
@@ -1054,6 +1093,7 @@
#define S3C2410_GSTATUS1_IDMASK (0xffff0000)
#define S3C2410_GSTATUS1_2410 (0x32410000)
#define S3C2410_GSTATUS1_2412 (0x32412001)
#define S3C2410_GSTATUS1_2440 (0x32440000)
#define S3C2410_GSTATUS1_2442 (0x32440aaa)
...
...
@@ -1077,5 +1117,22 @@
#define S3C2400_OPENCR_OPC_MOSIDIS (0<<5)
#define S3C2400_OPENCR_OPC_MOSIEN (1<<5)
/* 2412/2413 sleep configuration registers */
#define S3C2412_GPBSLPCON S3C2410_GPIOREG(0x1C)
#define S3C2412_GPCSLPCON S3C2410_GPIOREG(0x2C)
#define S3C2412_GPDSLPCON S3C2410_GPIOREG(0x3C)
#define S3C2412_GPESLPCON S3C2410_GPIOREG(0x4C)
#define S3C2412_GPFSLPCON S3C2410_GPIOREG(0x5C)
#define S3C2412_GPGSLPCON S3C2410_GPIOREG(0x6C)
#define S3C2412_GPHSLPCON S3C2410_GPIOREG(0x7C)
/* definitions for each pin bit */
#define S3C2412_SLPCON_LOW(x) ( 0x00 << ((x) * 2))
#define S3C2412_SLPCON_HI(x) ( 0x01 << ((x) * 2))
#define S3C2412_SLPCON_IN(x) ( 0x02 << ((x) * 2))
#define S3C2412_SLPCON_PDWN(x) ( 0x03 << ((x) * 2))
#define S3C2412_SLPCON_MASK(x) ( 0x03 << ((x) * 2))
#endif
/* __ASM_ARCH_REGS_GPIO_H */
include/asm-arm/arch-s3c2410/regs-gpioj.h
浏览文件 @
e11c910b
...
...
@@ -32,6 +32,11 @@
#define S3C2440_GPJDAT S3C2410_GPIOREG(0xd4)
#define S3C2440_GPJUP S3C2410_GPIOREG(0xd8)
#define S3C2413_GPJCON S3C2410_GPIOREG(0x80)
#define S3C2413_GPJDAT S3C2410_GPIOREG(0x84)
#define S3C2413_GPJUP S3C2410_GPIOREG(0x88)
#define S3C2413_GPJSLPCON S3C2410_GPIOREG(0x8C)
#define S3C2440_GPJ0 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 0)
#define S3C2440_GPJ0_INP (0x00 << 0)
#define S3C2440_GPJ0_OUTP (0x01 << 0)
...
...
include/asm-arm/arch-s3c2410/regs-irq.h
浏览文件 @
e11c910b
...
...
@@ -23,6 +23,7 @@
#define S3C2410_IRQREG(x) ((x) + S3C24XX_VA_IRQ)
#define S3C2410_EINTREG(x) ((x) + S3C24XX_VA_GPIO)
#define S3C24XX_EINTREG(x) ((x) + S3C24XX_VA_GPIO2)
#define S3C2410_SRCPND S3C2410_IRQREG(0x000)
#define S3C2410_INTMOD S3C2410_IRQREG(0x004)
...
...
@@ -40,5 +41,10 @@
#define S3C2410_EINTMASK S3C2410_EINTREG(0x0A4)
#define S3C2410_EINTPEND S3C2410_EINTREG(0X0A8)
#define S3C2412_EINTMASK S3C2410_EINTREG(0x0B4)
#define S3C2412_EINTPEND S3C2410_EINTREG(0X0B8)
#define S3C24XX_EINTMASK S3C24XX_EINTREG(0x0A4)
#define S3C24XX_EINTPEND S3C24XX_EINTREG(0X0A8)
#endif
/* ___ASM_ARCH_REGS_IRQ_H */
include/asm-arm/arch-s3c2410/regs-serial.h
浏览文件 @
e11c910b
...
...
@@ -82,6 +82,12 @@
#define S3C2440_UCON2_DIVMASK (7 << 12)
#define S3C2440_UCON_DIVSHIFT (12)
#define S3C2412_UCON_CLKMASK (3<<10)
#define S3C2412_UCON_UCLK (1<<10)
#define S3C2412_UCON_USYSCLK (3<<10)
#define S3C2412_UCON_PCLK (0<<10)
#define S3C2412_UCON_PCLK2 (2<<10)
#define S3C2410_UCON_UCLK (1<<10)
#define S3C2410_UCON_SBREAK (1<<4)
...
...
@@ -124,6 +130,15 @@
#define S3C2410_UMCOM_AFC (1<<4)
#define S3C2410_UMCOM_RTS_LOW (1<<0)
#define S3C2412_UMCON_AFC_63 (0<<5)
#define S3C2412_UMCON_AFC_56 (1<<5)
#define S3C2412_UMCON_AFC_48 (2<<5)
#define S3C2412_UMCON_AFC_40 (3<<5)
#define S3C2412_UMCON_AFC_32 (4<<5)
#define S3C2412_UMCON_AFC_24 (5<<5)
#define S3C2412_UMCON_AFC_16 (6<<5)
#define S3C2412_UMCON_AFC_8 (7<<5)
#define S3C2410_UFSTAT_TXFULL (1<<9)
#define S3C2410_UFSTAT_RXFULL (1<<8)
#define S3C2410_UFSTAT_TXMASK (15<<4)
...
...
include/linux/serial_core.h
浏览文件 @
e11c910b
...
...
@@ -130,6 +130,9 @@
/* SUN4V Hypervisor Console */
#define PORT_SUNHV 72
#define PORT_S3C2412 73
#ifdef __KERNEL__
#include <linux/compiler.h>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录