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
Kirill Smelkov
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