1
0
Fork 0

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:
  gcc-4.6: ACPI: fix unused but set variables in ACPI
  ACPI thermal: make procfs I/F depend on CONFIG_ACPI_PROCFS
  ACPI video: make procfs I/F depend on CONFIG_ACPI_PROCFS
  ACPI processor: remove deprecated ACPI procfs I/F
  ACPI power_resource: remove unused procfs I/F
  ACPI: remove deprecated ACPI procfs I/F
  ACPI: introduce drivers/acpi/sysfs.c
  ACPI: introduce module parameter acpi.aml_debug_output
  ACPI: introduce drivers/acpi/debugfs.c
  ACPI, APEI, ERST debug support
  ACPI, APEI, Manage GHES as platform devices
  ACPI, APEI, Rename CPER and GHES severity constants
  ACPI, APEI, Fix a typo of error path of apei_resources_request
  ACPI / ACPICA: Fix reference counting problems with GPE handlers
  ACPI: Add the check of ADR flag in course of finding ACPI handle for PCI device
  ACPI / Sleep: Drop acpi_suspend_finish()
  ACPI / Sleep: Consolidate suspend and hibernation routines
  ACPI / Wakeup: Simplify enabling of wakeup devices
  ACPI / Sleep: Rework enabling wakeup devices
  ACPI / Sleep: Free NVS copy if suspending of devices fails

Fixed up totally buggered "ACPI: fix unused but set variables in ACPI"
patch that doesn't even compile in the merge.

Thanks to Sedat Dilek <sedat.dilek@googlemail.com> for noticing the
breakage before I even pulled.  And a big "Grrr.." at Len for not even
bothering to compile the tree before asking me to pull.
wifi-calibration
Linus Torvalds 2010-08-15 17:37:07 -07:00
commit 2245ba2a3a
40 changed files with 1087 additions and 1495 deletions

View File

@ -19,6 +19,8 @@ Note: Only ACPI METHOD can be overridden, any other object types like
"Device", "OperationRegion", are not recognized. "Device", "OperationRegion", are not recognized.
Note: The same ACPI control method can be overridden for many times, Note: The same ACPI control method can be overridden for many times,
and it's always the latest one that used by Linux/kernel. and it's always the latest one that used by Linux/kernel.
Note: To get the ACPI debug object output (Store (AAAA, Debug)),
please run "echo 1 > /sys/module/acpi/parameters/aml_debug_output".
1. override an existing method 1. override an existing method
a) get the ACPI table via ACPI sysfs I/F. e.g. to get the DSDT, a) get the ACPI table via ACPI sysfs I/F. e.g. to get the DSDT,

View File

@ -80,7 +80,7 @@ int apei_write_mce(struct mce *m)
rcd.hdr.revision = CPER_RECORD_REV; rcd.hdr.revision = CPER_RECORD_REV;
rcd.hdr.signature_end = CPER_SIG_END; rcd.hdr.signature_end = CPER_SIG_END;
rcd.hdr.section_count = 1; rcd.hdr.section_count = 1;
rcd.hdr.error_severity = CPER_SER_FATAL; rcd.hdr.error_severity = CPER_SEV_FATAL;
/* timestamp, platform_id, partition_id are all invalid */ /* timestamp, platform_id, partition_id are all invalid */
rcd.hdr.validation_bits = 0; rcd.hdr.validation_bits = 0;
rcd.hdr.record_length = sizeof(rcd); rcd.hdr.record_length = sizeof(rcd);
@ -96,7 +96,7 @@ int apei_write_mce(struct mce *m)
rcd.sec_hdr.validation_bits = 0; rcd.sec_hdr.validation_bits = 0;
rcd.sec_hdr.flags = CPER_SEC_PRIMARY; rcd.sec_hdr.flags = CPER_SEC_PRIMARY;
rcd.sec_hdr.section_type = CPER_SECTION_TYPE_MCE; rcd.sec_hdr.section_type = CPER_SECTION_TYPE_MCE;
rcd.sec_hdr.section_severity = CPER_SER_FATAL; rcd.sec_hdr.section_severity = CPER_SEV_FATAL;
memcpy(&rcd.mce, m, sizeof(*m)); memcpy(&rcd.mce, m, sizeof(*m));

View File

@ -54,17 +54,10 @@ config ACPI_PROCFS
they have been replaced by functions in /sys. they have been replaced by functions in /sys.
The deprecated files (and their replacements) include: The deprecated files (and their replacements) include:
/proc/acpi/sleep (/sys/power/state)
/proc/acpi/info (/sys/module/acpi/parameters/acpica_version)
/proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT)
/proc/acpi/fadt (/sys/firmware/acpi/tables/FACP)
/proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer)
/proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level)
/proc/acpi/processor/*/power (/sys/devices/system/cpu/*/cpuidle/*)
/proc/acpi/processor/*/performance (/sys/devices/system/cpu/*/
cpufreq/*)
/proc/acpi/processor/*/throttling (/sys/class/thermal/ /proc/acpi/processor/*/throttling (/sys/class/thermal/
cooling_device*/*) 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 This option has no effect on /proc/acpi/ files
and functions which do not yet exist in /sys. and functions which do not yet exist in /sys.

View File

@ -37,8 +37,9 @@ acpi-y += ec.o
acpi-$(CONFIG_ACPI_DOCK) += dock.o acpi-$(CONFIG_ACPI_DOCK) += dock.o
acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
acpi-y += power.o acpi-y += power.o
acpi-y += system.o event.o acpi-y += event.o
acpi-$(CONFIG_ACPI_DEBUG) += debug.o acpi-y += sysfs.o
acpi-$(CONFIG_DEBUG_FS) += debugfs.o
acpi-$(CONFIG_ACPI_NUMA) += numa.o acpi-$(CONFIG_ACPI_NUMA) += numa.o
acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
ifdef CONFIG_ACPI_VIDEO ifdef CONFIG_ACPI_VIDEO

View File

@ -82,6 +82,10 @@ 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_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_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
u32 gpe_number); u32 gpe_number);

View File

@ -108,7 +108,7 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE);
/* /*
* Optionally enable output from the AML Debug Object. * Optionally enable output from the AML Debug Object.
*/ */
u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); u32 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE);
/* /*
* Optionally copy the entire DSDT to local memory (instead of simply * Optionally copy the entire DSDT to local memory (instead of simply

View File

@ -412,6 +412,7 @@ struct acpi_handler_info {
acpi_event_handler address; /* Address of handler, if any */ acpi_event_handler address; /* Address of handler, if any */
void *context; /* Context to be passed to handler */ void *context; /* Context to be passed to handler */
struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */
u8 orig_flags; /* Original misc info about this GPE */
}; };
union acpi_gpe_dispatch_info { union acpi_gpe_dispatch_info {

View File

@ -135,6 +135,79 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
} }
/*******************************************************************************
*
* FUNCTION: acpi_raw_enable_gpe
*
* PARAMETERS: gpe_event_info - GPE to enable
*
* RETURN: Status
*
* DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
* hardware-enabled.
*
******************************************************************************/
acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
{
acpi_status status = AE_OK;
if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) {
return_ACPI_STATUS(AE_LIMIT);
}
gpe_event_info->runtime_count++;
if (gpe_event_info->runtime_count == 1) {
status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
if (ACPI_SUCCESS(status)) {
status = acpi_ev_enable_gpe(gpe_event_info);
}
if (ACPI_FAILURE(status)) {
gpe_event_info->runtime_count--;
}
}
return_ACPI_STATUS(status);
}
/*******************************************************************************
*
* FUNCTION: acpi_raw_disable_gpe
*
* PARAMETERS: gpe_event_info - GPE to disable
*
* RETURN: Status
*
* DESCRIPTION: Remove a reference to a GPE. When the last reference is
* removed, the GPE is hardware-disabled.
*
******************************************************************************/
acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
{
acpi_status status = AE_OK;
if (!gpe_event_info->runtime_count) {
return_ACPI_STATUS(AE_LIMIT);
}
gpe_event_info->runtime_count--;
if (!gpe_event_info->runtime_count) {
status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
if (ACPI_SUCCESS(status)) {
status = acpi_hw_low_set_gpe(gpe_event_info,
ACPI_GPE_DISABLE);
}
if (ACPI_FAILURE(status)) {
gpe_event_info->runtime_count++;
}
}
return_ACPI_STATUS(status);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ev_low_get_gpe_info * FUNCTION: acpi_ev_low_get_gpe_info

View File

@ -691,23 +691,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
/* Ensure that we have a valid GPE number */ /* Allocate memory for the handler object */
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
/* Make sure that there isn't a handler there already */
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_HANDLER) {
status = AE_ALREADY_EXISTS;
goto unlock_and_exit;
}
/* Allocate and init handler object */
handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info)); handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info));
if (!handler) { if (!handler) {
@ -715,13 +699,45 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
goto unlock_and_exit; goto unlock_and_exit;
} }
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
/* Ensure that we have a valid GPE number */
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
goto free_and_exit;
}
/* Make sure that there isn't a handler there already */
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_HANDLER) {
status = AE_ALREADY_EXISTS;
goto free_and_exit;
}
/* Allocate and init handler object */
handler->address = address; handler->address = address;
handler->context = context; handler->context = context;
handler->method_node = gpe_event_info->dispatch.method_node; handler->method_node = gpe_event_info->dispatch.method_node;
handler->orig_flags = gpe_event_info->flags &
(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
/*
* If the GPE is associated with a method and it cannot wake up the
* system from sleep states, it was enabled automatically during
* initialization, so it has to be disabled now to avoid spurious
* execution of the handler.
*/
if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD)
&& !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE))
(void)acpi_raw_disable_gpe(gpe_event_info);
/* Install the handler */ /* Install the handler */
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
gpe_event_info->dispatch.handler = handler; gpe_event_info->dispatch.handler = handler;
/* Setup up dispatch flags to indicate handler (vs. method) */ /* Setup up dispatch flags to indicate handler (vs. method) */
@ -735,6 +751,11 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
unlock_and_exit: unlock_and_exit:
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
free_and_exit:
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
ACPI_FREE(handler);
goto unlock_and_exit;
} }
ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler) ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler)
@ -770,11 +791,17 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
return_ACPI_STATUS(AE_BAD_PARAMETER); return_ACPI_STATUS(AE_BAD_PARAMETER);
} }
/* Make sure all deferred tasks are completed */
acpi_os_wait_events_complete(NULL);
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
@ -798,34 +825,34 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
goto unlock_and_exit; goto unlock_and_exit;
} }
/* Make sure all deferred tasks are completed */
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
acpi_os_wait_events_complete(NULL);
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Remove the handler */ /* Remove the handler */
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
handler = gpe_event_info->dispatch.handler; handler = gpe_event_info->dispatch.handler;
/* Restore Method node (if any), set dispatch flags */ /* Restore Method node (if any), set dispatch flags */
gpe_event_info->dispatch.method_node = handler->method_node; gpe_event_info->dispatch.method_node = handler->method_node;
gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */ gpe_event_info->flags &=
if (handler->method_node) { ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
gpe_event_info->flags |= ACPI_GPE_DISPATCH_METHOD; gpe_event_info->flags |= handler->orig_flags;
}
acpi_os_release_lock(acpi_gbl_gpe_lock, flags); /*
* If the GPE was previously associated with a method and it cannot wake
* up the system from sleep states, it should be enabled at this point
* to restore the post-initialization configuration.
*/
if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD)
&& !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE))
(void)acpi_raw_enable_gpe(gpe_event_info);
/* Now we can free the handler object */ /* Now we can free the handler object */
ACPI_FREE(handler); ACPI_FREE(handler);
unlock_and_exit: unlock_and_exit:
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }

View File

@ -294,7 +294,7 @@ ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup)
******************************************************************************/ ******************************************************************************/
acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
{ {
acpi_status status = AE_OK; acpi_status status = AE_BAD_PARAMETER;
struct acpi_gpe_event_info *gpe_event_info; struct acpi_gpe_event_info *gpe_event_info;
acpi_cpu_flags flags; acpi_cpu_flags flags;
@ -305,28 +305,10 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) { if (gpe_event_info) {
status = AE_BAD_PARAMETER; status = acpi_raw_enable_gpe(gpe_event_info);
goto unlock_and_exit;
} }
if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) {
status = AE_LIMIT; /* Too many references */
goto unlock_and_exit;
}
gpe_event_info->runtime_count++;
if (gpe_event_info->runtime_count == 1) {
status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
if (ACPI_SUCCESS(status)) {
status = acpi_ev_enable_gpe(gpe_event_info);
}
if (ACPI_FAILURE(status)) {
gpe_event_info->runtime_count--;
}
}
unlock_and_exit:
acpi_os_release_lock(acpi_gbl_gpe_lock, flags); acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
@ -348,7 +330,7 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
******************************************************************************/ ******************************************************************************/
acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
{ {
acpi_status status = AE_OK; acpi_status status = AE_BAD_PARAMETER;
struct acpi_gpe_event_info *gpe_event_info; struct acpi_gpe_event_info *gpe_event_info;
acpi_cpu_flags flags; acpi_cpu_flags flags;
@ -359,32 +341,10 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
/* Ensure that we have a valid GPE number */ /* Ensure that we have a valid GPE number */
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) { if (gpe_event_info) {
status = AE_BAD_PARAMETER; status = acpi_raw_disable_gpe(gpe_event_info) ;
goto unlock_and_exit;
} }
/* Hardware-disable a runtime GPE on removal of the last reference */
if (!gpe_event_info->runtime_count) {
status = AE_LIMIT; /* There are no references to remove */
goto unlock_and_exit;
}
gpe_event_info->runtime_count--;
if (!gpe_event_info->runtime_count) {
status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
if (ACPI_SUCCESS(status)) {
status =
acpi_hw_low_set_gpe(gpe_event_info,
ACPI_GPE_DISABLE);
}
if (ACPI_FAILURE(status)) {
gpe_event_info->runtime_count++;
}
}
unlock_and_exit:
acpi_os_release_lock(acpi_gbl_gpe_lock, flags); acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
@ -411,7 +371,6 @@ acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number)
acpi_status status = AE_OK; acpi_status status = AE_OK;
struct acpi_gpe_event_info *gpe_event_info; struct acpi_gpe_event_info *gpe_event_info;
acpi_cpu_flags flags; acpi_cpu_flags flags;
u8 disable = 0;
ACPI_FUNCTION_TRACE(acpi_gpe_can_wake); ACPI_FUNCTION_TRACE(acpi_gpe_can_wake);
@ -430,15 +389,12 @@ acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number)
} }
gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
disable = (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) if (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) {
&& gpe_event_info->runtime_count; (void)acpi_raw_disable_gpe(gpe_event_info);
}
unlock_and_exit: unlock_and_exit:
acpi_os_release_lock(acpi_gbl_gpe_lock, flags); acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
if (disable)
status = acpi_disable_gpe(gpe_device, gpe_number);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake) ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake)

View File

