Commit 52cfd503 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6

* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (59 commits)
  ACPI / PM: Fix build problems for !CONFIG_ACPI related to NVS rework
  ACPI: fix resource check message
  ACPI / Battery: Update information on info notification and resume
  ACPI: Drop device flag wake_capable
  ACPI: Always check if _PRW is present before trying to evaluate it
  ACPI / PM: Check status of power resources under mutexes
  ACPI / PM: Rename acpi_power_off_device()
  ACPI / PM: Drop acpi_power_nocheck
  ACPI / PM: Drop acpi_bus_get_power()
  Platform / x86: Make fujitsu_laptop use acpi_bus_update_power()
  ACPI / Fan: Rework the handling of power resources
  ACPI / PM: Register power resource devices as soon as they are needed
  ACPI / PM: Register acpi_power_driver early
  ACPI / PM: Add function for updating device power state consistently
  ACPI / PM: Add function for device power state initialization
  ACPI / PM: Introduce __acpi_bus_get_power()
  ACPI / PM: Introduce function for refcounting device power resources
  ACPI / PM: Add functions for manipulating lists of power resources
  ACPI / PM: Prevent acpi_power_get_inferred_state() from making changes
  ACPICA: Update version to 20101209
  ...
parents dc8e7e3e 4263d9a3
What: A notification mechanism for thermal related events
Description:
This interface enables notification for thermal related events.
The notification is in the form of a netlink event.
......@@ -533,6 +533,33 @@ completion during sending a panic event.
Other Pieces
------------
Get the detailed info related with the IPMI device
--------------------------------------------------
Some users need more detailed information about a device, like where
the address came from or the raw base device for the IPMI interface.
You can use the IPMI smi_watcher to catch the IPMI interfaces as they
come or go, and to grab the information, you can use the function
ipmi_get_smi_info(), which returns the following structure:
struct ipmi_smi_info {
enum ipmi_addr_src addr_src;
struct device *dev;
union {
struct {
void *acpi_handle;
} acpi_info;
} addr_info;
};
Currently special info for only for SI_ACPI address sources is
returned. Others may be added as necessary.
Note that the dev pointer is included in the above structure, and
assuming ipmi_smi_get_info returns success, you must call put_device
on the dev pointer.
Watchdog
--------
......
APEI output format
~~~~~~~~~~~~~~~~~~
APEI uses printk as hardware error reporting interface, the output
format is as follow.
<error record> :=
APEI generic hardware error status
severity: <integer>, <severity string>
section: <integer>, severity: <integer>, <severity string>
flags: <integer>
<section flags strings>
fru_id: <uuid string>
fru_text: <string>
section_type: <section type string>
<section data>
<severity string>* := recoverable | fatal | corrected | info
<section flags strings># :=
[primary][, containment warning][, reset][, threshold exceeded]\
[, resource not accessible][, latent error]
<section type string> := generic processor error | memory error | \
PCIe error | unknown, <uuid string>
<section data> :=
<generic processor section data> | <memory section data> | \
<pcie section data> | <null>
<generic processor section data> :=
[processor_type: <integer>, <proc type string>]
[processor_isa: <integer>, <proc isa string>]
[error_type: <integer>
<proc error type strings>]
[operation: <integer>, <proc operation string>]
[flags: <integer>
<proc flags strings>]
[level: <integer>]
[version_info: <integer>]
[processor_id: <integer>]
[target_address: <integer>]
[requestor_id: <integer>]
[responder_id: <integer>]
[IP: <integer>]
<proc type string>* := IA32/X64 | IA64
<proc isa string>* := IA32 | IA64 | X64
<processor error type strings># :=
[cache error][, TLB error][, bus error][, micro-architectural error]
<proc operation string>* := unknown or generic | data read | data write | \
instruction execution
<proc flags strings># :=
[restartable][, precise IP][, overflow][, corrected]
<memory section data> :=
[error_status: <integer>]
[physical_address: <integer>]
[physical_address_mask: <integer>]
[node: <integer>]
[card: <integer>]
[module: <integer>]
[bank: <integer>]
[device: <integer>]
[row: <integer>]
[column: <integer>]
[bit_position: <integer>]
[requestor_id: <integer>]
[responder_id: <integer>]
[target_id: <integer>]
[error_type: <integer>, <mem error type string>]
<mem error type string>* :=
unknown | no error | single-bit ECC | multi-bit ECC | \
single-symbol chipkill ECC | multi-symbol chipkill ECC | master abort | \
target abort | parity error | watchdog timeout | invalid address | \
mirror Broken | memory sparing | scrub corrected error | \
scrub uncorrected error
<pcie section data> :=
[port_type: <integer>, <pcie port type string>]
[version: <integer>.<integer>]
[command: <integer>, status: <integer>]
[device_id: <integer>:<integer>:<integer>.<integer>
slot: <integer>
secondary_bus: <integer>
vendor_id: <integer>, device_id: <integer>
class_code: <integer>]
[serial number: <integer>, <integer>]
[bridge: secondary_status: <integer>, control: <integer>]
<pcie port type string>* := PCIe end point | legacy PCI end point | \
unknown | unknown | root port | upstream switch port | \
downstream switch port | PCIe to PCI/PCI-X bridge | \
PCI/PCI-X to PCIe bridge | root complex integrated endpoint device | \
root complex event collector
Where, [] designate corresponding content is optional
All <field string> description with * has the following format:
field: <integer>, <field string>
Where value of <integer> should be the position of "string" in <field
string> description. Otherwise, <field string> will be "unknown".
All <field strings> description with # has the following format:
field: <integer>
<field strings>
Where each string in <fields strings> corresponding to one set bit of
<integer>. The bit position is the position of "string" in <field
strings> description.
For more detailed explanation of every field, please refer to UEFI
specification version 2.3 or later, section Appendix N: Common
Platform Error Record.
......@@ -248,6 +248,17 @@ Who: Zhang Rui <rui.zhang@intel.com>
---------------------------
What: CONFIG_ACPI_PROCFS_POWER
When: 2.6.39
Why: sysfs I/F for ACPI power devices, including AC and Battery,
has been working in upstream kenrel since 2.6.24, Sep 2007.
In 2.6.37, we make the sysfs I/F always built in and this option
disabled by default.
Remove this option and the ACPI power procfs interface in 2.6.39.
Who: Zhang Rui <rui.zhang@intel.com>
---------------------------
What: /proc/acpi/button
When: August 2007
Why: /proc/acpi/button has been replaced by events to the input layer
......
......@@ -199,11 +199,6 @@ and is between 256 and 4096 characters. It is defined in the file
unusable. The "log_buf_len" parameter may be useful
if you need to capture more output.
acpi_display_output= [HW,ACPI]
acpi_display_output=vendor
acpi_display_output=video
See above.
acpi_irq_balance [HW,ACPI]
ACPI will balance active IRQs
default in APIC mode
......
......@@ -278,3 +278,15 @@ method, the sys I/F structure will be built like this:
|---name: acpitz
|---temp1_input: 37000
|---temp1_crit: 100000
4. Event Notification
The framework includes a simple notification mechanism, in the form of a
netlink event. Netlink socket initialization is done during the _init_
of the framework. Drivers which intend to use the notification mechanism
just need to call generate_netlink_event() with two arguments viz
(originator, event). Typically the originator will be an integer assigned
to a thermal_zone_device when it registers itself with the framework. The
event will be one of:{THERMAL_AUX0, THERMAL_AUX1, THERMAL_CRITICAL,
THERMAL_DEV_FAULT}. Notification can be sent when the current temperature
crosses any of the configured thresholds.
......@@ -426,6 +426,11 @@ extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size)
extern void iounmap (volatile void __iomem *addr);
extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size);
extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size)
{
return ioremap(phys_addr, size);
}
/*
* String version of IO memory access ops:
......
......@@ -509,6 +509,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
return 0;
}
EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
{
......
......@@ -234,6 +234,7 @@ unsigned __kprobes long oops_begin(void)
bust_spinlocks(1);
return flags;
}
EXPORT_SYMBOL_GPL(oops_begin);
void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
{
......
......@@ -14,6 +14,7 @@
#include <linux/bootmem.h>
#include <linux/pfn.h>
#include <linux/suspend.h>
#include <linux/acpi.h>
#include <linux/firmware-map.h>
#include <linux/memblock.h>
......
......@@ -51,12 +51,7 @@ config ACPI_PROCFS
For backwards compatibility, this option allows
deprecated /proc/acpi/ files to exist, even when
they have been replaced by functions in /sys.
The deprecated files (and their replacements) include:
/proc/acpi/processor/*/throttling (/sys/class/thermal/
cooling_device*/*)
/proc/acpi/video/*/brightness (/sys/class/backlight/)
/proc/acpi/thermal_zone/*/* (/sys/class/thermal/)
This option has no effect on /proc/acpi/ files
and functions which do not yet exist in /sys.
......@@ -74,6 +69,8 @@ config ACPI_PROCFS_POWER
/proc/acpi/ac_adapter/* (sys/class/power_supply/*)
This option has no effect on /proc/acpi/ directories
and functions, which do not yet exist in /sys
This option, together with the proc directories, will be
deleted in 2.6.39.
Say N to delete power /proc/acpi/ directories that have moved to /sys/
......@@ -209,6 +206,17 @@ config ACPI_PROCESSOR
To compile this driver as a module, choose M here:
the module will be called processor.
config ACPI_IPMI
tristate "IPMI"
depends on EXPERIMENTAL && IPMI_SI && IPMI_HANDLER
default n
help
This driver enables the ACPI to access the BMC controller. And it
uses the IPMI request/response message to communicate with BMC
controller, which can be found on on the server.
To compile this driver as a module, choose M here:
the module will be called as acpi_ipmi.
config ACPI_HOTPLUG_CPU
bool
......
......@@ -24,7 +24,7 @@ acpi-y += atomicio.o
# sleep related files
acpi-y += wakeup.o
acpi-y += sleep.o
acpi-$(CONFIG_ACPI_SLEEP) += proc.o
acpi-$(CONFIG_ACPI_SLEEP) += proc.o nvs.o
#
......@@ -69,5 +69,6 @@ processor-y += processor_idle.o processor_thermal.o
processor-$(CONFIG_CPU_FREQ) += processor_perflib.o
obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
obj-$(CONFIG_ACPI_IPMI) += acpi_ipmi.o
obj-$(CONFIG_ACPI_APEI) += apei/
......@@ -197,7 +197,8 @@ static int acpi_ac_add_fs(struct acpi_device *device)
{
struct proc_dir_entry *entry = NULL;
printk(KERN_WARNING PREFIX "Deprecated procfs I/F for AC is loaded,"
" please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
if (!acpi_device_dir(device)) {
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
acpi_ac_dir);
......
This diff is collapsed.
......@@ -14,7 +14,7 @@ acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \
acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \
evmisc.o evrgnini.o evxface.o evxfregn.o \
evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o
evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o evxfgpe.o
acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\
exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\
......
......@@ -51,8 +51,6 @@ acpi_status acpi_ev_initialize_events(void);
acpi_status acpi_ev_install_xrupt_handlers(void);
acpi_status acpi_ev_install_fadt_gpes(void);
u32 acpi_ev_fixed_event_detect(void);
/*
......@@ -82,9 +80,9 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info);
struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
u32 gpe_number);
......@@ -93,6 +91,8 @@ struct acpi_gpe_event_info *acpi_ev_low_get_gpe_info(u32 gpe_number,
struct acpi_gpe_block_info
*gpe_block);
acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info);
/*
* evgpeblk - Upper-level GPE block support
*/
......@@ -107,12 +107,13 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
acpi_status
acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block,
void *ignored);
void *context);
acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block);
u32
acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info,
acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
struct acpi_gpe_event_info *gpe_event_info,
u32 gpe_number);
/*
......@@ -126,10 +127,6 @@ acpi_status
acpi_ev_match_gpe_method(acpi_handle obj_handle,
u32 level, void *context, void **return_value);
acpi_status
acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
u32 level, void *context, void **return_value);
/*
* evgpeutil - GPE utilities
*/
......@@ -138,6 +135,10 @@ acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context);
u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info);
acpi_status
acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block, void *context);
struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number);
acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt);
......
......@@ -146,6 +146,9 @@ u8 acpi_gbl_system_awake_and_running;
extern u32 acpi_gbl_nesting_level;
ACPI_EXTERN u32 acpi_gpe_count;
ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS];
/* Support for dynamic control method tracing mechanism */
ACPI_EXTERN u32 acpi_gbl_original_dbg_level;
......@@ -370,7 +373,9 @@ ACPI_EXTERN struct acpi_fixed_event_handler
ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
ACPI_EXTERN struct acpi_gpe_block_info
*acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
ACPI_EXTERN u8 acpi_all_gpes_initialized;
ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized;
ACPI_EXTERN ACPI_GBL_EVENT_HANDLER acpi_gbl_global_event_handler;
ACPI_EXTERN void *acpi_gbl_global_event_handler_context;
/*****************************************************************************
*
......
......@@ -94,7 +94,7 @@ u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
struct acpi_gpe_register_info *gpe_register_info);
acpi_status
acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action);
acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action);
acpi_status
acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
......
......@@ -408,17 +408,18 @@ struct acpi_predefined_data {
/* Dispatch info for each GPE -- either a method or handler, cannot be both */
struct acpi_handler_info {
acpi_event_handler address; /* Address of handler, if any */
struct acpi_gpe_handler_info {
acpi_gpe_handler address; /* Address of handler, if any */
void *context; /* Context to be passed to handler */
struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */
u8 orig_flags; /* Original misc info about this GPE */
u8 orig_enabled; /* Set if the GPE was originally enabled */
u8 original_flags; /* Original (pre-handler) GPE info */
u8 originally_enabled; /* True if GPE was originally enabled */
};
union acpi_gpe_dispatch_info {
struct acpi_namespace_node *method_node; /* Method node for this GPE level */
struct acpi_handler_info *handler;
struct acpi_gpe_handler_info *handler; /* Installed GPE handler */
struct acpi_namespace_node *device_node; /* Parent _PRW device for implicit notify */
};
/*
......@@ -458,7 +459,7 @@ struct acpi_gpe_block_info {
u32 register_count; /* Number of register pairs in block */
u16 gpe_count; /* Number of individual GPEs in block */
u8 block_base_number; /* Base GPE number for this block */
u8 initialized; /* If set, the GPE block has been initialized */
u8 initialized; /* TRUE if this block is initialized */
};
/* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */
......
......@@ -217,9 +217,17 @@ u32 acpi_ev_fixed_event_detect(void)
status_bit_mask)
&& (fixed_enable & acpi_gbl_fixed_event_info[i].
enable_bit_mask)) {
/*
* Found an active (signalled) event. Invoke global event
* handler if present.
*/
acpi_fixed_event_count[i]++;
if (acpi_gbl_global_event_handler) {
acpi_gbl_global_event_handler
(ACPI_EVENT_TYPE_FIXED, NULL, i,
acpi_gbl_global_event_handler_context);
}
/* Found an active (signalled) event */
acpi_os_fixed_event_count(i);
int_status |= acpi_ev_fixed_event_dispatch(i);
}
}
......
This diff is collapsed.
......@@ -361,9 +361,9 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
gpe_block->node = gpe_device;
gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH);
gpe_block->initialized = FALSE;
gpe_block->register_count = register_count;
gpe_block->block_base_number = gpe_block_base_number;
gpe_block->initialized = FALSE;
ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address,
sizeof(struct acpi_generic_address));
......@@ -386,7 +386,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
return_ACPI_STATUS(status);
}
acpi_all_gpes_initialized = FALSE;
acpi_gbl_all_gpes_initialized = FALSE;
/* Find all GPE methods (_Lxx or_Exx) for this block */
......@@ -423,14 +423,12 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
*
* FUNCTION: acpi_ev_initialize_gpe_block
*
* PARAMETERS: gpe_device - Handle to the parent GPE block
* gpe_block - Gpe Block info
* PARAMETERS: acpi_gpe_callback
*
* RETURN: Status
*
* DESCRIPTION: Initialize and enable a GPE block. First find and run any
* _PRT methods associated with the block, then enable the
* appropriate GPEs.
* DESCRIPTION: Initialize and enable a GPE block. Enable GPEs that have
* associated methods.
* Note: Assumes namespace is locked.
*
******************************************************************************/
......@@ -450,8 +448,8 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
ACPI_FUNCTION_TRACE(ev_initialize_gpe_block);
/*
* Ignore a null GPE block (e.g., if no GPE block 1 exists) and
* GPE blocks that have been initialized already.
* Ignore a null GPE block (e.g., if no GPE block 1 exists), and
* any GPE blocks that have been initialized already.
*/
if (!gpe_block || gpe_block->initialized) {
return_ACPI_STATUS(AE_OK);
......@@ -459,8 +457,8 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
/*
* Enable all GPEs that have a corresponding method and have the
* ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block must
* be enabled via the acpi_enable_gpe() interface.
* ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block
* must be enabled via the acpi_enable_gpe() interface.
*/
gpe_enabled_count = 0;
......@@ -472,14 +470,19 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j;
gpe_event_info = &gpe_block->event_info[gpe_index];
/* Ignore GPEs that have no corresponding _Lxx/_Exx method */
if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)
/*
* Ignore GPEs that have no corresponding _Lxx/_Exx method
* and GPEs that are used to wake the system
*/
if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_NONE)
|| ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
== ACPI_GPE_DISPATCH_HANDLER)
|| (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
continue;
}
status = acpi_raw_enable_gpe(gpe_event_info);
status = acpi_ev_add_gpe_reference(gpe_event_info);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Could not enable GPE 0x%02X",
......
......@@ -45,11 +45,27 @@
#include "accommon.h"
#include "acevents.h"
#include "acnamesp.h"
#include "acinterp.h"
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME("evgpeinit")
/*
* Note: History of _PRW support in ACPICA
*
* Originally (2000 - 2010), the GPE initialization code performed a walk of
* the entire namespace to execute the _PRW methods and detect all GPEs
* capable of waking the system.
*
* As of 10/2010, the _PRW method execution has been removed since it is
* actually unnecessary. The host OS must in fact execute all _PRW methods
* in order to identify the device/power-resource dependencies. We now put
* the onus on the host OS to identify the wake GPEs as part of this process
* and to inform ACPICA of these GPEs via the acpi_setup_gpe_for_wake interface. This
* not only reduces the complexity of the ACPICA initialization code, but in
* some cases (on systems with very large namespaces) it should reduce the
* kernel boot time as well.
*/
/*******************************************************************************
*
* FUNCTION: acpi_ev_gpe_initialize
......@@ -222,7 +238,7 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
acpi_status status = AE_OK;
/*
* 2) Find any _Lxx/_Exx GPE methods that have just been loaded.
* Find any _Lxx/_Exx GPE methods that have just been loaded.
*
* Any GPEs that correspond to new _Lxx/_Exx methods are immediately
* enabled.
......@@ -235,9 +251,9 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
return;
}
walk_info.count = 0;
walk_info.owner_id = table_owner_id;
walk_info.execute_by_owner_id = TRUE;
walk_info.count = 0;
/* Walk the interrupt level descriptor list */
......@@ -298,7 +314,7 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
* xx - is the GPE number [in HEX]
*
* If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods
* with that owner.
* with that owner.
*
******************************************************************************/
......@@ -415,6 +431,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
* Add the GPE information from above to the gpe_event_info block for
* use during dispatch of this GPE.
*/
gpe_event_info->flags &= ~(ACPI_GPE_DISPATCH_MASK);
gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD);
gpe_event_info->dispatch.method_node = method_node;
......
......@@ -152,6 +152,45 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
return (FALSE);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_get_gpe_device
*
* PARAMETERS: GPE_WALK_CALLBACK
*
* RETURN: Status
*
* DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
* block device. NULL if the GPE is one of the FADT-defined GPEs.
*
******************************************************************************/
acpi_status
acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block, void *context)
{
struct acpi_gpe_device_info *info = context;
/* Increment Index by the number of GPEs in this block */
info->next_block_base_index += gpe_block->gpe_count;
if (info->index < info->next_block_base_index) {
/*
* The GPE index is within this block, get the node. Leave the node
* NULL for the FADT-defined GPEs
*/
if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
info->gpe_device = gpe_block->node;
}
info->status = AE_OK;
return (AE_CTRL_END);
}
return (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_get_gpe_xrupt_block
......
......@@ -284,41 +284,41 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
* RETURN: ACPI_INTERRUPT_HANDLED
*
* DESCRIPTION: Invoked directly from the SCI handler when a global lock
* release interrupt occurs. Attempt to acquire the global lock,
* if successful, signal the thread waiting for the lock.
* release interrupt occurs. If there's a thread waiting for
* the global lock, signal it.
*
* NOTE: Assumes that the semaphore can be signaled from interrupt level. If
* this is not possible for some reason, a separate thread will have to be
* scheduled to do this.
*
******************************************************************************/
static u8 acpi_ev_global_lock_pending;
static spinlock_t _acpi_ev_global_lock_pending_lock;
#define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock
static u32 acpi_ev_global_lock_handler(void *context)
{
u8 acquired = FALSE;
acpi_status status;
acpi_cpu_flags flags;
/*
* Attempt to get the lock.
*
* If we don't get it now, it will be marked pending and we will
* take another interrupt when it becomes free.
*/
ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
if (acquired) {
flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
/* Got the lock, now wake all threads waiting for it */
if (!acpi_ev_global_lock_pending) {
goto out;
}
acpi_gbl_global_lock_acquired = TRUE;
/* Send a unit to the semaphore */
/* Send a unit to the semaphore */
if (ACPI_FAILURE
(acpi_os_signal_semaphore
(acpi_gbl_global_lock_semaphore, 1))) {
ACPI_ERROR((AE_INFO,
"Could not signal Global Lock semaphore"));
}
status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
}
acpi_ev_global_lock_pending = FALSE;
out:
acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
return (ACPI_INTERRUPT_HANDLED);
}
......@@ -415,6 +415,7 @@ static int acpi_ev_global_lock_acquired;
acpi_status acpi_ev_acquire_global_lock(u16 timeout)
{
acpi_cpu_flags flags;
acpi_status status = AE_OK;
u8 acquired = FALSE;
......@@ -467,32 +468,47 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
return_ACPI_STATUS(AE_OK);
}
/* Attempt to acquire the actual hardware lock */
flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
do {
/* Attempt to acquire the actual hardware lock */
ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
if (acquired) {
acpi_gbl_global_lock_acquired = TRUE;
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"Acquired hardware Global Lock\n"));
break;
}
ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
if (acquired) {
acpi_ev_global_lock_pending = TRUE;
/* We got the lock */
acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
/*
* Did not get the lock. The pending bit was set above, and we
* must wait until we get the global lock released interrupt.
*/
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"Acquired hardware Global Lock\n"));
"Waiting for hardware Global Lock\n"));
acpi_gbl_global_lock_acquired = TRUE;
return_ACPI_STATUS(AE_OK);
}
/*
* Wait for handshake with the global lock interrupt handler.
* This interface releases the interpreter if we must wait.
*/
status = acpi_ex_system_wait_semaphore(
acpi_gbl_global_lock_semaphore,
ACPI_WAIT_FOREVER);
/*
* Did not get the lock. The pending bit was set above, and we must now
* wait until we get the global lock released interrupt.
*/
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));
flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
/*
* Wait for handshake with the global lock interrupt handler.
* This interface releases the interpreter if we must wait.
*/
status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
ACPI_WAIT_FOREVER);
} while (ACPI_SUCCESS(status));
acpi_ev_global_lock_pending = FALSE;
acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
return_ACPI_STATUS(status);
}
......
......@@ -92,6 +92,57 @@ acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
#endif /* ACPI_FUTURE_USAGE */
/*******************************************************************************
*
* FUNCTION: acpi_install_global_event_handler
*
* PARAMETERS: Handler - Pointer to the global event handler function
* Context - Value passed to the handler on each event
*
* RETURN: Status
*
* DESCRIPTION: Saves the pointer to the handler function. The global handler
* is invoked upon each incoming GPE and Fixed Event. It is
* invoked at interrupt level at the time of the event dispatch.
* Can be used to update event counters, etc.
*
******************************************************************************/
acpi_status
acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context)
{
acpi_status status;
ACPI_FUNCTION_TRACE(acpi_install_global_event_handler);
/* Parameter validation */
if (!handler) {
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Don't allow two handlers. */
if (acpi_gbl_global_event_handler) {
status = AE_ALREADY_EXISTS;
goto cleanup;
}
acpi_gbl_global_event_handler = handler;
acpi_gbl_global_event_handler_context = context;
cleanup:
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
return_ACPI_STATUS(status);
}
ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler)
/*******************************************************************************
*
* FUNCTION: acpi_install_fixed_event_handler
......@@ -671,10 +722,10 @@ ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler)
acpi_status
acpi_install_gpe_handler(acpi_handle gpe_device,
u32 gpe_number,
u32 type, acpi_event_handler address, void *context)
u32 type, acpi_gpe_handler address, void *context)
{
struct acpi_gpe_event_info *gpe_event_info;
struct acpi_handler_info *handler;
struct acpi_gpe_handler_info *handler;
acpi_status status;
acpi_cpu_flags flags;
......@@ -693,7 +744,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
/* Allocate memory for the handler object */
handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info));
handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_handler_info));
if (!handler) {
status = AE_NO_MEMORY;
goto unlock_and_exit;
......@@ -722,7 +773,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
handler->address = address;
handler->context = context;
handler->method_node = gpe_event_info->dispatch.method_node;
handler->orig_flags = gpe_event_info->flags &
handler->original_flags = gpe_event_info->flags &
(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
/*
......@@ -731,10 +782,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
* disabled now to avoid spurious execution of the handler.
*/
if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD)
if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD)
&& gpe_event_info->runtime_count) {
handler->orig_enabled = 1;
(void)acpi_raw_disable_gpe(gpe_event_info);
handler->originally_enabled = 1;
(void)acpi_ev_remove_gpe_reference(gpe_event_info);
}
/* Install the handler */
......@@ -777,10 +828,10 @@ ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler)
******************************************************************************/
acpi_status
acpi_remove_gpe_handler(acpi_handle gpe_device,
u32 gpe_number, acpi_event_handler address)
u32 gpe_number, acpi_gpe_handler address)
{
struct acpi_gpe_event_info *gpe_event_info;
struct acpi_handler_info *handler;
struct acpi_gpe_handler_info *handler;
acpi_status status;
acpi_cpu_flags flags;
......@@ -835,7 +886,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
gpe_event_info->dispatch.method_node = handler->method_node;
gpe_event_info->flags &=
~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
gpe_event_info->flags |= handler->orig_flags;
gpe_event_info->flags |= handler->original_flags;
/*
* If the GPE was previously associated with a method and it was
......@@ -843,9 +894,9 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
* post-initialization configuration.
*/
if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD)
&& handler->orig_enabled)
(void)acpi_raw_enable_gpe(gpe_event_info);
if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD)
&& handler->originally_enabled)
(void)acpi_ev_add_gpe_reference(gpe_event_info);
/* Now we can free the handler object */
......
This diff is collapsed.
This diff is collapsed.
......@@ -62,10 +62,10 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
* PARAMETERS: gpe_event_info - Info block for the GPE
* gpe_register_info - Info block for the GPE register
*
* RETURN: Status
* RETURN: Register mask with a one in the GPE bit position
*
* DESCRIPTION: Compute GPE enable mask with one bit corresponding to the given
* GPE set.
* DESCRIPTION: Compute the register mask for this GPE. One bit is set in the
* correct position for the input GPE.
*
******************************************************************************/
......@@ -85,12 +85,12 @@ u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
*
* RETURN: Status
*
* DESCRIPTION: Enable or disable a single GPE in its enable register.
* DESCRIPTION: Enable or disable a single GPE in the parent enable register.
*
******************************************************************************/
acpi_status
acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
{
struct acpi_gpe_register_info *gpe_register_info;
acpi_status status;
......@@ -113,14 +113,20 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
return (status);
}
/* Set ot clear just the bit that corresponds to this GPE */
/* Set or clear just the bit that corresponds to this GPE */
register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
gpe_register_info);
switch (action) {
case ACPI_GPE_COND_ENABLE:
if (!(register_bit & gpe_register_info->enable_for_run))
case ACPI_GPE_CONDITIONAL_ENABLE:
/* Only enable if the enable_for_run bit is set */
if (!(register_bit & gpe_register_info->enable_for_run)) {
return (AE_BAD_PARAMETER);
}
/*lint -fallthrough */
case ACPI_GPE_ENABLE:
ACPI_SET_BIT(enable_mask, register_bit);
......@@ -131,7 +137,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
break;
default:
ACPI_ERROR((AE_INFO, "Invalid action\n"));
ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u\n", action));
return (AE_BAD_PARAMETER);
}
......@@ -168,13 +174,13 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
return (AE_NOT_EXIST);
}
register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
gpe_register_info);
/*
* Write a one to the appropriate bit in the status register to
* clear this GPE.
*/
register_bit =
acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
status = acpi_hw_write(register_bit,
&gpe_register_info->status_address);
......@@ -201,8 +207,8 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
u32 in_byte;
u32 register_bit;
struct acpi_gpe_register_info *gpe_register_info;
acpi_status status;
acpi_event_status local_event_status = 0;
acpi_status status;
ACPI_FUNCTION_ENTRY();
......
......@@ -768,7 +768,7 @@ acpi_status acpi_ut_init_globals(void)
acpi_gbl_gpe_fadt_blocks[0] = NULL;
acpi_gbl_gpe_fadt_blocks[1] = NULL;
acpi_current_gpe_count = 0;
acpi_all_gpes_initialized = FALSE;
acpi_gbl_all_gpes_initialized = FALSE;
/* Global handlers */
......@@ -778,6 +778,7 @@ acpi_status acpi_ut_init_globals(void)
acpi_gbl_init_handler = NULL;
acpi_gbl_table_handler = NULL;
acpi_gbl_interface_handler = NULL;
acpi_gbl_global_event_handler = NULL;
/* Global Lock support */
......
......@@ -109,6 +109,8 @@ static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)
return sizeof(*estatus) + estatus->data_length;
}
void apei_estatus_print(const char *pfx,
const struct acpi_hest_generic_status *estatus);
int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus);
int apei_estatus_check(const struct acpi_hest_generic_status *estatus);
#endif
This diff is collapsed.
This diff is collapsed.
......@@ -631,6 +631,17 @@ static int acpi_battery_update(struct acpi_battery *battery)
return result;
}
static void acpi_battery_refresh(struct acpi_battery *battery)
{
if (!battery->bat.dev)
return;
acpi_battery_get_info(battery);
/* The battery may have changed its reporting units. */
sysfs_remove_battery(battery);
sysfs_add_battery(battery);
}
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
......@@ -868,6 +879,8 @@ static int acpi_battery_add_fs(struct acpi_device *device)
struct proc_dir_entry *entry = NULL;
int i;
printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded,"
" please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
if (!acpi_device_dir(device)) {
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
acpi_battery_dir);
......@@ -914,6 +927,8 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event)
if (!battery)
return;
old = battery->bat.dev;
if (event == ACPI_BATTERY_NOTIFY_INFO)
acpi_battery_refresh(battery);
acpi_battery_update(battery);
acpi_bus_generate_proc_event(device, event,
acpi_battery_present(battery));
......@@ -983,6 +998,7 @@ static int acpi_battery_resume(struct acpi_device *device)
if (!device)
return -EINVAL;
battery = acpi_driver_data(device);
acpi_battery_refresh(battery);
battery->update_time = 0;
acpi_battery_update(battery);
return 0;
......
......@@ -52,22 +52,6 @@ EXPORT_SYMBOL(acpi_root_dir);
#define STRUCT_TO_INT(s) (*((int*)&s))
static int set_power_nocheck(const struct dmi_system_id *id)
{
printk(KERN_NOTICE PREFIX "%s detected - "
"disable power check in power transition\n", id->ident);
acpi_power_nocheck = 1;
return 0;
}
static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = {
{
set_power_nocheck, "HP Pavilion 05", {
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
DMI_MATCH(DMI_SYS_VENDOR, "HP Pavilion 05"),
DMI_MATCH(DMI_PRODUCT_VERSION, "2001211RE101GLEND") }, NULL},
{},
};
#ifdef CONFIG_X86
static int set_copy_dsdt(const struct dmi_system_id *id)
......@@ -196,33 +180,24 @@ EXPORT_SYMBOL(acpi_bus_get_private_data);
Power Management
-------------------------------------------------------------------------- */
int acpi_bus_get_power(acpi_handle handle, int *state)
static int __acpi_bus_get_power(struct acpi_device *device, int *state)
{
int result = 0;
acpi_status status = 0;
struct acpi_device *device = NULL;
unsigned long long psc = 0;
result = acpi_bus_get_device(handle, &device);
if (result)
return result;
if (!device || !state)
return -EINVAL;
*state = ACPI_STATE_UNKNOWN;
if (!device->flags.power_manageable) {
/* TBD: Non-recursive algorithm for walking up hierarchy */
if (device->parent)
*state = device->parent->power.state;
else
*state = ACPI_STATE_D0;
} else {
if (device->flags.power_manageable) {
/*
* Get the device's power state either directly (via _PSC) or
* indirectly (via power resources).
*/
if (device->power.flags.power_resources) {
result = acpi_power_get_inferred_state(device);
result = acpi_power_get_inferred_state(device, state);
if (result)
return result;
} else if (device->power.flags.explicit_get) {
......@@ -230,59 +205,33 @@ int acpi_bus_get_power(acpi_handle handle, int *state)
NULL, &psc);
if (ACPI_FAILURE(status))
return -ENODEV;
device->power.state = (int)psc;
*state = (int)psc;
}
*state = device->power.state;
} else {
/* TBD: Non-recursive algorithm for walking up hierarchy. */
*state = device->parent ?
device->parent->power.state : ACPI_STATE_D0;
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n",
device->pnp.bus_id, device->power.state));
device->pnp.bus_id, *state));
return 0;
}
EXPORT_SYMBOL(acpi_bus_get_power);
int acpi_bus_set_power(acpi_handle handle, int state)
static int __acpi_bus_set_power(struct acpi_device *device, int state)
{
int result = 0;
acpi_status status = AE_OK;
struct acpi_device *device = NULL;
char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' };
result = acpi_bus_get_device(handle, &device);
if (result)
return result;
if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
return -EINVAL;
/* Make sure this is a valid target state */
if (!device->flags.power_manageable) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
kobject_name(&device->dev.kobj)));
return -ENODEV;
}
/*
* Get device's current power state
*/
if (!acpi_power_nocheck) {
/*
* Maybe the incorrect power state is returned on the bogus
* bios, which is different with the real power state.
* For example: the bios returns D0 state and the real power
* state is D3. OS expects to set the device to D0 state. In
* such case if OS uses the power state returned by the BIOS,
* the device can't be transisted to the correct power state.
* So if the acpi_power_nocheck is set, it is unnecessary to
* get the power state by calling acpi_bus_get_power.
*/
acpi_bus_get_power(device->handle, &device->power.state);
}
if ((state == device->power.state) && !device->flags.force_power_state) {
if (state == device->power.state) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
state));
return 0;
......@@ -351,8 +300,75 @@ int acpi_bus_set_power(acpi_handle handle, int state)
return result;
}
int acpi_bus_set_power(acpi_handle handle, int state)
{
struct acpi_device *device;
int result;
result = acpi_bus_get_device(handle, &device);
if (result)
return result;
if (!device->flags.power_manageable) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Device [%s] is not power manageable\n",
dev_name(&device->dev)));
return -ENODEV;
}
return __acpi_bus_set_power(device, state);
}
EXPORT_SYMBOL(acpi_bus_set_power);
int acpi_bus_init_power(struct acpi_device *device)
{
int state;
int result;
if (!device)
return -EINVAL;
device->power.state = ACPI_STATE_UNKNOWN;
result = __acpi_bus_get_power(device, &state);
if (result)
return result;
if (device->power.flags.power_resources)
result = acpi_power_on_resources(device, state);
if (!result)
device->power.state = state;
return result;
}
int acpi_bus_update_power(acpi_handle handle, int *state_p)
{
struct acpi_device *device;
int state;
int result;
result = acpi_bus_get_device(handle, &device);
if (result)
return result;
result = __acpi_bus_get_power(device, &state);
if (result)
return result;
result = __acpi_bus_set_power(device, state);
if (!result && state_p)
*state_p = state;
return result;
}
EXPORT_SYMBOL_GPL(acpi_bus_update_power);
bool acpi_bus_power_manageable(acpi_handle handle)
{
struct acpi_device *device;
......@@ -1023,15 +1039,8 @@ static int __init acpi_init(void)
if (acpi_disabled)
return result;
/*
* If the laptop falls into the DMI check table, the power state check
* will be disabled in the course of device power transition.
*/
dmi_check_system(power_nocheck_dmi_table);
acpi_scan_init();
acpi_ec_init();
acpi_power_init();
acpi_debugfs_init();
acpi_sleep_proc_init();
acpi_wakeup_device_init();
......
......@@ -279,6 +279,9 @@ static int acpi_lid_send_state(struct acpi_device *device)
input_report_switch(button->input, SW_LID, !state);
input_sync(button->input);
if (state)
pm_wakeup_event(&device->dev, 0);
ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
if (ret == NOTIFY_DONE)
ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
......@@ -314,6 +317,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
input_sync(input);
input_report_key(input, keycode, 0);
input_sync(input);
pm_wakeup_event(&device->dev, 0);
}
acpi_bus_generate_proc_event(device, event, ++button->pushed);
......@@ -426,7 +431,7 @@ static int acpi_button_add(struct acpi_device *device)
acpi_enable_gpe(device->wakeup.gpe_device,
device->wakeup.gpe_number);
device->wakeup.run_wake_count++;
device->wakeup.state.enabled = 1;
device_set_wakeup_enable(&device->dev, true);
}
printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
......@@ -449,7 +454,7 @@ static int acpi_button_remove(struct acpi_device *device, int type)
acpi_disable_gpe(device->wakeup.gpe_device,
device->wakeup.gpe_number);
device->wakeup.run_wake_count--;
device->wakeup.state.enabled = 0;
device_set_wakeup_enable(&device->dev, false);
}
acpi_button_remove_fs(device);
......
......@@ -725,7 +725,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
complete_dock(ds);
dock_event(ds, event, DOCK_EVENT);
dock_lock(ds, 1);
acpi_update_gpes();
acpi_update_all_gpes();
break;
}
if (dock_present(ds) || dock_in_progress(ds))
......
......@@ -606,7 +606,8 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
return 0;
}
static u32 acpi_ec_gpe_handler(void *data)
static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
u32 gpe_number, void *data)
{
struct acpi_ec *ec = data;
......@@ -618,7 +619,7 @@ static u32 acpi_ec_gpe_handler(void *data)
wake_up(&ec->wait);
ec_check_sci(ec, acpi_ec_read_status(ec));
}
return ACPI_INTERRUPT_HANDLED;
return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE;
}
/* --------------------------------------------------------------------------
......
......@@ -86,7 +86,7 @@ static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
if (!device)
return -EINVAL;
result = acpi_bus_get_power(device->handle, &acpi_state);
result = acpi_bus_update_power(device->handle, &acpi_state);
if (result)
return result;
......@@ -123,7 +123,6 @@ static struct thermal_cooling_device_ops fan_cooling_ops = {
static int acpi_fan_add(struct acpi_device *device)
{
int result = 0;
int state = 0;
struct thermal_cooling_device *cdev;
if (!device)
......@@ -132,16 +131,12 @@ static int acpi_fan_add(struct acpi_device *device)
strcpy(acpi_device_name(device), "Fan");
strcpy(acpi_device_class(device), ACPI_FAN_CLASS);
result = acpi_bus_get_power(device->handle, &state);
result = acpi_bus_update_power(device->handle, NULL);
if (result) {
printk(KERN_ERR PREFIX "Reading power state\n");
printk(KERN_ERR PREFIX "Setting initial power state\n");
goto end;
}
device->flags.force_power_state = 1;
acpi_bus_set_power(device->handle, state);
device->flags.force_power_state = 0;
cdev = thermal_cooling_device_register("Fan", device,
&fan_cooling_ops);
if (IS_ERR(cdev)) {
......@@ -200,22 +195,14 @@ static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
static int acpi_fan_resume(struct acpi_device *device)
{
int result = 0;
int power_state = 0;
int result;
if (!device)
return -EINVAL;
result = acpi_bus_get_power(device->handle, &power_state);
if (result) {
printk(KERN_ERR PREFIX
"Error reading fan power state\n");
return result;
}
device->flags.force_power_state = 1;
acpi_bus_set_power(device->handle, power_state);
device->flags.force_power_state = 0;
result = acpi_bus_update_power(device->handle, NULL);
if (result)
printk(KERN_ERR PREFIX "Error updating fan power state\n");
return result;
}
......
......@@ -167,11 +167,8 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
"firmware_node");
ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
"physical_node");
if (acpi_dev->wakeup.flags.valid) {
if (acpi_dev->wakeup.flags.valid)
device_set_wakeup_capable(dev, true);
device_set_wakeup_enable(dev,
acpi_dev->wakeup.state.enabled);
}
}
return 0;
......
......@@ -41,9 +41,10 @@ static inline int acpi_debugfs_init(void) { return 0; }
int acpi_power_init(void);
int acpi_device_sleep_wake(struct acpi_device *dev,
int enable, int sleep_state, int dev_state);
int acpi_power_get_inferred_state(struct acpi_device *device);
int acpi_power_get_inferred_state(struct acpi_device *device, int *state);
int acpi_power_on_resources(struct acpi_device *device, int state);
int acpi_power_transition(struct acpi_device *device, int state);
extern int acpi_power_nocheck;
int acpi_bus_init_power(struct acpi_device *device);
int acpi_wakeup_device_init(void);
void acpi_early_processor_set_pdc(void);
......@@ -82,8 +83,16 @@ extern int acpi_sleep_init(void);
#ifdef CONFIG_ACPI_SLEEP
int acpi_sleep_proc_init(void);
int suspend_nvs_alloc(void);
void suspend_nvs_free(void);
int suspend_nvs_save(void);
void suspend_nvs_restore(void);
#else
static inline int acpi_sleep_proc_init(void) { return 0; }
static inline int suspend_nvs_alloc(void) { return 0; }
static inline void suspend_nvs_free(void) {}
static inline int suspend_nvs_save(void) { return 0; }
static inline void suspend_nvs_restore(void) {}
#endif
#endif /* _ACPI_INTERNAL_H_ */
/*
* linux/kernel/power/hibernate_nvs.c - Routines for handling NVS memory
* nvs.c - Routines for saving and restoring ACPI NVS memory region
*
* Copyright (C) 2008,2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
* Copyright (C) 2008-2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
*
* This file is released under the GPLv2.
*/
......@@ -11,7 +11,8 @@
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/acpi.h>
#include <acpi/acpiosxf.h>
/*
* Platforms, like ACPI, may want us to save some memory used by them during
......@@ -79,7 +80,7 @@ void suspend_nvs_free(void)
free_page((unsigned long)entry->data);
entry->data = NULL;
if (entry->kaddr) {
iounmap(entry->kaddr);
acpi_os_unmap_memory(entry->kaddr, entry->size);
entry->kaddr = NULL;
}
}
......@@ -105,7 +106,7 @@ int suspend_nvs_alloc(void)
/**
* suspend_nvs_save - save NVS memory regions
*/
void suspend_nvs_save(void)
int suspend_nvs_save(void)
{
struct nvs_page *entry;
......@@ -113,9 +114,16 @@ void suspend_nvs_save(void)
list_for_each_entry(entry, &nvs_list, node)
if (entry->data) {
entry->kaddr = ioremap(entry->phys_start, entry->size);
entry->kaddr = acpi_os_map_memory(entry->phys_start,
entry->size);
if (!entry->kaddr) {
suspend_nvs_free();
return -ENOMEM;
}
memcpy(entry->data, entry->kaddr, entry->size);
}
return 0;
}
/**
......
......@@ -320,7 +320,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
pg_off = round_down(phys, PAGE_SIZE);
pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
virt = ioremap(pg_off, pg_sz);
virt = ioremap_cache(pg_off, pg_sz);
if (!virt) {
kfree(map);
return NULL;
......@@ -642,7 +642,7 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
rcu_read_unlock();
if (!virt_addr) {
virt_addr = ioremap(phys_addr, size);
virt_addr = ioremap_cache(phys_addr, size);
unmap = 1;
}
if (!value)
......@@ -678,7 +678,7 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
rcu_read_unlock();
if (!virt_addr) {
virt_addr = ioremap(phys_addr, size);
virt_addr = ioremap_cache(phys_addr, size);
unmap = 1;
}
......@@ -1233,8 +1233,7 @@ __setup("acpi_enforce_resources=", acpi_enforce_resources_setup);
int acpi_check_resource_conflict(const struct resource *res)
{
struct acpi_res_list *res_list_elem;
int ioport;
int clash = 0;
int ioport = 0, clash = 0;
if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
return 0;
......@@ -1264,9 +1263,13 @@ int acpi_check_resource_conflict(const struct resource *res)
if (clash) {
if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
printk(KERN_WARNING "ACPI: resource %s %pR"
" conflicts with ACPI region %s %pR\n",
" conflicts with ACPI region %s "
"[%s 0x%zx-0x%zx]\n",
res->name, res, res_list_elem->name,
res_list_elem);
(res_list_elem->resource_type ==
ACPI_ADR_SPACE_SYSTEM_IO) ? "io" : "mem",
(size_t) res_list_elem->start,
(size_t) res_list_elem->end);
if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX)
printk(KERN_NOTICE "ACPI: This conflict may"
" cause random problems and system"
......
......@@ -56,9 +56,6 @@ ACPI_MODULE_NAME("power");
#define ACPI_POWER_RESOURCE_STATE_ON 0x01
#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
int acpi_power_nocheck;
module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);
static int acpi_power_add(struct acpi_device *device);
static int acpi_power_remove(struct acpi_device *device, int type);
static int acpi_power_resume(struct acpi_device *device);
......@@ -148,9 +145,8 @@ static int acpi_power_get_state(acpi_handle handle, int *state)
static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
{
int result = 0, state1;
u32 i = 0;
int cur_state;
int i = 0;
if (!list || !state)
return -EINVAL;
......@@ -158,25 +154,33 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
/* The state of the list is 'on' IFF all resources are 'on'. */
for (i = 0; i < list->count; i++) {
/*
* The state of the power resource can be obtained by
* using the ACPI handle. In such case it is unnecessary to
* get the Power resource first and then get its state again.
*/
result = acpi_power_get_state(list->handles[i], &state1);
struct acpi_power_resource *resource;
acpi_handle handle = list->handles[i];
int result;
result = acpi_power_get_context(handle, &resource);
if (result)
return result;
*state = state1;
mutex_lock(&resource->resource_lock);
if (*state != ACPI_POWER_RESOURCE_STATE_ON)
result = acpi_power_get_state(handle, &cur_state);
mutex_unlock(&resource->resource_lock);
if (result)
return result;
if (cur_state != ACPI_POWER_RESOURCE_STATE_ON)
break;
}
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n",
*state ? "on" : "off"));
cur_state ? "on" : "off"));
return result;
*state = cur_state;
return 0;
}
static int __acpi_power_on(struct acpi_power_resource *resource)
......@@ -222,7 +226,7 @@ static int acpi_power_on(acpi_handle handle)
return result;
}
static int acpi_power_off_device(acpi_handle handle)
static int acpi_power_off(acpi_handle handle)
{
int result = 0;
acpi_status status = AE_OK;
......@@ -266,6 +270,35 @@ static int acpi_power_off_device(acpi_handle handle)
return result;
}
static void __acpi_power_off_list(struct acpi_handle_list *list, int num_res)
{
int i;
for (i = num_res - 1; i >= 0 ; i--)
acpi_power_off(list->handles[i]);
}
static void acpi_power_off_list(struct acpi_handle_list *list)
{
__acpi_power_off_list(list, list->count);
}
static int acpi_power_on_list(struct acpi_handle_list *list)
{
int result = 0;
int i;
for (i = 0; i < list->count; i++) {
result = acpi_power_on(list->handles[i]);
if (result) {
__acpi_power_off_list(list, i);
break;
}
}
return result;
}
/**
* acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in
* ACPI 3.0) _PSW (Power State Wake)
......@@ -404,8 +437,7 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
/* Close power resource */
for (i = 0; i < dev->wakeup.resources.count; i++) {
int ret = acpi_power_off_device(
dev->wakeup.resources.handles[i]);
int ret = acpi_power_off(dev->wakeup.resources.handles[i]);
if (ret) {
printk(KERN_ERR PREFIX "Transition power state\n");
dev->wakeup.flags.valid = 0;
......@@ -423,19 +455,16 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
Device Power Management
-------------------------------------------------------------------------- */
int acpi_power_get_inferred_state(struct acpi_device *device)
int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
{
int result = 0;
struct acpi_handle_list *list = NULL;
int list_state = 0;
int i = 0;
if (!device)
if (!device || !state)
return -EINVAL;
device->power.state = ACPI_STATE_UNKNOWN;
/*
* We know a device's inferred power state when all the resources
* required for a given D-state are 'on'.
......@@ -450,22 +479,26 @@ int acpi_power_get_inferred_state(struct acpi_device *device)
return result;
if (list_state == ACPI_POWER_RESOURCE_STATE_ON) {
device->power.state = i;
*state = i;
return 0;
}
}
device->power.state = ACPI_STATE_D3;
*state = ACPI_STATE_D3;
return 0;
}
int acpi_power_on_resources(struct acpi_device *device, int state)
{
if (!device || state < ACPI_STATE_D0 || state > ACPI_STATE_D3)
return -EINVAL;
return acpi_power_on_list(&device->power.states[state].resources);
}
int acpi_power_transition(struct acpi_device *device, int state)
{
int result = 0;
struct acpi_handle_list *cl = NULL; /* Current Resources */
struct acpi_handle_list *tl = NULL; /* Target Resources */
int i = 0;
int result;
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
return -EINVAL;
......@@ -477,37 +510,20 @@ int acpi_power_transition(struct acpi_device *device, int state)
|| (device->power.state > ACPI_STATE_D3))
return -ENODEV;
cl = &device->power.states[device->power.state].resources;
tl = &device->power.states[state].resources;
/* TBD: Resources must be ordered. */
/*
* First we reference all power resources required in the target list
* (e.g. so the device doesn't lose power while transitioning).
* (e.g. so the device doesn't lose power while transitioning). Then,
* we dereference all power resources used in the current list.
*/
for (i = 0; i < tl->count; i++) {
result = acpi_power_on(tl->handles[i]);
if (result)
goto end;
}
result = acpi_power_on_list(&device->power.states[state].resources);
if (!result)
acpi_power_off_list(
&device->power.states[device->power.state].resources);
/*
* Then we dereference all power resources used in the current list.
*/
for (i = 0; i < cl->count; i++) {
result = acpi_power_off_device(cl->handles[i]);
if (result)
goto end;
}
end:
if (result)
device->power.state = ACPI_STATE_UNKNOWN;
else {
/* We shouldn't change the state till all above operations succeed */
device->power.state = state;
}
/* We shouldn't change the state unless the above operations succeed. */
device->power.state = result ? ACPI_STATE_UNKNOWN : state;
return result;
}
......
......@@ -311,7 +311,9 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
dev->pnp.bus_id,
(u32) dev->wakeup.sleep_state,
dev->wakeup.flags.run_wake ? '*' : ' ',
dev->wakeup.state.enabled ? "enabled" : "disabled");
(device_may_wakeup(&dev->dev)
|| (ldev && device_may_wakeup(ldev))) ?
"enabled" : "disabled");
if (ldev)
seq_printf(seq, "%s:%s",
ldev->bus ? ldev->bus->name : "no-bus",
......@@ -328,8 +330,10 @@ static void physical_device_enable_wakeup(struct acpi_device *adev)
{
struct device *dev = acpi_get_physical_device(adev->handle);
if (dev && device_can_wakeup(dev))
device_set_wakeup_enable(dev, adev->wakeup.state.enabled);
if (dev && device_can_wakeup(dev)) {
bool enable = !device_may_wakeup(dev);
device_set_wakeup_enable(dev, enable);
}
}
static ssize_t
......@@ -341,7 +345,6 @@ acpi_system_write_wakeup_device(struct file *file,
char strbuf[5];
char str[5] = "";
unsigned int len = count;
struct acpi_device *found_dev = NULL;
if (len > 4)
len = 4;
......@@ -361,33 +364,13 @@ acpi_system_write_wakeup_device(struct file *file,
continue;
if (!strncmp(dev->pnp.bus_id, str, 4)) {
dev->wakeup.state.enabled =
dev->wakeup.state.enabled ? 0 : 1;
found_dev = dev;
break;
}
}
if (found_dev) {
physical_device_enable_wakeup(found_dev);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev = container_of(node,
struct
acpi_device,
wakeup_list);
if ((dev != found_dev) &&
(dev->wakeup.gpe_number ==
found_dev->wakeup.gpe_number)
&& (dev->wakeup.gpe_device ==
found_dev->wakeup.gpe_device)) {
printk(KERN_WARNING
"ACPI: '%s' and '%s' have the same GPE, "
"can't disable/enable one separately\n",
dev->pnp.bus_id, found_dev->pnp.bus_id);
dev->wakeup.state.enabled =
found_dev->wakeup.state.enabled;
if (device_can_wakeup(&dev->dev)) {
bool enable = !device_may_wakeup(&dev->dev);
device_set_wakeup_enable(&dev->dev, enable);
} else {
physical_device_enable_wakeup(dev);
}
break;
}
}
mutex_unlock(&acpi_device_lock);
......
This diff is collapsed.
This diff is collapsed.
......@@ -484,6 +484,8 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir,
const struct file_operations *state_fops,
const struct file_operations *alarm_fops, void *data)
{
printk(KERN_WARNING PREFIX "Deprecated procfs I/F for SBS is loaded,"
" please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
if (!*dir) {
*dir = proc_mkdir(dir_name, parent_dir);
if (!*dir) {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -1059,8 +1059,9 @@ static int acpi_thermal_resume(struct acpi_device *device)
break;
tz->trips.active[i].flags.enabled = 1;
for (j = 0; j < tz->trips.active[i].devices.count; j++) {
result = acpi_bus_get_power(tz->trips.active[i].devices.
handles[j], &power_state);
result = acpi_bus_update_power(
tz->trips.active[i].devices.handles[j],
&power_state);
if (result || (power_state != ACPI_STATE_D0)) {
tz->trips.active[i].flags.enabled = 0;
break;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -107,7 +107,6 @@ config DRM_I915
select FB_CFB_IMAGEBLIT
# i915 depends on ACPI_VIDEO when ACPI is enabled
# but for select to work, need to select ACPI_VIDEO's dependencies, ick
select VIDEO_OUTPUT_CONTROL if ACPI
select BACKLIGHT_CLASS_DEVICE if ACPI
select INPUT if ACPI
select ACPI_VIDEO if ACPI
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment