Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
fae119b6
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
fae119b6
编写于
10月 02, 2014
作者:
J
Jason Cooper
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'irqchip/gic' into irqchip/core
上级
f7472655
3708d52f
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
66 addition
and
21 deletion
+66
-21
drivers/irqchip/irq-gic-v3.c
drivers/irqchip/irq-gic-v3.c
+66
-21
未找到文件。
drivers/irqchip/irq-gic-v3.c
浏览文件 @
fae119b6
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
*/
*/
#include <linux/cpu.h>
#include <linux/cpu.h>
#include <linux/cpu_pm.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of.h>
...
@@ -155,7 +156,7 @@ static void gic_enable_sre(void)
...
@@ -155,7 +156,7 @@ static void gic_enable_sre(void)
pr_err
(
"GIC: unable to set SRE (disabled at EL2), panic ahead
\n
"
);
pr_err
(
"GIC: unable to set SRE (disabled at EL2), panic ahead
\n
"
);
}
}
static
void
gic_enable_redist
(
void
)
static
void
gic_enable_redist
(
bool
enable
)
{
{
void
__iomem
*
rbase
;
void
__iomem
*
rbase
;
u32
count
=
1000000
;
/* 1s! */
u32
count
=
1000000
;
/* 1s! */
...
@@ -163,20 +164,30 @@ static void gic_enable_redist(void)
...
@@ -163,20 +164,30 @@ static void gic_enable_redist(void)
rbase
=
gic_data_rdist_rd_base
();
rbase
=
gic_data_rdist_rd_base
();
/* Wake up this CPU redistributor */
val
=
readl_relaxed
(
rbase
+
GICR_WAKER
);
val
=
readl_relaxed
(
rbase
+
GICR_WAKER
);
val
&=
~
GICR_WAKER_ProcessorSleep
;
if
(
enable
)
/* Wake up this CPU redistributor */
val
&=
~
GICR_WAKER_ProcessorSleep
;
else
val
|=
GICR_WAKER_ProcessorSleep
;
writel_relaxed
(
val
,
rbase
+
GICR_WAKER
);
writel_relaxed
(
val
,
rbase
+
GICR_WAKER
);
while
(
readl_relaxed
(
rbase
+
GICR_WAKER
)
&
GICR_WAKER_ChildrenAsleep
)
{
if
(
!
enable
)
{
/* Check that GICR_WAKER is writeable */
count
--
;
val
=
readl_relaxed
(
rbase
+
GICR_WAKER
);
if
(
!
count
)
{
if
(
!
(
val
&
GICR_WAKER_ProcessorSleep
))
pr_err_ratelimited
(
"redist didn't wake up...
\n
"
);
return
;
/* No PM support in this redistributor */
return
;
}
}
while
(
count
--
)
{
val
=
readl_relaxed
(
rbase
+
GICR_WAKER
);
if
(
enable
^
(
val
&
GICR_WAKER_ChildrenAsleep
))
break
;
cpu_relax
();
cpu_relax
();
udelay
(
1
);
udelay
(
1
);
};
};
if
(
!
count
)
pr_err_ratelimited
(
"redistributor failed to %s...
\n
"
,
enable
?
"wakeup"
:
"sleep"
);
}
}
/*
/*
...
@@ -372,6 +383,21 @@ static int gic_populate_rdist(void)
...
@@ -372,6 +383,21 @@ static int gic_populate_rdist(void)
return
-
ENODEV
;
return
-
ENODEV
;
}
}
static
void
gic_cpu_sys_reg_init
(
void
)
{
/* Enable system registers */
gic_enable_sre
();
/* Set priority mask register */
gic_write_pmr
(
DEFAULT_PMR_VALUE
);
/* EOI deactivates interrupt too (mode 0) */
gic_write_ctlr
(
ICC_CTLR_EL1_EOImode_drop_dir
);
/* ... and let's hit the road... */
gic_write_grpen1
(
1
);
}
static
void
gic_cpu_init
(
void
)
static
void
gic_cpu_init
(
void
)
{
{
void
__iomem
*
rbase
;
void
__iomem
*
rbase
;
...
@@ -380,23 +406,14 @@ static void gic_cpu_init(void)
...
@@ -380,23 +406,14 @@ static void gic_cpu_init(void)
if
(
gic_populate_rdist
())
if
(
gic_populate_rdist
())
return
;
return
;
gic_enable_redist
();
gic_enable_redist
(
true
);
rbase
=
gic_data_rdist_sgi_base
();
rbase
=
gic_data_rdist_sgi_base
();
gic_cpu_config
(
rbase
,
gic_redist_wait_for_rwp
);
gic_cpu_config
(
rbase
,
gic_redist_wait_for_rwp
);
/* Enable system registers */
/* initialise system registers */
gic_enable_sre
();
gic_cpu_sys_reg_init
();
/* Set priority mask register */
gic_write_pmr
(
DEFAULT_PMR_VALUE
);
/* EOI deactivates interrupt too (mode 0) */
gic_write_ctlr
(
ICC_CTLR_EL1_EOImode_drop_dir
);
/* ... and let's hit the road... */
gic_write_grpen1
(
1
);
}
}
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
...
@@ -532,6 +549,33 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
...
@@ -532,6 +549,33 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
#define gic_smp_init() do { } while(0)
#define gic_smp_init() do { } while(0)
#endif
#endif
#ifdef CONFIG_CPU_PM
static
int
gic_cpu_pm_notifier
(
struct
notifier_block
*
self
,
unsigned
long
cmd
,
void
*
v
)
{
if
(
cmd
==
CPU_PM_EXIT
)
{
gic_enable_redist
(
true
);
gic_cpu_sys_reg_init
();
}
else
if
(
cmd
==
CPU_PM_ENTER
)
{
gic_write_grpen1
(
0
);
gic_enable_redist
(
false
);
}
return
NOTIFY_OK
;
}
static
struct
notifier_block
gic_cpu_pm_notifier_block
=
{
.
notifier_call
=
gic_cpu_pm_notifier
,
};
static
void
gic_cpu_pm_init
(
void
)
{
cpu_pm_register_notifier
(
&
gic_cpu_pm_notifier_block
);
}
#else
static
inline
void
gic_cpu_pm_init
(
void
)
{
}
#endif
/* CONFIG_CPU_PM */
static
struct
irq_chip
gic_chip
=
{
static
struct
irq_chip
gic_chip
=
{
.
name
=
"GICv3"
,
.
name
=
"GICv3"
,
.
irq_mask
=
gic_mask_irq
,
.
irq_mask
=
gic_mask_irq
,
...
@@ -671,6 +715,7 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
...
@@ -671,6 +715,7 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
gic_smp_init
();
gic_smp_init
();
gic_dist_init
();
gic_dist_init
();
gic_cpu_init
();
gic_cpu_init
();
gic_cpu_pm_init
();
return
0
;
return
0
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录