@ -279,13 +279,10 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
{ {
acpi_thread_id this_thread_id;
ACPI_FUNCTION_NAME(ut_release_mutex); ACPI_FUNCTION_NAME(ut_release_mutex);
this_thread_id = acpi_os_get_thread_id();
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n",
ACPI_CAST_PTR(void, this_thread_id), ACPI_CAST_PTR(void, acpi_os_get_thread_id()),
acpi_ut_get_mutex_name(mutex_id))); acpi_ut_get_mutex_name(mutex_id)));
if (mutex_id > ACPI_MAX_MUTEX) { if (mutex_id > ACPI_MAX_MUTEX) {

View File

@ -28,3 +28,12 @@ config ACPI_APEI_EINJ
EINJ provides a hardware error injection mechanism, it is EINJ provides a hardware error injection mechanism, it is
mainly used for debugging and testing the other parts of mainly used for debugging and testing the other parts of
APEI and some other RAS features. APEI and some other RAS features.
config ACPI_APEI_ERST_DEBUG
tristate "APEI Error Record Serialization Table (ERST) Debug Support"
depends on ACPI_APEI
help
ERST is a way provided by APEI to save and retrieve hardware
error infomation to and from a persistent store. Enable this
if you want to debugging and testing the ERST kernel support
and firmware implementation.

View File

@ -1,5 +1,6 @@
obj-$(CONFIG_ACPI_APEI) += apei.o obj-$(CONFIG_ACPI_APEI) += apei.o
obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o
obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o
obj-$(CONFIG_ACPI_APEI_ERST_DEBUG) += erst-dbg.o
apei-y := apei-base.o hest.o cper.o erst.o apei-y := apei-base.o hest.o cper.o erst.o

View File

@ -482,14 +482,14 @@ err_unmap_ioport:
list_for_each_entry(res, &resources->ioport, list) { list_for_each_entry(res, &resources->ioport, list) {
if (res == res_bak) if (res == res_bak)
break; break;
release_mem_region(res->start, res->end - res->start); release_region(res->start, res->end - res->start);
} }
res_bak = NULL; res_bak = NULL;
err_unmap_iomem: err_unmap_iomem:
list_for_each_entry(res, &resources->iomem, list) { list_for_each_entry(res, &resources->iomem, list) {
if (res == res_bak) if (res == res_bak)
break; break;
release_region(res->start, res->end - res->start); release_mem_region(res->start, res->end - res->start);
} }
return -EINVAL; return -EINVAL;
} }

View File

@ -0,0 +1,207 @@
/*
* APEI Error Record Serialization Table debug support
*
* ERST is a way provided by APEI to save and retrieve hardware error
* infomation to and from a persistent store. This file provide the
* debugging/testing support for ERST kernel support and firmware
* implementation.
*
* Copyright 2010 Intel Corp.
* Author: Huang Ying <ying.huang@intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/uaccess.h>
#include <acpi/apei.h>
#include <linux/miscdevice.h>
#include "apei-internal.h"
#define ERST_DBG_PFX "ERST DBG: "
#define ERST_DBG_RECORD_LEN_MAX 4096
static void *erst_dbg_buf;
static unsigned int erst_dbg_buf_len;
/* Prevent erst_dbg_read/write from being invoked concurrently */
static DEFINE_MUTEX(erst_dbg_mutex);
static int erst_dbg_open(struct inode *inode, struct file *file)
{
if (erst_disable)
return -ENODEV;
return nonseekable_open(inode, file);
}
static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
int rc;
u64 record_id;
u32 record_count;
switch (cmd) {
case APEI_ERST_CLEAR_RECORD:
rc = copy_from_user(&record_id, (void __user *)arg,
sizeof(record_id));
if (rc)
return -EFAULT;
return erst_clear(record_id);
case APEI_ERST_GET_RECORD_COUNT:
rc = erst_get_record_count();
if (rc < 0)
return rc;
record_count = rc;
rc = put_user(record_count, (u32 __user *)arg);
if (rc)
return rc;
return 0;
default:
return -ENOTTY;
}
}
static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf,
size_t usize, loff_t *off)
{
int rc;
ssize_t len = 0;
u64 id;
if (*off != 0)
return -EINVAL;
if (mutex_lock_interruptible(&erst_dbg_mutex) != 0)
return -EINTR;
retry_next:
rc = erst_get_next_record_id(&id);
if (rc)
goto out;
/* no more record */
if (id == APEI_ERST_INVALID_RECORD_ID)
goto out;
retry:
rc = len = erst_read(id, erst_dbg_buf, erst_dbg_buf_len);
/* The record may be cleared by others, try read next record */
if (rc == -ENOENT)
goto retry_next;
if (rc < 0)
goto out;
if (len > ERST_DBG_RECORD_LEN_MAX) {
pr_warning(ERST_DBG_PFX
"Record (ID: 0x%llx) length is too long: %zd\n",
id, len);
rc = -EIO;
goto out;
}
if (len > erst_dbg_buf_len) {
kfree(erst_dbg_buf);
rc = -ENOMEM;
erst_dbg_buf = kmalloc(len, GFP_KERNEL);
if (!erst_dbg_buf)
goto out;
erst_dbg_buf_len = len;
goto retry;
}
rc = -EINVAL;
if (len > usize)
goto out;
rc = -EFAULT;
if (copy_to_user(ubuf, erst_dbg_buf, len))
goto out;
rc = 0;
out:
mutex_unlock(&erst_dbg_mutex);
return rc ? rc : len;
}
static ssize_t erst_dbg_write(struct file *filp, const char __user *ubuf,
size_t usize, loff_t *off)
{
int rc;
struct cper_record_header *rcd;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (usize > ERST_DBG_RECORD_LEN_MAX) {
pr_err(ERST_DBG_PFX "Too long record to be written\n");
return -EINVAL;
}
if (mutex_lock_interruptible(&erst_dbg_mutex))
return -EINTR;
if (usize > erst_dbg_buf_len) {
kfree(erst_dbg_buf);
rc = -ENOMEM;
erst_dbg_buf = kmalloc(usize, GFP_KERNEL);
if (!erst_dbg_buf)
goto out;
erst_dbg_buf_len = usize;
}
rc = copy_from_user(erst_dbg_buf, ubuf, usize);
if (rc) {
rc = -EFAULT;
goto out;
}
rcd = erst_dbg_buf;
rc = -EINVAL;
if (rcd->record_length != usize)
goto out;
rc = erst_write(erst_dbg_buf);
out:
mutex_unlock(&erst_dbg_mutex);
return rc < 0 ? rc : usize;
}
static const struct file_operations erst_dbg_ops = {
.owner = THIS_MODULE,
.open = erst_dbg_open,
.read = erst_dbg_read,
.write = erst_dbg_write,
.unlocked_ioctl = erst_dbg_ioctl,
};
static struct miscdevice erst_dbg_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "erst_dbg",
.fops = &erst_dbg_ops,
};
static __init int erst_dbg_init(void)
{
return misc_register(&erst_dbg_dev);
}
static __exit void erst_dbg_exit(void)
{
misc_deregister(&erst_dbg_dev);
kfree(erst_dbg_buf);
}
module_init(erst_dbg_init);
module_exit(erst_dbg_exit);
MODULE_AUTHOR("Huang Ying");
MODULE_DESCRIPTION("APEI Error Record Serialization Table debug support");
MODULE_LICENSE("GPL");

View File

@ -41,6 +41,8 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/cper.h> #include <linux/cper.h>
#include <linux/kdebug.h> #include <linux/kdebug.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <acpi/apei.h> #include <acpi/apei.h>
#include <acpi/atomicio.h> #include <acpi/atomicio.h>
#include <acpi/hed.h> #include <acpi/hed.h>
@ -87,6 +89,7 @@ struct ghes {
* used for that. * used for that.
*/ */
static LIST_HEAD(ghes_sci); static LIST_HEAD(ghes_sci);
static DEFINE_MUTEX(ghes_list_mutex);
static struct ghes *ghes_new(struct acpi_hest_generic *generic) static struct ghes *ghes_new(struct acpi_hest_generic *generic)
{ {
@ -132,26 +135,26 @@ static void ghes_fini(struct ghes *ghes)
} }
enum { enum {
GHES_SER_NO = 0x0, GHES_SEV_NO = 0x0,
GHES_SER_CORRECTED = 0x1, GHES_SEV_CORRECTED = 0x1,
GHES_SER_RECOVERABLE = 0x2, GHES_SEV_RECOVERABLE = 0x2,
GHES_SER_PANIC = 0x3, GHES_SEV_PANIC = 0x3,
}; };
static inline int ghes_severity(int severity) static inline int ghes_severity(int severity)
{ {
switch (severity) { switch (severity) {
case CPER_SER_INFORMATIONAL: case CPER_SEV_INFORMATIONAL:
return GHES_SER_NO; return GHES_SEV_NO;
case CPER_SER_CORRECTED: case CPER_SEV_CORRECTED:
return GHES_SER_CORRECTED; return GHES_SEV_CORRECTED;
case CPER_SER_RECOVERABLE: case CPER_SEV_RECOVERABLE:
return GHES_SER_RECOVERABLE; return GHES_SEV_RECOVERABLE;
case CPER_SER_FATAL: case CPER_SEV_FATAL:
return GHES_SER_PANIC; return GHES_SEV_PANIC;
default: default:
/* Unkown, go panic */ /* Unkown, go panic */
return GHES_SER_PANIC; return GHES_SEV_PANIC;
} }
} }
@ -237,16 +240,16 @@ static void ghes_clear_estatus(struct ghes *ghes)
static void ghes_do_proc(struct ghes *ghes) static void ghes_do_proc(struct ghes *ghes)
{ {
int ser, processed = 0; int sev, processed = 0;
struct acpi_hest_generic_data *gdata; struct acpi_hest_generic_data *gdata;
ser = ghes_severity(ghes->estatus->error_severity); sev = ghes_severity(ghes->estatus->error_severity);
apei_estatus_for_each_section(ghes->estatus, gdata) { apei_estatus_for_each_section(ghes->estatus, gdata) {
#ifdef CONFIG_X86_MCE #ifdef CONFIG_X86_MCE
if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, if (!uuid_le_cmp(*(uuid_le *)gdata->section_type,
CPER_SEC_PLATFORM_MEM)) { CPER_SEC_PLATFORM_MEM)) {
apei_mce_report_mem_error( apei_mce_report_mem_error(
ser == GHES_SER_CORRECTED, sev == GHES_SEV_CORRECTED,
(struct cper_sec_mem_err *)(gdata+1)); (struct cper_sec_mem_err *)(gdata+1));
processed = 1; processed = 1;
} }
@ -293,18 +296,15 @@ static struct notifier_block ghes_notifier_sci = {
.notifier_call = ghes_notify_sci, .notifier_call = ghes_notify_sci,
}; };
static int hest_ghes_parse(struct acpi_hest_header *hest_hdr, void *data) static int __devinit ghes_probe(struct platform_device *ghes_dev)
{ {
struct acpi_hest_generic *generic; struct acpi_hest_generic *generic;
struct ghes *ghes = NULL; struct ghes *ghes = NULL;
int rc = 0; int rc = -EINVAL;
if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) generic = ghes_dev->dev.platform_data;
return 0;
generic = (struct acpi_hest_generic *)hest_hdr;
if (!generic->enabled) if (!generic->enabled)
return 0; return -ENODEV;
if (generic->error_block_length < if (generic->error_block_length <
sizeof(struct acpi_hest_generic_status)) { sizeof(struct acpi_hest_generic_status)) {
@ -327,62 +327,91 @@ static int hest_ghes_parse(struct acpi_hest_header *hest_hdr, void *data)
ghes = NULL; ghes = NULL;
goto err; goto err;
} }
switch (generic->notify.type) { if (generic->notify.type == ACPI_HEST_NOTIFY_SCI) {
case ACPI_HEST_NOTIFY_POLLED: mutex_lock(&ghes_list_mutex);
pr_warning(GHES_PFX
"Generic hardware error source: %d notified via POLL is not supported!\n",
generic->header.source_id);
break;
case ACPI_HEST_NOTIFY_EXTERNAL:
case ACPI_HEST_NOTIFY_LOCAL:
pr_warning(GHES_PFX
"Generic hardware error source: %d notified via IRQ is not supported!\n",
generic->header.source_id);
break;
case ACPI_HEST_NOTIFY_SCI:
if (list_empty(&ghes_sci)) if (list_empty(&ghes_sci))
register_acpi_hed_notifier(&ghes_notifier_sci); register_acpi_hed_notifier(&ghes_notifier_sci);
list_add_rcu(&ghes->list, &ghes_sci); list_add_rcu(&ghes->list, &ghes_sci);
break; mutex_unlock(&ghes_list_mutex);
case ACPI_HEST_NOTIFY_NMI: } else {
pr_warning(GHES_PFX unsigned char *notify = NULL;
"Generic hardware error source: %d notified via NMI is not supported!\n",
generic->header.source_id); switch (generic->notify.type) {
break; case ACPI_HEST_NOTIFY_POLLED:
default: notify = "POLL";
pr_warning(FW_WARN GHES_PFX break;
"Unknown notification type: %u for generic hardware error source: %d\n", case ACPI_HEST_NOTIFY_EXTERNAL:
generic->notify.type, generic->header.source_id); case ACPI_HEST_NOTIFY_LOCAL:
break; notify = "IRQ";
break;
case ACPI_HEST_NOTIFY_NMI:
notify = "NMI";
break;
}
if (notify) {
pr_warning(GHES_PFX
"Generic hardware error source: %d notified via %s is not supported!\n",
generic->header.source_id, notify);
} else {
pr_warning(FW_WARN GHES_PFX
"Unknown notification type: %u for generic hardware error source: %d\n",
generic->notify.type, generic->header.source_id);
}
rc = -ENODEV;
goto err;
} }
platform_set_drvdata(ghes_dev, ghes);
return 0; return 0;
err: err:
if (ghes) if (ghes) {
ghes_fini(ghes);
return rc;
}
static void ghes_cleanup(void)
{
struct ghes *ghes, *nghes;
if (!list_empty(&ghes_sci))
unregister_acpi_hed_notifier(&ghes_notifier_sci);
synchronize_rcu();
list_for_each_entry_safe(ghes, nghes, &ghes_sci, list) {
list_del(&ghes->list);
ghes_fini(ghes); ghes_fini(ghes);
kfree(ghes); kfree(ghes);
} }
return rc;
} }
static int __devexit ghes_remove(struct platform_device *ghes_dev)
{
struct ghes *ghes;
struct acpi_hest_generic *generic;
ghes = platform_get_drvdata(ghes_dev);
generic = ghes->generic;
switch (generic->notify.type) {
case ACPI_HEST_NOTIFY_SCI:
mutex_lock(&ghes_list_mutex);
list_del_rcu(&ghes->list);
if (list_empty(&ghes_sci))
unregister_acpi_hed_notifier(&ghes_notifier_sci);
mutex_unlock(&ghes_list_mutex);
break;
default:
BUG();
break;
}
synchronize_rcu();
ghes_fini(ghes);
kfree(ghes);
platform_set_drvdata(ghes_dev, NULL);
return 0;
}
static struct platform_driver ghes_platform_driver = {
.driver = {
.name = "GHES",
.owner = THIS_MODULE,
},
.probe = ghes_probe,
.remove = ghes_remove,
};
static int __init ghes_init(void) static int __init ghes_init(void)
{ {
int rc;
if (acpi_disabled) if (acpi_disabled)
return -ENODEV; return -ENODEV;
@ -391,32 +420,12 @@ static int __init ghes_init(void)
return -EINVAL; return -EINVAL;
} }
rc = apei_hest_parse(hest_ghes_parse, NULL); return platform_driver_register(&ghes_platform_driver);
if (rc) {
pr_err(GHES_PFX
"Error during parsing HEST generic hardware error sources.\n");
goto err_cleanup;
}
if (list_empty(&ghes_sci)) {
pr_info(GHES_PFX
"No functional generic hardware error sources.\n");
rc = -ENODEV;
goto err_cleanup;
}
pr_info(GHES_PFX
"Generic Hardware Error Source support is initialized.\n");
return 0;
err_cleanup:
ghes_cleanup();
return rc;
} }
static void __exit ghes_exit(void) static void __exit ghes_exit(void)
{ {
ghes_cleanup(); platform_driver_unregister(&ghes_platform_driver);
} }
module_init(ghes_init); module_init(ghes_init);
@ -425,3 +434,4 @@ module_exit(ghes_exit);
MODULE_AUTHOR("Huang Ying"); MODULE_AUTHOR("Huang Ying");
MODULE_DESCRIPTION("APEI Generic Hardware Error Source support"); MODULE_DESCRIPTION("APEI Generic Hardware Error Source support");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:GHES");

