Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
237f8aaf
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
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看板
提交
237f8aaf
编写于
8月 27, 2008
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
sparc: Convert uctrl driver to OF driver.
Signed-off-by:
N
David S. Miller
<
davem@davemloft.net
>
上级
a9540d34
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
121 addition
and
97 deletion
+121
-97
drivers/sbus/char/Kconfig
drivers/sbus/char/Kconfig
+1
-1
drivers/sbus/char/uctrl.c
drivers/sbus/char/uctrl.c
+120
-96
未找到文件。
drivers/sbus/char/Kconfig
浏览文件 @
237f8aaf
...
...
@@ -32,7 +32,7 @@ config OBP_FLASH
config TADPOLE_TS102_UCTRL
tristate "Tadpole TS102 Microcontroller support (EXPERIMENTAL)"
depends on EXPERIMENTAL
&& SPARC32
depends on EXPERIMENTAL
help
Say Y here to directly support the TS102 Microcontroller interface
on the Tadpole Sparcbook 3. This device handles power-management
...
...
drivers/sbus/char/uctrl.c
浏览文件 @
237f8aaf
/* $Id: uctrl.c,v 1.12 2001/10/08 22:19:51 davem Exp $
* uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3
/* uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3
*
* Copyright 1999 Derrick J Brashear (shadow@dementia.org)
* Copyright 2008 David S. Miller (davem@davemloft.net)
*/
#include <linux/module.h>
...
...
@@ -14,6 +14,8 @@
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
...
...
@@ -21,7 +23,6 @@
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/sbus.h>
#define UCTRL_MINOR 174
...
...
@@ -33,26 +34,26 @@
#endif
struct
uctrl_regs
{
volatile
u32
uctrl_intr
;
volatile
u32
uctrl_data
;
volatile
u32
uctrl_stat
;
volatile
u32
uctrl_xxx
[
5
];
u32
uctrl_intr
;
u32
uctrl_data
;
u32
uctrl_stat
;
u32
uctrl_xxx
[
5
];
};
struct
ts102_regs
{
volatile
u32
card_a_intr
;
volatile
u32
card_a_stat
;
volatile
u32
card_a_ctrl
;
volatile
u32
card_a_xxx
;
volatile
u32
card_b_intr
;
volatile
u32
card_b_stat
;
volatile
u32
card_b_ctrl
;
volatile
u32
card_b_xxx
;
volatile
u32
uctrl_intr
;
volatile
u32
uctrl_data
;
volatile
u32
uctrl_stat
;
volatile
u32
uctrl_xxx
;
volatile
u32
ts102_xxx
[
4
];
u32
card_a_intr
;
u32
card_a_stat
;
u32
card_a_ctrl
;
u32
card_a_xxx
;
u32
card_b_intr
;
u32
card_b_stat
;
u32
card_b_ctrl
;
u32
card_b_xxx
;
u32
uctrl_intr
;
u32
uctrl_data
;
u32
uctrl_stat
;
u32
uctrl_xxx
;
u32
ts102_xxx
[
4
];
};
/* Bits for uctrl_intr register */
...
...
@@ -186,17 +187,15 @@ enum uctrl_opcode {
POWER_RESTART
=
0x83
,
};
struct
uctrl_driver
{
struct
uctrl_regs
*
regs
;
st
atic
st
ruct
uctrl_driver
{
struct
uctrl_regs
__iomem
*
regs
;
int
irq
;
int
pending
;
struct
uctrl_status
status
;
};
static
struct
uctrl_driver
drv
;
}
*
global_driver
;
static
void
uctrl_get_event_status
(
void
);
static
void
uctrl_get_external_status
(
void
);
static
void
uctrl_get_event_status
(
struct
uctrl_driver
*
);
static
void
uctrl_get_external_status
(
struct
uctrl_driver
*
);
static
int
uctrl_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
...
...
@@ -213,16 +212,14 @@ static int
uctrl_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
lock_kernel
();
uctrl_get_event_status
();
uctrl_get_external_status
();
uctrl_get_event_status
(
global_driver
);
uctrl_get_external_status
(
global_driver
);
unlock_kernel
();
return
0
;
}
static
irqreturn_t
uctrl_interrupt
(
int
irq
,
void
*
dev_id
)
{
struct
uctrl_driver
*
driver
=
(
struct
uctrl_driver
*
)
dev_id
;
printk
(
"in uctrl_interrupt
\n
"
);
return
IRQ_HANDLED
;
}
...
...
@@ -244,11 +241,11 @@ static struct miscdevice uctrl_dev = {
{ \
unsigned int i; \
for (i = 0; i < 10000; i++) { \
if (UCTRL_STAT_TXNF_STA & driver->regs->uctrl_stat
) \
if (UCTRL_STAT_TXNF_STA & sbus_readl(&driver->regs->uctrl_stat)
) \
break; \
} \
dprintk(("write data 0x%02x\n", value)); \
driver->regs->uctrl_data = value
; \
sbus_writel(value, &driver->regs->uctrl_data)
; \
}
/* Wait for something to read, read it, then clear the bit */
...
...
@@ -257,24 +254,23 @@ static struct miscdevice uctrl_dev = {
unsigned int i; \
value = 0; \
for (i = 0; i < 10000; i++) { \
if ((UCTRL_STAT_RXNE_STA & driver->regs->uctrl_stat
) == 0) \
if ((UCTRL_STAT_RXNE_STA & sbus_readl(&driver->regs->uctrl_stat)
) == 0) \
break; \
udelay(1); \
} \
value =
driver->regs->uctrl_data
; \
value =
sbus_readl(&driver->regs->uctrl_data)
; \
dprintk(("read data 0x%02x\n", value)); \
driver->regs->uctrl_stat = UCTRL_STAT_RXNE_STA
; \
sbus_writel(UCTRL_STAT_RXNE_STA, &driver->regs->uctrl_stat)
; \
}
static
void
uctrl_do_txn
(
struct
uctrl_txn
*
txn
)
static
void
uctrl_do_txn
(
struct
uctrl_
driver
*
driver
,
struct
uctrl_
txn
*
txn
)
{
struct
uctrl_driver
*
driver
=
&
drv
;
int
stat
,
incnt
,
outcnt
,
bytecnt
,
intr
;
u32
byte
;
stat
=
driver
->
regs
->
uctrl_stat
;
intr
=
driver
->
regs
->
uctrl_intr
;
driver
->
regs
->
uctrl_stat
=
stat
;
stat
=
sbus_readl
(
&
driver
->
regs
->
uctrl_stat
)
;
intr
=
sbus_readl
(
&
driver
->
regs
->
uctrl_intr
)
;
sbus_writel
(
stat
,
&
driver
->
regs
->
uctrl_stat
)
;
dprintk
((
"interrupt stat 0x%x int 0x%x
\n
"
,
stat
,
intr
));
...
...
@@ -305,9 +301,8 @@ static void uctrl_do_txn(struct uctrl_txn *txn)
}
}
static
void
uctrl_get_event_status
(
void
)
static
void
uctrl_get_event_status
(
struct
uctrl_driver
*
driver
)
{
struct
uctrl_driver
*
driver
=
&
drv
;
struct
uctrl_txn
txn
;
u8
outbits
[
2
];
...
...
@@ -317,7 +312,7 @@ static void uctrl_get_event_status(void)
txn
.
inbuf
=
NULL
;
txn
.
outbuf
=
outbits
;
uctrl_do_txn
(
&
txn
);
uctrl_do_txn
(
driver
,
&
txn
);
dprintk
((
"bytes %x %x
\n
"
,
(
outbits
[
0
]
&
0xff
),
(
outbits
[
1
]
&
0xff
)));
driver
->
status
.
event_status
=
...
...
@@ -325,9 +320,8 @@ static void uctrl_get_event_status(void)
dprintk
((
"ev is %x
\n
"
,
driver
->
status
.
event_status
));
}
static
void
uctrl_get_external_status
(
void
)
static
void
uctrl_get_external_status
(
struct
uctrl_driver
*
driver
)
{
struct
uctrl_driver
*
driver
=
&
drv
;
struct
uctrl_txn
txn
;
u8
outbits
[
2
];
int
i
,
v
;
...
...
@@ -338,7 +332,7 @@ static void uctrl_get_external_status(void)
txn
.
inbuf
=
NULL
;
txn
.
outbuf
=
outbits
;
uctrl_do_txn
(
&
txn
);
uctrl_do_txn
(
driver
,
&
txn
);
dprintk
((
"bytes %x %x
\n
"
,
(
outbits
[
0
]
&
0xff
),
(
outbits
[
1
]
&
0xff
)));
driver
->
status
.
external_status
=
...
...
@@ -354,71 +348,101 @@ static void uctrl_get_external_status(void)
}
static
int
__init
ts102_uctrl_init
(
void
)
static
int
__devinit
uctrl_probe
(
struct
of_device
*
op
,
const
struct
of_device_id
*
match
)
{
struct
uctrl_driver
*
driver
=
&
drv
;
int
len
;
struct
linux_prom_irqs
tmp_irq
[
2
];
unsigned
int
vaddr
[
2
]
=
{
0
,
0
};
int
tmpnode
,
uctrlnode
=
prom_getchild
(
prom_root_node
);
int
err
;
struct
uctrl_driver
*
p
;
int
err
=
-
ENOMEM
;
tmpnode
=
prom_searchsiblings
(
uctrlnode
,
"obio"
);
p
=
kzalloc
(
sizeof
(
*
p
),
GFP_KERNEL
);
if
(
!
p
)
{
printk
(
KERN_ERR
"uctrl: Unable to allocate device struct.
\n
"
);
goto
out
;
}
if
(
tmpnode
)
uctrlnode
=
prom_getchild
(
tmpnode
);
p
->
regs
=
of_ioremap
(
&
op
->
resource
[
0
],
0
,
resource_size
(
&
op
->
resource
[
0
]),
"uctrl"
);
if
(
!
p
->
regs
)
{
printk
(
KERN_ERR
"uctrl: Unable to map registers.
\n
"
);
goto
out_free
;
}
uctrlnode
=
prom_searchsiblings
(
uctrlnode
,
"uctrl"
);
p
->
irq
=
op
->
irqs
[
0
];
err
=
request_irq
(
p
->
irq
,
uctrl_interrupt
,
0
,
"uctrl"
,
p
);
if
(
err
)
{
printk
(
KERN_ERR
"uctrl: Unable to register irq.
\n
"
);
goto
out_iounmap
;
}
if
(
!
uctrlnode
)
return
-
ENODEV
;
err
=
misc_register
(
&
uctrl_dev
);
if
(
err
)
{
printk
(
KERN_ERR
"uctrl: Unable to register misc device.
\n
"
);
goto
out_free_irq
;
}
/* the prom mapped it for us */
len
=
prom_getproperty
(
uctrlnode
,
"address"
,
(
void
*
)
vaddr
,
sizeof
(
vaddr
));
driver
->
regs
=
(
struct
uctrl_regs
*
)
vaddr
[
0
];
sbus_writel
(
UCTRL_INTR_RXNE_REQ
|
UCTRL_INTR_RXNE_MSK
,
&
p
->
regs
->
uctrl_intr
);
printk
(
KERN_INFO
"%s: uctrl regs[0x%p] (irq %d)
\n
"
,
op
->
node
->
full_name
,
p
->
regs
,
p
->
irq
);
uctrl_get_event_status
(
p
);
uctrl_get_external_status
(
p
);
len
=
prom_getproperty
(
uctrlnode
,
"intr"
,
(
char
*
)
tmp_irq
,
sizeof
(
tmp_irq
))
;
dev_set_drvdata
(
&
op
->
dev
,
p
);
global_driver
=
p
;
/* Flush device */
READUCTLDATA
(
len
)
;
out:
return
err
;
if
(
!
driver
->
irq
)
driver
->
irq
=
tmp_irq
[
0
].
pri
;
out_free_irq:
free_irq
(
p
->
irq
,
p
)
;
err
=
request_irq
(
driver
->
irq
,
uctrl_interrupt
,
0
,
"uctrl"
,
driver
);
if
(
err
)
{
printk
(
"%s: unable to register irq %d
\n
"
,
__func__
,
driver
->
irq
);
return
err
;
}
out_iounmap:
of_iounmap
(
&
op
->
resource
[
0
],
p
->
regs
,
resource_size
(
&
op
->
resource
[
0
]));
if
(
misc_register
(
&
uctrl_dev
))
{
printk
(
"%s: unable to get misc minor %d
\n
"
,
__func__
,
uctrl_dev
.
minor
);
free_irq
(
driver
->
irq
,
driver
);
return
-
ENODEV
;
}
out_free:
kfree
(
p
);
goto
out
;
}
static
int
__devexit
uctrl_remove
(
struct
of_device
*
op
)
{
struct
uctrl_driver
*
p
=
dev_get_drvdata
(
&
op
->
dev
);
driver
->
regs
->
uctrl_intr
=
UCTRL_INTR_RXNE_REQ
|
UCTRL_INTR_RXNE_MSK
;
printk
(
"uctrl: 0x%p (irq %d)
\n
"
,
driver
->
regs
,
driver
->
irq
);
uctrl_get_event_status
();
uctrl_get_external_status
();
if
(
p
)
{
misc_deregister
(
&
uctrl_dev
);
free_irq
(
p
->
irq
,
p
);
of_iounmap
(
&
op
->
resource
[
0
],
p
->
regs
,
resource_size
(
&
op
->
resource
[
0
]));
kfree
(
p
);
}
return
0
;
}
static
void
__exit
ts102_uctrl_cleanup
(
void
)
static
struct
of_device_id
uctrl_match
[]
=
{
{
.
name
=
"uctrl"
,
},
{},
};
MODULE_DEVICE_TABLE
(
of
,
uctrl_match
);
static
struct
of_platform_driver
uctrl_driver
=
{
.
name
=
"uctrl"
,
.
match_table
=
uctrl_match
,
.
probe
=
uctrl_probe
,
.
remove
=
__devexit_p
(
uctrl_remove
),
};
static
int
__init
uctrl_init
(
void
)
{
struct
uctrl_driver
*
driver
=
&
drv
;
return
of_register_driver
(
&
uctrl_driver
,
&
of_bus_type
);
}
misc_deregister
(
&
uctrl_dev
);
if
(
driver
->
irq
)
free_irq
(
driver
->
irq
,
driver
);
if
(
driver
->
regs
)
driver
->
regs
=
NULL
;
static
void
__exit
uctrl_exit
(
void
)
{
of_unregister_driver
(
&
uctrl_driver
);
}
module_init
(
ts102_
uctrl_init
);
module_exit
(
ts102_uctrl_cleanup
);
module_init
(
uctrl_init
);
module_exit
(
uctrl_exit
);
MODULE_LICENSE
(
"GPL"
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录