Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
c4d37215
K
Kernel
项目概览
openeuler
/
Kernel
接近 2 年 前同步成功
通知
8
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看板
提交
c4d37215
编写于
6月 29, 2006
作者:
D
David S. Miller
提交者:
David S. Miller
6月 29, 2006
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[SERIAL] sunsab: Convert to of_driver framework.
Signed-off-by:
N
David S. Miller
<
davem@davemloft.net
>
上级
9efc3715
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
144 addition
and
155 deletion
+144
-155
drivers/serial/sunsab.c
drivers/serial/sunsab.c
+144
-155
未找到文件。
drivers/serial/sunsab.c
浏览文件 @
c4d37215
/* sunsab.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
/* sunsab.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
*
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
* Copyright (C) 2002
David S. Miller (davem@redhat.com
)
* Copyright (C) 2002
, 2006 David S. Miller (davem@davemloft.net
)
*
*
* Rewrote buffer handling to use CIRC(Circular Buffer) macros.
* Rewrote buffer handling to use CIRC(Circular Buffer) macros.
* Maxim Krasnyanskiy <maxk@qualcomm.com>
* Maxim Krasnyanskiy <maxk@qualcomm.com>
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
* Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
* Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
*
*
* Ported to new 2.5.x UART layer.
* Ported to new 2.5.x UART layer.
* David S. Miller <davem@
redhat.com
>
* David S. Miller <davem@
davemloft.net
>
*/
*/
#include <linux/config.h>
#include <linux/config.h>
...
@@ -37,8 +37,8 @@
...
@@ -37,8 +37,8 @@
#include <asm/io.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/irq.h>
#include <asm/
oplib
.h>
#include <asm/
prom
.h>
#include <asm/
ebus
.h>
#include <asm/
of_device
.h>
#if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
#define SUPPORT_SYSRQ
...
@@ -976,199 +976,188 @@ static inline struct console *SUNSAB_CONSOLE(void)
...
@@ -976,199 +976,188 @@ static inline struct console *SUNSAB_CONSOLE(void)
#define sunsab_console_init() do { } while (0)
#define sunsab_console_init() do { } while (0)
#endif
#endif
static
void
__init
for_each_sab_edev
(
void
(
*
callback
)(
struct
linux_ebus_device
*
,
void
*
),
void
*
arg
)
static
int
__init
sunsab_init_one
(
struct
uart_sunsab_port
*
up
,
struct
of_device
*
op
,
unsigned
long
offset
,
int
line
)
{
{
struct
linux_ebus
*
ebus
;
up
->
port
.
line
=
line
;
struct
linux_ebus_device
*
edev
=
NULL
;
up
->
port
.
dev
=
&
op
->
dev
;
for_each_ebus
(
ebus
)
{
up
->
port
.
mapbase
=
op
->
resource
[
0
].
start
+
offset
;
for_each_ebusdev
(
edev
,
ebus
)
{
up
->
port
.
membase
=
of_ioremap
(
&
op
->
resource
[
0
],
offset
,
if
(
!
strcmp
(
edev
->
prom_node
->
name
,
"se"
))
{
sizeof
(
union
sab82532_async_regs
),
callback
(
edev
,
arg
);
"sab"
);
continue
;
if
(
!
up
->
port
.
membase
)
}
else
if
(
!
strcmp
(
edev
->
prom_node
->
name
,
"serial"
))
{
return
-
ENOMEM
;
char
*
compat
;
up
->
regs
=
(
union
sab82532_async_regs
__iomem
*
)
up
->
port
.
membase
;
int
clen
;
/* On RIO this can be an SE, check it. We could
* just check ebus->is_rio, but this is more portable.
*/
compat
=
of_get_property
(
edev
->
prom_node
,
"compatible"
,
&
clen
);
if
(
compat
&&
clen
>
0
)
{
if
(
strncmp
(
compat
,
"sab82532"
,
8
)
==
0
)
{
callback
(
edev
,
arg
);
continue
;
}
}
}
}
}
}
static
void
__init
sab_count_callback
(
struct
linux_ebus_device
*
edev
,
void
*
arg
)
up
->
port
.
irq
=
op
->
irqs
[
0
];
{
int
*
count_p
=
arg
;
(
*
count_p
)
++
;
up
->
port
.
fifosize
=
SAB82532_XMIT_FIFO_SIZE
;
}
up
->
port
.
iotype
=
UPIO_MEM
;
static
void
__init
sab_attach_callback
(
struct
linux_ebus_device
*
edev
,
void
*
arg
)
writeb
(
SAB82532_IPC_IC_ACT_LOW
,
&
up
->
regs
->
w
.
ipc
);
{
int
*
instance_p
=
arg
;
struct
uart_sunsab_port
*
up
;
unsigned
long
regs
,
offset
;
int
i
;
/* Note: ports are located in reverse order */
up
->
port
.
ops
=
&
sunsab_pops
;
regs
=
edev
->
resource
[
0
].
start
;
up
->
port
.
type
=
PORT_SUNSAB
;
offset
=
sizeof
(
union
sab82532_async_regs
);
up
->
port
.
uartclk
=
SAB_BASE_BAUD
;
for
(
i
=
0
;
i
<
2
;
i
++
)
{
up
=
&
sunsab_ports
[(
*
instance_p
*
2
)
+
1
-
i
];
memset
(
up
,
0
,
sizeof
(
*
up
));
up
->
type
=
readb
(
&
up
->
regs
->
r
.
vstr
)
&
0x0f
;
up
->
regs
=
ioremap
(
regs
+
offset
,
sizeof
(
union
sab82532_async_regs
));
writeb
(
~
((
1
<<
1
)
|
(
1
<<
2
)
|
(
1
<<
4
)),
&
up
->
regs
->
w
.
pcr
);
up
->
port
.
irq
=
edev
->
irqs
[
0
];
writeb
(
0xff
,
&
up
->
regs
->
w
.
pim
);
up
->
port
.
fifosize
=
SAB82532_XMIT_FIFO_SIZE
;
if
((
up
->
port
.
line
&
0x1
)
==
0
)
{
up
->
port
.
mapbase
=
(
unsigned
long
)
up
->
regs
;
up
->
pvr_dsr_bit
=
(
1
<<
0
);
up
->
port
.
iotype
=
UPIO_MEM
;
up
->
pvr_dtr_bit
=
(
1
<<
1
);
}
else
{
up
->
pvr_dsr_bit
=
(
1
<<
3
);
up
->
pvr_dtr_bit
=
(
1
<<
2
);
}
up
->
cached_pvr
=
(
1
<<
1
)
|
(
1
<<
2
)
|
(
1
<<
4
);
writeb
(
up
->
cached_pvr
,
&
up
->
regs
->
w
.
pvr
);
up
->
cached_mode
=
readb
(
&
up
->
regs
->
rw
.
mode
);
up
->
cached_mode
|=
SAB82532_MODE_FRTS
;
writeb
(
up
->
cached_mode
,
&
up
->
regs
->
rw
.
mode
);
up
->
cached_mode
|=
SAB82532_MODE_RTS
;
writeb
(
up
->
cached_mode
,
&
up
->
regs
->
rw
.
mode
);
writeb
(
SAB82532_IPC_IC_ACT_LOW
,
&
up
->
regs
->
w
.
ipc
);
up
->
tec_timeout
=
SAB82532_MAX_TEC_TIMEOUT
;
up
->
cec_timeout
=
SAB82532_MAX_CEC_TIMEOUT
;
offset
-=
sizeof
(
union
sab82532_async_regs
);
if
(
!
(
up
->
port
.
line
&
0x01
))
{
int
err
;
err
=
request_irq
(
up
->
port
.
irq
,
sunsab_interrupt
,
SA_SHIRQ
,
"sab"
,
up
);
if
(
err
)
{
of_iounmap
(
up
->
port
.
membase
,
sizeof
(
union
sab82532_async_regs
));
return
err
;
}
}
}
(
*
instance_p
)
++
;
return
0
;
}
}
static
int
__
init
probe_for_sabs
(
void
)
static
int
__
devinit
sab_probe
(
struct
of_device
*
op
,
const
struct
of_device_id
*
match
)
{
{
int
this_sab
=
0
;
static
int
inst
;
struct
uart_sunsab_port
*
up
;
int
err
;
up
=
&
sunsab_ports
[
inst
*
2
];
err
=
sunsab_init_one
(
&
up
[
0
],
op
,
sizeof
(
union
sab82532_async_regs
),
(
inst
*
2
)
+
0
);
if
(
err
)
return
err
;
err
=
sunsab_init_one
(
&
up
[
0
],
op
,
0
,
(
inst
*
2
)
+
1
);
if
(
err
)
{
of_iounmap
(
up
[
0
].
port
.
membase
,
sizeof
(
union
sab82532_async_regs
));
free_irq
(
up
[
0
].
port
.
irq
,
&
up
[
0
]);
return
err
;
}
/* Find device instances. */
uart_add_one_port
(
&
sunsab_reg
,
&
up
[
0
].
port
);
for_each_sab_edev
(
&
sab_count_callback
,
&
this_sab
);
uart_add_one_port
(
&
sunsab_reg
,
&
up
[
1
].
port
);
if
(
!
this_sab
)
return
-
ENODEV
;
/* Allocate tables. */
dev_set_drvdata
(
&
op
->
dev
,
&
up
[
0
]);
sunsab_ports
=
kmalloc
(
sizeof
(
struct
uart_sunsab_port
)
*
this_sab
*
2
,
GFP_KERNEL
);
if
(
!
sunsab_ports
)
return
-
ENOMEM
;
num_channels
=
this_sab
*
2
;
inst
++
;
this_sab
=
0
;
for_each_sab_edev
(
&
sab_attach_callback
,
&
this_sab
);
return
0
;
return
0
;
}
}
static
void
__
init
sunsab_init_hw
(
void
)
static
void
__
devexit
sab_remove_one
(
struct
uart_sunsab_port
*
up
)
{
{
int
i
;
uart_remove_one_port
(
&
sunsab_reg
,
&
up
->
port
);
if
(
!
(
up
->
port
.
line
&
1
))
for
(
i
=
0
;
i
<
num_channels
;
i
++
)
{
free_irq
(
up
->
port
.
irq
,
up
);
struct
uart_sunsab_port
*
up
=
&
sunsab_ports
[
i
];
of_iounmap
(
up
->
port
.
membase
,
sizeof
(
union
sab82532_async_regs
));
up
->
port
.
line
=
i
;
up
->
port
.
ops
=
&
sunsab_pops
;
up
->
port
.
type
=
PORT_SUNSAB
;
up
->
port
.
uartclk
=
SAB_BASE_BAUD
;
up
->
type
=
readb
(
&
up
->
regs
->
r
.
vstr
)
&
0x0f
;
writeb
(
~
((
1
<<
1
)
|
(
1
<<
2
)
|
(
1
<<
4
)),
&
up
->
regs
->
w
.
pcr
);
writeb
(
0xff
,
&
up
->
regs
->
w
.
pim
);
if
(
up
->
port
.
line
==
0
)
{
up
->
pvr_dsr_bit
=
(
1
<<
0
);
up
->
pvr_dtr_bit
=
(
1
<<
1
);
}
else
{
up
->
pvr_dsr_bit
=
(
1
<<
3
);
up
->
pvr_dtr_bit
=
(
1
<<
2
);
}
up
->
cached_pvr
=
(
1
<<
1
)
|
(
1
<<
2
)
|
(
1
<<
4
);
writeb
(
up
->
cached_pvr
,
&
up
->
regs
->
w
.
pvr
);
up
->
cached_mode
=
readb
(
&
up
->
regs
->
rw
.
mode
);
up
->
cached_mode
|=
SAB82532_MODE_FRTS
;
writeb
(
up
->
cached_mode
,
&
up
->
regs
->
rw
.
mode
);
up
->
cached_mode
|=
SAB82532_MODE_RTS
;
writeb
(
up
->
cached_mode
,
&
up
->
regs
->
rw
.
mode
);
up
->
tec_timeout
=
SAB82532_MAX_TEC_TIMEOUT
;
up
->
cec_timeout
=
SAB82532_MAX_CEC_TIMEOUT
;
if
(
!
(
up
->
port
.
line
&
0x01
))
{
if
(
request_irq
(
up
->
port
.
irq
,
sunsab_interrupt
,
SA_SHIRQ
,
"serial(sab82532)"
,
up
))
{
printk
(
"sunsab%d: can't get IRQ %x
\n
"
,
i
,
up
->
port
.
irq
);
continue
;
}
}
}
}
}
static
int
__
init
sunsab_init
(
void
)
static
int
__
devexit
sab_remove
(
struct
of_device
*
op
)
{
{
int
ret
=
probe_for_sabs
();
struct
uart_sunsab_port
*
up
=
dev_get_drvdata
(
&
op
->
dev
);
int
i
;
if
(
ret
<
0
)
return
ret
;
sunsab_init_hw
();
sab_remove_one
(
&
up
[
0
]);
sab_remove_one
(
&
up
[
1
]);
sunsab_reg
.
minor
=
sunserial_current_minor
;
dev_set_drvdata
(
&
op
->
dev
,
NULL
);
sunsab_reg
.
nr
=
num_channels
;
ret
=
uart_register_driver
(
&
sunsab_reg
);
return
0
;
if
(
ret
<
0
)
{
}
int
i
;
for
(
i
=
0
;
i
<
num_channels
;
i
++
)
{
static
struct
of_device_id
sab_match
[]
=
{
struct
uart_sunsab_port
*
up
=
&
sunsab_ports
[
i
];
{
.
name
=
"se"
,
},
{
.
name
=
"serial"
,
.
compatible
=
"sab82532"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
sab_match
);
if
(
!
(
up
->
port
.
line
&
0x01
))
static
struct
of_platform_driver
sab_driver
=
{
free_irq
(
up
->
port
.
irq
,
up
);
.
name
=
"sab"
,
iounmap
(
up
->
regs
);
.
match_table
=
sab_match
,
}
.
probe
=
sab_probe
,
kfree
(
sunsab_ports
);
.
remove
=
__devexit_p
(
sab_remove
),
sunsab_ports
=
NULL
;
}
;
return
ret
;
static
int
__init
sunsab_init
(
void
)
{
struct
device_node
*
dp
;
int
err
;
num_channels
=
0
;
for_each_node_by_name
(
dp
,
"su"
)
num_channels
+=
2
;
for_each_node_by_name
(
dp
,
"serial"
)
{
if
(
of_device_is_compatible
(
dp
,
"sab82532"
))
num_channels
+=
2
;
}
}
sunsab_reg
.
tty_driver
->
name_base
=
sunsab_reg
.
minor
-
64
;
if
(
num_channels
)
{
sunsab_ports
=
kzalloc
(
sizeof
(
struct
uart_sunsab_port
)
*
num_channels
,
GFP_KERNEL
);
if
(
!
sunsab_ports
)
return
-
ENOMEM
;
sunsab_reg
.
cons
=
SUNSAB_CONSOLE
();
sunsab_reg
.
minor
=
sunserial_current_minor
;
sunsab_reg
.
nr
=
num_channels
;
sunserial_current_minor
+=
num_channels
;
err
=
uart_register_driver
(
&
sunsab_reg
)
;
if
(
err
)
{
for
(
i
=
0
;
i
<
num_channels
;
i
++
)
{
kfree
(
sunsab_ports
);
struct
uart_sunsab_port
*
up
=
&
sunsab_ports
[
i
]
;
sunsab_ports
=
NULL
;
uart_add_one_port
(
&
sunsab_reg
,
&
up
->
port
);
return
err
;
}
sunsab_reg
.
tty_driver
->
name_base
=
sunsab_reg
.
minor
-
64
;
sunsab_reg
.
cons
=
SUNSAB_CONSOLE
();
sunserial_current_minor
+=
num_channels
;
}
}
return
0
;
return
of_register_driver
(
&
sab_driver
,
&
of_bus_type
)
;
}
}
static
void
__exit
sunsab_exit
(
void
)
static
void
__exit
sunsab_exit
(
void
)
{
{
int
i
;
of_unregister_driver
(
&
sab_driver
);
if
(
num_channels
)
{
for
(
i
=
0
;
i
<
num_channels
;
i
++
)
{
sunserial_current_minor
-=
num_channels
;
struct
uart_sunsab_port
*
up
=
&
sunsab_ports
[
i
];
uart_unregister_driver
(
&
sunsab_reg
);
uart_remove_one_port
(
&
sunsab_reg
,
&
up
->
port
);
if
(
!
(
up
->
port
.
line
&
0x01
))
free_irq
(
up
->
port
.
irq
,
up
);
iounmap
(
up
->
regs
);
}
}
sunserial_current_minor
-=
num_channels
;
uart_unregister_driver
(
&
sunsab_reg
);
kfree
(
sunsab_ports
);
kfree
(
sunsab_ports
);
sunsab_ports
=
NULL
;
sunsab_ports
=
NULL
;
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录