View File

@ -34,6 +34,7 @@
#include <linux/kdebug.h> #include <linux/kdebug.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/platform_device.h>
#include <acpi/apei.h> #include <acpi/apei.h>
#include "apei-internal.h" #include "apei-internal.h"
@ -47,11 +48,6 @@ EXPORT_SYMBOL_GPL(hest_disable);
static struct acpi_table_hest *hest_tab; static struct acpi_table_hest *hest_tab;
static int hest_void_parse(struct acpi_hest_header *hest_hdr, void *data)
{
return 0;
}
static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
[ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */
[ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1,
@ -125,6 +121,69 @@ int apei_hest_parse(apei_hest_func_t func, void *data)
} }
EXPORT_SYMBOL_GPL(apei_hest_parse); EXPORT_SYMBOL_GPL(apei_hest_parse);
struct ghes_arr {
struct platform_device **ghes_devs;
unsigned int count;
};
static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
{
int *count = data;
if (hest_hdr->type == ACPI_HEST_TYPE_GENERIC_ERROR)
(*count)++;
return 0;
}
static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
{
struct acpi_hest_generic *generic;
struct platform_device *ghes_dev;
struct ghes_arr *ghes_arr = data;
int rc;
if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR)
return 0;
generic = (struct acpi_hest_generic *)hest_hdr;
if (!generic->enabled)
return 0;
ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id);
if (!ghes_dev)
return -ENOMEM;
ghes_dev->dev.platform_data = generic;
rc = platform_device_add(ghes_dev);
if (rc)
goto err;
ghes_arr->ghes_devs[ghes_arr->count++] = ghes_dev;
return 0;
err:
platform_device_put(ghes_dev);
return rc;
}
static int hest_ghes_dev_register(unsigned int ghes_count)
{
int rc, i;
struct ghes_arr ghes_arr;
ghes_arr.count = 0;
ghes_arr.ghes_devs = kmalloc(sizeof(void *) * ghes_count, GFP_KERNEL);
if (!ghes_arr.ghes_devs)
return -ENOMEM;
rc = apei_hest_parse(hest_parse_ghes, &ghes_arr);
if (rc)
goto err;
out:
kfree(ghes_arr.ghes_devs);
return rc;
err:
for (i = 0; i < ghes_arr.count; i++)
platform_device_unregister(ghes_arr.ghes_devs[i]);
goto out;
}
static int __init setup_hest_disable(char *str) static int __init setup_hest_disable(char *str)
{ {
hest_disable = 1; hest_disable = 1;
@ -137,6 +196,7 @@ static int __init hest_init(void)
{ {
acpi_status status; acpi_status status;
int rc = -ENODEV; int rc = -ENODEV;
unsigned int ghes_count = 0;
if (acpi_disabled) if (acpi_disabled)
goto err; goto err;
@ -158,7 +218,11 @@ static int __init hest_init(void)
goto err; goto err;
} }
rc = apei_hest_parse(hest_void_parse, NULL); rc = apei_hest_parse(hest_parse_ghes_count, &ghes_count);
if (rc)
goto err;
rc = hest_ghes_dev_register(ghes_count);
if (rc) if (rc)
goto err; goto err;

View File

@ -1034,8 +1034,8 @@ static int __init acpi_init(void)
acpi_scan_init(); acpi_scan_init();
acpi_ec_init(); acpi_ec_init();
acpi_power_init(); acpi_power_init();
acpi_system_init(); acpi_sysfs_init();
acpi_debug_init(); acpi_debugfs_init();
acpi_sleep_proc_init(); acpi_sleep_proc_init();
acpi_wakeup_device_init(); acpi_wakeup_device_init();
return result; return result;

View File

@ -1,422 +0,0 @@
/*
* debug.c - ACPI debug interface to userspace.
*/
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <acpi/acpi_drivers.h>
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("debug");
struct acpi_dlayer {
const char *name;
unsigned long value;
};
struct acpi_dlevel {
const char *name;
unsigned long value;
};
#define ACPI_DEBUG_INIT(v) { .name = #v, .value = v }
static const struct acpi_dlayer acpi_debug_layers[] = {
ACPI_DEBUG_INIT(ACPI_UTILITIES),
ACPI_DEBUG_INIT(ACPI_HARDWARE),
ACPI_DEBUG_INIT(ACPI_EVENTS),
ACPI_DEBUG_INIT(ACPI_TABLES),
ACPI_DEBUG_INIT(ACPI_NAMESPACE),
ACPI_DEBUG_INIT(ACPI_PARSER),
ACPI_DEBUG_INIT(ACPI_DISPATCHER),
ACPI_DEBUG_INIT(ACPI_EXECUTER),
ACPI_DEBUG_INIT(ACPI_RESOURCES),
ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER),
ACPI_DEBUG_INIT(ACPI_OS_SERVICES),
ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER),
ACPI_DEBUG_INIT(ACPI_COMPILER),
ACPI_DEBUG_INIT(ACPI_TOOLS),
ACPI_DEBUG_INIT(ACPI_BUS_COMPONENT),
ACPI_DEBUG_INIT(ACPI_AC_COMPONENT),
ACPI_DEBUG_INIT(ACPI_BATTERY_COMPONENT),
ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT),
ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT),
ACPI_DEBUG_INIT(ACPI_FAN_COMPONENT),
ACPI_DEBUG_INIT(ACPI_PCI_COMPONENT),
ACPI_DEBUG_INIT(ACPI_POWER_COMPONENT),
ACPI_DEBUG_INIT(ACPI_CONTAINER_COMPONENT),
ACPI_DEBUG_INIT(ACPI_SYSTEM_COMPONENT),
ACPI_DEBUG_INIT(ACPI_THERMAL_COMPONENT),
ACPI_DEBUG_INIT(ACPI_MEMORY_DEVICE_COMPONENT),
ACPI_DEBUG_INIT(ACPI_VIDEO_COMPONENT),
ACPI_DEBUG_INIT(ACPI_PROCESSOR_COMPONENT),
};
static const struct acpi_dlevel acpi_debug_levels[] = {
ACPI_DEBUG_INIT(ACPI_LV_INIT),
ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT),
ACPI_DEBUG_INIT(ACPI_LV_INFO),
ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES),
ACPI_DEBUG_INIT(ACPI_LV_PARSE),
ACPI_DEBUG_INIT(ACPI_LV_LOAD),
ACPI_DEBUG_INIT(ACPI_LV_DISPATCH),
ACPI_DEBUG_INIT(ACPI_LV_EXEC),
ACPI_DEBUG_INIT(ACPI_LV_NAMES),
ACPI_DEBUG_INIT(ACPI_LV_OPREGION),
ACPI_DEBUG_INIT(ACPI_LV_BFIELD),
ACPI_DEBUG_INIT(ACPI_LV_TABLES),
ACPI_DEBUG_INIT(ACPI_LV_VALUES),
ACPI_DEBUG_INIT(ACPI_LV_OBJECTS),
ACPI_DEBUG_INIT(ACPI_LV_RESOURCES),
ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS),
ACPI_DEBUG_INIT(ACPI_LV_PACKAGE),
ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS),
ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS),
ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS),
ACPI_DEBUG_INIT(ACPI_LV_MUTEX),
ACPI_DEBUG_INIT(ACPI_LV_THREADS),
ACPI_DEBUG_INIT(ACPI_LV_IO),
ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS),
ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE),
ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO),
ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES),
ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
};
/* --------------------------------------------------------------------------
FS Interface (/sys)
-------------------------------------------------------------------------- */
static int param_get_debug_layer(char *buffer, const struct kernel_param *kp)
{
int result = 0;
int i;
result = sprintf(buffer, "%-25s\tHex SET\n", "Description");
for(i = 0; i <ARRAY_SIZE(acpi_debug_layers); i++) {
result += sprintf(buffer+result, "%-25s\t0x%08lX [%c]\n",
acpi_debug_layers[i].name,
acpi_debug_layers[i].value,
(acpi_dbg_layer & acpi_debug_layers[i].value) ? '*' : ' ');
}
result += sprintf(buffer+result, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS",
ACPI_ALL_DRIVERS,
(acpi_dbg_layer & ACPI_ALL_DRIVERS) ==
ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer &
ACPI_ALL_DRIVERS) == 0 ? ' ' : '-');
result += sprintf(buffer+result, "--\ndebug_layer = 0x%08X ( * = enabled)\n", acpi_dbg_layer);
return result;
}
static int param_get_debug_level(char *buffer, const struct kernel_param *kp)
{
int result = 0;
int i;
result = sprintf(buffer, "%-25s\tHex SET\n", "Description");
for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) {
result += sprintf(buffer+result, "%-25s\t0x%08lX [%c]\n",
acpi_debug_levels[i].name,
acpi_debug_levels[i].value,
(acpi_dbg_level & acpi_debug_levels[i].
value) ? '*' : ' ');
}
result += sprintf(buffer+result, "--\ndebug_level = 0x%08X (* = enabled)\n",
acpi_dbg_level);
return result;
}
static struct kernel_param_ops acpi_debug_layer_ops = {
.set = param_set_uint,
.get = param_get_debug_layer,
};
static struct kernel_param_ops acpi_debug_level_ops = {
.set = param_set_uint,
.get = param_get_debug_level,
};
module_param_cb(debug_layer, &acpi_debug_layer_ops, &acpi_dbg_layer, 0644);
module_param_cb(debug_level, &acpi_debug_level_ops, &acpi_dbg_level, 0644);
static char trace_method_name[6];
module_param_string(trace_method_name, trace_method_name, 6, 0644);
static unsigned int trace_debug_layer;
module_param(trace_debug_layer, uint, 0644);
static unsigned int trace_debug_level;
module_param(trace_debug_level, uint, 0644);
static int param_set_trace_state(const char *val, const struct kernel_param *kp)
{
int result = 0;
if (!strncmp(val, "enable", strlen("enable") - 1)) {
result = acpi_debug_trace(trace_method_name, trace_debug_level,
trace_debug_layer, 0);
if (result)
result = -EBUSY;
goto exit;
}
if (!strncmp(val, "disable", strlen("disable") - 1)) {
int name = 0;
result = acpi_debug_trace((char *)&name, trace_debug_level,
trace_debug_layer, 0);
if (result)
result = -EBUSY;
goto exit;
}
if (!strncmp(val, "1", 1)) {
result = acpi_debug_trace(trace_method_name, trace_debug_level,
trace_debug_layer, 1);
if (result)
result = -EBUSY;
goto exit;
}
result = -EINVAL;
exit:
return result;
}
static int param_get_trace_state(char *buffer, const struct kernel_param *kp)
{
if (!acpi_gbl_trace_method_name)
return sprintf(buffer, "disable");
else {
if (acpi_gbl_trace_flags & 1)
return sprintf(buffer, "1");
else
return sprintf(buffer, "enable");
}
return 0;
}
static struct kernel_param_ops param_ops_trace_state = {
.set = param_set_trace_state,
.get = param_get_trace_state,
};
module_param_cb(trace_state, &param_ops_trace_state, NULL, 0644);
/* --------------------------------------------------------------------------
DebugFS Interface
-------------------------------------------------------------------------- */
static ssize_t cm_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
static char *buf;
static int uncopied_bytes;
struct acpi_table_header table;
acpi_status status;
if (!(*ppos)) {
/* parse the table header to get the table length */
if (count <= sizeof(struct acpi_table_header))
return -EINVAL;
if (copy_from_user(&table, user_buf,
sizeof(struct acpi_table_header)))
return -EFAULT;
uncopied_bytes = table.length;
buf = kzalloc(uncopied_bytes, GFP_KERNEL);
if (!buf)
return -ENOMEM;
}
if (uncopied_bytes < count) {
kfree(buf);
return -EINVAL;
}
if (copy_from_user(buf + (*ppos), user_buf, count)) {
kfree(buf);
return -EFAULT;
}
uncopied_bytes -= count;
*ppos += count;
if (!uncopied_bytes) {
status = acpi_install_method(buf);
kfree(buf);
if (ACPI_FAILURE(status))
return -EINVAL;
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
}
return count;
}
static const struct file_operations cm_fops = {
.write = cm_write,
};
static int acpi_debugfs_init(void)
{
struct dentry *acpi_dir, *cm_dentry;
acpi_dir = debugfs_create_dir("acpi", NULL);
if (!acpi_dir)
goto err;
cm_dentry = debugfs_create_file("custom_method", S_IWUGO,
acpi_dir, NULL, &cm_fops);
if (!cm_dentry)
goto err;
return 0;
err:
if (acpi_dir)
debugfs_remove(acpi_dir);
return -EINVAL;
}
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
#ifdef CONFIG_ACPI_PROCFS
#define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer"
#define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level"
static int acpi_system_debug_proc_show(struct seq_file *m, void *v)
{
unsigned int i;
seq_printf(m, "%-25s\tHex SET\n", "Description");
switch ((unsigned long)m->private) {
case 0:
for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) {
seq_printf(m, "%-25s\t0x%08lX [%c]\n",
acpi_debug_layers[i].name,
acpi_debug_layers[i].value,
(acpi_dbg_layer & acpi_debug_layers[i].
value) ? '*' : ' ');
}
seq_printf(m, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS",
ACPI_ALL_DRIVERS,
(acpi_dbg_layer & ACPI_ALL_DRIVERS) ==
ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer &
ACPI_ALL_DRIVERS) ==
0 ? ' ' : '-');
seq_printf(m,
"--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n",
acpi_dbg_layer);
break;
case 1:
for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) {
seq_printf(m, "%-25s\t0x%08lX [%c]\n",
acpi_debug_levels[i].name,
acpi_debug_levels[i].value,
(acpi_dbg_level & acpi_debug_levels[i].
value) ? '*' : ' ');
}
seq_printf(m, "--\ndebug_level = 0x%08X (* = enabled)\n",
acpi_dbg_level);
break;
}
return 0;
}
static int acpi_system_debug_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, acpi_system_debug_proc_show, PDE(inode)->data);
}
static ssize_t acpi_system_debug_proc_write(struct file *file,
const char __user * buffer,
size_t count, loff_t *pos)
{
char debug_string[12] = { '\0' };
if (count > sizeof(debug_string) - 1)
return -EINVAL;
if (copy_from_user(debug_string, buffer, count))
return -EFAULT;
debug_string[count] = '\0';
switch ((unsigned long)PDE(file->f_path.dentry->d_inode)->data) {
case 0:
acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0);
break;
case 1:
acpi_dbg_level = simple_strtoul(debug_string, NULL, 0);
break;
default:
return -EINVAL;
}
return count;
}
static const struct file_operations acpi_system_debug_proc_fops = {
.owner = THIS_MODULE,
.open = acpi_system_debug_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.write = acpi_system_debug_proc_write,
};
#endif
int __init acpi_procfs_init(void)
{
#ifdef CONFIG_ACPI_PROCFS
struct proc_dir_entry *entry;
int error = 0;
char *name;
/* 'debug_layer' [R/W] */
name = ACPI_SYSTEM_FILE_DEBUG_LAYER;
entry = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR,
acpi_root_dir, &acpi_system_debug_proc_fops,
(void *)0);
if (!entry)
goto Error;
/* 'debug_level' [R/W] */
name = ACPI_SYSTEM_FILE_DEBUG_LEVEL;
entry = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR,
acpi_root_dir, &acpi_system_debug_proc_fops,
(void *)1);
if (!entry)
goto Error;
Done:
return error;
Error:
remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, acpi_root_dir);
remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir);
error = -ENODEV;
goto Done;
#else
return 0;
#endif
}
int __init acpi_debug_init(void)
{
acpi_debugfs_init();
acpi_procfs_init();
return 0;
}

