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
db72219b
Commit
db72219b
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
be8013e8
2a7a8597
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
707 additions
and
37 deletions
+707
-37
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/events/Makefile
drivers/acpi/events/Makefile
+1
-1
drivers/acpi/events/evgpeblk.c
drivers/acpi/events/evgpeblk.c
+545
-0
drivers/acpi/hardware/hwsleep.c
drivers/acpi/hardware/hwsleep.c
+45
-0
drivers/acpi/osl.c
drivers/acpi/osl.c
+34
-7
drivers/acpi/processor.c
drivers/acpi/processor.c
+14
-11
drivers/acpi/tables.c
drivers/acpi/tables.c
+28
-18
No files found.
Documentation/kernel-parameters.txt
View file @
db72219b
...
...
@@ -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 @
db72219b
...
...
@@ -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 @
db72219b
...
...
@@ -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 @
db72219b
...
...
@@ -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/events/Makefile
View file @
db72219b
...
...
@@ -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/evgpeblk.c
0 → 100644
View file @
db72219b
/******************************************************************************
*
* 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/hardware/hwsleep.c
View file @
db72219b
...
...
@@ -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_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_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 @
db72219b
...
...
@@ -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/processor.c
View file @
db72219b
...
...
@@ -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/tables.c
View file @
db72219b
...
...
@@ -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
))
{
...
...
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