Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
7896cd0f
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看板
提交
7896cd0f
编写于
2月 09, 2010
作者:
P
Paul Mundt
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'sh/intc-extension'
上级
7561f2dd
d5190953
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
194 addition
and
69 deletion
+194
-69
drivers/sh/intc.c
drivers/sh/intc.c
+173
-58
include/linux/sh_intc.h
include/linux/sh_intc.h
+21
-11
未找到文件。
drivers/sh/intc.c
浏览文件 @
7896cd0f
...
...
@@ -259,6 +259,43 @@ static void intc_disable(unsigned int irq)
}
}
static
void
(
*
intc_enable_noprio_fns
[])(
unsigned
long
addr
,
unsigned
long
handle
,
void
(
*
fn
)(
unsigned
long
,
unsigned
long
,
unsigned
long
),
unsigned
int
irq
)
=
{
[
MODE_ENABLE_REG
]
=
intc_mode_field
,
[
MODE_MASK_REG
]
=
intc_mode_zero
,
[
MODE_DUAL_REG
]
=
intc_mode_field
,
[
MODE_PRIO_REG
]
=
intc_mode_field
,
[
MODE_PCLR_REG
]
=
intc_mode_field
,
};
static
void
intc_enable_disable
(
struct
intc_desc_int
*
d
,
unsigned
long
handle
,
int
do_enable
)
{
unsigned
long
addr
;
unsigned
int
cpu
;
void
(
*
fn
)(
unsigned
long
,
unsigned
long
,
void
(
*
)(
unsigned
long
,
unsigned
long
,
unsigned
long
),
unsigned
int
);
if
(
do_enable
)
{
for
(
cpu
=
0
;
cpu
<
SMP_NR
(
d
,
_INTC_ADDR_E
(
handle
));
cpu
++
)
{
addr
=
INTC_REG
(
d
,
_INTC_ADDR_E
(
handle
),
cpu
);
fn
=
intc_enable_noprio_fns
[
_INTC_MODE
(
handle
)];
fn
(
addr
,
handle
,
intc_reg_fns
[
_INTC_FN
(
handle
)],
0
);
}
}
else
{
for
(
cpu
=
0
;
cpu
<
SMP_NR
(
d
,
_INTC_ADDR_D
(
handle
));
cpu
++
)
{
addr
=
INTC_REG
(
d
,
_INTC_ADDR_D
(
handle
),
cpu
);
fn
=
intc_disable_fns
[
_INTC_MODE
(
handle
)];
fn
(
addr
,
handle
,
intc_reg_fns
[
_INTC_FN
(
handle
)],
0
);
}
}
}
static
int
intc_set_wake
(
unsigned
int
irq
,
unsigned
int
on
)
{
return
0
;
/* allow wakeup, but setup hardware in intc_suspend() */
...
...
@@ -400,11 +437,11 @@ static unsigned int __init intc_get_reg(struct intc_desc_int *d,
static
intc_enum
__init
intc_grp_id
(
struct
intc_desc
*
desc
,
intc_enum
enum_id
)
{
struct
intc_group
*
g
=
desc
->
groups
;
struct
intc_group
*
g
=
desc
->
hw
.
groups
;
unsigned
int
i
,
j
;
for
(
i
=
0
;
g
&&
enum_id
&&
i
<
desc
->
nr_groups
;
i
++
)
{
g
=
desc
->
groups
+
i
;
for
(
i
=
0
;
g
&&
enum_id
&&
i
<
desc
->
hw
.
nr_groups
;
i
++
)
{
g
=
desc
->
hw
.
groups
+
i
;
for
(
j
=
0
;
g
->
enum_ids
[
j
];
j
++
)
{
if
(
g
->
enum_ids
[
j
]
!=
enum_id
)
...
...
@@ -417,19 +454,21 @@ static intc_enum __init intc_grp_id(struct intc_desc *desc,
return
0
;
}
static
unsigned
int
__init
intc_mask_data
(
struct
intc_desc
*
desc
,
struct
intc_desc_int
*
d
,
intc_enum
enum_id
,
int
do_grps
)
static
unsigned
int
__init
_intc_mask_data
(
struct
intc_desc
*
desc
,
struct
intc_desc_int
*
d
,
intc_enum
enum_id
,
unsigned
int
*
reg_idx
,
unsigned
int
*
fld_idx
)
{
struct
intc_mask_reg
*
mr
=
desc
->
mask_regs
;
unsigned
int
i
,
j
,
fn
,
mode
;
struct
intc_mask_reg
*
mr
=
desc
->
hw
.
mask_regs
;
unsigned
int
fn
,
mode
;
unsigned
long
reg_e
,
reg_d
;
for
(
i
=
0
;
mr
&&
enum_id
&&
i
<
desc
->
nr_mask_regs
;
i
++
)
{
mr
=
desc
->
mask_regs
+
i
;
while
(
mr
&&
enum_id
&&
*
reg_idx
<
desc
->
hw
.
nr_mask_regs
)
{
mr
=
desc
->
hw
.
mask_regs
+
*
reg_idx
;
for
(
j
=
0
;
j
<
ARRAY_SIZE
(
mr
->
enum_ids
);
j
++
)
{
if
(
mr
->
enum_ids
[
j
]
!=
enum_id
)
for
(
;
*
fld_idx
<
ARRAY_SIZE
(
mr
->
enum_ids
);
(
*
fld_idx
)
++
)
{
if
(
mr
->
enum_ids
[
*
fld_idx
]
!=
enum_id
)
continue
;
if
(
mr
->
set_reg
&&
mr
->
clr_reg
)
{
...
...
@@ -455,29 +494,49 @@ static unsigned int __init intc_mask_data(struct intc_desc *desc,
intc_get_reg
(
d
,
reg_e
),
intc_get_reg
(
d
,
reg_d
),
1
,
(
mr
->
reg_width
-
1
)
-
j
);
(
mr
->
reg_width
-
1
)
-
*
fld_idx
);
}
*
fld_idx
=
0
;
(
*
reg_idx
)
++
;
}
return
0
;
}
static
unsigned
int
__init
intc_mask_data
(
struct
intc_desc
*
desc
,
struct
intc_desc_int
*
d
,
intc_enum
enum_id
,
int
do_grps
)
{
unsigned
int
i
=
0
;
unsigned
int
j
=
0
;
unsigned
int
ret
;
ret
=
_intc_mask_data
(
desc
,
d
,
enum_id
,
&
i
,
&
j
);
if
(
ret
)
return
ret
;
if
(
do_grps
)
return
intc_mask_data
(
desc
,
d
,
intc_grp_id
(
desc
,
enum_id
),
0
);
return
0
;
}
static
unsigned
int
__init
intc_prio_data
(
struct
intc_desc
*
desc
,
struct
intc_desc_int
*
d
,
intc_enum
enum_id
,
int
do_grps
)
static
unsigned
int
__init
_intc_prio_data
(
struct
intc_desc
*
desc
,
struct
intc_desc_int
*
d
,
intc_enum
enum_id
,
unsigned
int
*
reg_idx
,
unsigned
int
*
fld_idx
)
{
struct
intc_prio_reg
*
pr
=
desc
->
prio_regs
;
unsigned
int
i
,
j
,
f
n
,
mode
,
bit
;
struct
intc_prio_reg
*
pr
=
desc
->
hw
.
prio_regs
;
unsigned
int
fn
,
n
,
mode
,
bit
;
unsigned
long
reg_e
,
reg_d
;
for
(
i
=
0
;
pr
&&
enum_id
&&
i
<
desc
->
nr_prio_regs
;
i
++
)
{
pr
=
desc
->
prio_regs
+
i
;
while
(
pr
&&
enum_id
&&
*
reg_idx
<
desc
->
hw
.
nr_prio_regs
)
{
pr
=
desc
->
hw
.
prio_regs
+
*
reg_idx
;
for
(
j
=
0
;
j
<
ARRAY_SIZE
(
pr
->
enum_ids
);
j
++
)
{
if
(
pr
->
enum_ids
[
j
]
!=
enum_id
)
for
(
;
*
fld_idx
<
ARRAY_SIZE
(
pr
->
enum_ids
);
(
*
fld_idx
)
++
)
{
if
(
pr
->
enum_ids
[
*
fld_idx
]
!=
enum_id
)
continue
;
if
(
pr
->
set_reg
&&
pr
->
clr_reg
)
{
...
...
@@ -495,34 +554,79 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc,
}
fn
+=
(
pr
->
reg_width
>>
3
)
-
1
;
n
=
*
fld_idx
+
1
;
BUG_ON
(
(
j
+
1
)
*
pr
->
field_width
>
pr
->
reg_width
);
BUG_ON
(
n
*
pr
->
field_width
>
pr
->
reg_width
);
bit
=
pr
->
reg_width
-
(
(
j
+
1
)
*
pr
->
field_width
);
bit
=
pr
->
reg_width
-
(
n
*
pr
->
field_width
);
return
_INTC_MK
(
fn
,
mode
,
intc_get_reg
(
d
,
reg_e
),
intc_get_reg
(
d
,
reg_d
),
pr
->
field_width
,
bit
);
}
*
fld_idx
=
0
;
(
*
reg_idx
)
++
;
}
return
0
;
}
static
unsigned
int
__init
intc_prio_data
(
struct
intc_desc
*
desc
,
struct
intc_desc_int
*
d
,
intc_enum
enum_id
,
int
do_grps
)
{
unsigned
int
i
=
0
;
unsigned
int
j
=
0
;
unsigned
int
ret
;
ret
=
_intc_prio_data
(
desc
,
d
,
enum_id
,
&
i
,
&
j
);
if
(
ret
)
return
ret
;
if
(
do_grps
)
return
intc_prio_data
(
desc
,
d
,
intc_grp_id
(
desc
,
enum_id
),
0
);
return
0
;
}
static
void
__init
intc_enable_disable_enum
(
struct
intc_desc
*
desc
,
struct
intc_desc_int
*
d
,
intc_enum
enum_id
,
int
enable
)
{
unsigned
int
i
,
j
,
data
;
/* go through and enable/disable all mask bits */
i
=
j
=
0
;
do
{
data
=
_intc_mask_data
(
desc
,
d
,
enum_id
,
&
i
,
&
j
);
if
(
data
)
intc_enable_disable
(
d
,
data
,
enable
);
j
++
;
}
while
(
data
);
/* go through and enable/disable all priority fields */
i
=
j
=
0
;
do
{
data
=
_intc_prio_data
(
desc
,
d
,
enum_id
,
&
i
,
&
j
);
if
(
data
)
intc_enable_disable
(
d
,
data
,
enable
);
j
++
;
}
while
(
data
);
}
static
unsigned
int
__init
intc_ack_data
(
struct
intc_desc
*
desc
,
struct
intc_desc_int
*
d
,
intc_enum
enum_id
)
{
struct
intc_mask_reg
*
mr
=
desc
->
ack_regs
;
struct
intc_mask_reg
*
mr
=
desc
->
hw
.
ack_regs
;
unsigned
int
i
,
j
,
fn
,
mode
;
unsigned
long
reg_e
,
reg_d
;
for
(
i
=
0
;
mr
&&
enum_id
&&
i
<
desc
->
nr_ack_regs
;
i
++
)
{
mr
=
desc
->
ack_regs
+
i
;
for
(
i
=
0
;
mr
&&
enum_id
&&
i
<
desc
->
hw
.
nr_ack_regs
;
i
++
)
{
mr
=
desc
->
hw
.
ack_regs
+
i
;
for
(
j
=
0
;
j
<
ARRAY_SIZE
(
mr
->
enum_ids
);
j
++
)
{
if
(
mr
->
enum_ids
[
j
]
!=
enum_id
)
...
...
@@ -549,11 +653,11 @@ static unsigned int __init intc_sense_data(struct intc_desc *desc,
struct
intc_desc_int
*
d
,
intc_enum
enum_id
)
{
struct
intc_sense_reg
*
sr
=
desc
->
sense_regs
;
struct
intc_sense_reg
*
sr
=
desc
->
hw
.
sense_regs
;
unsigned
int
i
,
j
,
fn
,
bit
;
for
(
i
=
0
;
sr
&&
enum_id
&&
i
<
desc
->
nr_sense_regs
;
i
++
)
{
sr
=
desc
->
sense_regs
+
i
;
for
(
i
=
0
;
sr
&&
enum_id
&&
i
<
desc
->
hw
.
nr_sense_regs
;
i
++
)
{
sr
=
desc
->
hw
.
sense_regs
+
i
;
for
(
j
=
0
;
j
<
ARRAY_SIZE
(
sr
->
enum_ids
);
j
++
)
{
if
(
sr
->
enum_ids
[
j
]
!=
enum_id
)
...
...
@@ -656,7 +760,7 @@ static void __init intc_register_irq(struct intc_desc *desc,
/* irq should be disabled by default */
d
->
chip
.
mask
(
irq
);
if
(
desc
->
ack_regs
)
if
(
desc
->
hw
.
ack_regs
)
ack_handle
[
irq
]
=
intc_ack_data
(
desc
,
d
,
enum_id
);
}
...
...
@@ -684,6 +788,7 @@ static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc)
void
__init
register_intc_controller
(
struct
intc_desc
*
desc
)
{
unsigned
int
i
,
k
,
smp
;
struct
intc_hw_desc
*
hw
=
&
desc
->
hw
;
struct
intc_desc_int
*
d
;
d
=
kzalloc
(
sizeof
(
*
d
),
GFP_NOWAIT
);
...
...
@@ -691,10 +796,10 @@ void __init register_intc_controller(struct intc_desc *desc)
INIT_LIST_HEAD
(
&
d
->
list
);
list_add
(
&
d
->
list
,
&
intc_list
);
d
->
nr_reg
=
desc
->
mask_regs
?
desc
->
nr_mask_regs
*
2
:
0
;
d
->
nr_reg
+=
desc
->
prio_regs
?
desc
->
nr_prio_regs
*
2
:
0
;
d
->
nr_reg
+=
desc
->
sense_regs
?
desc
->
nr_sense_regs
:
0
;
d
->
nr_reg
+=
desc
->
ack_regs
?
desc
->
nr_ack_regs
:
0
;
d
->
nr_reg
=
hw
->
mask_regs
?
hw
->
nr_mask_regs
*
2
:
0
;
d
->
nr_reg
+=
hw
->
prio_regs
?
hw
->
nr_prio_regs
*
2
:
0
;
d
->
nr_reg
+=
hw
->
sense_regs
?
hw
->
nr_sense_regs
:
0
;
d
->
nr_reg
+=
hw
->
ack_regs
?
hw
->
nr_ack_regs
:
0
;
d
->
reg
=
kzalloc
(
d
->
nr_reg
*
sizeof
(
*
d
->
reg
),
GFP_NOWAIT
);
#ifdef CONFIG_SMP
...
...
@@ -702,30 +807,31 @@ void __init register_intc_controller(struct intc_desc *desc)
#endif
k
=
0
;
if
(
desc
->
mask_regs
)
{
for
(
i
=
0
;
i
<
desc
->
nr_mask_regs
;
i
++
)
{
smp
=
IS_SMP
(
desc
->
mask_regs
[
i
]);
k
+=
save_reg
(
d
,
k
,
desc
->
mask_regs
[
i
].
set_reg
,
smp
);
k
+=
save_reg
(
d
,
k
,
desc
->
mask_regs
[
i
].
clr_reg
,
smp
);
if
(
hw
->
mask_regs
)
{
for
(
i
=
0
;
i
<
hw
->
nr_mask_regs
;
i
++
)
{
smp
=
IS_SMP
(
hw
->
mask_regs
[
i
]);
k
+=
save_reg
(
d
,
k
,
hw
->
mask_regs
[
i
].
set_reg
,
smp
);
k
+=
save_reg
(
d
,
k
,
hw
->
mask_regs
[
i
].
clr_reg
,
smp
);
}
}
if
(
desc
->
prio_regs
)
{
d
->
prio
=
kzalloc
(
desc
->
nr_vectors
*
sizeof
(
*
d
->
prio
),
GFP_NOWAIT
);
if
(
hw
->
prio_regs
)
{
d
->
prio
=
kzalloc
(
hw
->
nr_vectors
*
sizeof
(
*
d
->
prio
),
GFP_NOWAIT
);
for
(
i
=
0
;
i
<
desc
->
nr_prio_regs
;
i
++
)
{
smp
=
IS_SMP
(
desc
->
prio_regs
[
i
]);
k
+=
save_reg
(
d
,
k
,
desc
->
prio_regs
[
i
].
set_reg
,
smp
);
k
+=
save_reg
(
d
,
k
,
desc
->
prio_regs
[
i
].
clr_reg
,
smp
);
for
(
i
=
0
;
i
<
hw
->
nr_prio_regs
;
i
++
)
{
smp
=
IS_SMP
(
hw
->
prio_regs
[
i
]);
k
+=
save_reg
(
d
,
k
,
hw
->
prio_regs
[
i
].
set_reg
,
smp
);
k
+=
save_reg
(
d
,
k
,
hw
->
prio_regs
[
i
].
clr_reg
,
smp
);
}
}
if
(
desc
->
sense_regs
)
{
d
->
sense
=
kzalloc
(
desc
->
nr_vectors
*
sizeof
(
*
d
->
sense
),
GFP_NOWAIT
);
if
(
hw
->
sense_regs
)
{
d
->
sense
=
kzalloc
(
hw
->
nr_vectors
*
sizeof
(
*
d
->
sense
),
GFP_NOWAIT
);
for
(
i
=
0
;
i
<
desc
->
nr_sense_regs
;
i
++
)
{
k
+=
save_reg
(
d
,
k
,
desc
->
sense_regs
[
i
].
reg
,
0
);
}
for
(
i
=
0
;
i
<
hw
->
nr_sense_regs
;
i
++
)
k
+=
save_reg
(
d
,
k
,
hw
->
sense_regs
[
i
].
reg
,
0
);
}
d
->
chip
.
name
=
desc
->
name
;
...
...
@@ -738,18 +844,23 @@ void __init register_intc_controller(struct intc_desc *desc)
d
->
chip
.
set_type
=
intc_set_sense
;
d
->
chip
.
set_wake
=
intc_set_wake
;
if
(
desc
->
ack_regs
)
{
for
(
i
=
0
;
i
<
desc
->
nr_ack_regs
;
i
++
)
k
+=
save_reg
(
d
,
k
,
desc
->
ack_regs
[
i
].
set_reg
,
0
);
if
(
hw
->
ack_regs
)
{
for
(
i
=
0
;
i
<
hw
->
nr_ack_regs
;
i
++
)
k
+=
save_reg
(
d
,
k
,
hw
->
ack_regs
[
i
].
set_reg
,
0
);
d
->
chip
.
mask_ack
=
intc_mask_ack
;
}
/* disable bits matching force_enable before registering irqs */
if
(
desc
->
force_enable
)
intc_enable_disable_enum
(
desc
,
d
,
desc
->
force_enable
,
0
);
BUG_ON
(
k
>
256
);
/* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */
/* register the vectors one by one */
for
(
i
=
0
;
i
<
desc
->
nr_vectors
;
i
++
)
{
struct
intc_vect
*
vect
=
desc
->
vectors
+
i
;
for
(
i
=
0
;
i
<
hw
->
nr_vectors
;
i
++
)
{
struct
intc_vect
*
vect
=
hw
->
vectors
+
i
;
unsigned
int
irq
=
evt2irq
(
vect
->
vect
);
struct
irq_desc
*
irq_desc
;
...
...
@@ -764,8 +875,8 @@ void __init register_intc_controller(struct intc_desc *desc)
intc_register_irq
(
desc
,
d
,
vect
->
enum_id
,
irq
);
for
(
k
=
i
+
1
;
k
<
desc
->
nr_vectors
;
k
++
)
{
struct
intc_vect
*
vect2
=
desc
->
vectors
+
k
;
for
(
k
=
i
+
1
;
k
<
hw
->
nr_vectors
;
k
++
)
{
struct
intc_vect
*
vect2
=
hw
->
vectors
+
k
;
unsigned
int
irq2
=
evt2irq
(
vect2
->
vect
);
if
(
vect
->
enum_id
!=
vect2
->
enum_id
)
...
...
@@ -790,6 +901,10 @@ void __init register_intc_controller(struct intc_desc *desc)
set_irq_data
(
irq2
,
(
void
*
)
irq
);
}
}
/* enable bits matching force_enable after registering irqs */
if
(
desc
->
force_enable
)
intc_enable_disable_enum
(
desc
,
d
,
desc
->
force_enable
,
1
);
}
static
int
intc_suspend
(
struct
sys_device
*
dev
,
pm_message_t
state
)
...
...
include/linux/sh_intc.h
浏览文件 @
7896cd0f
...
...
@@ -45,7 +45,7 @@ struct intc_sense_reg {
#define INTC_SMP(stride, nr)
#endif
struct
intc_desc
{
struct
intc_
hw_
desc
{
struct
intc_vect
*
vectors
;
unsigned
int
nr_vectors
;
struct
intc_group
*
groups
;
...
...
@@ -56,29 +56,39 @@ struct intc_desc {
unsigned
int
nr_prio_regs
;
struct
intc_sense_reg
*
sense_regs
;
unsigned
int
nr_sense_regs
;
char
*
name
;
struct
intc_mask_reg
*
ack_regs
;
unsigned
int
nr_ack_regs
;
};
#define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a)
#define INTC_HW_DESC(vectors, groups, mask_regs, \
prio_regs, sense_regs, ack_regs) \
{ \
_INTC_ARRAY(vectors), _INTC_ARRAY(groups), \
_INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \
_INTC_ARRAY(sense_regs), _INTC_ARRAY(ack_regs), \
}
struct
intc_desc
{
char
*
name
;
intc_enum
force_enable
;
struct
intc_hw_desc
hw
;
};
#define DECLARE_INTC_DESC(symbol, chipname, vectors, groups, \
mask_regs, prio_regs, sense_regs) \
struct intc_desc symbol __initdata = { \
_INTC_ARRAY(vectors), _INTC_ARRAY(groups), \
_INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \
_INTC_ARRAY(sense_regs), \
chipname, \
.name = chipname, \
.hw = INTC_HW_DESC(vectors, groups, mask_regs, \
prio_regs, sense_regs, NULL), \
}
#define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \
mask_regs, prio_regs, sense_regs, ack_regs) \
struct intc_desc symbol __initdata = { \
_INTC_ARRAY(vectors), _INTC_ARRAY(groups), \
_INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \
_INTC_ARRAY(sense_regs), \
chipname, \
_INTC_ARRAY(ack_regs), \
.name = chipname, \
.hw = INTC_HW_DESC(vectors, groups, mask_regs, \
prio_regs, sense_regs, ack_regs), \
}
void
__init
register_intc_controller
(
struct
intc_desc
*
desc
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录