View File

@ -0,0 +1,93 @@
/*
* debugfs.c - ACPI debugfs interface to userspace.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/debugfs.h>
#include <acpi/acpi_drivers.h>
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("debugfs");
/* /sys/modules/acpi/parameters/aml_debug_output */
module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object,
bool, 0644);
MODULE_PARM_DESC(aml_debug_output,
"To enable/disable the ACPI Debug Object output.");
/* /sys/kernel/debug/acpi/custom_method */
static ssize_t cm_write(struct file *file, const char __user * user_buf,
size_t count, loff_t *ppos)
{
static char *buf;
static int uncopied_bytes;
struct acpi_table_header table;
acpi_status status;
if (!(*ppos)) {
/* parse the table header to get the table length */
if (count <= sizeof(struct acpi_table_header))
return -EINVAL;
if (copy_from_user(&table, user_buf,
sizeof(struct acpi_table_header)))
return -EFAULT;
uncopied_bytes = table.length;
buf = kzalloc(uncopied_bytes, GFP_KERNEL);
if (!buf)
return -ENOMEM;
}
if (uncopied_bytes < count) {
kfree(buf);
return -EINVAL;
}
if (copy_from_user(buf + (*ppos), user_buf, count)) {
kfree(buf);
return -EFAULT;
}
uncopied_bytes -= count;
*ppos += count;
if (!uncopied_bytes) {
status = acpi_install_method(buf);
kfree(buf);
if (ACPI_FAILURE(status))
return -EINVAL;
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
}
return count;
}
static const struct file_operations cm_fops = {
.write = cm_write,
};
int __init acpi_debugfs_init(void)
{
struct dentry *acpi_dir, *cm_dentry;
acpi_dir = debugfs_create_dir("acpi", NULL);
if (!acpi_dir)
goto err;
cm_dentry = debugfs_create_file("custom_method", S_IWUGO,
acpi_dir, NULL, &cm_fops);
if (!cm_dentry)
goto err;
return 0;
err:
if (acpi_dir)
debugfs_remove(acpi_dir);
return -EINVAL;
}

View File

@ -100,7 +100,8 @@ do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv)
status = acpi_get_object_info(handle, &info); status = acpi_get_object_info(handle, &info);
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
if (info->address == find->address) if ((info->address == find->address)
&& (info->valid & ACPI_VALID_ADR))
find->handle = handle; find->handle = handle;
kfree(info); kfree(info);
} }

View File

@ -27,12 +27,12 @@
int init_acpi_device_notify(void); int init_acpi_device_notify(void);
int acpi_scan_init(void); int acpi_scan_init(void);
int acpi_system_init(void); int acpi_sysfs_init(void);
#ifdef CONFIG_ACPI_DEBUG #ifdef CONFIG_DEBUG_FS
int acpi_debug_init(void); int acpi_debugfs_init(void);
#else #else
static inline int acpi_debug_init(void) { return 0; } static inline int acpi_debugfs_init(void) { return 0; }
#endif #endif
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------

View File

@ -255,12 +255,10 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header,
static int __init acpi_parse_srat(struct acpi_table_header *table) static int __init acpi_parse_srat(struct acpi_table_header *table)
{ {
struct acpi_table_srat *srat;
if (!table) if (!table)
return -EINVAL; return -EINVAL;
srat = (struct acpi_table_srat *)table; /* Real work done in acpi_table_parse_srat below. */
return 0; return 0;
} }

View File

@ -141,15 +141,14 @@ static struct osi_linux {
static void __init acpi_request_region (struct acpi_generic_address *addr, static void __init acpi_request_region (struct acpi_generic_address *addr,
unsigned int length, char *desc) unsigned int length, char *desc)
{ {
struct resource *res;
if (!addr->address || !length) if (!addr->address || !length)
return; return;
/* Resources are never freed */
if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO) if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
res = request_region(addr->address, length, desc); request_region(addr->address, length, desc);
else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
res = request_mem_region(addr->address, length, desc); request_mem_region(addr->address, length, desc);
} }
static int __init acpi_reserve_resources(void) static int __init acpi_reserve_resources(void)

View File

@ -40,8 +40,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h> #include <acpi/acpi_drivers.h>
#include "sleep.h" #include "sleep.h"
@ -64,7 +62,6 @@ module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);
static int acpi_power_add(struct acpi_device *device); static int acpi_power_add(struct acpi_device *device);
static int acpi_power_remove(struct acpi_device *device, int type); static int acpi_power_remove(struct acpi_device *device, int type);
static int acpi_power_resume(struct acpi_device *device); static int acpi_power_resume(struct acpi_device *device);
static int acpi_power_open_fs(struct inode *inode, struct file *file);
static const struct acpi_device_id power_device_ids[] = { static const struct acpi_device_id power_device_ids[] = {
{ACPI_POWER_HID, 0}, {ACPI_POWER_HID, 0},
@ -99,14 +96,6 @@ struct acpi_power_resource {
static struct list_head acpi_power_resource_list; static struct list_head acpi_power_resource_list;
static const struct file_operations acpi_power_fops = {
.owner = THIS_MODULE,
.open = acpi_power_open_fs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Power Resource Management Power Resource Management
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
@ -255,7 +244,6 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
struct list_head *node, *next; struct list_head *node, *next;
struct acpi_power_reference *ref; struct acpi_power_reference *ref;
result = acpi_power_get_context(handle, &resource); result = acpi_power_get_context(handle, &resource);
if (result) if (result)
return result; return result;
@ -541,102 +529,6 @@ int acpi_power_transition(struct acpi_device *device, int state)
return result; return result;
} }
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
static struct proc_dir_entry *acpi_power_dir;
static int acpi_power_seq_show(struct seq_file *seq, void *offset)
{
int count = 0;
int result = 0, state;
struct acpi_power_resource *resource = NULL;
struct list_head *node, *next;
struct acpi_power_reference *ref;
resource = seq->private;
if (!resource)
goto end;
result = acpi_power_get_state(resource->device->handle, &state);
if (result)
goto end;
seq_puts(seq, "state: ");
switch (state) {
case ACPI_POWER_RESOURCE_STATE_ON:
seq_puts(seq, "on\n");
break;
case ACPI_POWER_RESOURCE_STATE_OFF:
seq_puts(seq, "off\n");
break;
default:
seq_puts(seq, "unknown\n");
break;
}
mutex_lock(&resource->resource_lock);
list_for_each_safe(node, next, &resource->reference) {
ref = container_of(node, struct acpi_power_reference, node);
count++;
}
mutex_unlock(&resource->resource_lock);
seq_printf(seq, "system level: S%d\n"
"order: %d\n"
"reference count: %d\n",
resource->system_level,
resource->order, count);
end:
return 0;
}
static int acpi_power_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_power_seq_show, PDE(inode)->data);
}
static int acpi_power_add_fs(struct acpi_device *device)
{
struct proc_dir_entry *entry = NULL;
if (!device)
return -EINVAL;
if (!acpi_device_dir(device)) {
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
acpi_power_dir);
if (!acpi_device_dir(device))
return -ENODEV;
}
/* 'status' [R] */
entry = proc_create_data(ACPI_POWER_FILE_STATUS,
S_IRUGO, acpi_device_dir(device),
&acpi_power_fops, acpi_driver_data(device));
if (!entry)
return -EIO;
return 0;
}
static int acpi_power_remove_fs(struct acpi_device *device)
{
if (acpi_device_dir(device)) {
remove_proc_entry(ACPI_POWER_FILE_STATUS,
acpi_device_dir(device));
remove_proc_entry(acpi_device_bid(device), acpi_power_dir);
acpi_device_dir(device) = NULL;
}
return 0;
}
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Driver Interface Driver Interface
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
@ -690,10 +582,6 @@ static int acpi_power_add(struct acpi_device *device)
break; break;
} }
result = acpi_power_add_fs(device);
if (result)
goto end;
printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device),
acpi_device_bid(device), state ? "on" : "off"); acpi_device_bid(device), state ? "on" : "off");
@ -715,8 +603,6 @@ static int acpi_power_remove(struct acpi_device *device, int type)
resource = acpi_driver_data(device); resource = acpi_driver_data(device);
acpi_power_remove_fs(device);
mutex_lock(&resource->resource_lock); mutex_lock(&resource->resource_lock);
list_for_each_safe(node, next, &resource->reference) { list_for_each_safe(node, next, &resource->reference) {
struct acpi_power_reference *ref = container_of(node, struct acpi_power_reference, node); struct acpi_power_reference *ref = container_of(node, struct acpi_power_reference, node);
@ -760,19 +646,6 @@ static int acpi_power_resume(struct acpi_device *device)
int __init acpi_power_init(void) int __init acpi_power_init(void)
{ {
int result = 0;
INIT_LIST_HEAD(&acpi_power_resource_list); INIT_LIST_HEAD(&acpi_power_resource_list);
return acpi_bus_register_driver(&acpi_power_driver);
acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir);
if (!acpi_power_dir)
return -ENODEV;
result = acpi_bus_register_driver(&acpi_power_driver);
if (result < 0) {
remove_proc_entry(ACPI_POWER_CLASS, acpi_root_dir);
return -ENODEV;
}
return 0;
} }

View File

@ -17,64 +17,11 @@
/* /*
* this file provides support for: * this file provides support for:
* /proc/acpi/sleep
* /proc/acpi/alarm * /proc/acpi/alarm
* /proc/acpi/wakeup * /proc/acpi/wakeup
*/ */
ACPI_MODULE_NAME("sleep") ACPI_MODULE_NAME("sleep")
#ifdef CONFIG_ACPI_PROCFS
static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
{
int i;
for (i = 0; i <= ACPI_STATE_S5; i++) {
if (sleep_states[i]) {
seq_printf(seq, "S%d ", i);
}
}
seq_puts(seq, "\n");
return 0;
}
static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_system_sleep_seq_show, PDE(inode)->data);
}
static ssize_t
acpi_system_write_sleep(struct file *file,
const char __user * buffer, size_t count, loff_t * ppos)
{
char str[12];
u32 state = 0;
int error = 0;
if (count > sizeof(str) - 1)
goto Done;
memset(str, 0, sizeof(str));
if (copy_from_user(str, buffer, count))
return -EFAULT;
/* Check for S4 bios request */
if (!strcmp(str, "4b")) {
error = acpi_suspend(4);
goto Done;
}
state = simple_strtoul(str, NULL, 0);
#ifdef CONFIG_HIBERNATION
if (state == 4) {
error = hibernate();
goto Done;
}
#endif
error = acpi_suspend(state);
Done:
return error ? error : count;
}
#endif /* CONFIG_ACPI_PROCFS */
#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86) #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86)
/* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */
@ -463,17 +410,6 @@ static const struct file_operations acpi_system_wakeup_device_fops = {
.release = single_release, .release = single_release,
}; };
#ifdef CONFIG_ACPI_PROCFS
static const struct file_operations acpi_system_sleep_fops = {
.owner = THIS_MODULE,
.open = acpi_system_sleep_open_fs,
.read = seq_read,
.write = acpi_system_write_sleep,
.llseek = seq_lseek,
.release = single_release,
};
#endif /* CONFIG_ACPI_PROCFS */
#ifdef HAVE_ACPI_LEGACY_ALARM #ifdef HAVE_ACPI_LEGACY_ALARM
static const struct file_operations acpi_system_alarm_fops = { static const struct file_operations acpi_system_alarm_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
@ -495,12 +431,6 @@ static u32 rtc_handler(void *context)
int __init acpi_sleep_proc_init(void) int __init acpi_sleep_proc_init(void)
{ {
#ifdef CONFIG_ACPI_PROCFS
/* 'sleep' [R/W] */
proc_create("sleep", S_IFREG | S_IRUGO | S_IWUSR,
acpi_root_dir, &acpi_system_sleep_fops);
#endif /* CONFIG_ACPI_PROCFS */
#ifdef HAVE_ACPI_LEGACY_ALARM #ifdef HAVE_ACPI_LEGACY_ALARM
/* 'alarm' [R/W] */ /* 'alarm' [R/W] */
proc_create("alarm", S_IFREG | S_IRUGO | S_IWUSR, proc_create("alarm", S_IFREG | S_IRUGO | S_IWUSR,

View File

@ -83,9 +83,6 @@ MODULE_LICENSE("GPL");
static int acpi_processor_add(struct acpi_device *device); static int acpi_processor_add(struct acpi_device *device);
static int acpi_processor_remove(struct acpi_device *device, int type); static int acpi_processor_remove(struct acpi_device *device, int type);
#ifdef CONFIG_ACPI_PROCFS
static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
#endif
static void acpi_processor_notify(struct acpi_device *device, u32 event); static void acpi_processor_notify(struct acpi_device *device, u32 event);
static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
static int acpi_processor_handle_eject(struct acpi_processor *pr); static int acpi_processor_handle_eject(struct acpi_processor *pr);
@ -113,15 +110,6 @@ static struct acpi_driver acpi_processor_driver = {
#define INSTALL_NOTIFY_HANDLER 1 #define INSTALL_NOTIFY_HANDLER 1
#define UNINSTALL_NOTIFY_HANDLER 2 #define UNINSTALL_NOTIFY_HANDLER 2
#ifdef CONFIG_ACPI_PROCFS
static const struct file_operations acpi_processor_info_fops = {
.owner = THIS_MODULE,
.open = acpi_processor_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
#endif
DEFINE_PER_CPU(struct acpi_processor *, processors); DEFINE_PER_CPU(struct acpi_processor *, processors);
EXPORT_PER_CPU_SYMBOL(processors); EXPORT_PER_CPU_SYMBOL(processors);
@ -256,44 +244,8 @@ static int acpi_processor_errata(struct acpi_processor *pr)
return result; return result;
} }
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
#ifdef CONFIG_ACPI_PROCFS
static struct proc_dir_entry *acpi_processor_dir = NULL; static struct proc_dir_entry *acpi_processor_dir = NULL;
static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
{
struct acpi_processor *pr = seq->private;
if (!pr)
goto end;
seq_printf(seq, "processor id: %d\n"
"acpi id: %d\n"
"bus mastering control: %s\n"
"power management: %s\n"
"throttling control: %s\n"
"limit interface: %s\n",
pr->id,
pr->acpi_id,
pr->flags.bm_control ? "yes" : "no",
pr->flags.power ? "yes" : "no",
pr->flags.throttling ? "yes" : "no",
pr->flags.limit ? "yes" : "no");
end:
return 0;
}
static int acpi_processor_info_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_processor_info_seq_show,
PDE(inode)->data);
}
static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) static int __cpuinit acpi_processor_add_fs(struct acpi_device *device)
{ {
struct proc_dir_entry *entry = NULL; struct proc_dir_entry *entry = NULL;
@ -306,14 +258,6 @@ static int __cpuinit acpi_processor_add_fs(struct acpi_device *device)
return -ENODEV; return -ENODEV;
} }
/* 'info' [R] */
entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO,
S_IRUGO, acpi_device_dir(device),
&acpi_processor_info_fops,
acpi_driver_data(device));
if (!entry)
return -EIO;
/* 'throttling' [R/W] */ /* 'throttling' [R/W] */
entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING, entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING,
S_IFREG | S_IRUGO | S_IWUSR, S_IFREG | S_IRUGO | S_IWUSR,
@ -322,43 +266,20 @@ static int __cpuinit acpi_processor_add_fs(struct acpi_device *device)
acpi_driver_data(device)); acpi_driver_data(device));
if (!entry) if (!entry)
return -EIO; return -EIO;
/* 'limit' [R/W] */
entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT,
S_IFREG | S_IRUGO | S_IWUSR,
acpi_device_dir(device),
&acpi_processor_limit_fops,
acpi_driver_data(device));
if (!entry)
return -EIO;
return 0; return 0;
} }
static int acpi_processor_remove_fs(struct acpi_device *device) static int acpi_processor_remove_fs(struct acpi_device *device)
{ {
if (acpi_device_dir(device)) { if (acpi_device_dir(device)) {
remove_proc_entry(ACPI_PROCESSOR_FILE_INFO,
acpi_device_dir(device));
remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
acpi_device_dir(device)); acpi_device_dir(device));
remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT,
acpi_device_dir(device));
remove_proc_entry(acpi_device_bid(device), acpi_processor_dir); remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
acpi_device_dir(device) = NULL; acpi_device_dir(device) = NULL;
} }
return 0; return 0;
} }
#else
static inline int acpi_processor_add_fs(struct acpi_device *device)
{
return 0;
}
static inline int acpi_processor_remove_fs(struct acpi_device *device)
{
return 0;
}
#endif
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Driver Interface Driver Interface
@ -921,11 +842,9 @@ static int __init acpi_processor_init(void)
memset(&errata, 0, sizeof(errata)); memset(&errata, 0, sizeof(errata));
#ifdef CONFIG_ACPI_PROCFS
acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
if (!acpi_processor_dir) if (!acpi_processor_dir)
return -ENOMEM; return -ENOMEM;
#endif
if (!cpuidle_register_driver(&acpi_idle_driver)) { if (!cpuidle_register_driver(&acpi_idle_driver)) {
printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n",
@ -952,9 +871,7 @@ static int __init acpi_processor_init(void)
out_cpuidle: out_cpuidle:
cpuidle_unregister_driver(&acpi_idle_driver); cpuidle_unregister_driver(&acpi_idle_driver);
#ifdef CONFIG_ACPI_PROCFS
remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
#endif
return result; return result;
} }
@ -974,9 +891,7 @@ static void __exit acpi_processor_exit(void)
cpuidle_unregister_driver(&acpi_idle_driver); cpuidle_unregister_driver(&acpi_idle_driver);
#ifdef CONFIG_ACPI_PROCFS
remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
#endif
return; return;
} }

