Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
35d48993
Commit
35d48993
authored
Feb 27, 2003
by
Andy Grover
Browse files
Options
Browse Files
Download
Plain Diff
Merge groveronline.com:/root/bk/linux-2.5
into groveronline.com:/root/bk/linux-acpi
parents
63ac2a63
6ad53b6d
Changes
39
Hide whitespace changes
Inline
Side-by-side
Showing
39 changed files
with
1455 additions
and
1059 deletions
+1455
-1059
Documentation/kernel-parameters.txt
Documentation/kernel-parameters.txt
+8
-0
arch/i386/kernel/acpi/wakeup.S
arch/i386/kernel/acpi/wakeup.S
+25
-0
arch/i386/kernel/setup.c
arch/i386/kernel/setup.c
+6
-0
drivers/acpi/Kconfig
drivers/acpi/Kconfig
+1
-0
drivers/acpi/acpi_ksyms.c
drivers/acpi/acpi_ksyms.c
+2
-0
drivers/acpi/ec.c
drivers/acpi/ec.c
+40
-33
drivers/acpi/events/Makefile
drivers/acpi/events/Makefile
+1
-1
drivers/acpi/events/evevent.c
drivers/acpi/events/evevent.c
+1
-11
drivers/acpi/events/evgpe.c
drivers/acpi/events/evgpe.c
+116
-461
drivers/acpi/events/evgpeblk.c
drivers/acpi/events/evgpeblk.c
+545
-0
drivers/acpi/events/evmisc.c
drivers/acpi/events/evmisc.c
+21
-95
drivers/acpi/events/evsci.c
drivers/acpi/events/evsci.c
+2
-16
drivers/acpi/events/evxface.c
drivers/acpi/events/evxface.c
+17
-17
drivers/acpi/events/evxfevnt.c
drivers/acpi/events/evxfevnt.c
+18
-9
drivers/acpi/hardware/hwgpe.c
drivers/acpi/hardware/hwgpe.c
+76
-91
drivers/acpi/hardware/hwregs.c
drivers/acpi/hardware/hwregs.c
+8
-5
drivers/acpi/hardware/hwsleep.c
drivers/acpi/hardware/hwsleep.c
+53
-8
drivers/acpi/osl.c
drivers/acpi/osl.c
+34
-7
drivers/acpi/pci_link.c
drivers/acpi/pci_link.c
+78
-73
drivers/acpi/processor.c
drivers/acpi/processor.c
+14
-11
drivers/acpi/resources/rsutils.c
drivers/acpi/resources/rsutils.c
+54
-0
drivers/acpi/resources/rsxface.c
drivers/acpi/resources/rsxface.c
+145
-0
drivers/acpi/sleep/main.c
drivers/acpi/sleep/main.c
+26
-5
drivers/acpi/sleep/proc.c
drivers/acpi/sleep/proc.c
+4
-1
drivers/acpi/tables.c
drivers/acpi/tables.c
+28
-18
drivers/acpi/tables/tbconvrt.c
drivers/acpi/tables/tbconvrt.c
+5
-5
drivers/acpi/utilities/utcopy.c
drivers/acpi/utilities/utcopy.c
+4
-4
drivers/acpi/utilities/utglobal.c
drivers/acpi/utilities/utglobal.c
+4
-2
drivers/hotplug/acpiphp_glue.c
drivers/hotplug/acpiphp_glue.c
+46
-124
include/acpi/acconfig.h
include/acpi/acconfig.h
+1
-1
include/acpi/acdebug.h
include/acpi/acdebug.h
+7
-0
include/acpi/acevents.h
include/acpi/acevents.h
+5
-13
include/acpi/acglobal.h
include/acpi/acglobal.h
+1
-16
include/acpi/achware.h
include/acpi/achware.h
+5
-9
include/acpi/aclocal.h
include/acpi/aclocal.h
+24
-23
include/acpi/acpixf.h
include/acpi/acpixf.h
+21
-0
include/acpi/acresrc.h
include/acpi/acresrc.h
+6
-0
include/acpi/acutils.h
include/acpi/acutils.h
+2
-0
include/linux/suspend.h
include/linux/suspend.h
+1
-0
No files found.
Documentation/kernel-parameters.txt
View file @
35d48993
...
...
@@ -516,6 +516,14 @@ running once the system is up.
[KNL,BOOT] Force usage of a specific region of memory
Region of memory to be used, from ss to ss+nn.
mem=nn[KMG]#ss[KMG]
[KNL,BOOT,ACPI] Mark specific memory as ACPI data.
Region of memory to be used, from ss to ss+nn.
mem=nn[KMG]$ss[KMG]
[KNL,BOOT,ACPI] Mark specific memory as reserved.
Region of memory to be used, from ss to ss+nn.
mem=nopentium [BUGS=IA-32] Disable usage of 4MB pages for kernel
memory.
...
...
arch/i386/kernel/acpi/wakeup.S
View file @
35d48993
...
...
@@ -319,6 +319,31 @@ ret_point:
pushl
saved_context_eflags
; popfl
ret
ENTRY
(
do_suspend_lowlevel_s4bios
)
cmpl
$
0
,
4
(%
esp
)
jne
ret_point
call
save_processor_state
movl
%
esp
,
saved_context_esp
movl
%
eax
,
saved_context_eax
movl
%
ebx
,
saved_context_ebx
movl
%
ecx
,
saved_context_ecx
movl
%
edx
,
saved_context_edx
movl
%
ebp
,
saved_context_ebp
movl
%
esi
,
saved_context_esi
movl
%
edi
,
saved_context_edi
pushfl
; popl saved_context_eflags
movl
$ret_point
,
saved_eip
movl
%
esp
,
saved_esp
movl
%
ebp
,
saved_ebp
movl
%
ebx
,
saved_ebx
movl
%
edi
,
saved_edi
movl
%
esi
,
saved_esi
call
acpi_enter_sleep_state_s4bios
ret
ALIGN
#
saved
registers
saved_gdt
:
.
long
0
,
0
...
...
arch/i386/kernel/setup.c
View file @
35d48993
...
...
@@ -552,6 +552,12 @@ static void __init parse_cmdline_early (char ** cmdline_p)
if
(
*
from
==
'@'
)
{
start_at
=
memparse
(
from
+
1
,
&
from
);
add_memory_region
(
start_at
,
mem_size
,
E820_RAM
);
}
else
if
(
*
from
==
'#'
)
{
start_at
=
memparse
(
from
+
1
,
&
from
);
add_memory_region
(
start_at
,
mem_size
,
E820_ACPI
);
}
else
if
(
*
from
==
'$'
)
{
start_at
=
memparse
(
from
+
1
,
&
from
);
add_memory_region
(
start_at
,
mem_size
,
E820_RESERVED
);
}
else
{
limit_regions
(
mem_size
);
userdef
=
1
;
...
...
drivers/acpi/Kconfig
View file @
35d48993
...
...
@@ -6,6 +6,7 @@ menu "ACPI Support"
config ACPI
bool "ACPI Support" if X86
depends on !X86_VISWS
default y if IA64 && (!IA64_HP_SIM || IA64_SGI_SN)
---help---
Advanced Configuration and Power Interface (ACPI) support for
...
...
drivers/acpi/acpi_ksyms.c
View file @
35d48993
...
...
@@ -76,6 +76,7 @@ EXPORT_SYMBOL(acpi_acquire_global_lock);
EXPORT_SYMBOL
(
acpi_release_global_lock
);
EXPORT_SYMBOL
(
acpi_get_current_resources
);
EXPORT_SYMBOL
(
acpi_get_possible_resources
);
EXPORT_SYMBOL
(
acpi_walk_resources
);
EXPORT_SYMBOL
(
acpi_set_current_resources
);
EXPORT_SYMBOL
(
acpi_enable_event
);
EXPORT_SYMBOL
(
acpi_disable_event
);
...
...
@@ -86,6 +87,7 @@ EXPORT_SYMBOL(acpi_get_sleep_type_data);
EXPORT_SYMBOL
(
acpi_get_register
);
EXPORT_SYMBOL
(
acpi_set_register
);
EXPORT_SYMBOL
(
acpi_enter_sleep_state
);
EXPORT_SYMBOL
(
acpi_enter_sleep_state_s4bios
);
EXPORT_SYMBOL
(
acpi_get_system_info
);
EXPORT_SYMBOL
(
acpi_get_devices
);
...
...
drivers/acpi/ec.c
View file @
35d48993
...
...
@@ -644,15 +644,46 @@ acpi_ec_remove (
}
static
acpi_status
acpi_ec_io_ports
(
struct
acpi_resource
*
resource
,
void
*
context
)
{
struct
acpi_ec
*
ec
=
(
struct
acpi_ec
*
)
context
;
struct
acpi_generic_address
*
addr
;
if
(
resource
->
id
!=
ACPI_RSTYPE_IO
)
{
return
AE_OK
;
}
/*
* The first address region returned is the data port, and
* the second address region returned is the status/command
* port.
*/
if
(
ec
->
data_addr
.
register_bit_width
==
0
)
{
addr
=
&
ec
->
data_addr
;
}
else
if
(
ec
->
command_addr
.
register_bit_width
==
0
)
{
addr
=
&
ec
->
command_addr
;
}
else
{
return
AE_CTRL_TERMINATE
;
}
addr
->
address_space_id
=
ACPI_ADR_SPACE_SYSTEM_IO
;
addr
->
register_bit_width
=
8
;
addr
->
register_bit_offset
=
0
;
addr
->
address
=
resource
->
data
.
io
.
min_base_address
;
return
AE_OK
;
}
static
int
acpi_ec_start
(
struct
acpi_device
*
device
)
{
int
result
=
0
;
acpi_status
status
=
AE_OK
;
struct
acpi_ec
*
ec
=
NULL
;
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
struct
acpi_resource
*
resource
=
NULL
;
ACPI_FUNCTION_TRACE
(
"acpi_ec_start"
);
...
...
@@ -667,33 +698,13 @@ acpi_ec_start (
/*
* Get I/O port addresses. Convert to GAS format.
*/
status
=
acpi_get_current_resources
(
ec
->
handle
,
&
buffer
);
if
(
ACPI_FAILURE
(
status
))
{
status
=
acpi_walk_resources
(
ec
->
handle
,
METHOD_NAME__CRS
,
acpi_ec_io_ports
,
ec
);
if
(
ACPI_FAILURE
(
status
)
||
ec
->
command_addr
.
register_bit_width
==
0
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Error getting I/O port addresses"
));
return_VALUE
(
-
ENODEV
);
}
resource
=
(
struct
acpi_resource
*
)
buffer
.
pointer
;
if
(
!
resource
||
(
resource
->
id
!=
ACPI_RSTYPE_IO
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid or missing resource
\n
"
));
result
=
-
ENODEV
;
goto
end
;
}
ec
->
data_addr
.
address_space_id
=
ACPI_ADR_SPACE_SYSTEM_IO
;
ec
->
data_addr
.
register_bit_width
=
8
;
ec
->
data_addr
.
register_bit_offset
=
0
;
ec
->
data_addr
.
address
=
resource
->
data
.
io
.
min_base_address
;
resource
=
ACPI_NEXT_RESOURCE
(
resource
);
if
(
!
resource
||
(
resource
->
id
!=
ACPI_RSTYPE_IO
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid or missing resource
\n
"
));
result
=
-
ENODEV
;
goto
end
;
}
ec
->
command_addr
.
address_space_id
=
ACPI_ADR_SPACE_SYSTEM_IO
;
ec
->
command_addr
.
register_bit_width
=
8
;
ec
->
command_addr
.
register_bit_offset
=
0
;
ec
->
command_addr
.
address
=
resource
->
data
.
io
.
min_base_address
;
ec
->
status_addr
=
ec
->
command_addr
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"gpe=0x%02x, ports=0x%2x,0x%2x
\n
"
,
...
...
@@ -706,8 +717,7 @@ acpi_ec_start (
status
=
acpi_install_gpe_handler
(
ec
->
gpe_bit
,
ACPI_EVENT_EDGE_TRIGGERED
,
&
acpi_ec_gpe_handler
,
ec
);
if
(
ACPI_FAILURE
(
status
))
{
result
=
-
ENODEV
;
goto
end
;
return_VALUE
(
-
ENODEV
);
}
status
=
acpi_install_address_space_handler
(
ec
->
handle
,
...
...
@@ -715,13 +725,10 @@ acpi_ec_start (
&
acpi_ec_space_setup
,
ec
);
if
(
ACPI_FAILURE
(
status
))
{
acpi_remove_gpe_handler
(
ec
->
gpe_bit
,
&
acpi_ec_gpe_handler
);
result
=
-
ENODEV
;
goto
end
;
return_VALUE
(
-
ENODEV
);
}
end:
acpi_os_free
(
buffer
.
pointer
);
return_VALUE
(
result
);
return_VALUE
(
AE_OK
);
}
...
...
drivers/acpi/events/Makefile
View file @
35d48993
...
...
@@ -4,6 +4,6 @@
obj-y
:=
evevent.o evregion.o evsci.o evxfevnt.o
\
evmisc.o evrgnini.o evxface.o evxfregn.o
\
evgpe.o
evgpe.o
evgpeblk.o
EXTRA_CFLAGS
+=
$(ACPI_CFLAGS)
drivers/acpi/events/evevent.c
View file @
35d48993
...
...
@@ -110,7 +110,7 @@ acpi_ev_initialize (
*
* RETURN: Status
*
* DESCRIPTION: Install
handlers for the SCI, Global Lock, and GPEs.
* DESCRIPTION: Install
interrupt handlers for the SCI and Global Lock
*
******************************************************************************/
...
...
@@ -134,16 +134,6 @@ acpi_ev_handler_initialize (
return_ACPI_STATUS
(
status
);
}
/* Install handlers for control method GPE handlers (_Lxx, _Exx) */
status
=
acpi_ev_init_gpe_control_methods
();
if
(
ACPI_FAILURE
(
status
))
{
ACPI_REPORT_ERROR
((
"Unable to initialize GPE control methods, %s
\n
"
,
acpi_format_exception
(
status
)));
return_ACPI_STATUS
(
status
);
}
/* Install the handler for the Global Lock */
status
=
acpi_ev_init_global_lock_handler
();
...
...
drivers/acpi/events/evgpe.c
View file @
35d48993
...
...
@@ -51,401 +51,54 @@
/*******************************************************************************
*
* FUNCTION: acpi_ev_g
pe_initialize
* FUNCTION: acpi_ev_g
et_gpe_event_info
*
* PARAMETERS:
None
* PARAMETERS:
gpe_number - Raw GPE number
*
* RETURN:
Status
* RETURN:
None.
*
* DESCRIPTION: Initialize the GPE data structures
* DESCRIPTION: Returns the event_info struct
* associated with this GPE.
*
******************************************************************************/
acpi_status
acpi_ev_gpe_initialize
(
void
)
{
acpi_native_uint
i
;
acpi_native_uint
j
;
u32
gpe_block
;
u32
gpe_register
;
u32
gpe_number_index
;
u32
gpe_number
;
struct
acpi_gpe_register_info
*
gpe_register_info
;
acpi_status
status
;
ACPI_FUNCTION_TRACE
(
"ev_gpe_initialize"
);
/*
* Initialize the GPE Block globals
*
* Why the GPE register block lengths are divided by 2: From the ACPI Spec,
* section "General-Purpose Event Registers", we have:
*
* "Each register block contains two registers of equal length
* GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
* GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
* The length of the GPE1_STS and GPE1_EN registers is equal to
* half the GPE1_LEN. If a generic register block is not supported
* then its respective block pointer and block length values in the
* FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
* to be the same size."
*/
acpi_gbl_gpe_block_info
[
0
].
register_count
=
0
;
acpi_gbl_gpe_block_info
[
1
].
register_count
=
0
;
acpi_gbl_gpe_block_info
[
0
].
block_address
=
&
acpi_gbl_FADT
->
xgpe0_blk
;
acpi_gbl_gpe_block_info
[
1
].
block_address
=
&
acpi_gbl_FADT
->
xgpe1_blk
;
acpi_gbl_gpe_block_info
[
0
].
block_base_number
=
0
;
acpi_gbl_gpe_block_info
[
1
].
block_base_number
=
acpi_gbl_FADT
->
gpe1_base
;
/*
* Determine the maximum GPE number for this machine.
*
* Note: both GPE0 and GPE1 are optional, and either can exist without
* the other.
* If EITHER the register length OR the block address are zero, then that
* particular block is not supported.
*/
if
(
acpi_gbl_FADT
->
xgpe0_blk
.
register_bit_width
&&
acpi_gbl_FADT
->
xgpe0_blk
.
address
)
{
/* GPE block 0 exists (has both length and address > 0) */
acpi_gbl_gpe_block_info
[
0
].
register_count
=
(
u16
)
(
acpi_gbl_FADT
->
xgpe0_blk
.
register_bit_width
/
(
ACPI_GPE_REGISTER_WIDTH
*
2
));
acpi_gbl_gpe_number_max
=
(
acpi_gbl_gpe_block_info
[
0
].
register_count
*
ACPI_GPE_REGISTER_WIDTH
)
-
1
;
}
if
(
acpi_gbl_FADT
->
xgpe1_blk
.
register_bit_width
&&
acpi_gbl_FADT
->
xgpe1_blk
.
address
)
{
/* GPE block 1 exists (has both length and address > 0) */
acpi_gbl_gpe_block_info
[
1
].
register_count
=
(
u16
)
(
acpi_gbl_FADT
->
xgpe1_blk
.
register_bit_width
/
(
ACPI_GPE_REGISTER_WIDTH
*
2
));
/* Check for GPE0/GPE1 overlap (if both banks exist) */
if
((
acpi_gbl_gpe_block_info
[
0
].
register_count
)
&&
(
acpi_gbl_gpe_number_max
>=
acpi_gbl_FADT
->
gpe1_base
))
{
ACPI_REPORT_ERROR
((
"GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1
\n
"
,
acpi_gbl_gpe_number_max
,
acpi_gbl_FADT
->
gpe1_base
,
acpi_gbl_FADT
->
gpe1_base
+
((
acpi_gbl_gpe_block_info
[
1
].
register_count
*
ACPI_GPE_REGISTER_WIDTH
)
-
1
)));
/* Ignore GPE1 block by setting the register count to zero */
acpi_gbl_gpe_block_info
[
1
].
register_count
=
0
;
}
else
{
/*
* GPE0 and GPE1 do not have to be contiguous in the GPE number space,
* But, GPE0 always starts at zero.
*/
acpi_gbl_gpe_number_max
=
acpi_gbl_FADT
->
gpe1_base
+
((
acpi_gbl_gpe_block_info
[
1
].
register_count
*
ACPI_GPE_REGISTER_WIDTH
)
-
1
);
}
}
/* Exit if there are no GPE registers */
acpi_gbl_gpe_register_count
=
acpi_gbl_gpe_block_info
[
0
].
register_count
+
acpi_gbl_gpe_block_info
[
1
].
register_count
;
if
(
!
acpi_gbl_gpe_register_count
)
{
/* GPEs are not required by ACPI, this is OK */
ACPI_REPORT_INFO
((
"There are no GPE blocks defined in the FADT
\n
"
));
return_ACPI_STATUS
(
AE_OK
);
}
/* Check for Max GPE number out-of-range */
if
(
acpi_gbl_gpe_number_max
>
ACPI_GPE_MAX
)
{
ACPI_REPORT_ERROR
((
"Maximum GPE number from FADT is too large: 0x%X
\n
"
,
acpi_gbl_gpe_number_max
));
return_ACPI_STATUS
(
AE_BAD_VALUE
);
}
/* Allocate the GPE number-to-index translation table */
acpi_gbl_gpe_number_to_index
=
ACPI_MEM_CALLOCATE
(
sizeof
(
struct
acpi_gpe_index_info
)
*
((
acpi_size
)
acpi_gbl_gpe_number_max
+
1
));
if
(
!
acpi_gbl_gpe_number_to_index
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Could not allocate the gpe_number_to_index table
\n
"
));
return_ACPI_STATUS
(
AE_NO_MEMORY
);
}
/* Set the Gpe index table to GPE_INVALID */
ACPI_MEMSET
(
acpi_gbl_gpe_number_to_index
,
(
int
)
ACPI_GPE_INVALID
,
sizeof
(
struct
acpi_gpe_index_info
)
*
((
acpi_size
)
acpi_gbl_gpe_number_max
+
1
));
/* Allocate the GPE register information block */
acpi_gbl_gpe_register_info
=
ACPI_MEM_CALLOCATE
(
(
acpi_size
)
acpi_gbl_gpe_register_count
*
sizeof
(
struct
acpi_gpe_register_info
));
if
(
!
acpi_gbl_gpe_register_info
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Could not allocate the gpe_register_info table
\n
"
));
goto
error_exit1
;
}
/*
* Allocate the GPE dispatch handler block. There are eight distinct GPEs
* per register. Initialization to zeros is sufficient.
*/
acpi_gbl_gpe_number_info
=
ACPI_MEM_CALLOCATE
(
((
acpi_size
)
acpi_gbl_gpe_register_count
*
ACPI_GPE_REGISTER_WIDTH
)
*
sizeof
(
struct
acpi_gpe_number_info
));
if
(
!
acpi_gbl_gpe_number_info
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Could not allocate the gpe_number_info table
\n
"
));
goto
error_exit2
;
}
/*
* Initialize the GPE information and validation tables. A goal of these
* tables is to hide the fact that there are two separate GPE register sets
* in a given gpe hardware block, the status registers occupy the first half,
* and the enable registers occupy the second half. Another goal is to hide
* the fact that there may be multiple GPE hardware blocks.
*/
gpe_register
=
0
;
gpe_number_index
=
0
;
for
(
gpe_block
=
0
;
gpe_block
<
ACPI_MAX_GPE_BLOCKS
;
gpe_block
++
)
{
for
(
i
=
0
;
i
<
acpi_gbl_gpe_block_info
[
gpe_block
].
register_count
;
i
++
)
{
gpe_register_info
=
&
acpi_gbl_gpe_register_info
[
gpe_register
];
/* Init the Register info for this entire GPE register (8 GPEs) */
gpe_register_info
->
base_gpe_number
=
(
u8
)
(
acpi_gbl_gpe_block_info
[
gpe_block
].
block_base_number
+
(
i
*
ACPI_GPE_REGISTER_WIDTH
));
ACPI_STORE_ADDRESS
(
gpe_register_info
->
status_address
.
address
,
(
acpi_gbl_gpe_block_info
[
gpe_block
].
block_address
->
address
+
i
));
ACPI_STORE_ADDRESS
(
gpe_register_info
->
enable_address
.
address
,
(
acpi_gbl_gpe_block_info
[
gpe_block
].
block_address
->
address
+
i
+
acpi_gbl_gpe_block_info
[
gpe_block
].
register_count
));
gpe_register_info
->
status_address
.
address_space_id
=
acpi_gbl_gpe_block_info
[
gpe_block
].
block_address
->
address_space_id
;
gpe_register_info
->
enable_address
.
address_space_id
=
acpi_gbl_gpe_block_info
[
gpe_block
].
block_address
->
address_space_id
;
gpe_register_info
->
status_address
.
register_bit_width
=
ACPI_GPE_REGISTER_WIDTH
;
gpe_register_info
->
enable_address
.
register_bit_width
=
ACPI_GPE_REGISTER_WIDTH
;
gpe_register_info
->
status_address
.
register_bit_offset
=
ACPI_GPE_REGISTER_WIDTH
;
gpe_register_info
->
enable_address
.
register_bit_offset
=
ACPI_GPE_REGISTER_WIDTH
;
/* Init the Index mapping info for each GPE number within this register */
for
(
j
=
0
;
j
<
ACPI_GPE_REGISTER_WIDTH
;
j
++
)
{
gpe_number
=
gpe_register_info
->
base_gpe_number
+
(
u32
)
j
;
acpi_gbl_gpe_number_to_index
[
gpe_number
].
number_index
=
(
u8
)
gpe_number_index
;
acpi_gbl_gpe_number_info
[
gpe_number_index
].
bit_mask
=
acpi_gbl_decode_to8bit
[
j
];
gpe_number_index
++
;
}
/*
* Clear the status/enable registers. Note that status registers
* are cleared by writing a '1', while enable registers are cleared
* by writing a '0'.
*/
status
=
acpi_hw_low_level_write
(
ACPI_GPE_REGISTER_WIDTH
,
0x00
,
&
gpe_register_info
->
enable_address
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
status
=
acpi_hw_low_level_write
(
ACPI_GPE_REGISTER_WIDTH
,
0xFF
,
&
gpe_register_info
->
status_address
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
gpe_register
++
;
}
if
(
i
)
{
/* Dump info about this valid GPE block */
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"GPE Block%d: %X registers at %8.8X%8.8X
\n
"
,
(
s32
)
gpe_block
,
acpi_gbl_gpe_block_info
[
0
].
register_count
,
ACPI_HIDWORD
(
acpi_gbl_gpe_block_info
[
gpe_block
].
block_address
->
address
),
ACPI_LODWORD
(
acpi_gbl_gpe_block_info
[
gpe_block
].
block_address
->
address
)));
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"GPE Block%d defined as GPE%d to GPE%d
\n
"
,
(
s32
)
gpe_block
,
(
u32
)
acpi_gbl_gpe_block_info
[
gpe_block
].
block_base_number
,
(
u32
)
(
acpi_gbl_gpe_block_info
[
gpe_block
].
block_base_number
+
((
acpi_gbl_gpe_block_info
[
gpe_block
].
register_count
*
ACPI_GPE_REGISTER_WIDTH
)
-
1
))));
}
}
return_ACPI_STATUS
(
AE_OK
);
/* Error cleanup */
error_exit2:
ACPI_MEM_FREE
(
acpi_gbl_gpe_register_info
);
error_exit1:
ACPI_MEM_FREE
(
acpi_gbl_gpe_number_to_index
);
return_ACPI_STATUS
(
AE_NO_MEMORY
);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_save_method_info
*
* PARAMETERS: None
*
* RETURN: None
*
* DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
* control method under the _GPE portion of the namespace.
* Extract the name and GPE type from the object, saving this
* information for quick lookup during GPE dispatch
*
* The name of each GPE control method is of the form:
* "_Lnn" or "_Enn"
* Where:
* L - means that the GPE is level triggered
* E - means that the GPE is edge triggered
* nn - is the GPE number [in HEX]
* TBD: this function will go away when full support of GPE block devices
* is implemented!
*
******************************************************************************/
static
acpi_status
acpi_ev_save_method_info
(
acpi_handle
obj_handle
,
u32
level
,
void
*
obj_desc
,
void
**
return_value
)
struct
acpi_gpe_event_info
*
acpi_ev_get_gpe_event_info
(
u32
gpe_number
)
{
u32
gpe_number
;
struct
acpi_gpe_number_info
*
gpe_number_info
;
char
name
[
ACPI_NAME_SIZE
+
1
];
u8
type
;
acpi_status
status
;
ACPI_FUNCTION_NAME
(
"ev_save_method_info"
);
/* Extract the name from the object and convert to a string */
ACPI_MOVE_UNALIGNED32_TO_32
(
name
,
&
((
struct
acpi_namespace_node
*
)
obj_handle
)
->
name
.
integer
);
name
[
ACPI_NAME_SIZE
]
=
0
;
/*
* Edge/Level determination is based on the 2nd character of the method name
*/
switch
(
name
[
1
])
{
case
'L'
:
type
=
ACPI_EVENT_LEVEL_TRIGGERED
;
break
;
case
'E'
:
type
=
ACPI_EVENT_EDGE_TRIGGERED
;
break
;
default:
/* Unknown method type, just ignore it! */
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Unknown GPE method type: %s (name not of form _Lnn or _Enn)
\n
"
,
name
));
return
(
AE_OK
);
}
struct
acpi_gpe_block_info
*
gpe_block
;
/* Convert the last two characters of the name to the GPE Number */
gpe_number
=
ACPI_STRTOUL
(
&
name
[
2
],
NULL
,
16
);
if
(
gpe_number
==
ACPI_UINT32_MAX
)
{
/* Conversion failed; invalid method, just ignore it */
/* Examine GPE Block 0 */
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Could not extract GPE number from name: %s (name not of form _Lnn or _Enn)
\n
"
,
name
));
return
(
AE_OK
);
gpe_block
=
acpi_gbl_gpe_block_list_head
;
if
(
!
gpe_block
)
{
return
(
NULL
);
}
/* Get GPE index and ensure that we have a valid GPE number */
gpe_number_info
=
acpi_ev_get_gpe_number_info
(
gpe_number
);
if
(
!
gpe_number_info
)
{
/* Not valid, all we can do here is ignore it */
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"GPE number associated with method is not valid %s
\n
"
,
name
));
return
(
AE_OK
);
if
((
gpe_number
>=
gpe_block
->
block_base_number
)
&&
(
gpe_number
<
gpe_block
->
block_base_number
+
(
gpe_block
->
register_count
*
8
)))
{
return
(
&
gpe_block
->
event_info
[
gpe_number
-
gpe_block
->
block_base_number
]);
}
/*
* Now we can add this information to the gpe_number_info block
* for use during dispatch of this GPE.
*/
gpe_number_info
->
type
=
type
;
gpe_number_info
->
method_node
=
(
struct
acpi_namespace_node
*
)
obj_handle
;
/* Examine GPE Block 1 */
/*
* Enable the GPE (SCIs should be disabled at this point)
*/
status
=
acpi_hw_enable_gpe
(
gpe_number
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
gpe_block
=
gpe_block
->
next
;
if
(
!
gpe_block
)
{
return
(
NULL
);
}
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Registered GPE method %s as GPE number %2.2X
\n
"
,
name
,
gpe_number
));
return
(
AE_OK
);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_init_gpe_control_methods
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Obtain the control methods associated with the GPEs.
* NOTE: Must be called AFTER namespace initialization!
*
******************************************************************************/
acpi_status
acpi_ev_init_gpe_control_methods
(
void
)
{
acpi_status
status
;
ACPI_FUNCTION_TRACE
(
"ev_init_gpe_control_methods"
);
/* Get a permanent handle to the _GPE object */
status
=
acpi_get_handle
(
NULL
,
"
\\
_GPE"
,
&
acpi_gbl_gpe_obj_handle
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
if
((
gpe_number
>=
gpe_block
->
block_base_number
)
&&
(
gpe_number
<
gpe_block
->
block_base_number
+
(
gpe_block
->
register_count
*
8
)))
{
return
(
&
gpe_block
->
event_info
[
gpe_number
-
gpe_block
->
block_base_number
]);
}
/* Traverse the namespace under \_GPE to find all methods there */
status
=
acpi_walk_namespace
(
ACPI_TYPE_METHOD
,
acpi_gbl_gpe_obj_handle
,
ACPI_UINT32_MAX
,
acpi_ev_save_method_info
,
NULL
,
NULL
);
return_ACPI_STATUS
(
status
);
return
(
NULL
);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_gpe_detect
...
...
@@ -470,62 +123,74 @@ acpi_ev_gpe_detect (void)
struct
acpi_gpe_register_info
*
gpe_register_info
;
u32
in_value
;
acpi_status
status
;
struct
acpi_gpe_block_info
*
gpe_block
;
ACPI_FUNCTION_NAME
(
"ev_gpe_detect"
);
/*
* Read all of the 8-bit GPE status and enable registers
* in both of the register blocks, saving all of it.
* Find all currently active GP events.
*/
for
(
i
=
0
;
i
<
acpi_gbl_gpe_register_count
;
i
++
)
{
gpe_register_info
=
&
acpi_gbl_gpe_register_info
[
i
];
/* Examine all GPE blocks attached to this interrupt level */
status
=
acpi_hw_low_level_read
(
ACPI_GPE_REGISTER_WIDTH
,
&
in_value
,
&
gpe_register_info
->
status_address
,
0
);
gpe_register_info
->
status
=
(
u8
)
in_value
;
if
(
ACPI_FAILURE
(
status
))
{
return
(
ACPI_INTERRUPT_NOT_HANDLED
);
}
gpe_block
=
acpi_gbl_gpe_block_list_head
;
while
(
gpe_block
)
{
/*
* Read all of the 8-bit GPE status and enable registers
* in this GPE block, saving all of them.
* Find all currently active GP events.
*/
for
(
i
=
0
;
i
<
gpe_block
->
register_count
;
i
++
)
{
/* Get the next status/enable pair */
status
=
acpi_hw_low_level_read
(
ACPI_GPE_REGISTER_WIDTH
,
&
in_value
,
&
gpe_register_info
->
enable_address
,
0
);
gpe_register_info
->
enable
=
(
u8
)
in_value
;
if
(
ACPI_FAILURE
(
status
))
{
return
(
ACPI_INTERRUPT_NOT_HANDLED
);
}
gpe_register_info
=
&
gpe_block
->
register_info
[
i
];
status
=
acpi_hw_low_level_read
(
ACPI_GPE_REGISTER_WIDTH
,
&
in_value
,
&
gpe_register_info
->
status_address
,
0
);
gpe_register_info
->
status
=
(
u8
)
in_value
;
if
(
ACPI_FAILURE
(
status
))
{
return
(
ACPI_INTERRUPT_NOT_HANDLED
);
}
ACPI_DEBUG_PRINT
((
ACPI_DB_INTERRUPTS
,
"GPE block at %8.8X%8.8X - Values: Enable %02X Status %02X
\n
"
,
ACPI_HIDWORD
(
gpe_register_info
->
enable_address
.
address
),
ACPI_LODWORD
(
gpe_register_info
->
enable_address
.
address
),
gpe_register_info
->
enable
,
gpe_register_info
->
status
));
status
=
acpi_hw_low_level_read
(
ACPI_GPE_REGISTER_WIDTH
,
&
in_value
,
&
gpe_register_info
->
enable_address
,
0
);
gpe_register_info
->
enable
=
(
u8
)
in_value
;
if
(
ACPI_FAILURE
(
status
))
{
return
(
ACPI_INTERRUPT_NOT_HANDLED
);
}
/* First check if there is anything active at all in this register */
ACPI_DEBUG_PRINT
((
ACPI_DB_INTERRUPTS
,
"GPE block at %8.8X%8.8X - Values: Enable %02X Status %02X
\n
"
,
ACPI_HIDWORD
(
gpe_register_info
->
enable_address
.
address
),
ACPI_LODWORD
(
gpe_register_info
->
enable_address
.
address
),
gpe_register_info
->
enable
,
gpe_register_info
->
status
));
enabled_status_byte
=
(
u8
)
(
gpe_register_info
->
status
&
gpe_register_info
->
enable
);
if
(
!
enabled_status_byte
)
{
/* No active GPEs in this register, move on */
/* First check if there is anything active at all in this register */
continue
;
}
enabled_status_byte
=
(
u8
)
(
gpe_register_info
->
status
&
gpe_register_info
->
enable
);
if
(
!
enabled_status_byte
)
{
/* No active GPEs in this register, move on */
/* Now look at the individual GPEs in this byte register */
continue
;
}
/* Now look at the individual GPEs in this byte register */
for
(
j
=
0
,
bit_mask
=
1
;
j
<
ACPI_GPE_REGISTER_WIDTH
;
j
++
,
bit_mask
<<=
1
)
{
/* Examine one GPE bit */
for
(
j
=
0
,
bit_mask
=
1
;
j
<
ACPI_GPE_REGISTER_WIDTH
;
j
++
,
bit_mask
<<=
1
)
{
/* Examine one GPE bit */
if
(
enabled_status_byte
&
bit_mask
)
{
/*
* Found an active GPE. Dispatch the event to a handler
* or method.
*/
int_status
|=
acpi_ev_gpe_dispatch
(
gpe_register_info
->
base_gpe_number
+
j
);
if
(
enabled_status_byte
&
bit_mask
)
{
/*
* Found an active GPE. Dispatch the event to a handler
* or method.
*/
int_status
|=
acpi_ev_gpe_dispatch
(
&
gpe_block
->
event_info
[(
i
*
ACPI_GPE_REGISTER_WIDTH
)
+
j
]);
}
}
}
gpe_block
=
gpe_block
->
next
;
}
return
(
int_status
);
...
...
@@ -536,7 +201,7 @@ acpi_ev_gpe_detect (void)
*
* FUNCTION: acpi_ev_asynch_execute_gpe_method
*
* PARAMETERS: gpe_
number - The 0-based GPE number
* PARAMETERS: gpe_
event_info - Info for this GPE
*
* RETURN: None
*
...
...
@@ -552,20 +217,14 @@ static void ACPI_SYSTEM_XFACE
acpi_ev_asynch_execute_gpe_method
(
void
*
context
)
{
u32
gpe_number
=
(
u32
)
ACPI_TO_INTEGER
(
context
);
u32
gpe_number_index
;
struct
acpi_gpe_number_info
gpe_number_info
;
struct
acpi_gpe_event_info
*
gpe_event_info
=
(
void
*
)
context
;
u32
gpe_number
=
0
;
acpi_status
status
;
ACPI_FUNCTION_TRACE
(
"ev_asynch_execute_gpe_method"
);
gpe_number_index
=
acpi_ev_get_gpe_number_index
(
gpe_number
);
if
(
gpe_number_index
==
ACPI_GPE_INVALID
)
{
return_VOID
;
}
/*
* Take a snapshot of the GPE info for this level - we copy the
* info to prevent a race condition with remove_handler.
...
...
@@ -575,40 +234,38 @@ acpi_ev_asynch_execute_gpe_method (
return_VOID
;
}
gpe_number_info
=
acpi_gbl_gpe_number_info
[
gpe_number_index
];
status
=
acpi_ut_release_mutex
(
ACPI_MTX_EVENTS
);
if
(
ACPI_FAILURE
(
status
))
{
return_VOID
;
}
if
(
gpe_
number_info
.
method_node
)
{
if
(
gpe_
event_info
->
method_node
)
{
/*
* Invoke the GPE Method (_Lxx, _Exx):
* (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.)
*/
status
=
acpi_ns_evaluate_by_handle
(
gpe_
number_info
.
method_node
,
NULL
,
NULL
);
status
=
acpi_ns_evaluate_by_handle
(
gpe_
event_info
->
method_node
,
NULL
,
NULL
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_REPORT_ERROR
((
"%s while evaluating method [%4.4s] for GPE[%2.2X]
\n
"
,
acpi_format_exception
(
status
),
gpe_
number_info
.
method_node
->
name
.
ascii
,
gpe_number
));
gpe_
event_info
->
method_node
->
name
.
ascii
,
gpe_number
));
}
}
if
(
gpe_
number_info
.
type
&
ACPI_EVENT_LEVEL_TRIGGERED
)
{
if
(
gpe_
event_info
->
type
&
ACPI_EVENT_LEVEL_TRIGGERED
)
{
/*
* GPE is level-triggered, we clear the GPE status bit after handling
* the event.
*/
status
=
acpi_hw_clear_gpe
(
gpe_
number
);
status
=
acpi_hw_clear_gpe
(
gpe_
event_info
);
if
(
ACPI_FAILURE
(
status
))
{
return_VOID
;
}
}
/*
* Enable the GPE.
*/
(
void
)
acpi_hw_enable_gpe
(
gpe_number
);
/* Enable this GPE */
(
void
)
acpi_hw_enable_gpe
(
gpe_event_info
);
return_VOID
;
}
...
...
@@ -617,7 +274,7 @@ acpi_ev_asynch_execute_gpe_method (
*
* FUNCTION: acpi_ev_gpe_dispatch
*
* PARAMETERS: gpe_
number - The 0-based GPE number
* PARAMETERS: gpe_
event_info - info for this GPE
*
* RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
*
...
...
@@ -629,33 +286,24 @@ acpi_ev_asynch_execute_gpe_method (
u32
acpi_ev_gpe_dispatch
(
u32
gpe_number
)
struct
acpi_gpe_event_info
*
gpe_event_info
)
{
struct
acpi_gpe_number_info
*
gpe_number_info
;
u32
gpe_number
=
0
;
/* TBD: remove */
acpi_status
status
;
ACPI_FUNCTION_TRACE
(
"ev_gpe_dispatch"
);
/*
* We don't have to worry about mutex on gpe_number_info because we are
* executing at interrupt level.
*/
gpe_number_info
=
acpi_ev_get_gpe_number_info
(
gpe_number
);
if
(
!
gpe_number_info
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"GPE[%X] is not a valid event
\n
"
,
gpe_number
));
return_VALUE
(
ACPI_INTERRUPT_NOT_HANDLED
);
}
/*
* If edge-triggered, clear the GPE status bit now. Note that
* level-triggered events are cleared after the GPE is serviced.
*/
if
(
gpe_
number
_info
->
type
&
ACPI_EVENT_EDGE_TRIGGERED
)
{
status
=
acpi_hw_clear_gpe
(
gpe_
number
);
if
(
gpe_
event
_info
->
type
&
ACPI_EVENT_EDGE_TRIGGERED
)
{
status
=
acpi_hw_clear_gpe
(
gpe_
event_info
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_REPORT_ERROR
((
"acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]
\n
"
,
gpe_number
));
ACPI_REPORT_ERROR
((
"acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]
\n
"
,
gpe_number
));
return_VALUE
(
ACPI_INTERRUPT_NOT_HANDLED
);
}
}
...
...
@@ -667,19 +315,20 @@ acpi_ev_gpe_dispatch (
* If there is neither a handler nor a method, we disable the level to
* prevent further events from coming in here.
*/
if
(
gpe_
number
_info
->
handler
)
{
if
(
gpe_
event
_info
->
handler
)
{
/* Invoke the installed handler (at interrupt level) */
gpe_
number_info
->
handler
(
gpe_number
_info
->
context
);
gpe_
event_info
->
handler
(
gpe_event
_info
->
context
);
}
else
if
(
gpe_
number
_info
->
method_node
)
{
else
if
(
gpe_
event
_info
->
method_node
)
{
/*
* Disable GPE, so it doesn't keep firing before the method has a
* chance to run.
*/
status
=
acpi_hw_disable_gpe
(
gpe_
number
);
status
=
acpi_hw_disable_gpe
(
gpe_
event_info
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_REPORT_ERROR
((
"acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]
\n
"
,
gpe_number
));
ACPI_REPORT_ERROR
((
"acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]
\n
"
,
gpe_number
));
return_VALUE
(
ACPI_INTERRUPT_NOT_HANDLED
);
}
...
...
@@ -688,22 +337,27 @@ acpi_ev_gpe_dispatch (
*/
if
(
ACPI_FAILURE
(
acpi_os_queue_for_execution
(
OSD_PRIORITY_GPE
,
acpi_ev_asynch_execute_gpe_method
,
ACPI_TO_POINTER
(
gpe_number
))))
{
ACPI_REPORT_ERROR
((
"acpi_ev_gpe_dispatch: Unable to queue handler for GPE[%2.2X], event is disabled
\n
"
,
gpe_number
));
gpe_event_info
)))
{
ACPI_REPORT_ERROR
((
"acpi_ev_gpe_dispatch: Unable to queue handler for GPE[%2.2X], event is disabled
\n
"
,
gpe_number
));
}
}
else
{
/* No handler or method to run! */
ACPI_REPORT_ERROR
((
"acpi_ev_gpe_dispatch: No handler or method for GPE[%2.2X], disabling event
\n
"
,
gpe_number
));
ACPI_REPORT_ERROR
((
"acpi_ev_gpe_dispatch: No handler or method for GPE[%2.2X], disabling event
\n
"
,
gpe_number
));
/*
* Disable the GPE. The GPE will remain disabled until the ACPI
* Core Subsystem is restarted, or the handler is reinstalled.
*/
status
=
acpi_hw_disable_gpe
(
gpe_
number
);
status
=
acpi_hw_disable_gpe
(
gpe_
event_info
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_REPORT_ERROR
((
"acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]
\n
"
,
gpe_number
));
ACPI_REPORT_ERROR
((
"acpi_ev_gpe_dispatch: Unable to disable GPE[%2.2X]
\n
"
,
gpe_number
));
return_VALUE
(
ACPI_INTERRUPT_NOT_HANDLED
);
}
}
...
...
@@ -711,10 +365,11 @@ acpi_ev_gpe_dispatch (
/*
* It is now safe to clear level-triggered evnets.
*/
if
(
gpe_
number
_info
->
type
&
ACPI_EVENT_LEVEL_TRIGGERED
)
{
status
=
acpi_hw_clear_gpe
(
gpe_
number
);
if
(
gpe_
event
_info
->
type
&
ACPI_EVENT_LEVEL_TRIGGERED
)
{
status
=
acpi_hw_clear_gpe
(
gpe_
event_info
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_REPORT_ERROR
((
"acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]
\n
"
,
gpe_number
));
ACPI_REPORT_ERROR
((
"acpi_ev_gpe_dispatch: Unable to clear GPE[%2.2X]
\n
"
,
gpe_number
));
return_VALUE
(
ACPI_INTERRUPT_NOT_HANDLED
);
}
}
...
...
drivers/acpi/events/evgpeblk.c
0 → 100644
View file @
35d48993
/******************************************************************************
*
* Module Name: evgpeblk - GPE block creation and initialization.
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2003, R. Byron Moore
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
#include <acpi/acpi.h>
#include <acpi/acevents.h>
#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME
(
"evgpe"
)
/*******************************************************************************
*
* FUNCTION: acpi_ev_save_method_info
*
* PARAMETERS: Callback from walk_namespace
*
* RETURN: None
*
* DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
* control method under the _GPE portion of the namespace.
* Extract the name and GPE type from the object, saving this
* information for quick lookup during GPE dispatch
*
* The name of each GPE control method is of the form:
* "_Lnn" or "_Enn"
* Where:
* L - means that the GPE is level triggered
* E - means that the GPE is edge triggered
* nn - is the GPE number [in HEX]
*
******************************************************************************/
static
acpi_status
acpi_ev_save_method_info
(
acpi_handle
obj_handle
,
u32
level
,
void
*
obj_desc
,
void
**
return_value
)
{
struct
acpi_gpe_block_info
*
gpe_block
=
(
void
*
)
obj_desc
;
struct
acpi_gpe_event_info
*
gpe_event_info
;
u32
gpe_number
;
char
name
[
ACPI_NAME_SIZE
+
1
];
u8
type
;
acpi_status
status
;
ACPI_FUNCTION_NAME
(
"ev_save_method_info"
);
/* Extract the name from the object and convert to a string */
ACPI_MOVE_UNALIGNED32_TO_32
(
name
,
&
((
struct
acpi_namespace_node
*
)
obj_handle
)
->
name
.
integer
);
name
[
ACPI_NAME_SIZE
]
=
0
;
/*
* Edge/Level determination is based on the 2nd character of the method name
*/
switch
(
name
[
1
])
{
case
'L'
:
type
=
ACPI_EVENT_LEVEL_TRIGGERED
;
break
;
case
'E'
:
type
=
ACPI_EVENT_EDGE_TRIGGERED
;
break
;
default:
/* Unknown method type, just ignore it! */
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Unknown GPE method type: %s (name not of form _Lnn or _Enn)
\n
"
,
name
));
return
(
AE_OK
);
}
/* Convert the last two characters of the name to the GPE Number */
gpe_number
=
ACPI_STRTOUL
(
&
name
[
2
],
NULL
,
16
);
if
(
gpe_number
==
ACPI_UINT32_MAX
)
{
/* Conversion failed; invalid method, just ignore it */
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Could not extract GPE number from name: %s (name is not of form _Lnn or _Enn)
\n
"
,
name
));
return
(
AE_OK
);
}
/* Ensure that we have a valid GPE number for this GPE block */
if
((
gpe_number
<
gpe_block
->
block_base_number
)
||
(
gpe_number
>=
(
gpe_block
->
register_count
*
8
)))
{
/* Not valid, all we can do here is ignore it */
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"GPE number associated with method %s is not valid
\n
"
,
name
));
return
(
AE_OK
);
}
/*
* Now we can add this information to the gpe_event_info block
* for use during dispatch of this GPE.
*/
gpe_event_info
=
&
gpe_block
->
event_info
[
gpe_number
-
gpe_block
->
block_base_number
];
gpe_event_info
->
type
=
type
;
gpe_event_info
->
method_node
=
(
struct
acpi_namespace_node
*
)
obj_handle
;
/*
* Enable the GPE (SCIs should be disabled at this point)
*/
status
=
acpi_hw_enable_gpe
(
gpe_event_info
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Registered GPE method %s as GPE number %2.2X
\n
"
,
name
,
gpe_number
));
return
(
AE_OK
);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_install_gpe_block
*
* PARAMETERS: gpe_block - New GPE block
*
* RETURN: Status
*
* DESCRIPTION: Install new GPE block with mutex support
*
******************************************************************************/
acpi_status
acpi_ev_install_gpe_block
(
struct
acpi_gpe_block_info
*
gpe_block
)
{
struct
acpi_gpe_block_info
*
next_gpe_block
;
acpi_status
status
;
status
=
acpi_ut_acquire_mutex
(
ACPI_MTX_EVENTS
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
/* Install the new block at the end of the global list */
if
(
acpi_gbl_gpe_block_list_head
)
{
next_gpe_block
=
acpi_gbl_gpe_block_list_head
;
while
(
next_gpe_block
->
next
)
{
next_gpe_block
=
next_gpe_block
->
next
;
}
next_gpe_block
->
next
=
gpe_block
;
gpe_block
->
previous
=
next_gpe_block
;
}
else
{
acpi_gbl_gpe_block_list_head
=
gpe_block
;
}
status
=
acpi_ut_release_mutex
(
ACPI_MTX_EVENTS
);
return
(
status
);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_create_gpe_info_blocks
*
* PARAMETERS: gpe_block - New GPE block
*
* RETURN: Status
*
* DESCRIPTION: Create the register_info and event_info blocks for this GPE block
*
******************************************************************************/
acpi_status
acpi_ev_create_gpe_info_blocks
(
struct
acpi_gpe_block_info
*
gpe_block
)
{
struct
acpi_gpe_register_info
*
gpe_register_info
=
NULL
;
struct
acpi_gpe_event_info
*
gpe_event_info
=
NULL
;
struct
acpi_gpe_event_info
*
this_event
;
struct
acpi_gpe_register_info
*
this_register
;
acpi_native_uint
i
;
acpi_native_uint
j
;
acpi_status
status
;
ACPI_FUNCTION_TRACE
(
"ev_create_gpe_info_blocks"
);
/* Allocate the GPE register information block */
gpe_register_info
=
ACPI_MEM_CALLOCATE
(
(
acpi_size
)
gpe_block
->
register_count
*
sizeof
(
struct
acpi_gpe_register_info
));
if
(
!
gpe_register_info
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Could not allocate the gpe_register_info table
\n
"
));
return_ACPI_STATUS
(
AE_NO_MEMORY
);
}
/*
* Allocate the GPE event_info block. There are eight distinct GPEs
* per register. Initialization to zeros is sufficient.
*/
gpe_event_info
=
ACPI_MEM_CALLOCATE
(
((
acpi_size
)
gpe_block
->
register_count
*
ACPI_GPE_REGISTER_WIDTH
)
*
sizeof
(
struct
acpi_gpe_event_info
));
if
(
!
gpe_event_info
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Could not allocate the gpe_event_info table
\n
"
));
status
=
AE_NO_MEMORY
;
goto
error_exit
;
}
/*
* Initialize the GPE Register and Event structures. A goal of these
* tables is to hide the fact that there are two separate GPE register sets
* in a given gpe hardware block, the status registers occupy the first half,
* and the enable registers occupy the second half. Another goal is to hide
* the fact that there may be multiple GPE hardware blocks.
*/
this_register
=
gpe_register_info
;
this_event
=
gpe_event_info
;
for
(
i
=
0
;
i
<
gpe_block
->
register_count
;
i
++
)
{
/* Init the register_info for this GPE register (8 GPEs) */
this_register
->
base_gpe_number
=
(
u8
)
(
gpe_block
->
block_base_number
+
(
i
*
ACPI_GPE_REGISTER_WIDTH
));
ACPI_STORE_ADDRESS
(
this_register
->
status_address
.
address
,
(
gpe_block
->
block_address
.
address
+
i
));
ACPI_STORE_ADDRESS
(
this_register
->
enable_address
.
address
,
(
gpe_block
->
block_address
.
address
+
i
+
gpe_block
->
register_count
));
this_register
->
status_address
.
address_space_id
=
gpe_block
->
block_address
.
address_space_id
;
this_register
->
enable_address
.
address_space_id
=
gpe_block
->
block_address
.
address_space_id
;
this_register
->
status_address
.
register_bit_width
=
ACPI_GPE_REGISTER_WIDTH
;
this_register
->
enable_address
.
register_bit_width
=
ACPI_GPE_REGISTER_WIDTH
;
this_register
->
status_address
.
register_bit_offset
=
ACPI_GPE_REGISTER_WIDTH
;
this_register
->
enable_address
.
register_bit_offset
=
ACPI_GPE_REGISTER_WIDTH
;
/* Init the event_info for each GPE within this register */
for
(
j
=
0
;
j
<
ACPI_GPE_REGISTER_WIDTH
;
j
++
)
{
this_event
->
bit_mask
=
acpi_gbl_decode_to8bit
[
j
];
this_event
->
register_info
=
this_register
;
this_event
++
;
}
/*
* Clear the status/enable registers. Note that status registers
* are cleared by writing a '1', while enable registers are cleared
* by writing a '0'.
*/
status
=
acpi_hw_low_level_write
(
ACPI_GPE_REGISTER_WIDTH
,
0x00
,
&
this_register
->
enable_address
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
goto
error_exit
;
}
status
=
acpi_hw_low_level_write
(
ACPI_GPE_REGISTER_WIDTH
,
0xFF
,
&
this_register
->
status_address
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
goto
error_exit
;
}
this_register
++
;
}
gpe_block
->
register_info
=
gpe_register_info
;
gpe_block
->
event_info
=
gpe_event_info
;
return_ACPI_STATUS
(
AE_OK
);
error_exit:
if
(
gpe_register_info
)
{
ACPI_MEM_FREE
(
gpe_register_info
);
}
if
(
gpe_event_info
)
{
ACPI_MEM_FREE
(
gpe_event_info
);
}
return_ACPI_STATUS
(
AE_OK
);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_create_gpe_block
*
* PARAMETERS: TBD
*
* RETURN: Status
*
* DESCRIPTION: Create and Install a block of GPE registers
*
******************************************************************************/
acpi_status
acpi_ev_create_gpe_block
(
char
*
pathname
,
struct
acpi_generic_address
*
gpe_block_address
,
u32
register_count
,
u8
gpe_block_base_number
,
u32
interrupt_level
)
{
struct
acpi_gpe_block_info
*
gpe_block
;
acpi_status
status
;
acpi_handle
obj_handle
;
ACPI_FUNCTION_TRACE
(
"ev_create_gpe_block"
);
if
(
!
register_count
)
{
return_ACPI_STATUS
(
AE_OK
);
}
/* Get a handle to the parent object for this GPE block */
status
=
acpi_get_handle
(
NULL
,
pathname
,
&
obj_handle
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
/* Allocate a new GPE block */
gpe_block
=
ACPI_MEM_CALLOCATE
(
sizeof
(
struct
acpi_gpe_block_info
));
if
(
!
gpe_block
)
{
return_ACPI_STATUS
(
AE_NO_MEMORY
);
}
/* Initialize the new GPE block */
gpe_block
->
register_count
=
register_count
;
gpe_block
->
block_base_number
=
gpe_block_base_number
;
ACPI_MEMCPY
(
&
gpe_block
->
block_address
,
gpe_block_address
,
sizeof
(
struct
acpi_generic_address
));
/* Create the register_info and event_info sub-structures */
status
=
acpi_ev_create_gpe_info_blocks
(
gpe_block
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_MEM_FREE
(
gpe_block
);
return_ACPI_STATUS
(
status
);
}
/* Install the new block in the global list(s) */
/* TBD: Install block in the interrupt handler list */
status
=
acpi_ev_install_gpe_block
(
gpe_block
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_MEM_FREE
(
gpe_block
);
return_ACPI_STATUS
(
status
);
}
/* Dump info about this GPE block */
ACPI_DEBUG_PRINT
((
ACPI_DB_INIT
,
"GPE Block: %X registers at %8.8X%8.8X
\n
"
,
gpe_block
->
register_count
,
ACPI_HIDWORD
(
gpe_block
->
block_address
.
address
),
ACPI_LODWORD
(
gpe_block
->
block_address
.
address
)));
ACPI_DEBUG_PRINT
((
ACPI_DB_INIT
,
"GPE Block defined as GPE%d to GPE%d
\n
"
,
gpe_block
->
block_base_number
,
(
u32
)
(
gpe_block
->
block_base_number
+
((
gpe_block
->
register_count
*
ACPI_GPE_REGISTER_WIDTH
)
-
1
))));
/* Find all GPE methods (_Lxx, _Exx) for this block */
status
=
acpi_walk_namespace
(
ACPI_TYPE_METHOD
,
obj_handle
,
ACPI_UINT32_MAX
,
acpi_ev_save_method_info
,
gpe_block
,
NULL
);
return_ACPI_STATUS
(
AE_OK
);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_gpe_initialize
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Initialize the GPE data structures
*
******************************************************************************/
acpi_status
acpi_ev_gpe_initialize
(
void
)
{
u32
register_count0
=
0
;
u32
register_count1
=
0
;
u32
gpe_number_max
=
0
;
ACPI_FUNCTION_TRACE
(
"ev_gpe_initialize"
);
/*
* Initialize the GPE Blocks defined in the FADT
*
* Why the GPE register block lengths are divided by 2: From the ACPI Spec,
* section "General-Purpose Event Registers", we have:
*
* "Each register block contains two registers of equal length
* GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
* GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN
* The length of the GPE1_STS and GPE1_EN registers is equal to
* half the GPE1_LEN. If a generic register block is not supported
* then its respective block pointer and block length values in the
* FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need
* to be the same size."
*/
/*
* Determine the maximum GPE number for this machine.
*
* Note: both GPE0 and GPE1 are optional, and either can exist without
* the other.
* If EITHER the register length OR the block address are zero, then that
* particular block is not supported.
*/
if
(
acpi_gbl_FADT
->
gpe0_blk_len
&&
acpi_gbl_FADT
->
xgpe0_blk
.
address
)
{
/* GPE block 0 exists (has both length and address > 0) */
register_count0
=
(
u16
)
(
acpi_gbl_FADT
->
gpe0_blk_len
/
2
);
gpe_number_max
=
(
register_count0
*
ACPI_GPE_REGISTER_WIDTH
)
-
1
;
acpi_ev_create_gpe_block
(
"
\\
_GPE"
,
&
acpi_gbl_FADT
->
xgpe0_blk
,
register_count0
,
0
,
acpi_gbl_FADT
->
sci_int
);
}
if
(
acpi_gbl_FADT
->
gpe1_blk_len
&&
acpi_gbl_FADT
->
xgpe1_blk
.
address
)
{
/* GPE block 1 exists (has both length and address > 0) */
register_count1
=
(
u16
)
(
acpi_gbl_FADT
->
gpe1_blk_len
/
2
);
/* Check for GPE0/GPE1 overlap (if both banks exist) */
if
((
register_count0
)
&&
(
gpe_number_max
>=
acpi_gbl_FADT
->
gpe1_base
))
{
ACPI_REPORT_ERROR
((
"GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1
\n
"
,
gpe_number_max
,
acpi_gbl_FADT
->
gpe1_base
,
acpi_gbl_FADT
->
gpe1_base
+
((
register_count1
*
ACPI_GPE_REGISTER_WIDTH
)
-
1
)));
/* Ignore GPE1 block by setting the register count to zero */
register_count1
=
0
;
}
else
{
acpi_ev_create_gpe_block
(
"
\\
_GPE"
,
&
acpi_gbl_FADT
->
xgpe1_blk
,
register_count1
,
acpi_gbl_FADT
->
gpe1_base
,
acpi_gbl_FADT
->
sci_int
);
/*
* GPE0 and GPE1 do not have to be contiguous in the GPE number space,
* But, GPE0 always starts at zero.
*/
gpe_number_max
=
acpi_gbl_FADT
->
gpe1_base
+
((
register_count1
*
ACPI_GPE_REGISTER_WIDTH
)
-
1
);
}
}
/* Exit if there are no GPE registers */
if
((
register_count0
+
register_count1
)
==
0
)
{
/* GPEs are not required by ACPI, this is OK */
ACPI_REPORT_INFO
((
"There are no GPE blocks defined in the FADT
\n
"
));
return_ACPI_STATUS
(
AE_OK
);
}
/* Check for Max GPE number out-of-range */
if
(
gpe_number_max
>
ACPI_GPE_MAX
)
{
ACPI_REPORT_ERROR
((
"Maximum GPE number from FADT is too large: 0x%X
\n
"
,
gpe_number_max
));
return_ACPI_STATUS
(
AE_BAD_VALUE
);
}
return_ACPI_STATUS
(
AE_OK
);
}
drivers/acpi/events/evmisc.c
View file @
35d48993
...
...
@@ -84,84 +84,6 @@ acpi_ev_is_notify_object (
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_get_gpe_register_info
*
* PARAMETERS: gpe_number - Raw GPE number
*
* RETURN: Pointer to the info struct for this GPE register.
*
* DESCRIPTION: Returns the register index (index into the GPE register info
* table) associated with this GPE.
*
******************************************************************************/
struct
acpi_gpe_register_info
*
acpi_ev_get_gpe_register_info
(
u32
gpe_number
)
{
if
(
gpe_number
>
acpi_gbl_gpe_number_max
)
{
return
(
NULL
);
}
return
(
&
acpi_gbl_gpe_register_info
[
ACPI_DIV_8
(
acpi_gbl_gpe_number_to_index
[
gpe_number
].
number_index
)]);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_get_gpe_number_info
*
* PARAMETERS: gpe_number - Raw GPE number
*
* RETURN: None.
*
* DESCRIPTION: Returns the number index (index into the GPE number info table)
* associated with this GPE.
*
******************************************************************************/
struct
acpi_gpe_number_info
*
acpi_ev_get_gpe_number_info
(
u32
gpe_number
)
{
if
(
gpe_number
>
acpi_gbl_gpe_number_max
)
{
return
(
NULL
);
}
return
(
&
acpi_gbl_gpe_number_info
[
acpi_gbl_gpe_number_to_index
[
gpe_number
].
number_index
]);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_get_gpe_number_index
*
* PARAMETERS: gpe_number - Raw GPE number
*
* RETURN: None.
*
* DESCRIPTION: Returns the number index (index into the GPE number info table)
* associated with this GPE.
*
******************************************************************************/
u32
acpi_ev_get_gpe_number_index
(
u32
gpe_number
)
{
if
(
gpe_number
>
acpi_gbl_gpe_number_max
)
{
return
(
ACPI_GPE_INVALID
);
}
return
(
acpi_gbl_gpe_number_to_index
[
gpe_number
].
number_index
);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_queue_notify_request
...
...
@@ -601,6 +523,9 @@ acpi_ev_terminate (void)
{
acpi_native_uint
i
;
acpi_status
status
;
struct
acpi_gpe_block_info
*
gpe_block
;
struct
acpi_gpe_block_info
*
next_gpe_block
;
struct
acpi_gpe_event_info
*
gpe_event_info
;
ACPI_FUNCTION_TRACE
(
"ev_terminate"
);
...
...
@@ -625,13 +550,19 @@ acpi_ev_terminate (void)
/*
* Disable all GPEs
*/
for
(
i
=
0
;
i
<
acpi_gbl_gpe_number_max
;
i
++
)
{
if
(
acpi_ev_get_gpe_number_index
((
u32
)
i
)
!=
ACPI_GPE_INVALID
)
{
status
=
acpi_hw_disable_gpe
((
u32
)
i
);
gpe_block
=
acpi_gbl_gpe_block_list_head
;
while
(
gpe_block
)
{
gpe_event_info
=
gpe_block
->
event_info
;
for
(
i
=
0
;
i
<
(
gpe_block
->
register_count
*
8
);
i
++
)
{
status
=
acpi_hw_disable_gpe
(
gpe_event_info
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Could not disable GPE %d
\n
"
,
(
u32
)
i
));
}
gpe_event_info
++
;
}
gpe_block
=
gpe_block
->
next
;
}
/*
...
...
@@ -654,21 +585,16 @@ acpi_ev_terminate (void)
}
/*
* Free global
tables, etc.
* Free global
GPE blocks and related info structures
*/
if
(
acpi_gbl_gpe_register_info
)
{
ACPI_MEM_FREE
(
acpi_gbl_gpe_register_info
);
acpi_gbl_gpe_register_info
=
NULL
;
}
if
(
acpi_gbl_gpe_number_info
)
{
ACPI_MEM_FREE
(
acpi_gbl_gpe_number_info
);
acpi_gbl_gpe_number_info
=
NULL
;
}
if
(
acpi_gbl_gpe_number_to_index
)
{
ACPI_MEM_FREE
(
acpi_gbl_gpe_number_to_index
);
acpi_gbl_gpe_number_to_index
=
NULL
;
gpe_block
=
acpi_gbl_gpe_block_list_head
;
while
(
gpe_block
)
{
next_gpe_block
=
gpe_block
->
next
;
ACPI_MEM_FREE
(
gpe_block
->
event_info
);
ACPI_MEM_FREE
(
gpe_block
->
register_info
);
ACPI_MEM_FREE
(
gpe_block
);
gpe_block
=
next_gpe_block
;
}
return_VOID
;
...
...
drivers/acpi/events/evsci.c
View file @
35d48993
...
...
@@ -69,38 +69,24 @@ acpi_ev_sci_handler (
void
*
context
)
{
u32
interrupt_handled
=
ACPI_INTERRUPT_NOT_HANDLED
;
u32
value
;
acpi_status
status
;
ACPI_FUNCTION_TRACE
(
"ev_sci_handler"
);
/*
*
Make sure that ACPI is enabled by checking SCI_EN. Note that we are
*
required to treat the SCI interrupt as sharable, level, active low
.
*
We are guaranteed by the ACPI CA initialization/shutdown code that
*
if this interrupt handler is installed, ACPI is enabled
.
*/
status
=
acpi_get_register
(
ACPI_BITREG_SCI_ENABLE
,
&
value
,
ACPI_MTX_DO_NOT_LOCK
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
ACPI_INTERRUPT_NOT_HANDLED
);
}
if
(
!
value
)
{
/* ACPI is not enabled; this interrupt cannot be for us */
return_VALUE
(
ACPI_INTERRUPT_NOT_HANDLED
);
}
/*
* Fixed acpi_events:
* -------------
* Check for and dispatch any Fixed acpi_events that have occurred
*/
interrupt_handled
|=
acpi_ev_fixed_event_detect
();
/*
* GPEs:
* -----
* Check for and dispatch any GPEs that have occurred
*/
interrupt_handled
|=
acpi_ev_gpe_detect
();
...
...
drivers/acpi/events/evxface.c
View file @
35d48993
...
...
@@ -492,7 +492,7 @@ acpi_install_gpe_handler (
void
*
context
)
{
acpi_status
status
;
struct
acpi_gpe_
number_info
*
gpe_number
_info
;
struct
acpi_gpe_
event_info
*
gpe_event
_info
;
ACPI_FUNCTION_TRACE
(
"acpi_install_gpe_handler"
);
...
...
@@ -506,8 +506,8 @@ acpi_install_gpe_handler (
/* Ensure that we have a valid GPE number */
gpe_
number_info
=
acpi_ev_get_gpe_number
_info
(
gpe_number
);
if
(
!
gpe_
number
_info
)
{
gpe_
event_info
=
acpi_ev_get_gpe_event
_info
(
gpe_number
);
if
(
!
gpe_
event
_info
)
{
return_ACPI_STATUS
(
AE_BAD_PARAMETER
);
}
...
...
@@ -518,25 +518,25 @@ acpi_install_gpe_handler (
/* Make sure that there isn't a handler there already */
if
(
gpe_
number
_info
->
handler
)
{
if
(
gpe_
event
_info
->
handler
)
{
status
=
AE_ALREADY_EXISTS
;
goto
cleanup
;
}
/* Install the handler */
gpe_
number
_info
->
handler
=
handler
;
gpe_
number
_info
->
context
=
context
;
gpe_
number
_info
->
type
=
(
u8
)
type
;
gpe_
event
_info
->
handler
=
handler
;
gpe_
event
_info
->
context
=
context
;
gpe_
event
_info
->
type
=
(
u8
)
type
;
/* Clear the GPE (of stale events), the enable it */
status
=
acpi_hw_clear_gpe
(
gpe_
number
);
status
=
acpi_hw_clear_gpe
(
gpe_
event_info
);
if
(
ACPI_FAILURE
(
status
))
{
goto
cleanup
;
}
status
=
acpi_hw_enable_gpe
(
gpe_
number
);
status
=
acpi_hw_enable_gpe
(
gpe_
event_info
);
cleanup:
...
...
@@ -564,7 +564,7 @@ acpi_remove_gpe_handler (
acpi_gpe_handler
handler
)
{
acpi_status
status
;
struct
acpi_gpe_
number_info
*
gpe_number
_info
;
struct
acpi_gpe_
event_info
*
gpe_event
_info
;
ACPI_FUNCTION_TRACE
(
"acpi_remove_gpe_handler"
);
...
...
@@ -578,14 +578,14 @@ acpi_remove_gpe_handler (
/* Ensure that we have a valid GPE number */
gpe_
number_info
=
acpi_ev_get_gpe_number
_info
(
gpe_number
);
if
(
!
gpe_
number
_info
)
{
gpe_
event_info
=
acpi_ev_get_gpe_event
_info
(
gpe_number
);
if
(
!
gpe_
event
_info
)
{
return_ACPI_STATUS
(
AE_BAD_PARAMETER
);
}
/* Disable the GPE before removing the handler */
status
=
acpi_hw_disable_gpe
(
gpe_
number
);
status
=
acpi_hw_disable_gpe
(
gpe_
event_info
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
...
...
@@ -597,16 +597,16 @@ acpi_remove_gpe_handler (
/* Make sure that the installed handler is the same */
if
(
gpe_
number
_info
->
handler
!=
handler
)
{
(
void
)
acpi_hw_enable_gpe
(
gpe_
number
);
if
(
gpe_
event
_info
->
handler
!=
handler
)
{
(
void
)
acpi_hw_enable_gpe
(
gpe_
event_info
);
status
=
AE_BAD_PARAMETER
;
goto
cleanup
;
}
/* Remove the handler */
gpe_
number
_info
->
handler
=
NULL
;
gpe_
number
_info
->
context
=
NULL
;
gpe_
event
_info
->
handler
=
NULL
;
gpe_
event
_info
->
context
=
NULL
;
cleanup:
...
...
drivers/acpi/events/evxfevnt.c
View file @
35d48993
...
...
@@ -163,6 +163,7 @@ acpi_enable_event (
{
acpi_status
status
=
AE_OK
;
u32
value
;
struct
acpi_gpe_event_info
*
gpe_event_info
;
ACPI_FUNCTION_TRACE
(
"acpi_enable_event"
);
...
...
@@ -209,19 +210,20 @@ acpi_enable_event (
/* Ensure that we have a valid GPE number */
if
(
acpi_ev_get_gpe_number_index
(
event
)
==
ACPI_GPE_INVALID
)
{
gpe_event_info
=
acpi_ev_get_gpe_event_info
(
event
);
if
(
!
gpe_event_info
)
{
return_ACPI_STATUS
(
AE_BAD_PARAMETER
);
}
/* Enable the requested GPE number */
status
=
acpi_hw_enable_gpe
(
event
);
status
=
acpi_hw_enable_gpe
(
gpe_event_info
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
if
(
flags
&
ACPI_EVENT_WAKE_ENABLE
)
{
acpi_hw_enable_gpe_for_wakeup
(
event
);
acpi_hw_enable_gpe_for_wakeup
(
gpe_event_info
);
}
break
;
...
...
@@ -257,6 +259,7 @@ acpi_disable_event (
{
acpi_status
status
=
AE_OK
;
u32
value
;
struct
acpi_gpe_event_info
*
gpe_event_info
;
ACPI_FUNCTION_TRACE
(
"acpi_disable_event"
);
...
...
@@ -301,7 +304,8 @@ acpi_disable_event (
/* Ensure that we have a valid GPE number */
if
(
acpi_ev_get_gpe_number_index
(
event
)
==
ACPI_GPE_INVALID
)
{
gpe_event_info
=
acpi_ev_get_gpe_event_info
(
event
);
if
(
!
gpe_event_info
)
{
return_ACPI_STATUS
(
AE_BAD_PARAMETER
);
}
...
...
@@ -311,10 +315,10 @@ acpi_disable_event (
*/
if
(
flags
&
ACPI_EVENT_WAKE_DISABLE
)
{
acpi_hw_disable_gpe_for_wakeup
(
event
);
acpi_hw_disable_gpe_for_wakeup
(
gpe_event_info
);
}
else
{
status
=
acpi_hw_disable_gpe
(
event
);
status
=
acpi_hw_disable_gpe
(
gpe_event_info
);
}
break
;
...
...
@@ -346,6 +350,7 @@ acpi_clear_event (
u32
type
)
{
acpi_status
status
=
AE_OK
;
struct
acpi_gpe_event_info
*
gpe_event_info
;
ACPI_FUNCTION_TRACE
(
"acpi_clear_event"
);
...
...
@@ -375,11 +380,12 @@ acpi_clear_event (
/* Ensure that we have a valid GPE number */
if
(
acpi_ev_get_gpe_number_index
(
event
)
==
ACPI_GPE_INVALID
)
{
gpe_event_info
=
acpi_ev_get_gpe_event_info
(
event
);
if
(
!
gpe_event_info
)
{
return_ACPI_STATUS
(
AE_BAD_PARAMETER
);
}
status
=
acpi_hw_clear_gpe
(
event
);
status
=
acpi_hw_clear_gpe
(
gpe_event_info
);
break
;
...
...
@@ -415,6 +421,7 @@ acpi_get_event_status (
acpi_event_status
*
event_status
)
{
acpi_status
status
=
AE_OK
;
struct
acpi_gpe_event_info
*
gpe_event_info
;
ACPI_FUNCTION_TRACE
(
"acpi_get_event_status"
);
...
...
@@ -447,7 +454,8 @@ acpi_get_event_status (
/* Ensure that we have a valid GPE number */
if
(
acpi_ev_get_gpe_number_index
(
event
)
==
ACPI_GPE_INVALID
)
{
gpe_event_info
=
acpi_ev_get_gpe_event_info
(
event
);
if
(
!
gpe_event_info
)
{
return_ACPI_STATUS
(
AE_BAD_PARAMETER
);
}
...
...
@@ -464,3 +472,4 @@ acpi_get_event_status (
return_ACPI_STATUS
(
status
);
}
drivers/acpi/hardware/hwgpe.c
View file @
35d48993
...
...
@@ -49,26 +49,6 @@
ACPI_MODULE_NAME
(
"hwgpe"
)
/******************************************************************************
*
* FUNCTION: acpi_hw_get_gpe_bit_mask
*
* PARAMETERS: gpe_number - The GPE
*
* RETURN: Gpe register bitmask for this gpe level
*
* DESCRIPTION: Get the bitmask for this GPE
*
******************************************************************************/
u8
acpi_hw_get_gpe_bit_mask
(
u32
gpe_number
)
{
return
(
acpi_gbl_gpe_number_info
[
acpi_ev_get_gpe_number_index
(
gpe_number
)].
bit_mask
);
}
/******************************************************************************
*
* FUNCTION: acpi_hw_enable_gpe
...
...
@@ -83,37 +63,29 @@ acpi_hw_get_gpe_bit_mask (
acpi_status
acpi_hw_enable_gpe
(
u32
gpe_number
)
struct
acpi_gpe_event_info
*
gpe_event_info
)
{
u32
in_byte
;
acpi_status
status
;
struct
acpi_gpe_register_info
*
gpe_register_info
;
ACPI_FUNCTION_ENTRY
();
/* Get the info block for the entire GPE register */
gpe_register_info
=
acpi_ev_get_gpe_register_info
(
gpe_number
);
if
(
!
gpe_register_info
)
{
return
(
AE_BAD_PARAMETER
);
}
/*
* Read the current value of the register, set the appropriate bit
* to enable the GPE, and write out the new register.
*/
status
=
acpi_hw_low_level_read
(
8
,
&
in_byte
,
&
gpe_register_info
->
enable_address
,
0
);
&
gpe_
event_info
->
register_info
->
enable_address
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
/* Write with the new GPE bit enabled */
status
=
acpi_hw_low_level_write
(
8
,
(
in_byte
|
acpi_hw_get_gpe_bit_mask
(
gpe_number
)
),
&
gpe_register_info
->
enable_address
,
0
);
status
=
acpi_hw_low_level_write
(
8
,
(
in_byte
|
gpe_event_info
->
bit_mask
),
&
gpe_
event_info
->
register_info
->
enable_address
,
0
);
return
(
status
);
}
...
...
@@ -134,7 +106,7 @@ acpi_hw_enable_gpe (
void
acpi_hw_enable_gpe_for_wakeup
(
u32
gpe_number
)
struct
acpi_gpe_event_info
*
gpe_event_info
)
{
struct
acpi_gpe_register_info
*
gpe_register_info
;
...
...
@@ -144,7 +116,7 @@ acpi_hw_enable_gpe_for_wakeup (
/* Get the info block for the entire GPE register */
gpe_register_info
=
acpi_ev_get_gpe_register_info
(
gpe_number
)
;
gpe_register_info
=
gpe_event_info
->
register_info
;
if
(
!
gpe_register_info
)
{
return
;
}
...
...
@@ -152,7 +124,7 @@ acpi_hw_enable_gpe_for_wakeup (
/*
* Set the bit so we will not disable this when sleeping
*/
gpe_register_info
->
wake_enable
|=
acpi_hw_get_gpe_bit_mask
(
gpe_number
)
;
gpe_register_info
->
wake_enable
|=
gpe_event_info
->
bit_mask
;
}
...
...
@@ -170,7 +142,7 @@ acpi_hw_enable_gpe_for_wakeup (
acpi_status
acpi_hw_disable_gpe
(
u32
gpe_number
)
struct
acpi_gpe_event_info
*
gpe_event_info
)
{
u32
in_byte
;
acpi_status
status
;
...
...
@@ -182,7 +154,7 @@ acpi_hw_disable_gpe (
/* Get the info block for the entire GPE register */
gpe_register_info
=
acpi_ev_get_gpe_register_info
(
gpe_number
)
;
gpe_register_info
=
gpe_event_info
->
register_info
;
if
(
!
gpe_register_info
)
{
return
(
AE_BAD_PARAMETER
);
}
...
...
@@ -199,13 +171,13 @@ acpi_hw_disable_gpe (
/* Write the byte with this GPE bit cleared */
status
=
acpi_hw_low_level_write
(
8
,
(
in_byte
&
~
(
acpi_hw_get_gpe_bit_mask
(
gpe_number
)
)),
status
=
acpi_hw_low_level_write
(
8
,
(
in_byte
&
~
(
gpe_event_info
->
bit_mask
)),
&
gpe_register_info
->
enable_address
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
acpi_hw_disable_gpe_for_wakeup
(
gpe_number
);
acpi_hw_disable_gpe_for_wakeup
(
gpe_event_info
);
return
(
AE_OK
);
}
...
...
@@ -225,7 +197,7 @@ acpi_hw_disable_gpe (
void
acpi_hw_disable_gpe_for_wakeup
(
u32
gpe_number
)
struct
acpi_gpe_event_info
*
gpe_event_info
)
{
struct
acpi_gpe_register_info
*
gpe_register_info
;
...
...
@@ -235,7 +207,7 @@ acpi_hw_disable_gpe_for_wakeup (
/* Get the info block for the entire GPE register */
gpe_register_info
=
acpi_ev_get_gpe_register_info
(
gpe_number
)
;
gpe_register_info
=
gpe_event_info
->
register_info
;
if
(
!
gpe_register_info
)
{
return
;
}
...
...
@@ -243,7 +215,7 @@ acpi_hw_disable_gpe_for_wakeup (
/*
* Clear the bit so we will disable this when sleeping
*/
gpe_register_info
->
wake_enable
&=
~
(
acpi_hw_get_gpe_bit_mask
(
gpe_number
)
);
gpe_register_info
->
wake_enable
&=
~
(
gpe_event_info
->
bit_mask
);
}
...
...
@@ -261,28 +233,20 @@ acpi_hw_disable_gpe_for_wakeup (
acpi_status
acpi_hw_clear_gpe
(
u32
gpe_number
)
struct
acpi_gpe_event_info
*
gpe_event_info
)
{
acpi_status
status
;
struct
acpi_gpe_register_info
*
gpe_register_info
;
ACPI_FUNCTION_ENTRY
();
/* Get the info block for the entire GPE register */
gpe_register_info
=
acpi_ev_get_gpe_register_info
(
gpe_number
);
if
(
!
gpe_register_info
)
{
return
(
AE_BAD_PARAMETER
);
}
/*
* Write a one to the appropriate bit in the status register to
* clear this GPE.
*/
status
=
acpi_hw_low_level_write
(
8
,
acpi_hw_get_gpe_bit_mask
(
gpe_number
)
,
&
gpe_register_info
->
status_address
,
0
);
status
=
acpi_hw_low_level_write
(
8
,
gpe_event_info
->
bit_mask
,
&
gpe_
event_info
->
register_info
->
status_address
,
0
);
return
(
status
);
}
...
...
@@ -308,6 +272,7 @@ acpi_hw_get_gpe_status (
u32
in_byte
;
u8
bit_mask
;
struct
acpi_gpe_register_info
*
gpe_register_info
;
struct
acpi_gpe_event_info
*
gpe_event_info
;
acpi_status
status
;
acpi_event_status
local_event_status
=
0
;
...
...
@@ -319,16 +284,18 @@ acpi_hw_get_gpe_status (
return
(
AE_BAD_PARAMETER
);
}
/* Get the info block for the entire GPE register */
gpe_register_info
=
acpi_ev_get_gpe_register_info
(
gpe_number
);
if
(
!
gpe_register_info
)
{
gpe_event_info
=
acpi_ev_get_gpe_event_info
(
gpe_number
);
if
(
!
gpe_event_info
)
{
return
(
AE_BAD_PARAMETER
);
}
/* Get the info block for the entire GPE register */
gpe_register_info
=
gpe_event_info
->
register_info
;
/* Get the register bitmask for this GPE */
bit_mask
=
acpi_hw_get_gpe_bit_mask
(
gpe_number
)
;
bit_mask
=
gpe_event_info
->
bit_mask
;
/* GPE Enabled? */
...
...
@@ -375,7 +342,7 @@ acpi_hw_get_gpe_status (
*
* DESCRIPTION: Disable all non-wakeup GPEs
* Call with interrupts disabled. The interrupt handler also
* modifies
acpi_gbl_gpe_register_info[i].
Enable, so it should not be
* modifies
gpe_register_info->
Enable, so it should not be
* given the chance to run until after non-wake GPEs are
* re-enabled.
*
...
...
@@ -389,40 +356,49 @@ acpi_hw_disable_non_wakeup_gpes (
struct
acpi_gpe_register_info
*
gpe_register_info
;
u32
in_value
;
acpi_status
status
;
struct
acpi_gpe_block_info
*
gpe_block
;
ACPI_FUNCTION_ENTRY
();
for
(
i
=
0
;
i
<
acpi_gbl_gpe_register_count
;
i
++
)
{
/* Get the info block for the entire GPE register */
gpe_block
=
acpi_gbl_gpe_block_list_head
;
while
(
gpe_block
)
{
/* Get the register info for the entire GPE block */
gpe_register_info
=
&
acpi_gbl_gpe_register_info
[
i
]
;
gpe_register_info
=
gpe_block
->
register_info
;
if
(
!
gpe_register_info
)
{
return
(
AE_BAD_PARAMETER
);
}
/*
* Read the enabled status of all GPEs. We
* will be using it to restore all the GPEs later.
*/
status
=
acpi_hw_low_level_read
(
8
,
&
in_value
,
&
gpe_register_info
->
enable_address
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
for
(
i
=
0
;
i
<
gpe_block
->
register_count
;
i
++
)
{
/*
* Read the enabled status of all GPEs. We
* will be using it to restore all the GPEs later.
*/
status
=
acpi_hw_low_level_read
(
8
,
&
in_value
,
&
gpe_register_info
->
enable_address
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
gpe_register_info
->
enable
=
(
u8
)
in_value
;
/*
* Disable all GPEs except wakeup GPEs.
*/
status
=
acpi_hw_low_level_write
(
8
,
gpe_register_info
->
wake_enable
,
&
gpe_register_info
->
enable_address
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
gpe_register_info
++
;
}
gpe_register_info
->
enable
=
(
u8
)
in_value
;
/*
* Disable all GPEs except wakeup GPEs.
*/
status
=
acpi_hw_low_level_write
(
8
,
gpe_register_info
->
wake_enable
,
&
gpe_register_info
->
enable_address
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
gpe_block
=
gpe_block
->
next
;
}
return
(
AE_OK
);
}
...
...
@@ -446,28 +422,37 @@ acpi_hw_enable_non_wakeup_gpes (
u32
i
;
struct
acpi_gpe_register_info
*
gpe_register_info
;
acpi_status
status
;
struct
acpi_gpe_block_info
*
gpe_block
;
ACPI_FUNCTION_ENTRY
();
for
(
i
=
0
;
i
<
acpi_gbl_gpe_register_count
;
i
++
)
{
/* Get the info block for the entire GPE register */
gpe_block
=
acpi_gbl_gpe_block_list_head
;
while
(
gpe_block
)
{
/* Get the register info for the entire GPE block */
gpe_register_info
=
&
acpi_gbl_gpe_register_info
[
i
]
;
gpe_register_info
=
gpe_block
->
register_info
;
if
(
!
gpe_register_info
)
{
return
(
AE_BAD_PARAMETER
);
}
/*
* We previously stored the enabled status of all GPEs.
* Blast them back in.
*/
status
=
acpi_hw_low_level_write
(
8
,
gpe_register_info
->
enable
,
&
gpe_register_info
->
enable_address
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
for
(
i
=
0
;
i
<
gpe_block
->
register_count
;
i
++
)
{
/*
* We previously stored the enabled status of all GPEs.
* Blast them back in.
*/
status
=
acpi_hw_low_level_write
(
8
,
gpe_register_info
->
enable
,
&
gpe_register_info
->
enable_address
,
0
);
if
(
ACPI_FAILURE
(
status
))
{
return
(
status
);
}
gpe_register_info
++
;
}
gpe_block
=
gpe_block
->
next
;
}
return
(
AE_OK
);
}
drivers/acpi/hardware/hwregs.c
View file @
35d48993
...
...
@@ -67,8 +67,8 @@ acpi_status
acpi_hw_clear_acpi_status
(
void
)
{
acpi_native_uint
i
;
acpi_native_uint
gpe_block
;
acpi_status
status
;
struct
acpi_gpe_block_info
*
gpe_block
;
ACPI_FUNCTION_TRACE
(
"hw_clear_acpi_status"
);
...
...
@@ -100,16 +100,19 @@ acpi_hw_clear_acpi_status (void)
}
}
/* Clear the GPE Bits */
/* Clear the GPE Bits
in all GPE registers in all GPE blocks
*/
for
(
gpe_block
=
0
;
gpe_block
<
ACPI_MAX_GPE_BLOCKS
;
gpe_block
++
)
{
for
(
i
=
0
;
i
<
acpi_gbl_gpe_block_info
[
gpe_block
].
register_count
;
i
++
)
{
gpe_block
=
acpi_gbl_gpe_block_list_head
;
while
(
gpe_block
)
{
for
(
i
=
0
;
i
<
gpe_block
->
register_count
;
i
++
)
{
status
=
acpi_hw_low_level_write
(
8
,
0xFF
,
acpi_gbl_gpe_block_info
[
gpe_block
].
block
_address
,
(
u32
)
i
);
&
gpe_block
->
register_info
[
i
].
status
_address
,
(
u32
)
i
);
if
(
ACPI_FAILURE
(
status
))
{
goto
unlock_and_exit
;
}
}
gpe_block
=
gpe_block
->
next
;
}
unlock_and_exit:
...
...
drivers/acpi/hardware/hwsleep.c
View file @
35d48993
...
...
@@ -250,7 +250,7 @@ acpi_enter_sleep_state (
/* Get current value of PM1A control */
status
=
acpi_hw_register_read
(
ACPI_MTX_LOCK
,
ACPI_REGISTER_PM1_CONTROL
,
&
PM1Acontrol
);
status
=
acpi_hw_register_read
(
ACPI_MTX_
DO_NOT_
LOCK
,
ACPI_REGISTER_PM1_CONTROL
,
&
PM1Acontrol
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
...
...
@@ -268,12 +268,12 @@ acpi_enter_sleep_state (
/* Write #1: fill in SLP_TYP data */
status
=
acpi_hw_register_write
(
ACPI_MTX_LOCK
,
ACPI_REGISTER_PM1A_CONTROL
,
PM1Acontrol
);
status
=
acpi_hw_register_write
(
ACPI_MTX_
DO_NOT_
LOCK
,
ACPI_REGISTER_PM1A_CONTROL
,
PM1Acontrol
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
status
=
acpi_hw_register_write
(
ACPI_MTX_LOCK
,
ACPI_REGISTER_PM1B_CONTROL
,
PM1Bcontrol
);
status
=
acpi_hw_register_write
(
ACPI_MTX_
DO_NOT_
LOCK
,
ACPI_REGISTER_PM1B_CONTROL
,
PM1Bcontrol
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
...
...
@@ -287,12 +287,12 @@ acpi_enter_sleep_state (
ACPI_FLUSH_CPU_CACHE
();
status
=
acpi_hw_register_write
(
ACPI_MTX_LOCK
,
ACPI_REGISTER_PM1A_CONTROL
,
PM1Acontrol
);
status
=
acpi_hw_register_write
(
ACPI_MTX_
DO_NOT_
LOCK
,
ACPI_REGISTER_PM1A_CONTROL
,
PM1Acontrol
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
status
=
acpi_hw_register_write
(
ACPI_MTX_LOCK
,
ACPI_REGISTER_PM1B_CONTROL
,
PM1Bcontrol
);
status
=
acpi_hw_register_write
(
ACPI_MTX_
DO_NOT_
LOCK
,
ACPI_REGISTER_PM1B_CONTROL
,
PM1Bcontrol
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
...
...
@@ -308,7 +308,7 @@ acpi_enter_sleep_state (
*/
acpi_os_stall
(
10000000
);
status
=
acpi_hw_register_write
(
ACPI_MTX_LOCK
,
ACPI_REGISTER_PM1_CONTROL
,
status
=
acpi_hw_register_write
(
ACPI_MTX_
DO_NOT_
LOCK
,
ACPI_REGISTER_PM1_CONTROL
,
sleep_enable_reg_info
->
access_bit_mask
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
...
...
@@ -318,7 +318,7 @@ acpi_enter_sleep_state (
/* Wait until we enter sleep state */
do
{
status
=
acpi_get_register
(
ACPI_BITREG_WAKE_STATUS
,
&
in_value
,
ACPI_MTX_LOCK
);
status
=
acpi_get_register
(
ACPI_BITREG_WAKE_STATUS
,
&
in_value
,
ACPI_MTX_
DO_NOT_
LOCK
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
...
...
@@ -327,7 +327,7 @@ acpi_enter_sleep_state (
}
while
(
!
in_value
);
status
=
acpi_set_register
(
ACPI_BITREG_ARB_DISABLE
,
0
,
ACPI_MTX_LOCK
);
status
=
acpi_set_register
(
ACPI_BITREG_ARB_DISABLE
,
0
,
ACPI_MTX_
DO_NOT_
LOCK
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
...
...
@@ -335,6 +335,51 @@ acpi_enter_sleep_state (
return_ACPI_STATUS
(
AE_OK
);
}
/******************************************************************************
*
* FUNCTION: acpi_enter_sleep_state_s4bios
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Perform a S4 bios request.
* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
*
******************************************************************************/
acpi_status
acpi_enter_sleep_state_s4bios
(
void
)
{
u32
in_value
;
acpi_status
status
;
ACPI_FUNCTION_TRACE
(
"acpi_enter_sleep_state_s4bios"
);
acpi_set_register
(
ACPI_BITREG_WAKE_STATUS
,
1
,
ACPI_MTX_DO_NOT_LOCK
);
acpi_hw_clear_acpi_status
();
acpi_hw_disable_non_wakeup_gpes
();
ACPI_FLUSH_CPU_CACHE
();
status
=
acpi_os_write_port
(
acpi_gbl_FADT
->
smi_cmd
,
(
acpi_integer
)
acpi_gbl_FADT
->
S4bios_req
,
8
);
do
{
acpi_os_stall
(
1000
);
status
=
acpi_get_register
(
ACPI_BITREG_WAKE_STATUS
,
&
in_value
,
ACPI_MTX_DO_NOT_LOCK
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
}
while
(
!
in_value
);
return_ACPI_STATUS
(
AE_OK
);
}
/******************************************************************************
*
* FUNCTION: acpi_leave_sleep_state
...
...
drivers/acpi/osl.c
View file @
35d48993
...
...
@@ -514,10 +514,12 @@ acpi_os_write_pci_configuration (
/* TODO: Change code to take advantage of driver model more */
void
acpi_os_derive_pci_id
(
acpi_os_derive_pci_id
_2
(
acpi_handle
rhandle
,
/* upper bound */
acpi_handle
chandle
,
/* current node */
struct
acpi_pci_id
**
id
)
struct
acpi_pci_id
**
id
,
int
*
is_bridge
,
u8
*
bus_number
)
{
acpi_handle
handle
;
struct
acpi_pci_id
*
pci_id
=
*
id
;
...
...
@@ -528,7 +530,7 @@ acpi_os_derive_pci_id (
acpi_get_parent
(
chandle
,
&
handle
);
if
(
handle
!=
rhandle
)
{
acpi_os_derive_pci_id
(
rhandle
,
handle
,
&
pci_id
);
acpi_os_derive_pci_id
_2
(
rhandle
,
handle
,
&
pci_id
,
is_bridge
,
bus_number
);
status
=
acpi_get_type
(
handle
,
&
type
);
if
(
(
ACPI_FAILURE
(
status
))
||
(
type
!=
ACPI_TYPE_DEVICE
)
)
...
...
@@ -539,17 +541,42 @@ acpi_os_derive_pci_id (
pci_id
->
device
=
ACPI_HIWORD
(
ACPI_LODWORD
(
temp
));
pci_id
->
function
=
ACPI_LOWORD
(
ACPI_LODWORD
(
temp
));
if
(
*
is_bridge
)
pci_id
->
bus
=
*
bus_number
;
/* any nicer way to get bus number of bridge ? */
status
=
acpi_os_read_pci_configuration
(
pci_id
,
0x0e
,
&
tu8
,
8
);
if
(
ACPI_SUCCESS
(
status
)
&&
(
tu8
&
0x7f
)
==
1
)
{
if
(
ACPI_SUCCESS
(
status
)
&&
((
tu8
&
0x7f
)
==
1
||
(
tu8
&
0x7f
)
==
2
))
{
status
=
acpi_os_read_pci_configuration
(
pci_id
,
0x18
,
&
tu8
,
8
);
if
(
!
ACPI_SUCCESS
(
status
))
{
/* Certainly broken... FIX ME */
return
;
}
*
is_bridge
=
1
;
pci_id
->
bus
=
tu8
;
status
=
acpi_os_read_pci_configuration
(
pci_id
,
0x19
,
&
tu8
,
8
);
if
(
ACPI_SUCCESS
(
status
))
pci_id
->
bus
=
tu8
;
}
if
(
ACPI_SUCCESS
(
status
))
{
*
bus_number
=
tu8
;
}
}
else
*
is_bridge
=
0
;
}
}
}
void
acpi_os_derive_pci_id
(
acpi_handle
rhandle
,
/* upper bound */
acpi_handle
chandle
,
/* current node */
struct
acpi_pci_id
**
id
)
{
int
is_bridge
=
1
;
u8
bus_number
=
(
*
id
)
->
bus
;
acpi_os_derive_pci_id_2
(
rhandle
,
chandle
,
id
,
&
is_bridge
,
&
bus_number
);
}
#else
/*!CONFIG_ACPI_PCI*/
acpi_status
...
...
drivers/acpi/pci_link.c
View file @
35d48993
...
...
@@ -90,42 +90,25 @@ static struct {
PCI Link Device Management
-------------------------------------------------------------------------- */
static
int
acpi_pci_link_get_possible
(
struct
acpi_pci_link
*
link
)
static
acpi_status
acpi_pci_link_check_possible
(
struct
acpi_resource
*
resource
,
void
*
context
)
{
int
result
=
0
;
acpi_status
status
=
AE_OK
;
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
struct
acpi_resource
*
resource
=
NULL
;
struct
acpi_pci_link
*
link
=
(
struct
acpi_pci_link
*
)
context
;
int
i
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_link_get_possible"
);
if
(
!
link
)
return_VALUE
(
-
EINVAL
);
status
=
acpi_get_possible_resources
(
link
->
handle
,
&
buffer
);
if
(
ACPI_FAILURE
(
status
)
||
!
buffer
.
pointer
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Error evaluating _PRS
\n
"
));
result
=
-
ENODEV
;
goto
end
;
}
resource
=
(
struct
acpi_resource
*
)
buffer
.
pointer
;
/* skip past dependent function resource (if present) */
if
(
resource
->
id
==
ACPI_RSTYPE_START_DPF
)
resource
=
ACPI_NEXT_RESOURCE
(
resource
);
ACPI_FUNCTION_TRACE
(
"acpi_pci_link_check_possible"
);
switch
(
resource
->
id
)
{
case
ACPI_RSTYPE_START_DPF
:
return
AE_OK
;
case
ACPI_RSTYPE_IRQ
:
{
struct
acpi_resource_irq
*
p
=
&
resource
->
data
.
irq
;
if
(
!
p
||
!
p
->
number_of_interrupts
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"Blank IRQ resource
\n
"
));
result
=
-
ENODEV
;
goto
end
;
return
AE_OK
;
}
for
(
i
=
0
;
(
i
<
p
->
number_of_interrupts
&&
i
<
ACPI_PCI_LINK_MAX_POSSIBLE
);
i
++
)
{
if
(
!
p
->
interrupts
[
i
])
{
...
...
@@ -143,8 +126,7 @@ acpi_pci_link_get_possible (
if
(
!
p
||
!
p
->
number_of_interrupts
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"Blank IRQ resource
\n
"
));
result
=
-
ENODEV
;
goto
end
;
return
AE_OK
;
}
for
(
i
=
0
;
(
i
<
p
->
number_of_interrupts
&&
i
<
ACPI_PCI_LINK_MAX_POSSIBLE
);
i
++
)
{
if
(
!
p
->
interrupts
[
i
])
{
...
...
@@ -159,18 +141,76 @@ acpi_pci_link_get_possible (
default:
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Resource is not an IRQ entry
\n
"
));
result
=
-
ENODEV
;
goto
end
;
break
;
return
AE_OK
;
}
return
AE_CTRL_TERMINATE
;
}
static
int
acpi_pci_link_get_possible
(
struct
acpi_pci_link
*
link
)
{
acpi_status
status
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_link_get_possible"
);
if
(
!
link
)
return_VALUE
(
-
EINVAL
);
status
=
acpi_walk_resources
(
link
->
handle
,
METHOD_NAME__PRS
,
acpi_pci_link_check_possible
,
link
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Error evaluating _PRS
\n
"
));
return_VALUE
(
-
ENODEV
);
}
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Found %d possible IRQs
\n
"
,
link
->
irq
.
possible_count
));
end:
acpi_os_free
(
buffer
.
pointer
);
return_VALUE
(
0
);
}
return_VALUE
(
result
);
static
acpi_status
acpi_pci_link_check_current
(
struct
acpi_resource
*
resource
,
void
*
context
)
{
int
*
irq
=
(
int
*
)
context
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_link_check_current"
);
switch
(
resource
->
id
)
{
case
ACPI_RSTYPE_IRQ
:
{
struct
acpi_resource_irq
*
p
=
&
resource
->
data
.
irq
;
if
(
!
p
||
!
p
->
number_of_interrupts
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"Blank IRQ resource
\n
"
));
return
AE_OK
;
}
*
irq
=
p
->
interrupts
[
0
];
break
;
}
case
ACPI_RSTYPE_EXT_IRQ
:
{
struct
acpi_resource_ext_irq
*
p
=
&
resource
->
data
.
extended_irq
;
if
(
!
p
||
!
p
->
number_of_interrupts
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"Blank IRQ resource
\n
"
));
return
AE_OK
;
}
*
irq
=
p
->
interrupts
[
0
];
break
;
}
default:
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Resource isn't an IRQ
\n
"
));
return
AE_OK
;
}
return
AE_CTRL_TERMINATE
;
}
...
...
@@ -180,8 +220,6 @@ acpi_pci_link_get_current (
{
int
result
=
0
;
acpi_status
status
=
AE_OK
;
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
struct
acpi_resource
*
resource
=
NULL
;
int
irq
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_pci_link_get_current"
);
...
...
@@ -206,47 +244,16 @@ acpi_pci_link_get_current (
* Query and parse _CRS to get the current IRQ assignment.
*/
status
=
acpi_get_current_resources
(
link
->
handle
,
&
buffer
);
status
=
acpi_walk_resources
(
link
->
handle
,
METHOD_NAME__CRS
,
acpi_pci_link_check_current
,
&
irq
);
if
(
ACPI_FAILURE
(
status
))
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Error evaluating _CRS
\n
"
));
result
=
-
ENODEV
;
goto
end
;
}
resource
=
(
struct
acpi_resource
*
)
buffer
.
pointer
;
switch
(
resource
->
id
)
{
case
ACPI_RSTYPE_IRQ
:
{
struct
acpi_resource_irq
*
p
=
&
resource
->
data
.
irq
;
if
(
!
p
||
!
p
->
number_of_interrupts
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"Blank IRQ resource
\n
"
));
result
=
-
ENODEV
;
goto
end
;
}
irq
=
p
->
interrupts
[
0
];
break
;
}
case
ACPI_RSTYPE_EXT_IRQ
:
{
struct
acpi_resource_ext_irq
*
p
=
&
resource
->
data
.
extended_irq
;
if
(
!
p
||
!
p
->
number_of_interrupts
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_WARN
,
"Blank IRQ resource
\n
"
));
result
=
-
ENODEV
;
goto
end
;
}
irq
=
p
->
interrupts
[
0
];
break
;
}
default:
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Resource isn't an IRQ
\n
"
));
result
=
-
ENODEV
;
goto
end
;
}
if
(
!
irq
)
{
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"
Invalid use of IRQ 0
\n
"
));
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"
No IRQ resource found
\n
"
));
result
=
-
ENODEV
;
goto
end
;
}
...
...
@@ -263,8 +270,6 @@ acpi_pci_link_get_current (
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Link at IRQ %d
\n
"
,
link
->
irq
.
active
));
end:
acpi_os_free
(
buffer
.
pointer
);
return_VALUE
(
result
);
}
...
...
drivers/acpi/processor.c
View file @
35d48993
...
...
@@ -1560,7 +1560,7 @@ acpi_processor_get_info (
acpi_status
status
=
0
;
union
acpi_object
object
=
{
0
};
struct
acpi_buffer
buffer
=
{
sizeof
(
union
acpi_object
),
&
object
};
static
int
cpu_
count
=
0
;
static
int
cpu_
index
=
0
;
ACPI_FUNCTION_TRACE
(
"acpi_processor_get_info"
);
...
...
@@ -1570,6 +1570,13 @@ acpi_processor_get_info (
if
(
num_online_cpus
()
>
1
)
errata
.
smp
=
TRUE
;
/*
* Extra Processor objects may be enumerated on MP systems with
* less than the max # of CPUs. They should be ignored.
*/
if
((
cpu_index
+
1
)
>
num_online_cpus
())
return_VALUE
(
-
ENODEV
);
acpi_processor_errata
(
pr
);
/*
...
...
@@ -1601,7 +1608,7 @@ acpi_processor_get_info (
* TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
* >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c
*/
pr
->
id
=
cpu_
count
++
;
pr
->
id
=
cpu_
index
++
;
pr
->
acpi_id
=
object
.
processor
.
proc_id
;
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"Processor [%d:%d]
\n
"
,
pr
->
id
,
...
...
@@ -1609,21 +1616,17 @@ acpi_processor_get_info (
if
(
!
object
.
processor
.
pblk_address
)
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"No PBLK (NULL address)
\n
"
));
else
if
(
object
.
processor
.
pblk_length
<
4
)
else
if
(
object
.
processor
.
pblk_length
!=
6
)
ACPI_DEBUG_PRINT
((
ACPI_DB_ERROR
,
"Invalid PBLK length [%d]
\n
"
,
object
.
processor
.
pblk_length
));
else
{
pr
->
throttling
.
address
=
object
.
processor
.
pblk_address
;
pr
->
throttling
.
duty_offset
=
acpi_fadt
.
duty_offset
;
pr
->
throttling
.
duty_width
=
acpi_fadt
.
duty_width
;
if
(
object
.
processor
.
pblk_length
>=
5
)
pr
->
power
.
states
[
ACPI_STATE_C2
].
address
=
object
.
processor
.
pblk_address
+
4
;
if
(
object
.
processor
.
pblk_length
>=
6
)
pr
->
power
.
states
[
ACPI_STATE_C3
].
address
=
object
.
processor
.
pblk_address
+
5
;
pr
->
power
.
states
[
ACPI_STATE_C2
].
address
=
object
.
processor
.
pblk_address
+
4
;
pr
->
power
.
states
[
ACPI_STATE_C3
].
address
=
object
.
processor
.
pblk_address
+
5
;
}
acpi_processor_get_power_info
(
pr
);
...
...
drivers/acpi/resources/rsutils.c
View file @
35d48993
...
...
@@ -212,6 +212,60 @@ acpi_rs_get_prs_method_data (
}
/*******************************************************************************
*
* FUNCTION: acpi_rs_get_method_data
*
* PARAMETERS: Handle - a handle to the containing object
* ret_buffer - a pointer to a buffer structure for the
* results
*
* RETURN: Status
*
* DESCRIPTION: This function is called to get the _CRS or _PRS value of an
* object contained in an object specified by the handle passed in
*
* If the function fails an appropriate status will be returned
* and the contents of the callers buffer is undefined.
*
******************************************************************************/
acpi_status
acpi_rs_get_method_data
(
acpi_handle
handle
,
char
*
path
,
struct
acpi_buffer
*
ret_buffer
)
{
union
acpi_operand_object
*
obj_desc
;
acpi_status
status
;
ACPI_FUNCTION_TRACE
(
"rs_get_method_data"
);
/* Parameters guaranteed valid by caller */
/*
* Execute the method, no parameters
*/
status
=
acpi_ut_evaluate_object
(
handle
,
path
,
ACPI_BTYPE_BUFFER
,
&
obj_desc
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
/*
* Make the call to create a resource linked list from the
* byte stream buffer that comes back from the method
* execution.
*/
status
=
acpi_rs_create_resource_list
(
obj_desc
,
ret_buffer
);
/* On exit, we must delete the object returned by evaluate_object */
acpi_ut_remove_reference
(
obj_desc
);
return_ACPI_STATUS
(
status
);
}
/*******************************************************************************
*
* FUNCTION: acpi_rs_set_srs_method_data
...
...
drivers/acpi/resources/rsxface.c
View file @
35d48993
...
...
@@ -210,6 +210,90 @@ acpi_get_possible_resources (
}
/*******************************************************************************
*
* FUNCTION: acpi_walk_resources
*
* PARAMETERS: device_handle - a handle to the device object for the
* device we are querying
* Path - method name of the resources we want
* (METHOD_NAME__CRS or METHOD_NAME__PRS)
* user_function - called for each resource
* Context - passed to user_function
*
* RETURN: Status
*
* DESCRIPTION: Retrieves the current or possible resource list for the
* specified device. The user_function is called once for
* each resource in the list.
*
******************************************************************************/
acpi_status
acpi_walk_resources
(
acpi_handle
device_handle
,
char
*
path
,
ACPI_WALK_RESOURCE_CALLBACK
user_function
,
void
*
context
)
{
acpi_status
status
;
struct
acpi_buffer
buffer
=
{
ACPI_ALLOCATE_BUFFER
,
NULL
};
struct
acpi_resource
*
resource
;
ACPI_FUNCTION_TRACE
(
"acpi_walk_resources"
);
if
(
!
device_handle
||
(
ACPI_STRNCMP
(
path
,
METHOD_NAME__CRS
,
sizeof
(
METHOD_NAME__CRS
))
&&
ACPI_STRNCMP
(
path
,
METHOD_NAME__PRS
,
sizeof
(
METHOD_NAME__PRS
))))
{
return_ACPI_STATUS
(
AE_BAD_PARAMETER
);
}
status
=
acpi_rs_get_method_data
(
device_handle
,
path
,
&
buffer
);
if
(
ACPI_FAILURE
(
status
))
{
return_ACPI_STATUS
(
status
);
}
resource
=
(
struct
acpi_resource
*
)
buffer
.
pointer
;
for
(;;)
{
if
(
!
resource
||
resource
->
id
==
ACPI_RSTYPE_END_TAG
)
{
break
;
}
status
=
user_function
(
resource
,
context
);
switch
(
status
)
{
case
AE_OK
:
case
AE_CTRL_DEPTH
:
/* Just keep going */
status
=
AE_OK
;
break
;
case
AE_CTRL_TERMINATE
:
/* Exit now, with OK stats */
status
=
AE_OK
;
goto
cleanup
;
default:
/* All others are valid exceptions */
goto
cleanup
;
}
resource
=
ACPI_NEXT_RESOURCE
(
resource
);
}
cleanup:
acpi_os_free
(
buffer
.
pointer
);
return_ACPI_STATUS
(
status
);
}
/*******************************************************************************
*
* FUNCTION: acpi_set_current_resources
...
...
@@ -252,3 +336,64 @@ acpi_set_current_resources (
status
=
acpi_rs_set_srs_method_data
(
device_handle
,
in_buffer
);
return_ACPI_STATUS
(
status
);
}
#define COPY_FIELD(out, in, field) out->field = in->field
#define COPY_ADDRESS(out, in) \
COPY_FIELD(out, in, resource_type); \
COPY_FIELD(out, in, producer_consumer); \
COPY_FIELD(out, in, decode); \
COPY_FIELD(out, in, min_address_fixed); \
COPY_FIELD(out, in, max_address_fixed); \
COPY_FIELD(out, in, attribute); \
COPY_FIELD(out, in, granularity); \
COPY_FIELD(out, in, min_address_range); \
COPY_FIELD(out, in, max_address_range); \
COPY_FIELD(out, in, address_translation_offset); \
COPY_FIELD(out, in, address_length); \
COPY_FIELD(out, in, resource_source);
/*******************************************************************************
*
* FUNCTION: acpi_resource_to_address64
*
* PARAMETERS: resource - Pointer to a resource
* out - Pointer to the users's return
* buffer (a struct
* struct acpi_resource_address64)
*
* RETURN: Status
*
* DESCRIPTION: If the resource is an address16, address32, or address64,
* copy it to the address64 return buffer. This saves the
* caller from having to duplicate code for different-sized
* addresses.
*
******************************************************************************/
acpi_status
acpi_resource_to_address64
(
struct
acpi_resource
*
resource
,
struct
acpi_resource_address64
*
out
)
{
struct
acpi_resource_address16
*
address16
;
struct
acpi_resource_address32
*
address32
;
struct
acpi_resource_address64
*
address64
;
switch
(
resource
->
id
)
{
case
ACPI_RSTYPE_ADDRESS16
:
address16
=
(
struct
acpi_resource_address16
*
)
&
resource
->
data
;
COPY_ADDRESS
(
out
,
address16
);
break
;
case
ACPI_RSTYPE_ADDRESS32
:
address32
=
(
struct
acpi_resource_address32
*
)
&
resource
->
data
;
COPY_ADDRESS
(
out
,
address32
);
break
;
case
ACPI_RSTYPE_ADDRESS64
:
address64
=
(
struct
acpi_resource_address64
*
)
&
resource
->
data
;
COPY_ADDRESS
(
out
,
address64
);
break
;
default:
return
(
AE_BAD_PARAMETER
);
}
return
(
AE_OK
);
}
drivers/acpi/sleep/main.c
View file @
35d48993
...
...
@@ -183,14 +183,21 @@ acpi_system_suspend(
status
=
acpi_enter_sleep_state
(
state
);
break
;
case
ACPI_STATE_S2
:
#ifdef CONFIG_SOFTWARE_SUSPEND
case
ACPI_STATE_S2
:
case
ACPI_STATE_S3
:
do_suspend_lowlevel
(
0
);
break
;
#endif
case
ACPI_STATE_S4
:
do_suspend_lowlevel_s4bios
(
0
);
break
;
default:
printk
(
KERN_WARNING
PREFIX
"don't know how to handle %d state.
\n
"
,
state
);
break
;
}
local_irq_restore
(
flags
);
printk
(
KERN_CRIT
"Back to C!
\n
"
);
return
status
;
}
...
...
@@ -211,21 +218,31 @@ acpi_suspend (
if
(
state
<
ACPI_STATE_S1
||
state
>
ACPI_STATE_S5
)
return
AE_ERROR
;
/* Since we handle S4OS via a different path (swsusp), give up if no s4bios. */
if
(
state
==
ACPI_STATE_S4
&&
!
acpi_gbl_FACS
->
S4bios_f
)
return
AE_ERROR
;
/*
* TBD: S1 can be done without device_suspend. Make a CONFIG_XX
* to handle however when S1 failed without device_suspend.
*/
freeze_processes
();
/* device_suspend needs processes to be stopped */
/* do we have a wakeup address for S2 and S3? */
if
(
state
==
ACPI_STATE_S2
||
state
==
ACPI_STATE_S3
)
{
/* Here, we support only S4BIOS, those we set the wakeup address */
/* S4OS is only supported for now via swsusp.. */
if
(
state
==
ACPI_STATE_S2
||
state
==
ACPI_STATE_S3
||
ACPI_STATE_S4
)
{
if
(
!
acpi_wakeup_address
)
return
AE_ERROR
;
acpi_set_firmware_waking_vector
((
acpi_physical_address
)
acpi_wakeup_address
);
}
acpi_enter_sleep_state_prep
(
state
);
status
=
acpi_system_save_state
(
state
);
if
(
!
ACPI_SUCCESS
(
status
))
return
status
;
acpi_enter_sleep_state_prep
(
state
);
/* disable interrupts and flush caches */
ACPI_DISABLE_IRQS
();
ACPI_FLUSH_CPU_CACHE
();
...
...
@@ -237,8 +254,8 @@ acpi_suspend (
* mode. So, we run these unconditionaly to make sure we have a usable system
* no matter what.
*/
acpi_system_restore_state
(
state
);
acpi_leave_sleep_state
(
state
);
acpi_system_restore_state
(
state
);
/* make sure interrupts are enabled */
ACPI_ENABLE_IRQS
();
...
...
@@ -268,6 +285,10 @@ static int __init acpi_sleep_init(void)
sleep_states
[
i
]
=
1
;
printk
(
" S%d"
,
i
);
}
if
(
i
==
ACPI_STATE_S4
&&
acpi_gbl_FACS
->
S4bios_f
)
{
sleep_states
[
i
]
=
1
;
printk
(
" S4bios"
);
}
}
printk
(
")
\n
"
);
...
...
drivers/acpi/sleep/proc.c
View file @
35d48993
...
...
@@ -27,8 +27,11 @@ static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
ACPI_FUNCTION_TRACE
(
"acpi_system_sleep_seq_show"
);
for
(
i
=
0
;
i
<=
ACPI_STATE_S5
;
i
++
)
{
if
(
sleep_states
[
i
])
if
(
sleep_states
[
i
])
{
seq_printf
(
seq
,
"S%d "
,
i
);
if
(
i
==
ACPI_STATE_S4
&&
acpi_gbl_FACS
->
S4bios_f
)
seq_printf
(
seq
,
"S4bios "
);
}
}
seq_puts
(
seq
,
"
\n
"
);
...
...
drivers/acpi/tables.c
View file @
35d48993
...
...
@@ -379,6 +379,7 @@ acpi_table_get_sdt (
sdt
.
pa
=
((
struct
acpi20_table_rsdp
*
)
rsdp
)
->
xsdt_address
;
/* map in just the header */
header
=
(
struct
acpi_table_header
*
)
__acpi_map_table
(
sdt
.
pa
,
sizeof
(
struct
acpi_table_header
));
...
...
@@ -387,6 +388,15 @@ acpi_table_get_sdt (
return
-
ENODEV
;
}
/* remap in the entire table before processing */
mapped_xsdt
=
(
struct
acpi_table_xsdt
*
)
__acpi_map_table
(
sdt
.
pa
,
header
->
length
);
if
(
!
mapped_xsdt
)
{
printk
(
KERN_WARNING
PREFIX
"Unable to map XSDT
\n
"
);
return
-
ENODEV
;
}
header
=
&
mapped_xsdt
->
header
;
if
(
strncmp
(
header
->
signature
,
"XSDT"
,
4
))
{
printk
(
KERN_WARNING
PREFIX
"XSDT signature incorrect
\n
"
);
return
-
ENODEV
;
...
...
@@ -404,15 +414,6 @@ acpi_table_get_sdt (
sdt
.
count
=
ACPI_MAX_TABLES
;
}
mapped_xsdt
=
(
struct
acpi_table_xsdt
*
)
__acpi_map_table
(
sdt
.
pa
,
header
->
length
);
if
(
!
mapped_xsdt
)
{
printk
(
KERN_WARNING
PREFIX
"Unable to map XSDT
\n
"
);
return
-
ENODEV
;
}
header
=
&
mapped_xsdt
->
header
;
for
(
i
=
0
;
i
<
sdt
.
count
;
i
++
)
sdt
.
entry
[
i
].
pa
=
(
unsigned
long
)
mapped_xsdt
->
entry
[
i
];
}
...
...
@@ -425,6 +426,7 @@ acpi_table_get_sdt (
sdt
.
pa
=
rsdp
->
rsdt_address
;
/* map in just the header */
header
=
(
struct
acpi_table_header
*
)
__acpi_map_table
(
sdt
.
pa
,
sizeof
(
struct
acpi_table_header
));
if
(
!
header
)
{
...
...
@@ -432,6 +434,15 @@ acpi_table_get_sdt (
return
-
ENODEV
;
}
/* remap in the entire table before processing */
mapped_rsdt
=
(
struct
acpi_table_rsdt
*
)
__acpi_map_table
(
sdt
.
pa
,
header
->
length
);
if
(
!
mapped_rsdt
)
{
printk
(
KERN_WARNING
PREFIX
"Unable to map RSDT
\n
"
);
return
-
ENODEV
;
}
header
=
&
mapped_rsdt
->
header
;
if
(
strncmp
(
header
->
signature
,
"RSDT"
,
4
))
{
printk
(
KERN_WARNING
PREFIX
"RSDT signature incorrect
\n
"
);
return
-
ENODEV
;
...
...
@@ -449,15 +460,6 @@ acpi_table_get_sdt (
sdt
.
count
=
ACPI_MAX_TABLES
;
}
mapped_rsdt
=
(
struct
acpi_table_rsdt
*
)
__acpi_map_table
(
sdt
.
pa
,
header
->
length
);
if
(
!
mapped_rsdt
)
{
printk
(
KERN_WARNING
PREFIX
"Unable to map RSDT
\n
"
);
return
-
ENODEV
;
}
header
=
&
mapped_rsdt
->
header
;
for
(
i
=
0
;
i
<
sdt
.
count
;
i
++
)
sdt
.
entry
[
i
].
pa
=
(
unsigned
long
)
mapped_rsdt
->
entry
[
i
];
}
...
...
@@ -471,12 +473,20 @@ acpi_table_get_sdt (
for
(
i
=
0
;
i
<
sdt
.
count
;
i
++
)
{
/* map in just the header */
header
=
(
struct
acpi_table_header
*
)
__acpi_map_table
(
sdt
.
entry
[
i
].
pa
,
sizeof
(
struct
acpi_table_header
));
if
(
!
header
)
continue
;
/* remap in the entire table before processing */
header
=
(
struct
acpi_table_header
*
)
__acpi_map_table
(
sdt
.
entry
[
i
].
pa
,
header
->
length
);
if
(
!
header
)
continue
;
acpi_table_print
(
header
,
sdt
.
entry
[
i
].
pa
);
if
(
acpi_table_compute_checksum
(
header
,
header
->
length
))
{
...
...
drivers/acpi/tables/tbconvrt.c
View file @
35d48993
...
...
@@ -239,9 +239,8 @@ acpi_tb_convert_fadt1 (
ASL_BUILD_GAS_FROM_V1_ENTRY
(
local_fadt
->
xpm1b_cnt_blk
,
local_fadt
->
pm1_cnt_len
,
local_fadt
->
V1_pm1b_cnt_blk
);
ASL_BUILD_GAS_FROM_V1_ENTRY
(
local_fadt
->
xpm2_cnt_blk
,
local_fadt
->
pm2_cnt_len
,
local_fadt
->
V1_pm2_cnt_blk
);
ASL_BUILD_GAS_FROM_V1_ENTRY
(
local_fadt
->
xpm_tmr_blk
,
local_fadt
->
pm_tm_len
,
local_fadt
->
V1_pm_tmr_blk
);
ASL_BUILD_GAS_FROM_V1_ENTRY
(
local_fadt
->
xgpe0_blk
,
local_fadt
->
gpe0_blk_len
,
local_fadt
->
V1_gpe0_blk
);
ASL_BUILD_GAS_FROM_V1_ENTRY
(
local_fadt
->
xgpe1_blk
,
local_fadt
->
gpe1_blk_len
,
local_fadt
->
V1_gpe1_blk
);
ASL_BUILD_GAS_FROM_V1_ENTRY
(
local_fadt
->
xgpe0_blk
,
0
,
local_fadt
->
V1_gpe0_blk
);
ASL_BUILD_GAS_FROM_V1_ENTRY
(
local_fadt
->
xgpe1_blk
,
0
,
local_fadt
->
V1_gpe1_blk
);
}
...
...
@@ -314,15 +313,16 @@ acpi_tb_convert_fadt2 (
if
(
!
(
local_fadt
->
xgpe0_blk
.
address
))
{
ASL_BUILD_GAS_FROM_V1_ENTRY
(
local_fadt
->
xgpe0_blk
,
local_fadt
->
gpe0_blk_len
,
local_fadt
->
V1_gpe0_blk
);
0
,
local_fadt
->
V1_gpe0_blk
);
}
if
(
!
(
local_fadt
->
xgpe1_blk
.
address
))
{
ASL_BUILD_GAS_FROM_V1_ENTRY
(
local_fadt
->
xgpe1_blk
,
local_fadt
->
gpe1_blk_len
,
local_fadt
->
V1_gpe1_blk
);
0
,
local_fadt
->
V1_gpe1_blk
);
}
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_convert_table_fadt
...
...
drivers/acpi/utilities/utcopy.c
View file @
35d48993
...
...
@@ -645,11 +645,11 @@ acpi_ut_copy_simple_object (
/*
* Allocate and copy the actual buffer if and only if:
* 1) There is a valid buffer
(length > 0)
* 1) There is a valid buffer
pointer
* 2) The buffer is not static (not in an ACPI table) (in this case,
* the actual pointer was already copied above)
*/
if
((
source_desc
->
buffer
.
length
)
&&
if
((
source_desc
->
buffer
.
pointer
)
&&
(
!
(
source_desc
->
common
.
flags
&
AOPOBJ_STATIC_POINTER
)))
{
dest_desc
->
buffer
.
pointer
=
ACPI_MEM_ALLOCATE
(
source_desc
->
buffer
.
length
);
if
(
!
dest_desc
->
buffer
.
pointer
)
{
...
...
@@ -665,11 +665,11 @@ acpi_ut_copy_simple_object (
/*
* Allocate and copy the actual string if and only if:
* 1) There is a valid string
(length > 0)
* 1) There is a valid string
pointer
* 2) The string is not static (not in an ACPI table) (in this case,
* the actual pointer was already copied above)
*/
if
((
source_desc
->
string
.
length
)
&&
if
((
source_desc
->
string
.
pointer
)
&&
(
!
(
source_desc
->
common
.
flags
&
AOPOBJ_STATIC_POINTER
)))
{
dest_desc
->
string
.
pointer
=
ACPI_MEM_ALLOCATE
((
acpi_size
)
source_desc
->
string
.
length
+
1
);
if
(
!
dest_desc
->
string
.
pointer
)
{
...
...
drivers/acpi/utilities/utglobal.c
View file @
35d48993
...
...
@@ -729,6 +729,10 @@ acpi_ut_init_globals (
acpi_gbl_acpi_mutex_info
[
i
].
use_count
=
0
;
}
/* GPE support */
acpi_gbl_gpe_block_list_head
=
NULL
;
/* Global notify handlers */
acpi_gbl_sys_notify
.
handler
=
NULL
;
...
...
@@ -766,8 +770,6 @@ acpi_ut_init_globals (
/* Hardware oriented */
acpi_gbl_gpe_register_info
=
NULL
;
acpi_gbl_gpe_number_info
=
NULL
;
acpi_gbl_events_initialized
=
FALSE
;
/* Namespace */
...
...
drivers/hotplug/acpiphp_glue.c
View file @
35d48993
...
...
@@ -229,136 +229,55 @@ static int detect_ejectable_slots (acpi_handle *bridge_handle)
/* decode ACPI _CRS data and convert into our internal resource list
* TBD: _TRA, etc.
*/
static
void
decode_acpi_resource
(
struct
acpi_resource
*
resource
,
struct
acpiphp_bridge
*
bridge
)
static
acpi_status
decode_acpi_resource
(
struct
acpi_resource
*
resource
,
void
*
context
)
{
struct
acpi_resource_address16
*
address16_data
;
struct
acpi_resource_address32
*
address32_data
;
struct
acpi_resource_address64
*
address64_data
;
struct
acpiphp_bridge
*
bridge
=
(
struct
acpiphp_bridge
*
)
context
;
struct
acpi_resource_address64
address
;
struct
pci_resource
*
res
;
u32
resource_type
,
producer_consumer
,
address_length
;
u64
min_address_range
,
max_address_range
;
u16
cache_attribute
=
0
;
int
done
=
0
,
found
;
/* shut up gcc */
resource_type
=
producer_consumer
=
address_length
=
0
;
min_address_range
=
max_address_range
=
0
;
while
(
!
done
)
{
found
=
0
;
switch
(
resource
->
id
)
{
case
ACPI_RSTYPE_ADDRESS16
:
address16_data
=
(
struct
acpi_resource_address16
*
)
&
resource
->
data
;
resource_type
=
address16_data
->
resource_type
;
producer_consumer
=
address16_data
->
producer_consumer
;
min_address_range
=
address16_data
->
min_address_range
;
max_address_range
=
address16_data
->
max_address_range
;
address_length
=
address16_data
->
address_length
;
if
(
resource_type
==
ACPI_MEMORY_RANGE
)
cache_attribute
=
address16_data
->
attribute
.
memory
.
cache_attribute
;
found
=
1
;
break
;
if
(
resource
->
id
!=
ACPI_RSTYPE_ADDRESS16
&&
resource
->
id
!=
ACPI_RSTYPE_ADDRESS32
&&
resource
->
id
!=
ACPI_RSTYPE_ADDRESS64
)
return
AE_OK
;
case
ACPI_RSTYPE_ADDRESS32
:
address32_data
=
(
struct
acpi_resource_address32
*
)
&
resource
->
data
;
resource_type
=
address32_data
->
resource_type
;
producer_consumer
=
address32_data
->
producer_consumer
;
min_address_range
=
address32_data
->
min_address_range
;
max_address_range
=
address32_data
->
max_address_range
;
address_length
=
address32_data
->
address_length
;
if
(
resource_type
==
ACPI_MEMORY_RANGE
)
cache_attribute
=
address32_data
->
attribute
.
memory
.
cache_attribute
;
found
=
1
;
break
;
acpi_resource_to_address64
(
resource
,
&
address
);
case
ACPI_RSTYPE_ADDRESS64
:
address64_data
=
(
struct
acpi_resource_address64
*
)
&
resource
->
data
;
resource_type
=
address64_data
->
resource_type
;
producer_consumer
=
address64_data
->
producer_consumer
;
min_address_range
=
address64_data
->
min_address_range
;
max_address_range
=
address64_data
->
max_address_range
;
address_length
=
address64_data
->
address_length
;
if
(
resource_type
==
ACPI_MEMORY_RANGE
)
cache_attribute
=
address64_data
->
attribute
.
memory
.
cache_attribute
;
found
=
1
;
break
;
if
(
address
.
producer_consumer
==
ACPI_PRODUCER
&&
address
.
address_length
>
0
)
{
dbg
(
"resource type: %d: 0x%llx - 0x%llx
\n
"
,
address
.
resource_type
,
address
.
min_address_range
,
address
.
max_address_range
);
res
=
acpiphp_make_resource
(
address
.
min_address_range
,
address
.
address_length
);
if
(
!
res
)
{
err
(
"out of memory
\n
"
);
return
AE_OK
;
}
case
ACPI_RSTYPE_END_TAG
:
done
=
1
;
switch
(
address
.
resource_type
)
{
case
ACPI_MEMORY_RANGE
:
if
(
address
.
attribute
.
memory
.
cache_attribute
==
ACPI_PREFETCHABLE_MEMORY
)
{
res
->
next
=
bridge
->
p_mem_head
;
bridge
->
p_mem_head
=
res
;
}
else
{
res
->
next
=
bridge
->
mem_head
;
bridge
->
mem_head
=
res
;
}
break
;
case
ACPI_IO_RANGE
:
res
->
next
=
bridge
->
io_head
;
bridge
->
io_head
=
res
;
break
;
case
ACPI_BUS_NUMBER_RANGE
:
res
->
next
=
bridge
->
bus_head
;
bridge
->
bus_head
=
res
;
break
;
default:
/* ignore */
/* invalid type */
kfree
(
res
);
break
;
}
resource
=
(
struct
acpi_resource
*
)((
char
*
)
resource
+
resource
->
length
);
if
(
found
&&
producer_consumer
==
ACPI_PRODUCER
&&
address_length
>
0
)
{
switch
(
resource_type
)
{
case
ACPI_MEMORY_RANGE
:
if
(
cache_attribute
==
ACPI_PREFETCHABLE_MEMORY
)
{
dbg
(
"resource type: prefetchable memory 0x%x - 0x%x
\n
"
,
(
u32
)
min_address_range
,
(
u32
)
max_address_range
);
res
=
acpiphp_make_resource
(
min_address_range
,
address_length
);
if
(
!
res
)
{
err
(
"out of memory
\n
"
);
return
;
}
res
->
next
=
bridge
->
p_mem_head
;
bridge
->
p_mem_head
=
res
;
}
else
{
dbg
(
"resource type: memory 0x%x - 0x%x
\n
"
,
(
u32
)
min_address_range
,
(
u32
)
max_address_range
);
res
=
acpiphp_make_resource
(
min_address_range
,
address_length
);
if
(
!
res
)
{
err
(
"out of memory
\n
"
);
return
;
}
res
->
next
=
bridge
->
mem_head
;
bridge
->
mem_head
=
res
;
}
break
;
case
ACPI_IO_RANGE
:
dbg
(
"resource type: io 0x%x - 0x%x
\n
"
,
(
u32
)
min_address_range
,
(
u32
)
max_address_range
);
res
=
acpiphp_make_resource
(
min_address_range
,
address_length
);
if
(
!
res
)
{
err
(
"out of memory
\n
"
);
return
;
}
res
->
next
=
bridge
->
io_head
;
bridge
->
io_head
=
res
;
break
;
case
ACPI_BUS_NUMBER_RANGE
:
dbg
(
"resource type: bus number %d - %d
\n
"
,
(
u32
)
min_address_range
,
(
u32
)
max_address_range
);
res
=
acpiphp_make_resource
(
min_address_range
,
address_length
);
if
(
!
res
)
{
err
(
"out of memory
\n
"
);
return
;
}
res
->
next
=
bridge
->
bus_head
;
bridge
->
bus_head
=
res
;
break
;
default:
/* invalid type */
break
;
}
}
}
acpiphp_resource_sort_and_combine
(
&
bridge
->
io_head
);
acpiphp_resource_sort_and_combine
(
&
bridge
->
mem_head
);
acpiphp_resource_sort_and_combine
(
&
bridge
->
p_mem_head
);
acpiphp_resource_sort_and_combine
(
&
bridge
->
bus_head
);
dbg
(
"ACPI _CRS resource:
\n
"
);
acpiphp_dump_resource
(
bridge
);
return
AE_OK
;
}
...
...
@@ -476,9 +395,6 @@ static void init_bridge_misc (struct acpiphp_bridge *bridge)
static
void
add_host_bridge
(
acpi_handle
*
handle
,
int
seg
,
int
bus
)
{
acpi_status
status
;
struct
acpi_buffer
buffer
=
{
.
length
=
ACPI_ALLOCATE_BUFFER
,
.
pointer
=
NULL
};
struct
acpiphp_bridge
*
bridge
;
bridge
=
kmalloc
(
sizeof
(
struct
acpiphp_bridge
),
GFP_KERNEL
);
...
...
@@ -501,7 +417,8 @@ static void add_host_bridge (acpi_handle *handle, int seg, int bus)
/* decode resources */
status
=
acpi_get_current_resources
(
handle
,
&
buffer
);
status
=
acpi_walk_resources
(
handle
,
METHOD_NAME__CRS
,
decode_acpi_resource
,
bridge
);
if
(
ACPI_FAILURE
(
status
))
{
err
(
"failed to decode bridge resources
\n
"
);
...
...
@@ -509,8 +426,13 @@ static void add_host_bridge (acpi_handle *handle, int seg, int bus)
return
;
}
decode_acpi_resource
(
buffer
.
pointer
,
bridge
);
kfree
(
buffer
.
pointer
);
acpiphp_resource_sort_and_combine
(
&
bridge
->
io_head
);
acpiphp_resource_sort_and_combine
(
&
bridge
->
mem_head
);
acpiphp_resource_sort_and_combine
(
&
bridge
->
p_mem_head
);
acpiphp_resource_sort_and_combine
(
&
bridge
->
bus_head
);
dbg
(
"ACPI _CRS resource:
\n
"
);
acpiphp_dump_resource
(
bridge
);
if
(
bridge
->
bus_head
)
{
bridge
->
bus
=
bridge
->
bus_head
->
base
;
...
...
include/acpi/acconfig.h
View file @
35d48993
...
...
@@ -72,7 +72,7 @@
/* Version string */
#define ACPI_CA_VERSION 0x20030
122
#define ACPI_CA_VERSION 0x20030
228
/* Version of ACPI supported */
...
...
include/acpi/acdebug.h
View file @
35d48993
...
...
@@ -176,6 +176,9 @@ void
acpi_db_display_resources
(
char
*
object_arg
);
void
acpi_db_display_gpes
(
void
);
void
acpi_db_check_integrity
(
void
);
...
...
@@ -208,6 +211,10 @@ acpi_db_walk_for_specific_objects (
void
*
context
,
void
**
return_value
);
void
acpi_db_generate_gpe
(
char
*
gpe_arg
,
char
*
block_arg
);
/*
* dbdisply - debug display commands
...
...
include/acpi/acevents.h
View file @
35d48993
...
...
@@ -91,14 +91,6 @@ acpi_status
acpi_ev_init_global_lock_handler
(
void
);
struct
acpi_gpe_register_info
*
acpi_ev_get_gpe_register_info
(
u32
gpe_number
);
struct
acpi_gpe_number_info
*
acpi_ev_get_gpe_number_info
(
u32
gpe_number
);
u32
acpi_ev_get_gpe_number_index
(
u32
gpe_number
);
...
...
@@ -117,17 +109,17 @@ acpi_ev_notify_dispatch (
* Evgpe - GPE handling and dispatch
*/
acpi_status
acpi_ev_g
pe_initialize
(
void
);
struct
acpi_gpe_event_info
*
acpi_ev_g
et_gpe_event_info
(
u32
gpe_number
);
acpi_status
acpi_ev_
init_gpe_control_methods
(
acpi_ev_
gpe_initialize
(
void
);
u32
acpi_ev_gpe_dispatch
(
u32
gpe_number
);
struct
acpi_gpe_event_info
*
gpe_event_info
);
u32
acpi_ev_gpe_detect
(
...
...
include/acpi/acglobal.h
View file @
35d48993
...
...
@@ -234,22 +234,7 @@ ACPI_EXTERN u8 acpi_gbl_sleep_type_b;
extern
struct
acpi_fixed_event_info
acpi_gbl_fixed_event_info
[
ACPI_NUM_FIXED_EVENTS
];
ACPI_EXTERN
struct
acpi_fixed_event_handler
acpi_gbl_fixed_event_handlers
[
ACPI_NUM_FIXED_EVENTS
];
ACPI_EXTERN
acpi_handle
acpi_gbl_gpe_obj_handle
;
ACPI_EXTERN
u32
acpi_gbl_gpe_register_count
;
ACPI_EXTERN
u32
acpi_gbl_gpe_number_max
;
ACPI_EXTERN
struct
acpi_gpe_register_info
*
acpi_gbl_gpe_register_info
;
ACPI_EXTERN
struct
acpi_gpe_number_info
*
acpi_gbl_gpe_number_info
;
ACPI_EXTERN
struct
acpi_gpe_block_info
acpi_gbl_gpe_block_info
[
ACPI_MAX_GPE_BLOCKS
];
/*
* GPE translation table
* Indexed by the GPE number, returns a valid index into the global GPE tables.
*
* This table is needed because the GPE numbers supported by block 1 do not
* have to be contiguous with the GPE numbers supported by block 0.
*/
ACPI_EXTERN
struct
acpi_gpe_index_info
*
acpi_gbl_gpe_number_to_index
;
ACPI_EXTERN
struct
acpi_gpe_block_info
*
acpi_gbl_gpe_block_list_head
;
/*****************************************************************************
...
...
include/acpi/achware.h
View file @
35d48993
...
...
@@ -115,29 +115,25 @@ acpi_hw_clear_acpi_status (
/* GPE support */
u8
acpi_hw_get_gpe_bit_mask
(
u32
gpe_number
);
acpi_status
acpi_hw_enable_gpe
(
u32
gpe_number
);
struct
acpi_gpe_event_info
*
gpe_event_info
);
void
acpi_hw_enable_gpe_for_wakeup
(
u32
gpe_number
);
struct
acpi_gpe_event_info
*
gpe_event_info
);
acpi_status
acpi_hw_disable_gpe
(
u32
gpe_number
);
struct
acpi_gpe_event_info
*
gpe_event_info
);
void
acpi_hw_disable_gpe_for_wakeup
(
u32
gpe_number
);
struct
acpi_gpe_event_info
*
gpe_event_info
);
acpi_status
acpi_hw_clear_gpe
(
u32
gpe_number
);
struct
acpi_gpe_event_info
*
gpe_event_info
);
acpi_status
acpi_hw_get_gpe_status
(
...
...
include/acpi/aclocal.h
View file @
35d48993
...
...
@@ -308,25 +308,28 @@ struct acpi_create_field_info
*
****************************************************************************/
/* Information about each
GPE register block
*/
/* Information about each
particular GPE level
*/
struct
acpi_gpe_
block
_info
struct
acpi_gpe_
event
_info
{
struct
acpi_generic_address
*
block_address
;
u16
register_count
;
u8
block_base_number
;
struct
acpi_namespace_node
*
method_node
;
/* Method node for this GPE level */
acpi_gpe_handler
handler
;
/* Address of handler, if any */
void
*
context
;
/* Context to be passed to handler */
struct
acpi_gpe_register_info
*
register_info
;
u8
type
;
/* Level or Edge */
u8
bit_mask
;
};
/* Information about a particular GPE register pair */
struct
acpi_gpe_register_info
{
struct
acpi_generic_address
status_address
;
/* Address of status reg */
struct
acpi_generic_address
enable_address
;
/* Address of enable reg */
u8
status
;
/* Current value of status reg */
u8
enable
;
/* Current value of enable reg */
u8
wake_enable
;
/* Mask of bits to keep enabled when sleeping */
u8
base_gpe_number
;
/* Base GPE number for this register */
struct
acpi_generic_address
status_address
;
/* Address of status reg */
struct
acpi_generic_address
enable_address
;
/* Address of enable reg */
u8
status
;
/* Current value of status reg */
u8
enable
;
/* Current value of enable reg */
u8
wake_enable
;
/* Mask of bits to keep enabled when sleeping */
u8
base_gpe_number
;
/* Base GPE number for this register */
};
...
...
@@ -334,23 +337,21 @@ struct acpi_gpe_register_info
#define ACPI_GPE_EDGE_TRIGGERED 2
/* Information about each
particular GPE level
*/
/* Information about each
GPE register block
*/
struct
acpi_gpe_
number
_info
struct
acpi_gpe_
block
_info
{
struct
acpi_namespace_node
*
method_node
;
/* Method node for this GPE level */
acpi_gpe_handler
handler
;
/* Address of handler, if any */
void
*
context
;
/* Context to be passed to handler */
u8
type
;
/* Level or Edge */
u8
bit_mask
;
struct
acpi_gpe_block_info
*
previous
;
struct
acpi_gpe_block_info
*
next
;
struct
acpi_gpe_block_info
*
next_on_interrupt
;
struct
acpi_gpe_register_info
*
register_info
;
struct
acpi_gpe_event_info
*
event_info
;
struct
acpi_generic_address
block_address
;
u32
register_count
;
u8
block_base_number
;
};
struct
acpi_gpe_index_info
{
u8
number_index
;
};
/* Information about each particular fixed event */
struct
acpi_fixed_event_handler
...
...
include/acpi/acpixf.h
View file @
35d48993
...
...
@@ -339,6 +339,12 @@ acpi_get_event_status (
* Resource interfaces
*/
typedef
acpi_status
(
*
ACPI_WALK_RESOURCE_CALLBACK
)
(
struct
acpi_resource
*
resource
,
void
*
context
);
acpi_status
acpi_get_current_resources
(
acpi_handle
device_handle
,
...
...
@@ -349,6 +355,13 @@ acpi_get_possible_resources(
acpi_handle
device_handle
,
struct
acpi_buffer
*
ret_buffer
);
acpi_status
acpi_walk_resources
(
acpi_handle
device_handle
,
char
*
path
,
ACPI_WALK_RESOURCE_CALLBACK
user_function
,
void
*
context
);
acpi_status
acpi_set_current_resources
(
acpi_handle
device_handle
,
...
...
@@ -359,6 +372,10 @@ acpi_get_irq_routing_table (
acpi_handle
bus_device_handle
,
struct
acpi_buffer
*
ret_buffer
);
acpi_status
acpi_resource_to_address64
(
struct
acpi_resource
*
resource
,
struct
acpi_resource_address64
*
out
);
/*
* Hardware (ACPI device) interfaces
...
...
@@ -398,6 +415,10 @@ acpi_status
acpi_enter_sleep_state
(
u8
sleep_state
);
acpi_status
acpi_enter_sleep_state_s4bios
(
void
);
acpi_status
acpi_leave_sleep_state
(
u8
sleep_state
);
...
...
include/acpi/acresrc.h
View file @
35d48993
...
...
@@ -65,6 +65,12 @@ acpi_rs_get_prs_method_data (
acpi_handle
handle
,
struct
acpi_buffer
*
ret_buffer
);
acpi_status
acpi_rs_get_method_data
(
acpi_handle
handle
,
char
*
path
,
struct
acpi_buffer
*
ret_buffer
);
acpi_status
acpi_rs_set_srs_method_data
(
acpi_handle
handle
,
...
...
include/acpi/acutils.h
View file @
35d48993
...
...
@@ -463,6 +463,8 @@ acpi_ut_delete_internal_object_list (
#define METHOD_NAME__SEG "_SEG"
#define METHOD_NAME__BBN "_BBN"
#define METHOD_NAME__PRT "_PRT"
#define METHOD_NAME__CRS "_CRS"
#define METHOD_NAME__PRS "_PRS"
acpi_status
...
...
include/linux/suspend.h
View file @
35d48993
...
...
@@ -73,6 +73,7 @@ extern void do_magic_suspend_2(void);
/* Communication between acpi and arch/i386/suspend.c */
extern
void
do_suspend_lowlevel
(
int
resume
);
extern
void
do_suspend_lowlevel_s4bios
(
int
resume
);
#else
static
inline
void
software_suspend
(
void
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment