Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
e5e54bc8
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看板
提交
e5e54bc8
编写于
2月 07, 2008
作者:
L
Len Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge branches 'release' and 'stats' into release
上级
70ec75c5
5229e87d
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
325 addition
and
9 deletion
+325
-9
Documentation/ABI/testing/sysfs-firmware-acpi
Documentation/ABI/testing/sysfs-firmware-acpi
+99
-0
drivers/acpi/events/evevent.c
drivers/acpi/events/evevent.c
+1
-1
drivers/acpi/events/evgpe.c
drivers/acpi/events/evgpe.c
+1
-1
drivers/acpi/osl.c
drivers/acpi/osl.c
+11
-1
drivers/acpi/system.c
drivers/acpi/system.c
+208
-0
drivers/acpi/utilities/utglobal.c
drivers/acpi/utilities/utglobal.c
+0
-2
include/acpi/acglobal.h
include/acpi/acglobal.h
+0
-4
include/acpi/acpiosxf.h
include/acpi/acpiosxf.h
+3
-0
include/linux/acpi.h
include/linux/acpi.h
+2
-0
未找到文件。
Documentation/ABI/testing/sysfs-firmware-acpi
0 → 100644
浏览文件 @
e5e54bc8
What: /sys/firmware/acpi/interrupts/
Date: February 2008
Contact: Len Brown <lenb@kernel.org>
Description:
All ACPI interrupts are handled via a single IRQ,
the System Control Interrupt (SCI), which appears
as "acpi" in /proc/interrupts.
However, one of the main functions of ACPI is to make
the platform understand random hardware without
special driver support. So while the SCI handles a few
well known (fixed feature) interrupts sources, such
as the power button, it can also handle a variable
number of a "General Purpose Events" (GPE).
A GPE vectors to a specified handler in AML, which
can do a anything the BIOS writer wants from
OS context. GPE 0x12, for example, would vector
to a level or edge handler called _L12 or _E12.
The handler may do its business and return.
Or the handler may send send a Notify event
to a Linux device driver registered on an ACPI device,
such as a battery, or a processor.
To figure out where all the SCI's are coming from,
/sys/firmware/acpi/interrupts contains a file listing
every possible source, and the count of how many
times it has triggered.
$ cd /sys/firmware/acpi/interrupts
$ grep . *
error:0
ff_gbl_lock:0
ff_pmtimer:0
ff_pwr_btn:0
ff_rt_clk:0
ff_slp_btn:0
gpe00:0
gpe01:0
gpe02:0
gpe03:0
gpe04:0
gpe05:0
gpe06:0
gpe07:0
gpe08:0
gpe09:174
gpe0A:0
gpe0B:0
gpe0C:0
gpe0D:0
gpe0E:0
gpe0F:0
gpe10:0
gpe11:60
gpe12:0
gpe13:0
gpe14:0
gpe15:0
gpe16:0
gpe17:0
gpe18:0
gpe19:7
gpe1A:0
gpe1B:0
gpe1C:0
gpe1D:0
gpe1E:0
gpe1F:0
gpe_all:241
sci:241
sci - The total number of times the ACPI SCI
has claimed an interrupt.
gpe_all - count of SCI caused by GPEs.
gpeXX - count for individual GPE source
ff_gbl_lock - Global Lock
ff_pmtimer - PM Timer
ff_pwr_btn - Power Button
ff_rt_clk - Real Time Clock
ff_slp_btn - Sleep Button
error - an interrupt that can't be accounted for above.
Root has permission to clear any of these counters. Eg.
# echo 0 > gpe11
All counters can be cleared by clearing the total "sci":
# echo 0 > sci
None of these counters has an effect on the function
of the system, they are simply statistics.
drivers/acpi/events/evevent.c
浏览文件 @
e5e54bc8
...
...
@@ -259,7 +259,7 @@ u32 acpi_ev_fixed_event_detect(void)
enable_bit_mask
))
{
/* Found an active (signalled) event */
acpi_os_fixed_event_count
(
i
);
int_status
|=
acpi_ev_fixed_event_dispatch
((
u32
)
i
);
}
}
...
...
drivers/acpi/events/evgpe.c
浏览文件 @
e5e54bc8
...
...
@@ -627,7 +627,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
ACPI_FUNCTION_TRACE
(
ev_gpe_dispatch
);
acpi_
gpe_count
++
;
acpi_
os_gpe_count
(
gpe_number
)
;
/*
* If edge-triggered, clear the GPE status bit now. Note that
...
...
drivers/acpi/osl.c
浏览文件 @
e5e54bc8
...
...
@@ -337,7 +337,15 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
static
irqreturn_t
acpi_irq
(
int
irq
,
void
*
dev_id
)
{
return
(
*
acpi_irq_handler
)
(
acpi_irq_context
)
?
IRQ_HANDLED
:
IRQ_NONE
;
u32
handled
;
handled
=
(
*
acpi_irq_handler
)
(
acpi_irq_context
);
if
(
handled
)
{
acpi_irq_handled
++
;
return
IRQ_HANDLED
;
}
else
return
IRQ_NONE
;
}
acpi_status
...
...
@@ -346,6 +354,8 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
{
unsigned
int
irq
;
acpi_irq_stats_init
();
/*
* Ignore the GSI from the core, and use the value in our copy of the
* FADT. It may not be the same if an interrupt source override exists
...
...
drivers/acpi/system.c
浏览文件 @
e5e54bc8
...
...
@@ -40,6 +40,8 @@ ACPI_MODULE_NAME("system");
#define ACPI_SYSTEM_CLASS "system"
#define ACPI_SYSTEM_DEVICE_NAME "System"
u32
acpi_irq_handled
;
/*
* Make ACPICA version work as module param
*/
...
...
@@ -166,6 +168,212 @@ static int acpi_system_sysfs_init(void)
return
0
;
}
/*
* Detailed ACPI IRQ counters in /sys/firmware/acpi/interrupts/
* See Documentation/ABI/testing/sysfs-firmware-acpi
*/
#define COUNT_GPE 0
#define COUNT_SCI 1
/* acpi_irq_handled */
#define COUNT_ERROR 2
/* other */
#define NUM_COUNTERS_EXTRA 3
static
u32
*
all_counters
;
static
u32
num_gpes
;
static
u32
num_counters
;
static
struct
attribute
**
all_attrs
;
static
u32
acpi_gpe_count
;
static
struct
attribute_group
interrupt_stats_attr_group
=
{
.
name
=
"interrupts"
,
};
static
struct
kobj_attribute
*
counter_attrs
;
static
int
count_num_gpes
(
void
)
{
int
count
=
0
;
struct
acpi_gpe_xrupt_info
*
gpe_xrupt_info
;
struct
acpi_gpe_block_info
*
gpe_block
;
acpi_cpu_flags
flags
;
flags
=
acpi_os_acquire_lock
(
acpi_gbl_gpe_lock
);
gpe_xrupt_info
=
acpi_gbl_gpe_xrupt_list_head
;
while
(
gpe_xrupt_info
)
{
gpe_block
=
gpe_xrupt_info
->
gpe_block_list_head
;
while
(
gpe_block
)
{
count
+=
gpe_block
->
register_count
*
ACPI_GPE_REGISTER_WIDTH
;
gpe_block
=
gpe_block
->
next
;
}
gpe_xrupt_info
=
gpe_xrupt_info
->
next
;
}
acpi_os_release_lock
(
acpi_gbl_gpe_lock
,
flags
);
return
count
;
}
static
void
delete_gpe_attr_array
(
void
)
{
u32
*
tmp
=
all_counters
;
all_counters
=
NULL
;
kfree
(
tmp
);
if
(
counter_attrs
)
{
int
i
;
for
(
i
=
0
;
i
<
num_gpes
;
i
++
)
kfree
(
counter_attrs
[
i
].
attr
.
name
);
kfree
(
counter_attrs
);
}
kfree
(
all_attrs
);
return
;
}
void
acpi_os_gpe_count
(
u32
gpe_number
)
{
acpi_gpe_count
++
;
if
(
!
all_counters
)
return
;
if
(
gpe_number
<
num_gpes
)
all_counters
[
gpe_number
]
++
;
else
all_counters
[
num_gpes
+
ACPI_NUM_FIXED_EVENTS
+
COUNT_ERROR
]
++
;
return
;
}
void
acpi_os_fixed_event_count
(
u32
event_number
)
{
if
(
!
all_counters
)
return
;
if
(
event_number
<
ACPI_NUM_FIXED_EVENTS
)
all_counters
[
num_gpes
+
event_number
]
++
;
else
all_counters
[
num_gpes
+
ACPI_NUM_FIXED_EVENTS
+
COUNT_ERROR
]
++
;
return
;
}
static
ssize_t
counter_show
(
struct
kobject
*
kobj
,
struct
kobj_attribute
*
attr
,
char
*
buf
)
{
all_counters
[
num_gpes
+
ACPI_NUM_FIXED_EVENTS
+
COUNT_SCI
]
=
acpi_irq_handled
;
all_counters
[
num_gpes
+
ACPI_NUM_FIXED_EVENTS
+
COUNT_GPE
]
=
acpi_gpe_count
;
return
sprintf
(
buf
,
"%d
\n
"
,
all_counters
[
attr
-
counter_attrs
]);
}
/*
* counter_set() sets the specified counter.
* setting the total "sci" file to any value clears all counters.
*/
static
ssize_t
counter_set
(
struct
kobject
*
kobj
,
struct
kobj_attribute
*
attr
,
const
char
*
buf
,
size_t
size
)
{
int
index
=
attr
-
counter_attrs
;
if
(
index
==
num_gpes
+
ACPI_NUM_FIXED_EVENTS
+
COUNT_SCI
)
{
int
i
;
for
(
i
=
0
;
i
<
num_counters
;
++
i
)
all_counters
[
i
]
=
0
;
acpi_gpe_count
=
0
;
acpi_irq_handled
=
0
;
}
else
all_counters
[
index
]
=
strtoul
(
buf
,
NULL
,
0
);
return
size
;
}
void
acpi_irq_stats_init
(
void
)
{
int
i
;
if
(
all_counters
)
return
;
num_gpes
=
count_num_gpes
();
num_counters
=
num_gpes
+
ACPI_NUM_FIXED_EVENTS
+
NUM_COUNTERS_EXTRA
;
all_attrs
=
kzalloc
(
sizeof
(
struct
attribute
*
)
*
(
num_counters
+
1
),
GFP_KERNEL
);
if
(
all_attrs
==
NULL
)
return
;
all_counters
=
kzalloc
(
sizeof
(
u32
)
*
(
num_counters
),
GFP_KERNEL
);
if
(
all_counters
==
NULL
)
goto
fail
;
counter_attrs
=
kzalloc
(
sizeof
(
struct
kobj_attribute
)
*
(
num_counters
),
GFP_KERNEL
);
if
(
counter_attrs
==
NULL
)
goto
fail
;
for
(
i
=
0
;
i
<
num_counters
;
++
i
)
{
char
buffer
[
10
];
char
*
name
;
if
(
i
<
num_gpes
)
sprintf
(
buffer
,
"gpe%02X"
,
i
);
else
if
(
i
==
num_gpes
+
ACPI_EVENT_PMTIMER
)
sprintf
(
buffer
,
"ff_pmtimer"
);
else
if
(
i
==
num_gpes
+
ACPI_EVENT_GLOBAL
)
sprintf
(
buffer
,
"ff_gbl_lock"
);
else
if
(
i
==
num_gpes
+
ACPI_EVENT_POWER_BUTTON
)
sprintf
(
buffer
,
"ff_pwr_btn"
);
else
if
(
i
==
num_gpes
+
ACPI_EVENT_SLEEP_BUTTON
)
sprintf
(
buffer
,
"ff_slp_btn"
);
else
if
(
i
==
num_gpes
+
ACPI_EVENT_RTC
)
sprintf
(
buffer
,
"ff_rt_clk"
);
else
if
(
i
==
num_gpes
+
ACPI_NUM_FIXED_EVENTS
+
COUNT_GPE
)
sprintf
(
buffer
,
"gpe_all"
);
else
if
(
i
==
num_gpes
+
ACPI_NUM_FIXED_EVENTS
+
COUNT_SCI
)
sprintf
(
buffer
,
"sci"
);
else
if
(
i
==
num_gpes
+
ACPI_NUM_FIXED_EVENTS
+
COUNT_ERROR
)
sprintf
(
buffer
,
"error"
);
else
sprintf
(
buffer
,
"bug%02X"
,
i
);
name
=
kzalloc
(
strlen
(
buffer
)
+
1
,
GFP_KERNEL
);
if
(
name
==
NULL
)
goto
fail
;
strncpy
(
name
,
buffer
,
strlen
(
buffer
)
+
1
);
counter_attrs
[
i
].
attr
.
name
=
name
;
counter_attrs
[
i
].
attr
.
mode
=
0644
;
counter_attrs
[
i
].
show
=
counter_show
;
counter_attrs
[
i
].
store
=
counter_set
;
all_attrs
[
i
]
=
&
counter_attrs
[
i
].
attr
;
}
interrupt_stats_attr_group
.
attrs
=
all_attrs
;
sysfs_create_group
(
acpi_kobj
,
&
interrupt_stats_attr_group
);
return
;
fail:
delete_gpe_attr_array
();
return
;
}
static
void
__exit
interrupt_stats_exit
(
void
)
{
sysfs_remove_group
(
acpi_kobj
,
&
interrupt_stats_attr_group
);
delete_gpe_attr_array
();
return
;
}
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
...
...
drivers/acpi/utilities/utglobal.c
浏览文件 @
e5e54bc8
...
...
@@ -671,7 +671,6 @@ void acpi_ut_init_globals(void)
/* GPE support */
acpi_gpe_count
=
0
;
acpi_gbl_gpe_xrupt_list_head
=
NULL
;
acpi_gbl_gpe_fadt_blocks
[
0
]
=
NULL
;
acpi_gbl_gpe_fadt_blocks
[
1
]
=
NULL
;
...
...
@@ -735,4 +734,3 @@ void acpi_ut_init_globals(void)
ACPI_EXPORT_SYMBOL
(
acpi_dbg_level
)
ACPI_EXPORT_SYMBOL
(
acpi_dbg_layer
)
ACPI_EXPORT_SYMBOL
(
acpi_gpe_count
)
include/acpi/acglobal.h
浏览文件 @
e5e54bc8
...
...
@@ -117,10 +117,6 @@ extern u32 acpi_dbg_layer;
extern
u32
acpi_gbl_nesting_level
;
/* Event counters */
ACPI_EXTERN
u32
acpi_gpe_count
;
/* Support for dynamic control method tracing mechanism */
ACPI_EXTERN
u32
acpi_gbl_original_dbg_level
;
...
...
include/acpi/acpiosxf.h
浏览文件 @
e5e54bc8
...
...
@@ -181,6 +181,9 @@ acpi_os_install_interrupt_handler(u32 gsi,
acpi_status
acpi_os_remove_interrupt_handler
(
u32
gsi
,
acpi_osd_handler
service_routine
);
void
acpi_os_gpe_count
(
u32
gpe_number
);
void
acpi_os_fixed_event_count
(
u32
fixed_event_number
);
/*
* Threads and Scheduling
*/
...
...
include/linux/acpi.h
浏览文件 @
e5e54bc8
...
...
@@ -114,7 +114,9 @@ int acpi_unmap_lsapic(int cpu);
int
acpi_register_ioapic
(
acpi_handle
handle
,
u64
phys_addr
,
u32
gsi_base
);
int
acpi_unregister_ioapic
(
acpi_handle
handle
,
u32
gsi_base
);
void
acpi_irq_stats_init
(
void
);
extern
u32
acpi_irq_handled
;
extern
int
acpi_mp_config
;
extern
struct
acpi_mcfg_allocation
*
pci_mmcfg_config
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录