View File

@ -33,8 +33,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
@ -82,13 +80,6 @@ module_param(bm_check_disable, uint, 0000);
static unsigned int latency_factor __read_mostly = 2; static unsigned int latency_factor __read_mostly = 2;
module_param(latency_factor, uint, 0644); module_param(latency_factor, uint, 0644);
#ifdef CONFIG_ACPI_PROCFS
static u64 us_to_pm_timer_ticks(s64 t)
{
return div64_u64(t * PM_TIMER_FREQUENCY, 1000000);
}
#endif
/* /*
* IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
* For now disable this. Probably a bug somewhere else. * For now disable this. Probably a bug somewhere else.
@ -689,78 +680,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
return 0; return 0;
} }
#ifdef CONFIG_ACPI_PROCFS
static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
{
struct acpi_processor *pr = seq->private;
unsigned int i;
if (!pr)
goto end;
seq_printf(seq, "active state: C%zd\n"
"max_cstate: C%d\n"
"maximum allowed latency: %d usec\n",
pr->power.state ? pr->power.state - pr->power.states : 0,
max_cstate, pm_qos_request(PM_QOS_CPU_DMA_LATENCY));
seq_puts(seq, "states:\n");
for (i = 1; i <= pr->power.count; i++) {
seq_printf(seq, " %cC%d: ",
(&pr->power.states[i] ==
pr->power.state ? '*' : ' '), i);
if (!pr->power.states[i].valid) {
seq_puts(seq, "<not supported>\n");
continue;
}
switch (pr->power.states[i].type) {
case ACPI_STATE_C1:
seq_printf(seq, "type[C1] ");
break;
case ACPI_STATE_C2:
seq_printf(seq, "type[C2] ");
break;
case ACPI_STATE_C3:
seq_printf(seq, "type[C3] ");
break;
default:
seq_printf(seq, "type[--] ");
break;
}
seq_puts(seq, "promotion[--] ");
seq_puts(seq, "demotion[--] ");
seq_printf(seq, "latency[%03d] usage[%08d] duration[%020Lu]\n",
pr->power.states[i].latency,
pr->power.states[i].usage,
us_to_pm_timer_ticks(pr->power.states[i].time));
}
end:
return 0;
}
static int acpi_processor_power_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_processor_power_seq_show,
PDE(inode)->data);
}
static const struct file_operations acpi_processor_power_fops = {
.owner = THIS_MODULE,
.open = acpi_processor_power_open_fs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
#endif
/** /**
* acpi_idle_bm_check - checks if bus master activity was detected * acpi_idle_bm_check - checks if bus master activity was detected
*/ */
@ -803,13 +722,12 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
} else if (cx->entry_method == ACPI_CSTATE_HALT) { } else if (cx->entry_method == ACPI_CSTATE_HALT) {
acpi_safe_halt(); acpi_safe_halt();
} else { } else {
int unused;
/* IO port based C-state */ /* IO port based C-state */
inb(cx->address); inb(cx->address);
/* Dummy wait op - must do something useless after P_LVL2 read /* Dummy wait op - must do something useless after P_LVL2 read
because chipsets cannot guarantee that STPCLK# signal because chipsets cannot guarantee that STPCLK# signal
gets asserted in time to freeze execution properly. */ gets asserted in time to freeze execution properly. */
unused = inl(acpi_gbl_FADT.xpm_timer_block.address); inl(acpi_gbl_FADT.xpm_timer_block.address);
} }
start_critical_timings(); start_critical_timings();
} }
@ -1172,9 +1090,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
{ {
acpi_status status = 0; acpi_status status = 0;
static int first_run; static int first_run;
#ifdef CONFIG_ACPI_PROCFS
struct proc_dir_entry *entry = NULL;
#endif
if (boot_option_idle_override) if (boot_option_idle_override)
return 0; return 0;
@ -1223,15 +1138,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
if (cpuidle_register_device(&pr->power.dev)) if (cpuidle_register_device(&pr->power.dev))
return -EIO; return -EIO;
} }
#ifdef CONFIG_ACPI_PROCFS
/* 'power' [R] */
entry = proc_create_data(ACPI_PROCESSOR_FILE_POWER,
S_IRUGO, acpi_device_dir(device),
&acpi_processor_power_fops,
acpi_driver_data(device));
if (!entry)
return -EIO;
#endif
return 0; return 0;
} }
@ -1244,11 +1150,5 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
cpuidle_unregister_device(&pr->power.dev); cpuidle_unregister_device(&pr->power.dev);
pr->flags.power_setup_done = 0; pr->flags.power_setup_done = 0;
#ifdef CONFIG_ACPI_PROCFS
if (acpi_device_dir(device))
remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,
acpi_device_dir(device));
#endif
return 0; return 0;
} }

View File

@ -30,8 +30,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/sysdev.h> #include <linux/sysdev.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
@ -438,84 +436,3 @@ struct thermal_cooling_device_ops processor_cooling_ops = {
.get_cur_state = processor_get_cur_state, .get_cur_state = processor_get_cur_state,
.set_cur_state = processor_set_cur_state, .set_cur_state = processor_set_cur_state,
}; };
/* /proc interface */
#ifdef CONFIG_ACPI_PROCFS
static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset)
{
struct acpi_processor *pr = seq->private;
if (!pr)
goto end;
if (!pr->flags.limit) {
seq_puts(seq, "<not supported>\n");
goto end;
}
seq_printf(seq, "active limit: P%d:T%d\n"
"user limit: P%d:T%d\n"
"thermal limit: P%d:T%d\n",
pr->limit.state.px, pr->limit.state.tx,
pr->limit.user.px, pr->limit.user.tx,
pr->limit.thermal.px, pr->limit.thermal.tx);
end:
return 0;
}
static int acpi_processor_limit_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_processor_limit_seq_show,
PDE(inode)->data);
}
static ssize_t acpi_processor_write_limit(struct file * file,
const char __user * buffer,
size_t count, loff_t * data)
{
int result = 0;
struct seq_file *m = file->private_data;
struct acpi_processor *pr = m->private;
char limit_string[25] = { '\0' };
int px = 0;
int tx = 0;
if (!pr || (count > sizeof(limit_string) - 1)) {
return -EINVAL;
}
if (copy_from_user(limit_string, buffer, count)) {
return -EFAULT;
}
limit_string[count] = '\0';
if (sscanf(limit_string, "%d:%d", &px, &tx) != 2) {
printk(KERN_ERR PREFIX "Invalid data format\n");
return -EINVAL;
}
if (pr->flags.throttling) {
if ((tx < 0) || (tx > (pr->throttling.state_count - 1))) {
printk(KERN_ERR PREFIX "Invalid tx\n");
return -EINVAL;
}
pr->limit.user.tx = tx;
}
result = acpi_processor_apply_limit(pr);
return count;
}
const struct file_operations acpi_processor_limit_fops = {
.owner = THIS_MODULE,
.open = acpi_processor_limit_open_fs,
.read = seq_read,
.write = acpi_processor_write_limit,
.llseek = seq_lseek,
.release = single_release,
};
#endif

View File

@ -1215,7 +1215,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
} }
/* proc interface */ /* proc interface */
#ifdef CONFIG_ACPI_PROCFS
static int acpi_processor_throttling_seq_show(struct seq_file *seq, static int acpi_processor_throttling_seq_show(struct seq_file *seq,
void *offset) void *offset)
{ {
@ -1323,4 +1322,3 @@ const struct file_operations acpi_processor_throttling_fops = {
.llseek = seq_lseek, .llseek = seq_lseek,
.release = single_release, .release = single_release,
}; };
#endif

View File

@ -70,10 +70,10 @@ static int acpi_sleep_prepare(u32 acpi_state)
} }
ACPI_FLUSH_CPU_CACHE(); ACPI_FLUSH_CPU_CACHE();
acpi_enable_wakeup_device_prep(acpi_state);
#endif #endif
printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n", printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n",
acpi_state); acpi_state);
acpi_enable_wakeup_devices(acpi_state);
acpi_enter_sleep_state_prep(acpi_state); acpi_enter_sleep_state_prep(acpi_state);
return 0; return 0;
} }
@ -118,6 +118,16 @@ static int acpi_pm_freeze(void)
return 0; return 0;
} }
/**
* acpi_pre_suspend - Enable wakeup devices, "freeze" EC and save NVS.
*/
static int acpi_pm_pre_suspend(void)
{
acpi_pm_freeze();
suspend_nvs_save();
return 0;
}
/** /**
* __acpi_pm_prepare - Prepare the platform to enter the target state. * __acpi_pm_prepare - Prepare the platform to enter the target state.
* *
@ -127,11 +137,9 @@ static int acpi_pm_freeze(void)
static int __acpi_pm_prepare(void) static int __acpi_pm_prepare(void)
{ {
int error = acpi_sleep_prepare(acpi_target_sleep_state); int error = acpi_sleep_prepare(acpi_target_sleep_state);
suspend_nvs_save();
if (error) if (error)
acpi_target_sleep_state = ACPI_STATE_S0; acpi_target_sleep_state = ACPI_STATE_S0;
return error; return error;
} }
@ -142,9 +150,8 @@ static int __acpi_pm_prepare(void)
static int acpi_pm_prepare(void) static int acpi_pm_prepare(void)
{ {
int error = __acpi_pm_prepare(); int error = __acpi_pm_prepare();
if (!error) if (!error)
acpi_pm_freeze(); acpi_pm_pre_suspend();
return error; return error;
} }
@ -159,7 +166,6 @@ static void acpi_pm_finish(void)
{ {
u32 acpi_state = acpi_target_sleep_state; u32 acpi_state = acpi_target_sleep_state;
suspend_nvs_free();
acpi_ec_unblock_transactions(); acpi_ec_unblock_transactions();
if (acpi_state == ACPI_STATE_S0) if (acpi_state == ACPI_STATE_S0)
@ -167,7 +173,7 @@ static void acpi_pm_finish(void)
printk(KERN_INFO PREFIX "Waking up from system sleep state S%d\n", printk(KERN_INFO PREFIX "Waking up from system sleep state S%d\n",
acpi_state); acpi_state);
acpi_disable_wakeup_device(acpi_state); acpi_disable_wakeup_devices(acpi_state);
acpi_leave_sleep_state(acpi_state); acpi_leave_sleep_state(acpi_state);
/* reset firmware waking vector */ /* reset firmware waking vector */
@ -181,6 +187,7 @@ static void acpi_pm_finish(void)
*/ */
static void acpi_pm_end(void) static void acpi_pm_end(void)
{ {
suspend_nvs_free();
/* /*
* This is necessary in case acpi_pm_finish() is not called during a * This is necessary in case acpi_pm_finish() is not called during a
* failing transition to a sleep state. * failing transition to a sleep state.
@ -251,7 +258,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
} }
local_irq_save(flags); local_irq_save(flags);
acpi_enable_wakeup_device(acpi_state);
switch (acpi_state) { switch (acpi_state) {
case ACPI_STATE_S1: case ACPI_STATE_S1:
barrier(); barrier();
@ -297,11 +303,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
return ACPI_SUCCESS(status) ? 0 : -EFAULT; return ACPI_SUCCESS(status) ? 0 : -EFAULT;
} }
static void acpi_suspend_finish(void)
{
acpi_pm_finish();
}
static int acpi_suspend_state_valid(suspend_state_t pm_state) static int acpi_suspend_state_valid(suspend_state_t pm_state)
{ {
u32 acpi_state; u32 acpi_state;
@ -323,7 +324,7 @@ static struct platform_suspend_ops acpi_suspend_ops = {
.begin = acpi_suspend_begin, .begin = acpi_suspend_begin,
.prepare_late = acpi_pm_prepare, .prepare_late = acpi_pm_prepare,
.enter = acpi_suspend_enter, .enter = acpi_suspend_enter,
.wake = acpi_suspend_finish, .wake = acpi_pm_finish,
.end = acpi_pm_end, .end = acpi_pm_end,
}; };
@ -336,9 +337,9 @@ static struct platform_suspend_ops acpi_suspend_ops = {
static int acpi_suspend_begin_old(suspend_state_t pm_state) static int acpi_suspend_begin_old(suspend_state_t pm_state)
{ {
int error = acpi_suspend_begin(pm_state); int error = acpi_suspend_begin(pm_state);
if (!error) if (!error)
error = __acpi_pm_prepare(); error = __acpi_pm_prepare();
return error; return error;
} }
@ -349,9 +350,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state)
static struct platform_suspend_ops acpi_suspend_ops_old = { static struct platform_suspend_ops acpi_suspend_ops_old = {
.valid = acpi_suspend_state_valid, .valid = acpi_suspend_state_valid,
.begin = acpi_suspend_begin_old, .begin = acpi_suspend_begin_old,
.prepare_late = acpi_pm_freeze, .prepare_late = acpi_pm_pre_suspend,
.enter = acpi_suspend_enter, .enter = acpi_suspend_enter,
.wake = acpi_suspend_finish, .wake = acpi_pm_finish,
.end = acpi_pm_end, .end = acpi_pm_end,
.recover = acpi_pm_finish, .recover = acpi_pm_finish,
}; };
@ -423,16 +424,6 @@ static int acpi_hibernation_begin(void)
return error; return error;
} }
static int acpi_hibernation_pre_snapshot(void)
{
int error = acpi_pm_prepare();
if (!error)
suspend_nvs_save();
return error;
}
static int acpi_hibernation_enter(void) static int acpi_hibernation_enter(void)
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
@ -441,7 +432,6 @@ static int acpi_hibernation_enter(void)
ACPI_FLUSH_CPU_CACHE(); ACPI_FLUSH_CPU_CACHE();
local_irq_save(flags); local_irq_save(flags);
acpi_enable_wakeup_device(ACPI_STATE_S4);
/* This shouldn't return. If it returns, we have a problem */ /* This shouldn't return. If it returns, we have a problem */
status = acpi_enter_sleep_state(ACPI_STATE_S4); status = acpi_enter_sleep_state(ACPI_STATE_S4);
/* Reprogram control registers and execute _BFS */ /* Reprogram control registers and execute _BFS */
@ -481,7 +471,7 @@ static void acpi_pm_thaw(void)
static struct platform_hibernation_ops acpi_hibernation_ops = { static struct platform_hibernation_ops acpi_hibernation_ops = {
.begin = acpi_hibernation_begin, .begin = acpi_hibernation_begin,
.end = acpi_pm_end, .end = acpi_pm_end,
.pre_snapshot = acpi_hibernation_pre_snapshot, .pre_snapshot = acpi_pm_prepare,
.finish = acpi_pm_finish, .finish = acpi_pm_finish,
.prepare = acpi_pm_prepare, .prepare = acpi_pm_prepare,
.enter = acpi_hibernation_enter, .enter = acpi_hibernation_enter,
@ -517,13 +507,6 @@ static int acpi_hibernation_begin_old(void)
return error; return error;
} }
static int acpi_hibernation_pre_snapshot_old(void)
{
acpi_pm_freeze();
suspend_nvs_save();
return 0;
}
/* /*
* The following callbacks are used if the pre-ACPI 2.0 suspend ordering has * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has
* been requested. * been requested.
@ -531,7 +514,7 @@ static int acpi_hibernation_pre_snapshot_old(void)
static struct platform_hibernation_ops acpi_hibernation_ops_old = { static struct platform_hibernation_ops acpi_hibernation_ops_old = {
.begin = acpi_hibernation_begin_old, .begin = acpi_hibernation_begin_old,
.end = acpi_pm_end, .end = acpi_pm_end,
.pre_snapshot = acpi_hibernation_pre_snapshot_old, .pre_snapshot = acpi_pm_pre_suspend,
.prepare = acpi_pm_freeze, .prepare = acpi_pm_freeze,
.finish = acpi_pm_finish, .finish = acpi_pm_finish,
.enter = acpi_hibernation_enter, .enter = acpi_hibernation_enter,
@ -686,7 +669,6 @@ static void acpi_power_off(void)
/* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
printk(KERN_DEBUG "%s called\n", __func__); printk(KERN_DEBUG "%s called\n", __func__);
local_irq_disable(); local_irq_disable();
acpi_enable_wakeup_device(ACPI_STATE_S5);
acpi_enter_sleep_state(ACPI_STATE_S5); acpi_enter_sleep_state(ACPI_STATE_S5);
} }

View File

@ -2,9 +2,8 @@
extern u8 sleep_states[]; extern u8 sleep_states[];
extern int acpi_suspend(u32 state); extern int acpi_suspend(u32 state);
extern void acpi_enable_wakeup_device_prep(u8 sleep_state); extern void acpi_enable_wakeup_devices(u8 sleep_state);
extern void acpi_enable_wakeup_device(u8 sleep_state); extern void acpi_disable_wakeup_devices(u8 sleep_state);
extern void acpi_disable_wakeup_device(u8 sleep_state);
extern struct list_head acpi_wakeup_device_list; extern struct list_head acpi_wakeup_device_list;
extern struct mutex acpi_device_lock; extern struct mutex acpi_device_lock;

View File

@ -1,51 +1,218 @@
/* /*
* acpi_system.c - ACPI System Driver ($Revision: 63 $) * sysfs.c - ACPI sysfs interface to userspace.
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/ */
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/string.h> #include <linux/kernel.h>
#include <asm/uaccess.h> #include <linux/moduleparam.h>
#include <acpi/acpi_drivers.h> #include <acpi/acpi_drivers.h>
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("sysfs");
#define PREFIX "ACPI: " #define PREFIX "ACPI: "
#define _COMPONENT ACPI_SYSTEM_COMPONENT #ifdef CONFIG_ACPI_DEBUG
ACPI_MODULE_NAME("system");
#define ACPI_SYSTEM_CLASS "system"
#define ACPI_SYSTEM_DEVICE_NAME "System"
u32 acpi_irq_handled;
u32 acpi_irq_not_handled;
/* /*
* Make ACPICA version work as module param * ACPI debug sysfs I/F, including:
* /sys/modules/acpi/parameters/debug_layer
* /sys/modules/acpi/parameters/debug_level
* /sys/modules/acpi/parameters/trace_method_name
* /sys/modules/acpi/parameters/trace_state
* /sys/modules/acpi/parameters/trace_debug_layer
* /sys/modules/acpi/parameters/trace_debug_level
*/ */
struct acpi_dlayer {
const char *name;
unsigned long value;
};
struct acpi_dlevel {
const char *name;
unsigned long value;
};
#define ACPI_DEBUG_INIT(v) { .name = #v, .value = v }
static const struct acpi_dlayer acpi_debug_layers[] = {
ACPI_DEBUG_INIT(ACPI_UTILITIES),
ACPI_DEBUG_INIT(ACPI_HARDWARE),
ACPI_DEBUG_INIT(ACPI_EVENTS),
ACPI_DEBUG_INIT(ACPI_TABLES),
ACPI_DEBUG_INIT(ACPI_NAMESPACE),
ACPI_DEBUG_INIT(ACPI_PARSER),
ACPI_DEBUG_INIT(ACPI_DISPATCHER),
ACPI_DEBUG_INIT(ACPI_EXECUTER),
ACPI_DEBUG_INIT(ACPI_RESOURCES),
ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER),
ACPI_DEBUG_INIT(ACPI_OS_SERVICES),
ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER),
ACPI_DEBUG_INIT(ACPI_COMPILER),
ACPI_DEBUG_INIT(ACPI_TOOLS),
ACPI_DEBUG_INIT(ACPI_BUS_COMPONENT),
ACPI_DEBUG_INIT(ACPI_AC_COMPONENT),
ACPI_DEBUG_INIT(ACPI_BATTERY_COMPONENT),
ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT),
ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT),
ACPI_DEBUG_INIT(ACPI_FAN_COMPONENT),
ACPI_DEBUG_INIT(ACPI_PCI_COMPONENT),
ACPI_DEBUG_INIT(ACPI_POWER_COMPONENT),
ACPI_DEBUG_INIT(ACPI_CONTAINER_COMPONENT),
ACPI_DEBUG_INIT(ACPI_SYSTEM_COMPONENT),
ACPI_DEBUG_INIT(ACPI_THERMAL_COMPONENT),
ACPI_DEBUG_INIT(ACPI_MEMORY_DEVICE_COMPONENT),
ACPI_DEBUG_INIT(ACPI_VIDEO_COMPONENT),
ACPI_DEBUG_INIT(ACPI_PROCESSOR_COMPONENT),
};
static const struct acpi_dlevel acpi_debug_levels[] = {
ACPI_DEBUG_INIT(ACPI_LV_INIT),
ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT),
ACPI_DEBUG_INIT(ACPI_LV_INFO),
ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES),
ACPI_DEBUG_INIT(ACPI_LV_PARSE),
ACPI_DEBUG_INIT(ACPI_LV_LOAD),
ACPI_DEBUG_INIT(ACPI_LV_DISPATCH),
ACPI_DEBUG_INIT(ACPI_LV_EXEC),
ACPI_DEBUG_INIT(ACPI_LV_NAMES),
ACPI_DEBUG_INIT(ACPI_LV_OPREGION),
ACPI_DEBUG_INIT(ACPI_LV_BFIELD),
ACPI_DEBUG_INIT(ACPI_LV_TABLES),
ACPI_DEBUG_INIT(ACPI_LV_VALUES),
ACPI_DEBUG_INIT(ACPI_LV_OBJECTS),
ACPI_DEBUG_INIT(ACPI_LV_RESOURCES),
ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS),
ACPI_DEBUG_INIT(ACPI_LV_PACKAGE),
ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS),
ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS),
ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS),
ACPI_DEBUG_INIT(ACPI_LV_MUTEX),
ACPI_DEBUG_INIT(ACPI_LV_THREADS),
ACPI_DEBUG_INIT(ACPI_LV_IO),
ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS),
ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE),
ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO),
ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES),
ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
};
static int param_get_debug_layer(char *buffer, struct kernel_param *kp)
{
int result = 0;
int i;
result = sprintf(buffer, "%-25s\tHex SET\n", "Description");
for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) {
result += sprintf(buffer + result, "%-25s\t0x%08lX [%c]\n",
acpi_debug_layers[i].name,
acpi_debug_layers[i].value,
(acpi_dbg_layer & acpi_debug_layers[i].value)
? '*' : ' ');
}
result +=
sprintf(buffer + result, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS",
ACPI_ALL_DRIVERS,
(acpi_dbg_layer & ACPI_ALL_DRIVERS) ==
ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & ACPI_ALL_DRIVERS)
== 0 ? ' ' : '-');
result +=
sprintf(buffer + result,
"--\ndebug_layer = 0x%08X ( * = enabled)\n",
acpi_dbg_layer);
return result;
}
static int param_get_debug_level(char *buffer, struct kernel_param *kp)
{
int result = 0;
int i;
result = sprintf(buffer, "%-25s\tHex SET\n", "Description");
for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) {
result += sprintf(buffer + result, "%-25s\t0x%08lX [%c]\n",
acpi_debug_levels[i].name,
acpi_debug_levels[i].value,
(acpi_dbg_level & acpi_debug_levels[i].value)
? '*' : ' ');
}
result +=
sprintf(buffer + result, "--\ndebug_level = 0x%08X (* = enabled)\n",
acpi_dbg_level);
return result;
}
module_param_call(debug_layer, param_set_uint, param_get_debug_layer,
&acpi_dbg_layer, 0644);
module_param_call(debug_level, param_set_uint, param_get_debug_level,
&acpi_dbg_level, 0644);
static char trace_method_name[6];
module_param_string(trace_method_name, trace_method_name, 6, 0644);
static unsigned int trace_debug_layer;
module_param(trace_debug_layer, uint, 0644);
static unsigned int trace_debug_level;
module_param(trace_debug_level, uint, 0644);
static int param_set_trace_state(const char *val, struct kernel_param *kp)
{
int result = 0;
if (!strncmp(val, "enable", strlen("enable") - 1)) {
result = acpi_debug_trace(trace_method_name, trace_debug_level,
trace_debug_layer, 0);
if (result)
result = -EBUSY;
goto exit;
}
if (!strncmp(val, "disable", strlen("disable") - 1)) {
int name = 0;
result = acpi_debug_trace((char *)&name, trace_debug_level,
trace_debug_layer, 0);
if (result)
result = -EBUSY;
goto exit;
}
if (!strncmp(val, "1", 1)) {
result = acpi_debug_trace(trace_method_name, trace_debug_level,
trace_debug_layer, 1);
if (result)
result = -EBUSY;
goto exit;
}
result = -EINVAL;
exit:
return result;
}
static int param_get_trace_state(char *buffer, struct kernel_param *kp)
{
if (!acpi_gbl_trace_method_name)
return sprintf(buffer, "disable");
else {
if (acpi_gbl_trace_flags & 1)
return sprintf(buffer, "1");
else
return sprintf(buffer, "enable");
}
return 0;
}
module_param_call(trace_state, param_set_trace_state, param_get_trace_state,
NULL, 0644);
#endif /* CONFIG_ACPI_DEBUG */
/* /sys/module/acpi/parameters/acpica_version */
static int param_get_acpica_version(char *buffer, struct kernel_param *kp) static int param_get_acpica_version(char *buffer, struct kernel_param *kp)
{ {
int result; int result;
@ -57,9 +224,12 @@ static int param_get_acpica_version(char *buffer, struct kernel_param *kp)
module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
/* -------------------------------------------------------------------------- /*
FS Interface (/sys) * ACPI table sysfs I/F:
-------------------------------------------------------------------------- */ * /sys/firmware/acpi/tables/
* /sys/firmware/acpi/tables/dynamic/
*/
static LIST_HEAD(acpi_table_attr_list); static LIST_HEAD(acpi_table_attr_list);
static struct kobject *tables_kobj; static struct kobject *tables_kobj;
static struct kobject *dynamic_tables_kobj; static struct kobject *dynamic_tables_kobj;
@ -86,14 +256,12 @@ static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj,
else else
memcpy(name, "\0\0\0\0", 4); memcpy(name, "\0\0\0\0", 4);
status = status = acpi_get_table(name, table_attr->instance, &table_header);
acpi_get_table(name, table_attr->instance,
&table_header);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status))
return -ENODEV; return -ENODEV;
return memory_read_from_buffer(buf, count, &offset, return memory_read_from_buffer(buf, count, &offset,
table_header, table_header->length); table_header, table_header->length);
} }
static void acpi_table_attr_init(struct acpi_table_attr *table_attr, static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
@ -105,7 +273,7 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
sysfs_attr_init(&table_attr->attr.attr); sysfs_attr_init(&table_attr->attr.attr);
if (table_header->signature[0] != '\0') if (table_header->signature[0] != '\0')
memcpy(table_attr->name, table_header->signature, memcpy(table_attr->name, table_header->signature,
ACPI_NAME_SIZE); ACPI_NAME_SIZE);
else else
memcpy(table_attr->name, "NULL", 4); memcpy(table_attr->name, "NULL", 4);
@ -117,8 +285,8 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
table_attr->instance++; table_attr->instance++;
if (table_attr->instance > 1 || (table_attr->instance == 1 && if (table_attr->instance > 1 || (table_attr->instance == 1 &&
!acpi_get_table !acpi_get_table
(table_header->signature, 2, &header))) (table_header->signature, 2, &header)))
sprintf(table_attr->name + ACPI_NAME_SIZE, "%d", sprintf(table_attr->name + ACPI_NAME_SIZE, "%d",
table_attr->instance); table_attr->instance);
@ -138,18 +306,17 @@ acpi_sysfs_table_handler(u32 event, void *table, void *context)
switch (event) { switch (event) {
case ACPI_TABLE_EVENT_LOAD: case ACPI_TABLE_EVENT_LOAD:
table_attr = table_attr =
kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
if (!table_attr) if (!table_attr)
return AE_NO_MEMORY; return AE_NO_MEMORY;
acpi_table_attr_init(table_attr, table); acpi_table_attr_init(table_attr, table);
if (sysfs_create_bin_file(dynamic_tables_kobj, if (sysfs_create_bin_file(dynamic_tables_kobj,
&table_attr->attr)) { &table_attr->attr)) {
kfree(table_attr); kfree(table_attr);
return AE_ERROR; return AE_ERROR;
} else } else
list_add_tail(&table_attr->node, list_add_tail(&table_attr->node, &acpi_table_attr_list);
&acpi_table_attr_list);
break; break;
case ACPI_TABLE_EVENT_UNLOAD: case ACPI_TABLE_EVENT_UNLOAD:
/* /*
@ -164,7 +331,7 @@ acpi_sysfs_table_handler(u32 event, void *table, void *context)
return AE_OK; return AE_OK;
} }
static int acpi_system_sysfs_init(void) static int acpi_tables_sysfs_init(void)
{ {
struct acpi_table_attr *table_attr; struct acpi_table_attr *table_attr;
struct acpi_table_header *table_header = NULL; struct acpi_table_header *table_header = NULL;
@ -213,14 +380,17 @@ err:
} }
/* /*
* Detailed ACPI IRQ counters in /sys/firmware/acpi/interrupts/ * Detailed ACPI IRQ counters:
* See Documentation/ABI/testing/sysfs-firmware-acpi * /sys/firmware/acpi/interrupts/
*/ */
u32 acpi_irq_handled;
u32 acpi_irq_not_handled;
#define COUNT_GPE 0 #define COUNT_GPE 0
#define COUNT_SCI 1 /* acpi_irq_handled */ #define COUNT_SCI 1 /* acpi_irq_handled */
#define COUNT_SCI_NOT 2 /* acpi_irq_not_handled */ #define COUNT_SCI_NOT 2 /* acpi_irq_not_handled */
#define COUNT_ERROR 3 /* other */ #define COUNT_ERROR 3 /* other */
#define NUM_COUNTERS_EXTRA 4 #define NUM_COUNTERS_EXTRA 4
struct event_counter { struct event_counter {
@ -237,6 +407,7 @@ static u32 acpi_gpe_count;
static struct attribute_group interrupt_stats_attr_group = { static struct attribute_group interrupt_stats_attr_group = {
.name = "interrupts", .name = "interrupts",
}; };
static struct kobj_attribute *counter_attrs; static struct kobj_attribute *counter_attrs;
static void delete_gpe_attr_array(void) static void delete_gpe_attr_array(void)
@ -269,8 +440,8 @@ void acpi_os_gpe_count(u32 gpe_number)
if (gpe_number < num_gpes) if (gpe_number < num_gpes)
all_counters[gpe_number].count++; all_counters[gpe_number].count++;
else else
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]. all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS +
count++; COUNT_ERROR].count++;
return; return;
} }
@ -283,13 +454,14 @@ void acpi_os_fixed_event_count(u32 event_number)
if (event_number < ACPI_NUM_FIXED_EVENTS) if (event_number < ACPI_NUM_FIXED_EVENTS)
all_counters[num_gpes + event_number].count++; all_counters[num_gpes + event_number].count++;
else else
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]. all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS +
count++; COUNT_ERROR].count++;
return; return;
} }
static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) static int get_status(u32 index, acpi_event_status *status,
acpi_handle *handle)
{ {
int result = 0; int result = 0;
@ -300,7 +472,7 @@ static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle)
result = acpi_get_gpe_device(index, handle); result = acpi_get_gpe_device(index, handle);
if (result) { if (result) {
ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND, ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND,
"Invalid GPE 0x%x\n", index)); "Invalid GPE 0x%x\n", index));
goto end; goto end;
} }
result = acpi_get_gpe_status(*handle, index, status); result = acpi_get_gpe_status(*handle, index, status);
@ -312,7 +484,7 @@ end:
} }
static ssize_t counter_show(struct kobject *kobj, static ssize_t counter_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf) struct kobj_attribute *attr, char *buf)
{ {
int index = attr - counter_attrs; int index = attr - counter_attrs;
int size; int size;
@ -321,12 +493,11 @@ static ssize_t counter_show(struct kobject *kobj,
int result = 0; int result = 0;
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count = all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count =
acpi_irq_handled; acpi_irq_handled;
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count = all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count =
acpi_irq_not_handled; acpi_irq_not_handled;
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count = all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count =
acpi_gpe_count; acpi_gpe_count;
size = sprintf(buf, "%8d", all_counters[index].count); size = sprintf(buf, "%8d", all_counters[index].count);
/* "gpe_all" or "sci" */ /* "gpe_all" or "sci" */
@ -338,13 +509,13 @@ static ssize_t counter_show(struct kobject *kobj,
goto end; goto end;
if (!(status & ACPI_EVENT_FLAG_HANDLE)) if (!(status & ACPI_EVENT_FLAG_HANDLE))
size += sprintf(buf + size, " invalid"); size += sprintf(buf + size, " invalid");
else if (status & ACPI_EVENT_FLAG_ENABLED) else if (status & ACPI_EVENT_FLAG_ENABLED)
size += sprintf(buf + size, " enabled"); size += sprintf(buf + size, " enabled");
else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED) else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED)
size += sprintf(buf + size, " wake_enabled"); size += sprintf(buf + size, " wake_enabled");
else else
size += sprintf(buf + size, " disabled"); size += sprintf(buf + size, " disabled");
end: end:
size += sprintf(buf + size, "\n"); size += sprintf(buf + size, "\n");
@ -357,7 +528,8 @@ end:
* enable/disable/clear a gpe/fixed event in user space. * enable/disable/clear a gpe/fixed event in user space.
*/ */
static ssize_t counter_set(struct kobject *kobj, static ssize_t counter_set(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t size) struct kobj_attribute *attr, const char *buf,
size_t size)
{ {
int index = attr - counter_attrs; int index = attr - counter_attrs;
acpi_event_status status; acpi_event_status status;
@ -381,32 +553,32 @@ static ssize_t counter_set(struct kobject *kobj,
if (!(status & ACPI_EVENT_FLAG_HANDLE)) { if (!(status & ACPI_EVENT_FLAG_HANDLE)) {
printk(KERN_WARNING PREFIX printk(KERN_WARNING PREFIX
"Can not change Invalid GPE/Fixed Event status\n"); "Can not change Invalid GPE/Fixed Event status\n");
return -EINVAL; return -EINVAL;
} }
if (index < num_gpes) { if (index < num_gpes) {
if (!strcmp(buf, "disable\n") && if (!strcmp(buf, "disable\n") &&
(status & ACPI_EVENT_FLAG_ENABLED)) (status & ACPI_EVENT_FLAG_ENABLED))
result = acpi_disable_gpe(handle, index); result = acpi_disable_gpe(handle, index);
else if (!strcmp(buf, "enable\n") && else if (!strcmp(buf, "enable\n") &&
!(status & ACPI_EVENT_FLAG_ENABLED)) !(status & ACPI_EVENT_FLAG_ENABLED))
result = acpi_enable_gpe(handle, index); result = acpi_enable_gpe(handle, index);
else if (!strcmp(buf, "clear\n") && else if (!strcmp(buf, "clear\n") &&
(status & ACPI_EVENT_FLAG_SET)) (status & ACPI_EVENT_FLAG_SET))
result = acpi_clear_gpe(handle, index); result = acpi_clear_gpe(handle, index);
else else
all_counters[index].count = strtoul(buf, NULL, 0); all_counters[index].count = strtoul(buf, NULL, 0);
} else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) {
int event = index - num_gpes; int event = index - num_gpes;
if (!strcmp(buf, "disable\n") && if (!strcmp(buf, "disable\n") &&
(status & ACPI_EVENT_FLAG_ENABLED)) (status & ACPI_EVENT_FLAG_ENABLED))
result = acpi_disable_event(event, ACPI_NOT_ISR); result = acpi_disable_event(event, ACPI_NOT_ISR);
else if (!strcmp(buf, "enable\n") && else if (!strcmp(buf, "enable\n") &&
!(status & ACPI_EVENT_FLAG_ENABLED)) !(status & ACPI_EVENT_FLAG_ENABLED))
result = acpi_enable_event(event, ACPI_NOT_ISR); result = acpi_enable_event(event, ACPI_NOT_ISR);
else if (!strcmp(buf, "clear\n") && else if (!strcmp(buf, "clear\n") &&
(status & ACPI_EVENT_FLAG_SET)) (status & ACPI_EVENT_FLAG_SET))
result = acpi_clear_event(event); result = acpi_clear_event(event);
else else
all_counters[index].count = strtoul(buf, NULL, 0); all_counters[index].count = strtoul(buf, NULL, 0);
@ -430,17 +602,17 @@ void acpi_irq_stats_init(void)
num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA; num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA;
all_attrs = kzalloc(sizeof(struct attribute *) * (num_counters + 1), all_attrs = kzalloc(sizeof(struct attribute *) * (num_counters + 1),
GFP_KERNEL); GFP_KERNEL);
if (all_attrs == NULL) if (all_attrs == NULL)
return; return;
all_counters = kzalloc(sizeof(struct event_counter) * (num_counters), all_counters = kzalloc(sizeof(struct event_counter) * (num_counters),
GFP_KERNEL); GFP_KERNEL);
if (all_counters == NULL) if (all_counters == NULL)
goto fail; goto fail;
counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters),
GFP_KERNEL); GFP_KERNEL);
if (counter_attrs == NULL) if (counter_attrs == NULL)
goto fail; goto fail;
@ -503,135 +675,11 @@ static void __exit interrupt_stats_exit(void)
return; return;
} }
/* -------------------------------------------------------------------------- int __init acpi_sysfs_init(void)
FS Interface (/proc)
-------------------------------------------------------------------------- */
#ifdef CONFIG_ACPI_PROCFS
#define ACPI_SYSTEM_FILE_INFO "info"
#define ACPI_SYSTEM_FILE_EVENT "event"
#define ACPI_SYSTEM_FILE_DSDT "dsdt"
#define ACPI_SYSTEM_FILE_FADT "fadt"
static int acpi_system_read_info(struct seq_file *seq, void *offset)
{
seq_printf(seq, "version: %x\n", ACPI_CA_VERSION);
return 0;
}
static int acpi_system_info_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_system_read_info, PDE(inode)->data);
}
static const struct file_operations acpi_system_info_ops = {
.owner = THIS_MODULE,
.open = acpi_system_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
loff_t *);
static const struct file_operations acpi_system_dsdt_ops = {
.owner = THIS_MODULE,
.read = acpi_system_read_dsdt,
};
static ssize_t
acpi_system_read_dsdt(struct file *file,
char __user * buffer, size_t count, loff_t * ppos)
{
acpi_status status = AE_OK;
struct acpi_table_header *dsdt = NULL;
ssize_t res;
status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt);
if (ACPI_FAILURE(status))
return -ENODEV;
res = simple_read_from_buffer(buffer, count, ppos, dsdt, dsdt->length);
return res;
}
static ssize_t acpi_system_read_fadt(struct file *, char __user *, size_t,
loff_t *);
static const struct file_operations acpi_system_fadt_ops = {
.owner = THIS_MODULE,
.read = acpi_system_read_fadt,
};
static ssize_t
acpi_system_read_fadt(struct file *file,
char __user * buffer, size_t count, loff_t * ppos)
{
acpi_status status = AE_OK;
struct acpi_table_header *fadt = NULL;
ssize_t res;
status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt);
if (ACPI_FAILURE(status))
return -ENODEV;
res = simple_read_from_buffer(buffer, count, ppos, fadt, fadt->length);
return res;
}
static int acpi_system_procfs_init(void)
{
struct proc_dir_entry *entry;
int error = 0;
/* 'info' [R] */
entry = proc_create(ACPI_SYSTEM_FILE_INFO, S_IRUGO, acpi_root_dir,
&acpi_system_info_ops);
if (!entry)
goto Error;
/* 'dsdt' [R] */
entry = proc_create(ACPI_SYSTEM_FILE_DSDT, S_IRUSR, acpi_root_dir,
&acpi_system_dsdt_ops);
if (!entry)
goto Error;
/* 'fadt' [R] */
entry = proc_create(ACPI_SYSTEM_FILE_FADT, S_IRUSR, acpi_root_dir,
&acpi_system_fadt_ops);
if (!entry)
goto Error;
Done:
return error;
Error:
remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);
error = -EFAULT;
goto Done;
}
#else
static int acpi_system_procfs_init(void)
{
return 0;
}
#endif
int __init acpi_system_init(void)
{ {
int result; int result;
result = acpi_system_procfs_init(); result = acpi_tables_sysfs_init();
if (result)
return result;
result = acpi_system_sysfs_init();
return result; return result;
} }

View File

@ -37,10 +37,14 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/types.h> #include <linux/types.h>
#ifdef CONFIG_ACPI_PROCFS
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h>
#endif
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/kmod.h> #include <linux/kmod.h>
#include <linux/seq_file.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/device.h> #include <linux/device.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
@ -102,16 +106,6 @@ static int acpi_thermal_add(struct acpi_device *device);
static int acpi_thermal_remove(struct acpi_device *device, int type); static int acpi_thermal_remove(struct acpi_device *device, int type);
static int acpi_thermal_resume(struct acpi_device *device); static int acpi_thermal_resume(struct acpi_device *device);
static void acpi_thermal_notify(struct acpi_device *device, u32 event); static void acpi_thermal_notify(struct acpi_device *device, u32 event);
static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file);
static ssize_t acpi_thermal_write_cooling_mode(struct file *,
const char __user *, size_t,
loff_t *);
static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file);
static ssize_t acpi_thermal_write_polling(struct file *, const char __user *,
size_t, loff_t *);
static const struct acpi_device_id thermal_device_ids[] = { static const struct acpi_device_id thermal_device_ids[] = {
{ACPI_THERMAL_HID, 0}, {ACPI_THERMAL_HID, 0},
@ -201,6 +195,18 @@ struct acpi_thermal {
struct mutex lock; struct mutex lock;
}; };
#ifdef CONFIG_ACPI_PROCFS
static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file);
static ssize_t acpi_thermal_write_cooling_mode(struct file *,
const char __user *, size_t,
loff_t *);
static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file);
static ssize_t acpi_thermal_write_polling(struct file *, const char __user *,
size_t, loff_t *);
static const struct file_operations acpi_thermal_state_fops = { static const struct file_operations acpi_thermal_state_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = acpi_thermal_state_open_fs, .open = acpi_thermal_state_open_fs,
@ -242,6 +248,7 @@ static const struct file_operations acpi_thermal_polling_fops = {
.llseek = seq_lseek, .llseek = seq_lseek,
.release = single_release, .release = single_release,
}; };
#endif /* CONFIG_ACPI_PROCFS*/
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Thermal Zone Management Thermal Zone Management
@ -287,26 +294,6 @@ static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
return 0; return 0;
} }
static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
{
if (!tz)
return -EINVAL;
tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */
tz->thermal_zone->polling_delay = seconds * 1000;
if (tz->tz_enabled)
thermal_zone_device_update(tz->thermal_zone);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Polling frequency set to %lu seconds\n",
tz->polling_frequency/10));
return 0;
}
static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode)
{ {
acpi_status status = AE_OK; acpi_status status = AE_OK;
@ -973,7 +960,7 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
FS Interface (/proc) FS Interface (/proc)
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
#ifdef CONFIG_ACPI_PROCFS
static struct proc_dir_entry *acpi_thermal_dir; static struct proc_dir_entry *acpi_thermal_dir;
static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
@ -1187,6 +1174,26 @@ static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file)
PDE(inode)->data); PDE(inode)->data);
} }
static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
{
if (!tz)
return -EINVAL;
/* Convert value to deci-seconds */
tz->polling_frequency = seconds * 10;
tz->thermal_zone->polling_delay = seconds * 1000;
if (tz->tz_enabled)
thermal_zone_device_update(tz->thermal_zone);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Polling frequency set to %lu seconds\n",
tz->polling_frequency/10));
return 0;
}
static ssize_t static ssize_t
acpi_thermal_write_polling(struct file *file, acpi_thermal_write_polling(struct file *file,
const char __user * buffer, const char __user * buffer,
@ -1295,7 +1302,13 @@ static int acpi_thermal_remove_fs(struct acpi_device *device)
return 0; return 0;
} }
#else
static inline int acpi_thermal_add_fs(struct acpi_device *device) { return 0; }
static inline int acpi_thermal_remove_fs(struct acpi_device *device)
{
return 0;
}
#endif /* CONFIG_ACPI_PROCFS */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Driver Interface Driver Interface
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
@ -1566,13 +1579,18 @@ static int __init acpi_thermal_init(void)
printk(KERN_NOTICE "ACPI: thermal control disabled\n"); printk(KERN_NOTICE "ACPI: thermal control disabled\n");
return -ENODEV; return -ENODEV;
} }
#ifdef CONFIG_ACPI_PROCFS
acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
if (!acpi_thermal_dir) if (!acpi_thermal_dir)
return -ENODEV; return -ENODEV;
#endif
result = acpi_bus_register_driver(&acpi_thermal_driver); result = acpi_bus_register_driver(&acpi_thermal_driver);
if (result < 0) { if (result < 0) {
#ifdef CONFIG_ACPI_PROCFS
remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
#endif
return -ENODEV; return -ENODEV;
} }
@ -1584,7 +1602,9 @@ static void __exit acpi_thermal_exit(void)
acpi_bus_unregister_driver(&acpi_thermal_driver); acpi_bus_unregister_driver(&acpi_thermal_driver);
#ifdef CONFIG_ACPI_PROCFS
remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
#endif
return; return;
} }

View File

@ -152,7 +152,9 @@ struct acpi_video_bus {
struct acpi_video_bus_flags flags; struct acpi_video_bus_flags flags;
struct list_head video_device_list; struct list_head video_device_list;
struct mutex device_list_lock; /* protects video_device_list */ struct mutex device_list_lock; /* protects video_device_list */
#ifdef CONFIG_ACPI_PROCFS
struct proc_dir_entry *dir; struct proc_dir_entry *dir;
#endif
struct input_dev *input; struct input_dev *input;
char phys[32]; /* for input device */ char phys[32]; /* for input device */
struct notifier_block pm_nb; struct notifier_block pm_nb;
@ -208,6 +210,7 @@ struct acpi_video_device {
struct output_device *output_dev; struct output_device *output_dev;
}; };
#ifdef CONFIG_ACPI_PROCFS
/* bus */ /* bus */
static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file); static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
static const struct file_operations acpi_video_bus_info_fops = { static const struct file_operations acpi_video_bus_info_fops = {
@ -307,6 +310,7 @@ static const struct file_operations acpi_video_device_EDID_fops = {
.llseek = seq_lseek, .llseek = seq_lseek,
.release = single_release, .release = single_release,
}; };
#endif /* CONFIG_ACPI_PROCFS */
static const char device_decode[][30] = { static const char device_decode[][30] = {
"motherboard VGA device", "motherboard VGA device",
@ -449,16 +453,6 @@ static struct thermal_cooling_device_ops video_cooling_ops = {
/* device */ /* device */
static int
acpi_video_device_query(struct acpi_video_device *device, unsigned long long *state)
{
int status;
status = acpi_evaluate_integer(device->dev->handle, "_DGS", NULL, state);
return status;
}
static int static int
acpi_video_device_get_state(struct acpi_video_device *device, acpi_video_device_get_state(struct acpi_video_device *device,
unsigned long long *state) unsigned long long *state)
@ -698,46 +692,6 @@ acpi_video_device_EDID(struct acpi_video_device *device,
/* bus */ /* bus */
static int
acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option)
{
int status;
unsigned long long tmp;
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list args = { 1, &arg0 };
arg0.integer.value = option;
status = acpi_evaluate_integer(video->device->handle, "_SPD", &args, &tmp);
if (ACPI_SUCCESS(status))
status = tmp ? (-EINVAL) : (AE_OK);
return status;
}
static int
acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id)
{
int status;
status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id);
return status;
}
static int
acpi_video_bus_POST_options(struct acpi_video_bus *video,
unsigned long long *options)
{
int status;
status = acpi_evaluate_integer(video->device->handle, "_VPO", NULL, options);
*options &= 3;
return status;
}
/* /*
* Arg: * Arg:
* video : video bus device pointer * video : video bus device pointer
@ -1159,6 +1113,7 @@ static int acpi_video_bus_check(struct acpi_video_bus *video)
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
FS Interface (/proc) FS Interface (/proc)
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
#ifdef CONFIG_ACPI_PROCFS
static struct proc_dir_entry *acpi_video_dir; static struct proc_dir_entry *acpi_video_dir;
@ -1198,6 +1153,18 @@ acpi_video_device_info_open_fs(struct inode *inode, struct file *file)
PDE(inode)->data); PDE(inode)->data);
} }
static int
acpi_video_device_query(struct acpi_video_device *device,
unsigned long long *state)
{
int status;
status = acpi_evaluate_integer(device->dev->handle, "_DGS",
NULL, state);
return status;
}
static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
{ {
int status; int status;
@ -1492,6 +1459,19 @@ static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data); return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data);
} }
static int
acpi_video_bus_POST_options(struct acpi_video_bus *video,
unsigned long long *options)
{
int status;
status = acpi_evaluate_integer(video->device->handle, "_VPO",
NULL, options);
*options &= 3;
return status;
}
static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
{ {
struct acpi_video_bus *video = seq->private; struct acpi_video_bus *video = seq->private;
@ -1530,6 +1510,16 @@ acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file)
PDE(inode)->data); PDE(inode)->data);
} }
static int
acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id)
{
int status;
status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id);
return status;
}
static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
{ {
struct acpi_video_bus *video = seq->private; struct acpi_video_bus *video = seq->private;
@ -1572,6 +1562,25 @@ static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data); return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data);
} }
static int
acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option)
{
int status;
unsigned long long tmp;
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list args = { 1, &arg0 };
arg0.integer.value = option;
status = acpi_evaluate_integer(video->device->handle, "_SPD",
&args, &tmp);
if (ACPI_SUCCESS(status))
status = tmp ? (-EINVAL) : (AE_OK);
return status;
}
static ssize_t static ssize_t
acpi_video_bus_write_POST(struct file *file, acpi_video_bus_write_POST(struct file *file,
const char __user * buffer, const char __user * buffer,
@ -1722,6 +1731,24 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device)
return 0; return 0;
} }
#else
static inline int acpi_video_device_add_fs(struct acpi_device *device)
{
return 0;
}
static inline int acpi_video_device_remove_fs(struct acpi_device *device)
{
return 0;
}
static inline int acpi_video_bus_add_fs(struct acpi_device *device)
{
return 0;
}
static inline int acpi_video_bus_remove_fs(struct acpi_device *device)
{
return 0;
}
#endif /* CONFIG_ACPI_PROCFS */
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Driver Interface Driver Interface
@ -2140,7 +2167,7 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
status = acpi_video_bus_get_one_device(dev, video); status = acpi_video_bus_get_one_device(dev, video);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
printk(KERN_WARNING PREFIX printk(KERN_WARNING PREFIX
"Cant attach device"); "Cant attach device\n");
continue; continue;
} }
} }
@ -2150,19 +2177,19 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
static int acpi_video_bus_put_one_device(struct acpi_video_device *device) static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
{ {
acpi_status status; acpi_status status;
struct acpi_video_bus *video;
if (!device || !device->video) if (!device || !device->video)
return -ENOENT; return -ENOENT;
video = device->video;
acpi_video_device_remove_fs(device->dev); acpi_video_device_remove_fs(device->dev);
status = acpi_remove_notify_handler(device->dev->handle, status = acpi_remove_notify_handler(device->dev->handle,
ACPI_DEVICE_NOTIFY, ACPI_DEVICE_NOTIFY,
acpi_video_device_notify); acpi_video_device_notify);
if (ACPI_FAILURE(status)) {
printk(KERN_WARNING PREFIX
"Cant remove video notify handler\n");
}
if (device->backlight) { if (device->backlight) {
sysfs_remove_link(&device->backlight->dev.kobj, "device"); sysfs_remove_link(&device->backlight->dev.kobj, "device");
backlight_device_unregister(device->backlight); backlight_device_unregister(device->backlight);
@ -2557,9 +2584,11 @@ int acpi_video_register(void)
return 0; return 0;
} }
#ifdef CONFIG_ACPI_PROCFS
acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
if (!acpi_video_dir) if (!acpi_video_dir)
return -ENODEV; return -ENODEV;
#endif
result = acpi_bus_register_driver(&acpi_video_bus); result = acpi_bus_register_driver(&acpi_video_bus);
if (result < 0) { if (result < 0) {
@ -2588,7 +2617,9 @@ void acpi_video_unregister(void)
} }
acpi_bus_unregister_driver(&acpi_video_bus); acpi_bus_unregister_driver(&acpi_video_bus);
#ifdef CONFIG_ACPI_PROCFS
remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
#endif
register_count = 0; register_count = 0;

View File

@ -21,45 +21,17 @@
ACPI_MODULE_NAME("wakeup_devices") ACPI_MODULE_NAME("wakeup_devices")
/** /**
* acpi_enable_wakeup_device_prep - Prepare wake-up devices. * acpi_enable_wakeup_devices - Enable wake-up device GPEs.
* @sleep_state: ACPI system sleep state. * @sleep_state: ACPI system sleep state.
* *
* Enable all wake-up devices' power, unless the requested system sleep state is * Enable wakeup device power of devices with the state.enable flag set and set
* too deep. * the wakeup enable mask bits in the GPE registers that correspond to wakeup
* devices.
*/ */
void acpi_enable_wakeup_device_prep(u8 sleep_state) void acpi_enable_wakeup_devices(u8 sleep_state)
{ {
struct list_head *node, *next; struct list_head *node, *next;
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev = container_of(node,
struct acpi_device,
wakeup_list);
if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled
|| (sleep_state > (u32) dev->wakeup.sleep_state))
continue;
acpi_enable_wakeup_device_power(dev, sleep_state);
}
}
/**
* acpi_enable_wakeup_device - Enable wake-up device GPEs.
* @sleep_state: ACPI system sleep state.
*
* Enable all wake-up devices' GPEs, with the assumption that
* acpi_disable_all_gpes() was executed before, so we don't need to disable any
* GPEs here.
*/
void acpi_enable_wakeup_device(u8 sleep_state)
{
struct list_head *node, *next;
/*
* Caution: this routine must be invoked when interrupt is disabled
* Refer ACPI2.0: P212
*/
list_for_each_safe(node, next, &acpi_wakeup_device_list) { list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev = struct acpi_device *dev =
container_of(node, struct acpi_device, wakeup_list); container_of(node, struct acpi_device, wakeup_list);
@ -69,6 +41,9 @@ void acpi_enable_wakeup_device(u8 sleep_state)
|| sleep_state > (u32) dev->wakeup.sleep_state) || sleep_state > (u32) dev->wakeup.sleep_state)
continue; continue;
if (dev->wakeup.state.enabled)
acpi_enable_wakeup_device_power(dev, sleep_state);
/* The wake-up power should have been enabled already. */ /* The wake-up power should have been enabled already. */
acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
ACPI_GPE_ENABLE); ACPI_GPE_ENABLE);
@ -76,13 +51,10 @@ void acpi_enable_wakeup_device(u8 sleep_state)
} }
/** /**
* acpi_disable_wakeup_device - Disable devices' wakeup capability. * acpi_disable_wakeup_devices - Disable devices' wakeup capability.
* @sleep_state: ACPI system sleep state. * @sleep_state: ACPI system sleep state.
*
* This function only affects devices with wakeup.state.enabled set, which means
* that it reverses the changes made by acpi_enable_wakeup_device_prep().
*/ */
void acpi_disable_wakeup_device(u8 sleep_state) void acpi_disable_wakeup_devices(u8 sleep_state)
{ {
struct list_head *node, *next; struct list_head *node, *next;

View File

@ -145,12 +145,6 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
struct ata_eh_info *ehi = &ap->link.eh_info; struct ata_eh_info *ehi = &ap->link.eh_info;
int wait = 0; int wait = 0;
unsigned long flags; unsigned long flags;
acpi_handle handle;
if (dev)
handle = dev->acpi_handle;
else
handle = ap->acpi_handle;
spin_lock_irqsave(ap->lock, flags); spin_lock_irqsave(ap->lock, flags);
/* /*

View File

@ -66,7 +66,7 @@ extern u8 acpi_gbl_create_osi_method;
extern u8 acpi_gbl_use_default_register_widths; extern u8 acpi_gbl_use_default_register_widths;
extern acpi_name acpi_gbl_trace_method_name; extern acpi_name acpi_gbl_trace_method_name;
extern u32 acpi_gbl_trace_flags; extern u32 acpi_gbl_trace_flags;
extern u8 acpi_gbl_enable_aml_debug_object; extern u32 acpi_gbl_enable_aml_debug_object;
extern u8 acpi_gbl_copy_dsdt_locally; extern u8 acpi_gbl_copy_dsdt_locally;
extern u8 acpi_gbl_truncate_io_addresses; extern u8 acpi_gbl_truncate_io_addresses;

View File

@ -338,7 +338,6 @@ extern struct cpuidle_driver acpi_idle_driver;
/* in processor_thermal.c */ /* in processor_thermal.c */
int acpi_processor_get_limit_info(struct acpi_processor *pr); int acpi_processor_get_limit_info(struct acpi_processor *pr);
extern const struct file_operations acpi_processor_limit_fops;
extern struct thermal_cooling_device_ops processor_cooling_ops; extern struct thermal_cooling_device_ops processor_cooling_ops;
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
void acpi_thermal_cpufreq_init(void); void acpi_thermal_cpufreq_init(void);

View File

@ -39,10 +39,10 @@
* Severity difinition for error_severity in struct cper_record_header * Severity difinition for error_severity in struct cper_record_header
* and section_severity in struct cper_section_descriptor * and section_severity in struct cper_section_descriptor
*/ */
#define CPER_SER_RECOVERABLE 0x0 #define CPER_SEV_RECOVERABLE 0x0
#define CPER_SER_FATAL 0x1 #define CPER_SEV_FATAL 0x1
#define CPER_SER_CORRECTED 0x2 #define CPER_SEV_CORRECTED 0x2
#define CPER_SER_INFORMATIONAL 0x3 #define CPER_SEV_INFORMATIONAL 0x3
/* /*
* Validation bits difinition for validation_bits in struct * Validation bits difinition for validation_bits in struct