diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-15 20:37:07 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-15 20:37:07 -0400 |
| commit | 2245ba2a3a975656bb303dfaa115accaa4667083 (patch) | |
| tree | cbeb348c43d58461d851907373c34a7b9a985e41 | |
| parent | e2e96c663639a3361bb1a84e666887d308c6c87e (diff) | |
| parent | 95ee46aa8698f2000647dfb362400fadbb5807cf (diff) | |
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.
40 files changed, 1071 insertions, 1479 deletions
diff --git a/Documentation/acpi/method-customizing.txt b/Documentation/acpi/method-customizing.txt index e628cd23ca80..3e1d25aee3fb 100644 --- a/Documentation/acpi/method-customizing.txt +++ b/Documentation/acpi/method-customizing.txt | |||
| @@ -19,6 +19,8 @@ Note: Only ACPI METHOD can be overridden, any other object types like | |||
| 19 | "Device", "OperationRegion", are not recognized. | 19 | "Device", "OperationRegion", are not recognized. |
| 20 | Note: The same ACPI control method can be overridden for many times, | 20 | Note: The same ACPI control method can be overridden for many times, |
| 21 | and it's always the latest one that used by Linux/kernel. | 21 | and it's always the latest one that used by Linux/kernel. |
| 22 | Note: To get the ACPI debug object output (Store (AAAA, Debug)), | ||
| 23 | please run "echo 1 > /sys/module/acpi/parameters/aml_debug_output". | ||
| 22 | 24 | ||
| 23 | 1. override an existing method | 25 | 1. override an existing method |
| 24 | a) get the ACPI table via ACPI sysfs I/F. e.g. to get the DSDT, | 26 | a) get the ACPI table via ACPI sysfs I/F. e.g. to get the DSDT, |
diff --git a/arch/x86/kernel/cpu/mcheck/mce-apei.c b/arch/x86/kernel/cpu/mcheck/mce-apei.c index 745b54f9be89..8209472b27a5 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-apei.c +++ b/arch/x86/kernel/cpu/mcheck/mce-apei.c | |||
| @@ -80,7 +80,7 @@ int apei_write_mce(struct mce *m) | |||
| 80 | rcd.hdr.revision = CPER_RECORD_REV; | 80 | rcd.hdr.revision = CPER_RECORD_REV; |
| 81 | rcd.hdr.signature_end = CPER_SIG_END; | 81 | rcd.hdr.signature_end = CPER_SIG_END; |
| 82 | rcd.hdr.section_count = 1; | 82 | rcd.hdr.section_count = 1; |
| 83 | rcd.hdr.error_severity = CPER_SER_FATAL; | 83 | rcd.hdr.error_severity = CPER_SEV_FATAL; |
| 84 | /* timestamp, platform_id, partition_id are all invalid */ | 84 | /* timestamp, platform_id, partition_id are all invalid */ |
| 85 | rcd.hdr.validation_bits = 0; | 85 | rcd.hdr.validation_bits = 0; |
| 86 | rcd.hdr.record_length = sizeof(rcd); | 86 | rcd.hdr.record_length = sizeof(rcd); |
| @@ -96,7 +96,7 @@ int apei_write_mce(struct mce *m) | |||
| 96 | rcd.sec_hdr.validation_bits = 0; | 96 | rcd.sec_hdr.validation_bits = 0; |
| 97 | rcd.sec_hdr.flags = CPER_SEC_PRIMARY; | 97 | rcd.sec_hdr.flags = CPER_SEC_PRIMARY; |
| 98 | rcd.sec_hdr.section_type = CPER_SECTION_TYPE_MCE; | 98 | rcd.sec_hdr.section_type = CPER_SECTION_TYPE_MCE; |
| 99 | rcd.sec_hdr.section_severity = CPER_SER_FATAL; | 99 | rcd.sec_hdr.section_severity = CPER_SEV_FATAL; |
| 100 | 100 | ||
| 101 | memcpy(&rcd.mce, m, sizeof(*m)); | 101 | memcpy(&rcd.mce, m, sizeof(*m)); |
| 102 | 102 | ||
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 08e0140920e1..b811f2173f6f 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
| @@ -54,17 +54,10 @@ config ACPI_PROCFS | |||
| 54 | they have been replaced by functions in /sys. | 54 | they have been replaced by functions in /sys. |
| 55 | The deprecated files (and their replacements) include: | 55 | The deprecated files (and their replacements) include: |
| 56 | 56 | ||
| 57 | /proc/acpi/sleep (/sys/power/state) | ||
| 58 | /proc/acpi/info (/sys/module/acpi/parameters/acpica_version) | ||
| 59 | /proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT) | ||
| 60 | /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP) | ||
| 61 | /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer) | ||
| 62 | /proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level) | ||
| 63 | /proc/acpi/processor/*/power (/sys/devices/system/cpu/*/cpuidle/*) | ||
| 64 | /proc/acpi/processor/*/performance (/sys/devices/system/cpu/*/ | ||
| 65 | cpufreq/*) | ||
| 66 | /proc/acpi/processor/*/throttling (/sys/class/thermal/ | 57 | /proc/acpi/processor/*/throttling (/sys/class/thermal/ |
| 67 | cooling_device*/*) | 58 | cooling_device*/*) |
| 59 | /proc/acpi/video/*/brightness (/sys/class/backlight/) | ||
| 60 | /proc/acpi/thermal_zone/*/* (/sys/class/thermal/) | ||
| 68 | This option has no effect on /proc/acpi/ files | 61 | This option has no effect on /proc/acpi/ files |
| 69 | and functions which do not yet exist in /sys. | 62 | and functions which do not yet exist in /sys. |
| 70 | 63 | ||
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 833b582d1762..3d031d02e54b 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
| @@ -37,8 +37,9 @@ acpi-y += ec.o | |||
| 37 | acpi-$(CONFIG_ACPI_DOCK) += dock.o | 37 | acpi-$(CONFIG_ACPI_DOCK) += dock.o |
| 38 | acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o | 38 | acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o |
| 39 | acpi-y += power.o | 39 | acpi-y += power.o |
| 40 | acpi-y += system.o event.o | 40 | acpi-y += event.o |
| 41 | acpi-$(CONFIG_ACPI_DEBUG) += debug.o | 41 | acpi-y += sysfs.o |
| 42 | acpi-$(CONFIG_DEBUG_FS) += debugfs.o | ||
| 42 | acpi-$(CONFIG_ACPI_NUMA) += numa.o | 43 | acpi-$(CONFIG_ACPI_NUMA) += numa.o |
| 43 | acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o | 44 | acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o |
| 44 | ifdef CONFIG_ACPI_VIDEO | 45 | ifdef CONFIG_ACPI_VIDEO |
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index e0e6affb0d80..36867cd70eac 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
| @@ -82,6 +82,10 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info); | |||
| 82 | 82 | ||
| 83 | acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); | 83 | acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); |
| 84 | 84 | ||
| 85 | acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); | ||
| 86 | |||
| 87 | acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); | ||
| 88 | |||
| 85 | struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, | 89 | struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, |
| 86 | u32 gpe_number); | 90 | u32 gpe_number); |
| 87 | 91 | ||
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 18e796fe4295..1d192142c691 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
| @@ -108,7 +108,7 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE); | |||
| 108 | /* | 108 | /* |
| 109 | * Optionally enable output from the AML Debug Object. | 109 | * Optionally enable output from the AML Debug Object. |
| 110 | */ | 110 | */ |
| 111 | u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); | 111 | u32 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); |
| 112 | 112 | ||
| 113 | /* | 113 | /* |
| 114 | * Optionally copy the entire DSDT to local memory (instead of simply | 114 | * Optionally copy the entire DSDT to local memory (instead of simply |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 1ee0bcf399aa..df85b53a674f 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
| @@ -412,6 +412,7 @@ struct acpi_handler_info { | |||
| 412 | acpi_event_handler address; /* Address of handler, if any */ | 412 | acpi_event_handler address; /* Address of handler, if any */ |
| 413 | void *context; /* Context to be passed to handler */ | 413 | void *context; /* Context to be passed to handler */ |
| 414 | struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ | 414 | struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ |
| 415 | u8 orig_flags; /* Original misc info about this GPE */ | ||
| 415 | }; | 416 | }; |
| 416 | 417 | ||
| 417 | union acpi_gpe_dispatch_info { | 418 | union acpi_gpe_dispatch_info { |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 7a6a3e6f4be0..f226eac314db 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
| @@ -137,6 +137,79 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
| 137 | 137 | ||
| 138 | /******************************************************************************* | 138 | /******************************************************************************* |
| 139 | * | 139 | * |
| 140 | * FUNCTION: acpi_raw_enable_gpe | ||
| 141 | * | ||
| 142 | * PARAMETERS: gpe_event_info - GPE to enable | ||
| 143 | * | ||
| 144 | * RETURN: Status | ||
| 145 | * | ||
| 146 | * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is | ||
| 147 | * hardware-enabled. | ||
| 148 | * | ||
| 149 | ******************************************************************************/ | ||
| 150 | |||
| 151 | acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | ||
| 152 | { | ||
| 153 | acpi_status status = AE_OK; | ||
| 154 | |||
| 155 | if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { | ||
| 156 | return_ACPI_STATUS(AE_LIMIT); | ||
| 157 | } | ||
| 158 | |||
| 159 | gpe_event_info->runtime_count++; | ||
| 160 | if (gpe_event_info->runtime_count == 1) { | ||
| 161 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); | ||
| 162 | if (ACPI_SUCCESS(status)) { | ||
| 163 | status = acpi_ev_enable_gpe(gpe_event_info); | ||
| 164 | } | ||
| 165 | |||
| 166 | if (ACPI_FAILURE(status)) { | ||
| 167 | gpe_event_info->runtime_count--; | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 171 | return_ACPI_STATUS(status); | ||
| 172 | } | ||
| 173 | |||
| 174 | /******************************************************************************* | ||
| 175 | * | ||
| 176 | * FUNCTION: acpi_raw_disable_gpe | ||
| 177 | * | ||
| 178 | * PARAMETERS: gpe_event_info - GPE to disable | ||
| 179 | * | ||
| 180 | * RETURN: Status | ||
| 181 | * | ||
| 182 | * DESCRIPTION: Remove a reference to a GPE. When the last reference is | ||
| 183 | * removed, the GPE is hardware-disabled. | ||
| 184 | * | ||
| 185 | ******************************************************************************/ | ||
| 186 | |||
| 187 | acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | ||
| 188 | { | ||
| 189 | acpi_status status = AE_OK; | ||
| 190 | |||
| 191 | if (!gpe_event_info->runtime_count) { | ||
| 192 | return_ACPI_STATUS(AE_LIMIT); | ||
| 193 | } | ||
| 194 | |||
| 195 | gpe_event_info->runtime_count--; | ||
| 196 | if (!gpe_event_info->runtime_count) { | ||
| 197 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); | ||
| 198 | if (ACPI_SUCCESS(status)) { | ||
| 199 | status = acpi_hw_low_set_gpe(gpe_event_info, | ||
| 200 | ACPI_GPE_DISABLE); | ||
| 201 | } | ||
| 202 | |||
| 203 | if (ACPI_FAILURE(status)) { | ||
| 204 | gpe_event_info->runtime_count++; | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | return_ACPI_STATUS(status); | ||
| 209 | } | ||
| 210 | |||
| 211 | /******************************************************************************* | ||
| 212 | * | ||
| 140 | * FUNCTION: acpi_ev_low_get_gpe_info | 213 | * FUNCTION: acpi_ev_low_get_gpe_info |
| 141 | * | 214 | * |
| 142 | * PARAMETERS: gpe_number - Raw GPE number | 215 | * PARAMETERS: gpe_number - Raw GPE number |
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 4a531cdf7942..14e48add32fa 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
| @@ -691,12 +691,22 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
| 691 | return_ACPI_STATUS(status); | 691 | return_ACPI_STATUS(status); |
| 692 | } | 692 | } |
| 693 | 693 | ||
| 694 | /* Allocate memory for the handler object */ | ||
| 695 | |||
| 696 | handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info)); | ||
| 697 | if (!handler) { | ||
| 698 | status = AE_NO_MEMORY; | ||
| 699 | goto unlock_and_exit; | ||
| 700 | } | ||
| 701 | |||
| 702 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
| 703 | |||
| 694 | /* Ensure that we have a valid GPE number */ | 704 | /* Ensure that we have a valid GPE number */ |
| 695 | 705 | ||
| 696 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | 706 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
| 697 | if (!gpe_event_info) { | 707 | if (!gpe_event_info) { |
| 698 | status = AE_BAD_PARAMETER; | 708 | status = AE_BAD_PARAMETER; |
| 699 | goto unlock_and_exit; | 709 | goto free_and_exit; |
| 700 | } | 710 | } |
| 701 | 711 | ||
| 702 | /* Make sure that there isn't a handler there already */ | 712 | /* Make sure that there isn't a handler there already */ |
| @@ -704,24 +714,30 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
| 704 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | 714 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == |
| 705 | ACPI_GPE_DISPATCH_HANDLER) { | 715 | ACPI_GPE_DISPATCH_HANDLER) { |
| 706 | status = AE_ALREADY_EXISTS; | 716 | status = AE_ALREADY_EXISTS; |
| 707 | goto unlock_and_exit; | 717 | goto free_and_exit; |
| 708 | } | 718 | } |
| 709 | 719 | ||
| 710 | /* Allocate and init handler object */ | 720 | /* Allocate and init handler object */ |
| 711 | 721 | ||
| 712 | handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info)); | ||
| 713 | if (!handler) { | ||
| 714 | status = AE_NO_MEMORY; | ||
| 715 | goto unlock_and_exit; | ||
| 716 | } | ||
| 717 | |||
| 718 | handler->address = address; | 722 | handler->address = address; |
| 719 | handler->context = context; | 723 | handler->context = context; |
| 720 | handler->method_node = gpe_event_info->dispatch.method_node; | 724 | handler->method_node = gpe_event_info->dispatch.method_node; |
| 725 | handler->orig_flags = gpe_event_info->flags & | ||
| 726 | (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); | ||
| 727 | |||
| 728 | /* | ||
| 729 | * If the GPE is associated with a method and it cannot wake up the | ||
| 730 | * system from sleep states, it was enabled automatically during | ||
| 731 | * initialization, so it has to be disabled now to avoid spurious | ||
| 732 | * execution of the handler. | ||
| 733 | */ | ||
| 734 | |||
| 735 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) | ||
| 736 | && !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) | ||
| 737 | (void)acpi_raw_disable_gpe(gpe_event_info); | ||
| 721 | 738 | ||
| 722 | /* Install the handler */ | 739 | /* Install the handler */ |
| 723 | 740 | ||
| 724 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
| 725 | gpe_event_info->dispatch.handler = handler; | 741 | gpe_event_info->dispatch.handler = handler; |
| 726 | 742 | ||
| 727 | /* Setup up dispatch flags to indicate handler (vs. method) */ | 743 | /* Setup up dispatch flags to indicate handler (vs. method) */ |
| @@ -735,6 +751,11 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
| 735 | unlock_and_exit: | 751 | unlock_and_exit: |
| 736 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 752 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
| 737 | return_ACPI_STATUS(status); | 753 | return_ACPI_STATUS(status); |
| 754 | |||
| 755 | free_and_exit: | ||
| 756 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
| 757 | ACPI_FREE(handler); | ||
| 758 | goto unlock_and_exit; | ||
| 738 | } | 759 | } |
| 739 | 760 | ||
| 740 | ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler) | 761 | ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler) |
| @@ -770,11 +791,17 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
| 770 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 791 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
| 771 | } | 792 | } |
| 772 | 793 | ||
| 794 | /* Make sure all deferred tasks are completed */ | ||
| 795 | |||
| 796 | acpi_os_wait_events_complete(NULL); | ||
| 797 | |||
| 773 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | 798 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); |
| 774 | if (ACPI_FAILURE(status)) { | 799 | if (ACPI_FAILURE(status)) { |
| 775 | return_ACPI_STATUS(status); | 800 | return_ACPI_STATUS(status); |
| 776 | } | 801 | } |
| 777 | 802 | ||
| 803 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
| 804 | |||
| 778 | /* Ensure that we have a valid GPE number */ | 805 | /* Ensure that we have a valid GPE number */ |
| 779 | 806 | ||
| 780 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | 807 | 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, | |||
| 798 | goto unlock_and_exit; | 825 | goto unlock_and_exit; |
| 799 | } | 826 | } |
| 800 | 827 | ||
| 801 | /* Make sure all deferred tasks are completed */ | ||
| 802 | |||
| 803 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
| 804 | acpi_os_wait_events_complete(NULL); | ||
| 805 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
| 806 | if (ACPI_FAILURE(status)) { | ||
| 807 | return_ACPI_STATUS(status); | ||
| 808 | } | ||
| 809 | |||
| 810 | /* Remove the handler */ | 828 | /* Remove the handler */ |
| 811 | 829 | ||
| 812 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
| 813 | handler = gpe_event_info->dispatch.handler; | 830 | handler = gpe_event_info->dispatch.handler; |
| 814 | 831 | ||
| 815 | /* Restore Method node (if any), set dispatch flags */ | 832 | /* Restore Method node (if any), set dispatch flags */ |
| 816 | 833 | ||
| 817 | gpe_event_info->dispatch.method_node = handler->method_node; | 834 | gpe_event_info->dispatch.method_node = handler->method_node; |
| 818 | gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */ | 835 | gpe_event_info->flags &= |
| 819 | if (handler->method_node) { | 836 | ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); |
| 820 | gpe_event_info->flags |= ACPI_GPE_DISPATCH_METHOD; | 837 | gpe_event_info->flags |= handler->orig_flags; |
| 821 | } | 838 | |
| 822 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 839 | /* |
| 840 | * If the GPE was previously associated with a method and it cannot wake | ||
| 841 | * up the system from sleep states, it should be enabled at this point | ||
| 842 | * to restore the post-initialization configuration. | ||
| 843 | */ | ||
| 844 | |||
| 845 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) | ||
| 846 | && !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) | ||
| 847 | (void)acpi_raw_enable_gpe(gpe_event_info); | ||
| 823 | 848 | ||
| 824 | /* Now we can free the handler object */ | 849 | /* Now we can free the handler object */ |
| 825 | 850 | ||
| 826 | ACPI_FREE(handler); | 851 | ACPI_FREE(handler); |
| 827 | 852 | ||
| 828 | unlock_and_exit: | 853 | unlock_and_exit: |
| 854 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
| 855 | |||
| 829 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 856 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
| 830 | return_ACPI_STATUS(status); | 857 | return_ACPI_STATUS(status); |
| 831 | } | 858 | } |
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index 0ec900da5794..304825528d48 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
| @@ -294,7 +294,7 @@ ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup) | |||
| 294 | ******************************************************************************/ | 294 | ******************************************************************************/ |
| 295 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) | 295 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) |
| 296 | { | 296 | { |
| 297 | acpi_status status = AE_OK; | 297 | acpi_status status = AE_BAD_PARAMETER; |
| 298 | struct acpi_gpe_event_info *gpe_event_info; | 298 | struct acpi_gpe_event_info *gpe_event_info; |
| 299 | acpi_cpu_flags flags; | 299 | acpi_cpu_flags flags; |
| 300 | 300 | ||
| @@ -305,28 +305,10 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) | |||
| 305 | /* Ensure that we have a valid GPE number */ | 305 | /* Ensure that we have a valid GPE number */ |
| 306 | 306 | ||
| 307 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | 307 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
| 308 | if (!gpe_event_info) { | 308 | if (gpe_event_info) { |
| 309 | status = AE_BAD_PARAMETER; | 309 | status = acpi_raw_enable_gpe(gpe_event_info); |
| 310 | goto unlock_and_exit; | ||
| 311 | } | 310 | } |
| 312 | 311 | ||
| 313 | if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { | ||
| 314 | status = AE_LIMIT; /* Too many references */ | ||
| 315 | goto unlock_and_exit; | ||
| 316 | } | ||
| 317 | |||
| 318 | gpe_event_info->runtime_count++; | ||
| 319 | if (gpe_event_info->runtime_count == 1) { | ||
| 320 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); | ||
| 321 | if (ACPI_SUCCESS(status)) { | ||
| 322 | status = acpi_ev_enable_gpe(gpe_event_info); | ||
| 323 | } | ||
| 324 | if (ACPI_FAILURE(status)) { | ||
| 325 | gpe_event_info->runtime_count--; | ||
| 326 | } | ||
| 327 | } | ||
| 328 | |||
| 329 | unlock_and_exit: | ||
| 330 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 312 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
| 331 | return_ACPI_STATUS(status); | 313 | return_ACPI_STATUS(status); |
| 332 | } | 314 | } |
| @@ -348,7 +330,7 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe) | |||
| 348 | ******************************************************************************/ | 330 | ******************************************************************************/ |
| 349 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) | 331 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) |
| 350 | { | 332 | { |
| 351 | acpi_status status = AE_OK; | 333 | acpi_status status = AE_BAD_PARAMETER; |
| 352 | struct acpi_gpe_event_info *gpe_event_info; | 334 | struct acpi_gpe_event_info *gpe_event_info; |
| 353 | acpi_cpu_flags flags; | 335 | acpi_cpu_flags flags; |
| 354 | 336 | ||
| @@ -359,32 +341,10 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) | |||
| 359 | /* Ensure that we have a valid GPE number */ | 341 | /* Ensure that we have a valid GPE number */ |
| 360 | 342 | ||
| 361 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | 343 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
| 362 | if (!gpe_event_info) { | 344 | if (gpe_event_info) { |
| 363 | status = AE_BAD_PARAMETER; | 345 | status = acpi_raw_disable_gpe(gpe_event_info) ; |
| 364 | goto unlock_and_exit; | ||
| 365 | } | ||
| 366 | |||
| 367 | /* Hardware-disable a runtime GPE on removal of the last reference */ | ||
| 368 | |||
| 369 | if (!gpe_event_info->runtime_count) { | ||
| 370 | status = AE_LIMIT; /* There are no references to remove */ | ||
| 371 | goto unlock_and_exit; | ||
| 372 | } | 346 | } |
| 373 | 347 | ||
| 374 | gpe_event_info->runtime_count--; | ||
| 375 | if (!gpe_event_info->runtime_count) { | ||
| 376 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); | ||
| 377 | if (ACPI_SUCCESS(status)) { | ||
| 378 | status = | ||
| 379 | acpi_hw_low_set_gpe(gpe_event_info, | ||
| 380 | ACPI_GPE_DISABLE); | ||
| 381 | } | ||
| 382 | if (ACPI_FAILURE(status)) { | ||
| 383 | gpe_event_info->runtime_count++; | ||
| 384 | } | ||
| 385 | } | ||
| 386 | |||
| 387 | unlock_and_exit: | ||
| 388 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 348 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
| 389 | return_ACPI_STATUS(status); | 349 | return_ACPI_STATUS(status); |
| 390 | } | 350 | } |
| @@ -411,7 +371,6 @@ acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number) | |||
| 411 | acpi_status status = AE_OK; | 371 | acpi_status status = AE_OK; |
| 412 | struct acpi_gpe_event_info *gpe_event_info; | 372 | struct acpi_gpe_event_info *gpe_event_info; |
| 413 | acpi_cpu_flags flags; | 373 | acpi_cpu_flags flags; |
| 414 | u8 disable = 0; | ||
| 415 | 374 | ||
| 416 | ACPI_FUNCTION_TRACE(acpi_gpe_can_wake); | 375 | ACPI_FUNCTION_TRACE(acpi_gpe_can_wake); |
| 417 | 376 | ||
| @@ -430,15 +389,12 @@ acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number) | |||
| 430 | } | 389 | } |
| 431 | 390 | ||
| 432 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | 391 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; |
| 433 | disable = (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) | 392 | if (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) { |
| 434 | && gpe_event_info->runtime_count; | 393 | (void)acpi_raw_disable_gpe(gpe_event_info); |
| 394 | } | ||
| 435 | 395 | ||
| 436 | unlock_and_exit: | 396 | unlock_and_exit: |
| 437 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 397 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
| 438 | |||
| 439 | if (disable) | ||
| 440 | status = acpi_disable_gpe(gpe_device, gpe_number); | ||
| 441 | |||
| 442 | return_ACPI_STATUS(status); | 398 | return_ACPI_STATUS(status); |
| 443 | } | 399 | } |
| 444 | ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake) | 400 | ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake) |
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 058b3df48271..f5cca3a1300c 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c | |||
| @@ -279,13 +279,10 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) | |||
| 279 | 279 | ||
| 280 | acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) | 280 | acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) |
| 281 | { | 281 | { |
| 282 | acpi_thread_id this_thread_id; | ||
| 283 | |||
| 284 | ACPI_FUNCTION_NAME(ut_release_mutex); | 282 | ACPI_FUNCTION_NAME(ut_release_mutex); |
| 285 | 283 | ||
| 286 | this_thread_id = acpi_os_get_thread_id(); | ||
| 287 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", | 284 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", |
| 288 | ACPI_CAST_PTR(void, this_thread_id), | 285 | ACPI_CAST_PTR(void, acpi_os_get_thread_id()), |
| 289 | acpi_ut_get_mutex_name(mutex_id))); | 286 | acpi_ut_get_mutex_name(mutex_id))); |
| 290 | 287 | ||
| 291 | if (mutex_id > ACPI_MAX_MUTEX) { | 288 | if (mutex_id > ACPI_MAX_MUTEX) { |
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index f8c668f27b5a..907e350f1c7d 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig | |||
| @@ -28,3 +28,12 @@ config ACPI_APEI_EINJ | |||
| 28 | EINJ provides a hardware error injection mechanism, it is | 28 | EINJ provides a hardware error injection mechanism, it is |
| 29 | mainly used for debugging and testing the other parts of | 29 | mainly used for debugging and testing the other parts of |
| 30 | APEI and some other RAS features. | 30 | APEI and some other RAS features. |
| 31 | |||
| 32 | config ACPI_APEI_ERST_DEBUG | ||
| 33 | tristate "APEI Error Record Serialization Table (ERST) Debug Support" | ||
| 34 | depends on ACPI_APEI | ||
| 35 | help | ||
| 36 | ERST is a way provided by APEI to save and retrieve hardware | ||
| 37 | error infomation to and from a persistent store. Enable this | ||
| 38 | if you want to debugging and testing the ERST kernel support | ||
| 39 | and firmware implementation. | ||
diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile index b13b03a17789..d1d1bc0a4ee1 100644 --- a/drivers/acpi/apei/Makefile +++ b/drivers/acpi/apei/Makefile | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | obj-$(CONFIG_ACPI_APEI) += apei.o | 1 | obj-$(CONFIG_ACPI_APEI) += apei.o |
| 2 | obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o | 2 | obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o |
| 3 | obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o | 3 | obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o |
| 4 | obj-$(CONFIG_ACPI_APEI_ERST_DEBUG) += erst-dbg.o | ||
| 4 | 5 | ||
| 5 | apei-y := apei-base.o hest.o cper.o erst.o | 6 | apei-y := apei-base.o hest.o cper.o erst.o |
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 216e1e948ff6..73fd0c7487c1 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
| @@ -482,14 +482,14 @@ err_unmap_ioport: | |||
| 482 | list_for_each_entry(res, &resources->ioport, list) { | 482 | list_for_each_entry(res, &resources->ioport, list) { |
| 483 | if (res == res_bak) | 483 | if (res == res_bak) |
| 484 | break; | 484 | break; |
| 485 | release_mem_region(res->start, res->end - res->start); | 485 | release_region(res->start, res->end - res->start); |
| 486 | } | 486 | } |
| 487 | res_bak = NULL; | 487 | res_bak = NULL; |
| 488 | err_unmap_iomem: | 488 | err_unmap_iomem: |
| 489 | list_for_each_entry(res, &resources->iomem, list) { | 489 | list_for_each_entry(res, &resources->iomem, list) { |
| 490 | if (res == res_bak) | 490 | if (res == res_bak) |
| 491 | break; | 491 | break; |
| 492 | release_region(res->start, res->end - res->start); | 492 | release_mem_region(res->start, res->end - res->start); |
| 493 | } | 493 | } |
| 494 | return -EINVAL; | 494 | return -EINVAL; |
| 495 | } | 495 | } |
diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c new file mode 100644 index 000000000000..5281ddda2777 --- /dev/null +++ b/drivers/acpi/apei/erst-dbg.c | |||
| @@ -0,0 +1,207 @@ | |||
| 1 | /* | ||
| 2 | * APEI Error Record Serialization Table debug support | ||
| 3 | * | ||
| 4 | * ERST is a way provided by APEI to save and retrieve hardware error | ||
| 5 | * infomation to and from a persistent store. This file provide the | ||
| 6 | * debugging/testing support for ERST kernel support and firmware | ||
| 7 | * implementation. | ||
| 8 | * | ||
| 9 | * Copyright 2010 Intel Corp. | ||
| 10 | * Author: Huang Ying <ying.huang@intel.com> | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or | ||
| 13 | * modify it under the terms of the GNU General Public License version | ||
| 14 | * 2 as published by the Free Software Foundation. | ||
| 15 | * | ||
| 16 | * This program is distributed in the hope that it will be useful, | ||
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 19 | * GNU General Public License for more details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, write to the Free Software | ||
| 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/kernel.h> | ||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/uaccess.h> | ||
| 29 | #include <acpi/apei.h> | ||
| 30 | #include <linux/miscdevice.h> | ||
| 31 | |||
| 32 | #include "apei-internal.h" | ||
| 33 | |||
| 34 | #define ERST_DBG_PFX "ERST DBG: " | ||
| 35 | |||
| 36 | #define ERST_DBG_RECORD_LEN_MAX 4096 | ||
| 37 | |||
| 38 | static void *erst_dbg_buf; | ||
| 39 | static unsigned int erst_dbg_buf_len; | ||
| 40 | |||
| 41 | /* Prevent erst_dbg_read/write from being invoked concurrently */ | ||
| 42 | static DEFINE_MUTEX(erst_dbg_mutex); | ||
| 43 | |||
| 44 | static int erst_dbg_open(struct inode *inode, struct file *file) | ||
| 45 | { | ||
| 46 | if (erst_disable) | ||
| 47 | return -ENODEV; | ||
| 48 | |||
| 49 | return nonseekable_open(inode, file); | ||
| 50 | } | ||
| 51 | |||
| 52 | static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | ||
| 53 | { | ||
| 54 | int rc; | ||
| 55 | u64 record_id; | ||
| 56 | u32 record_count; | ||
| 57 | |||
| 58 | switch (cmd) { | ||
| 59 | case APEI_ERST_CLEAR_RECORD: | ||
| 60 | rc = copy_from_user(&record_id, (void __user *)arg, | ||
| 61 | sizeof(record_id)); | ||
| 62 | if (rc) | ||
| 63 | return -EFAULT; | ||
| 64 | return erst_clear(record_id); | ||
| 65 | case APEI_ERST_GET_RECORD_COUNT: | ||
| 66 | rc = erst_get_record_count(); | ||
| 67 | if (rc < 0) | ||
| 68 | return rc; | ||
| 69 | record_count = rc; | ||
| 70 | rc = put_user(record_count, (u32 __user *)arg); | ||
| 71 | if (rc) | ||
| 72 | return rc; | ||
| 73 | return 0; | ||
| 74 | default: | ||
| 75 | return -ENOTTY; | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf, | ||
| 80 | size_t usize, loff_t *off) | ||
| 81 | { | ||
| 82 | int rc; | ||
| 83 | ssize_t len = 0; | ||
| 84 | u64 id; | ||
| 85 | |||
| 86 | if (*off != 0) | ||
| 87 | return -EINVAL; | ||
| 88 | |||
| 89 | if (mutex_lock_interruptible(&erst_dbg_mutex) != 0) | ||
| 90 | return -EINTR; | ||
| 91 | |||
| 92 | retry_next: | ||
| 93 | rc = erst_get_next_record_id(&id); | ||
| 94 | if (rc) | ||
| 95 | goto out; | ||
| 96 | /* no more record */ | ||
| 97 | if (id == APEI_ERST_INVALID_RECORD_ID) | ||
| 98 | goto out; | ||
| 99 | retry: | ||
| 100 | rc = len = erst_read(id, erst_dbg_buf, erst_dbg_buf_len); | ||
| 101 | /* The record may be cleared by others, try read next record */ | ||
| 102 | if (rc == -ENOENT) | ||
| 103 | goto retry_next; | ||
| 104 | if (rc < 0) | ||
| 105 | goto out; | ||
| 106 | if (len > ERST_DBG_RECORD_LEN_MAX) { | ||
| 107 | pr_warning(ERST_DBG_PFX | ||
| 108 | "Record (ID: 0x%llx) length is too long: %zd\n", | ||
| 109 | id, len); | ||
| 110 | rc = -EIO; | ||
| 111 | goto out; | ||
| 112 | } | ||
| 113 | if (len > erst_dbg_buf_len) { | ||
| 114 | kfree(erst_dbg_buf); | ||
| 115 | rc = -ENOMEM; | ||
| 116 | erst_dbg_buf = kmalloc(len, GFP_KERNEL); | ||
| 117 | if (!erst_dbg_buf) | ||
| 118 | goto out; | ||
| 119 | erst_dbg_buf_len = len; | ||
| 120 | goto retry; | ||
| 121 | } | ||
| 122 | |||
| 123 | rc = -EINVAL; | ||
| 124 | if (len > usize) | ||
| 125 | goto out; | ||
| 126 | |||
| 127 | rc = -EFAULT; | ||
| 128 | if (copy_to_user(ubuf, erst_dbg_buf, len)) | ||
| 129 | goto out; | ||
| 130 | rc = 0; | ||
| 131 | out: | ||
| 132 | mutex_unlock(&erst_dbg_mutex); | ||
| 133 | return rc ? rc : len; | ||
| 134 | } | ||
| 135 | |||
| 136 | static ssize_t erst_dbg_write(struct file *filp, const char __user *ubuf, | ||
| 137 | size_t usize, loff_t *off) | ||
| 138 | { | ||
| 139 | int rc; | ||
| 140 | struct cper_record_header *rcd; | ||
| 141 | |||
| 142 | if (!capable(CAP_SYS_ADMIN)) | ||
| 143 | return -EPERM; | ||
| 144 | |||
| 145 | if (usize > ERST_DBG_RECORD_LEN_MAX) { | ||
| 146 | pr_err(ERST_DBG_PFX "Too long record to be written\n"); | ||
| 147 | return -EINVAL; | ||
| 148 | } | ||
| 149 | |||
| 150 | if (mutex_lock_interruptible(&erst_dbg_mutex)) | ||
| 151 | return -EINTR; | ||
| 152 | if (usize > erst_dbg_buf_len) { | ||
| 153 | kfree(erst_dbg_buf); | ||
| 154 | rc = -ENOMEM; | ||
| 155 | erst_dbg_buf = kmalloc(usize, GFP_KERNEL); | ||
| 156 | if (!erst_dbg_buf) | ||
| 157 | goto out; | ||
| 158 | erst_dbg_buf_len = usize; | ||
| 159 | } | ||
| 160 | rc = copy_from_user(erst_dbg_buf, ubuf, usize); | ||
| 161 | if (rc) { | ||
| 162 | rc = -EFAULT; | ||
| 163 | goto out; | ||
| 164 | } | ||
| 165 | rcd = erst_dbg_buf; | ||
| 166 | rc = -EINVAL; | ||
| 167 | if (rcd->record_length != usize) | ||
| 168 | goto out; | ||
| 169 | |||
| 170 | rc = erst_write(erst_dbg_buf); | ||
| 171 | |||
| 172 | out: | ||
| 173 | mutex_unlock(&erst_dbg_mutex); | ||
| 174 | return rc < 0 ? rc : usize; | ||
| 175 | } | ||
| 176 | |||
| 177 | static const struct file_operations erst_dbg_ops = { | ||
| 178 | .owner = THIS_MODULE, | ||
| 179 | .open = erst_dbg_open, | ||
| 180 | .read = erst_dbg_read, | ||
| 181 | .write = erst_dbg_write, | ||
| 182 | .unlocked_ioctl = erst_dbg_ioctl, | ||
| 183 | }; | ||
| 184 | |||
| 185 | static struct miscdevice erst_dbg_dev = { | ||
| 186 | .minor = MISC_DYNAMIC_MINOR, | ||
| 187 | .name = "erst_dbg", | ||
| 188 | .fops = &erst_dbg_ops, | ||
| 189 | }; | ||
| 190 | |||
| 191 | static __init int erst_dbg_init(void) | ||
| 192 | { | ||
| 193 | return misc_register(&erst_dbg_dev); | ||
| 194 | } | ||
| 195 | |||
| 196 | static __exit void erst_dbg_exit(void) | ||
| 197 | { | ||
| 198 | misc_deregister(&erst_dbg_dev); | ||
| 199 | kfree(erst_dbg_buf); | ||
| 200 | } | ||
| 201 | |||
| 202 | module_init(erst_dbg_init); | ||
| 203 | module_exit(erst_dbg_exit); | ||
| 204 | |||
| 205 | MODULE_AUTHOR("Huang Ying"); | ||
| 206 | MODULE_DESCRIPTION("APEI Error Record Serialization Table debug support"); | ||
| 207 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index fd0cc016a099..385a6059714a 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
| @@ -41,6 +41,8 @@ | |||
| 41 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
| 42 | #include <linux/cper.h> | 42 | #include <linux/cper.h> |
| 43 | #include <linux/kdebug.h> | 43 | #include <linux/kdebug.h> |
| 44 | #include <linux/platform_device.h> | ||
| 45 | #include <linux/mutex.h> | ||
| 44 | #include <acpi/apei.h> | 46 | #include <acpi/apei.h> |
| 45 | #include <acpi/atomicio.h> | 47 | #include <acpi/atomicio.h> |
| 46 | #include <acpi/hed.h> | 48 | #include <acpi/hed.h> |
| @@ -87,6 +89,7 @@ struct ghes { | |||
| 87 | * used for that. | 89 | * used for that. |
| 88 | */ | 90 | */ |
| 89 | static LIST_HEAD(ghes_sci); | 91 | static LIST_HEAD(ghes_sci); |
| 92 | static DEFINE_MUTEX(ghes_list_mutex); | ||
| 90 | 93 | ||
| 91 | static struct ghes *ghes_new(struct acpi_hest_generic *generic) | 94 | static struct ghes *ghes_new(struct acpi_hest_generic *generic) |
| 92 | { | 95 | { |
| @@ -132,26 +135,26 @@ static void ghes_fini(struct ghes *ghes) | |||
| 132 | } | 135 | } |
| 133 | 136 | ||
| 134 | enum { | 137 | enum { |
| 135 | GHES_SER_NO = 0x0, | 138 | GHES_SEV_NO = 0x0, |
| 136 | GHES_SER_CORRECTED = 0x1, | 139 | GHES_SEV_CORRECTED = 0x1, |
| 137 | GHES_SER_RECOVERABLE = 0x2, | 140 | GHES_SEV_RECOVERABLE = 0x2, |
| 138 | GHES_SER_PANIC = 0x3, | 141 | GHES_SEV_PANIC = 0x3, |
| 139 | }; | 142 | }; |
| 140 | 143 | ||
| 141 | static inline int ghes_severity(int severity) | 144 | static inline int ghes_severity(int severity) |
| 142 | { | 145 | { |
| 143 | switch (severity) { | 146 | switch (severity) { |
| 144 | case CPER_SER_INFORMATIONAL: | 147 | case CPER_SEV_INFORMATIONAL: |
| 145 | return GHES_SER_NO; | 148 | return GHES_SEV_NO; |
| 146 | case CPER_SER_CORRECTED: | 149 | case CPER_SEV_CORRECTED: |
| 147 | return GHES_SER_CORRECTED; | 150 | return GHES_SEV_CORRECTED; |
| 148 | case CPER_SER_RECOVERABLE: | 151 | case CPER_SEV_RECOVERABLE: |
| 149 | return GHES_SER_RECOVERABLE; | 152 | return GHES_SEV_RECOVERABLE; |
| 150 | case CPER_SER_FATAL: | 153 | case CPER_SEV_FATAL: |
| 151 | return GHES_SER_PANIC; | 154 | return GHES_SEV_PANIC; |
| 152 | default: | 155 | default: |
| 153 | /* Unkown, go panic */ | 156 | /* Unkown, go panic */ |
| 154 | return GHES_SER_PANIC; | 157 | return GHES_SEV_PANIC; |
| 155 | } | 158 | } |
| 156 | } | 159 | } |
| 157 | 160 | ||
| @@ -237,16 +240,16 @@ static void ghes_clear_estatus(struct ghes *ghes) | |||
| 237 | 240 | ||
| 238 | static void ghes_do_proc(struct ghes *ghes) | 241 | static void ghes_do_proc(struct ghes *ghes) |
| 239 | { | 242 | { |
| 240 | int ser, processed = 0; | 243 | int sev, processed = 0; |
| 241 | struct acpi_hest_generic_data *gdata; | 244 | struct acpi_hest_generic_data *gdata; |
| 242 | 245 | ||
| 243 | ser = ghes_severity(ghes->estatus->error_severity); | 246 | sev = ghes_severity(ghes->estatus->error_severity); |
| 244 | apei_estatus_for_each_section(ghes->estatus, gdata) { | 247 | apei_estatus_for_each_section(ghes->estatus, gdata) { |
| 245 | #ifdef CONFIG_X86_MCE | 248 | #ifdef CONFIG_X86_MCE |
| 246 | if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, | 249 | if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, |
| 247 | CPER_SEC_PLATFORM_MEM)) { | 250 | CPER_SEC_PLATFORM_MEM)) { |
| 248 | apei_mce_report_mem_error( | 251 | apei_mce_report_mem_error( |
| 249 | ser == GHES_SER_CORRECTED, | 252 | sev == GHES_SEV_CORRECTED, |
| 250 | (struct cper_sec_mem_err *)(gdata+1)); | 253 | (struct cper_sec_mem_err *)(gdata+1)); |
| 251 | processed = 1; | 254 | processed = 1; |
| 252 | } | 255 | } |
| @@ -293,18 +296,15 @@ static struct notifier_block ghes_notifier_sci = { | |||
| 293 | .notifier_call = ghes_notify_sci, | 296 | .notifier_call = ghes_notify_sci, |
| 294 | }; | 297 | }; |
| 295 | 298 | ||
| 296 | static int hest_ghes_parse(struct acpi_hest_header *hest_hdr, void *data) | 299 | static int __devinit ghes_probe(struct platform_device *ghes_dev) |
| 297 | { | 300 | { |
| 298 | struct acpi_hest_generic *generic; | 301 | struct acpi_hest_generic *generic; |
| 299 | struct ghes *ghes = NULL; | 302 | struct ghes *ghes = NULL; |
| 300 | int rc = 0; | 303 | int rc = -EINVAL; |
| 301 | 304 | ||
| 302 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) | 305 | generic = ghes_dev->dev.platform_data; |
| 303 | return 0; | ||
| 304 | |||
| 305 | generic = (struct acpi_hest_generic *)hest_hdr; | ||
| 306 | if (!generic->enabled) | 306 | if (!generic->enabled) |
| 307 | return 0; | 307 | return -ENODEV; |
| 308 | 308 | ||
| 309 | if (generic->error_block_length < | 309 | if (generic->error_block_length < |
| 310 | sizeof(struct acpi_hest_generic_status)) { | 310 | sizeof(struct acpi_hest_generic_status)) { |
| @@ -327,62 +327,91 @@ static int hest_ghes_parse(struct acpi_hest_header *hest_hdr, void *data) | |||
| 327 | ghes = NULL; | 327 | ghes = NULL; |
| 328 | goto err; | 328 | goto err; |
| 329 | } | 329 | } |
| 330 | switch (generic->notify.type) { | 330 | if (generic->notify.type == ACPI_HEST_NOTIFY_SCI) { |
| 331 | case ACPI_HEST_NOTIFY_POLLED: | 331 | mutex_lock(&ghes_list_mutex); |
| 332 | pr_warning(GHES_PFX | ||
| 333 | "Generic hardware error source: %d notified via POLL is not supported!\n", | ||
| 334 | generic->header.source_id); | ||
| 335 | break; | ||
| 336 | case ACPI_HEST_NOTIFY_EXTERNAL: | ||
| 337 | case ACPI_HEST_NOTIFY_LOCAL: | ||
| 338 | pr_warning(GHES_PFX | ||
| 339 | "Generic hardware error source: %d notified via IRQ is not supported!\n", | ||
| 340 | generic->header.source_id); | ||
| 341 | break; | ||
| 342 | case ACPI_HEST_NOTIFY_SCI: | ||
| 343 | if (list_empty(&ghes_sci)) | 332 | if (list_empty(&ghes_sci)) |
| 344 | register_acpi_hed_notifier(&ghes_notifier_sci); | 333 | register_acpi_hed_notifier(&ghes_notifier_sci); |
| 345 | list_add_rcu(&ghes->list, &ghes_sci); | 334 | list_add_rcu(&ghes->list, &ghes_sci); |
| 346 | break; | 335 | mutex_unlock(&ghes_list_mutex); |
| 347 | case ACPI_HEST_NOTIFY_NMI: | 336 | } else { |
| 348 | pr_warning(GHES_PFX | 337 | unsigned char *notify = NULL; |
| 349 | "Generic hardware error source: %d notified via NMI is not supported!\n", | 338 | |
| 350 | generic->header.source_id); | 339 | switch (generic->notify.type) { |
| 351 | break; | 340 | case ACPI_HEST_NOTIFY_POLLED: |
| 352 | default: | 341 | notify = "POLL"; |
| 353 | pr_warning(FW_WARN GHES_PFX | 342 | break; |
| 354 | "Unknown notification type: %u for generic hardware error source: %d\n", | 343 | case ACPI_HEST_NOTIFY_EXTERNAL: |
| 355 | generic->notify.type, generic->header.source_id); | 344 | case ACPI_HEST_NOTIFY_LOCAL: |
| 356 | break; | 345 | notify = "IRQ"; |
| 346 | break; | ||
| 347 | case ACPI_HEST_NOTIFY_NMI: | ||
| 348 | notify = "NMI"; | ||
| 349 | break; | ||
| 350 | } | ||
| 351 | if (notify) { | ||
| 352 | pr_warning(GHES_PFX | ||
| 353 | "Generic hardware error source: %d notified via %s is not supported!\n", | ||
| 354 | generic->header.source_id, notify); | ||
| 355 | } else { | ||
| 356 | pr_warning(FW_WARN GHES_PFX | ||
| 357 | "Unknown notification type: %u for generic hardware error source: %d\n", | ||
| 358 | generic->notify.type, generic->header.source_id); | ||
| 359 | } | ||
| 360 | rc = -ENODEV; | ||
| 361 | goto err; | ||
| 357 | } | 362 | } |
| 363 | platform_set_drvdata(ghes_dev, ghes); | ||
| 358 | 364 | ||
| 359 | return 0; | 365 | return 0; |
| 360 | err: | 366 | err: |
| 361 | if (ghes) | 367 | if (ghes) { |
| 362 | ghes_fini(ghes); | 368 | ghes_fini(ghes); |
| 369 | kfree(ghes); | ||
| 370 | } | ||
| 363 | return rc; | 371 | return rc; |
| 364 | } | 372 | } |
| 365 | 373 | ||
| 366 | static void ghes_cleanup(void) | 374 | static int __devexit ghes_remove(struct platform_device *ghes_dev) |
| 367 | { | 375 | { |
| 368 | struct ghes *ghes, *nghes; | 376 | struct ghes *ghes; |
| 377 | struct acpi_hest_generic *generic; | ||
| 369 | 378 | ||
| 370 | if (!list_empty(&ghes_sci)) | 379 | ghes = platform_get_drvdata(ghes_dev); |
| 371 | unregister_acpi_hed_notifier(&ghes_notifier_sci); | 380 | generic = ghes->generic; |
| 381 | |||
| 382 | switch (generic->notify.type) { | ||
| 383 | case ACPI_HEST_NOTIFY_SCI: | ||
| 384 | mutex_lock(&ghes_list_mutex); | ||
| 385 | list_del_rcu(&ghes->list); | ||
| 386 | if (list_empty(&ghes_sci)) | ||
| 387 | unregister_acpi_hed_notifier(&ghes_notifier_sci); | ||
| 388 | mutex_unlock(&ghes_list_mutex); | ||
| 389 | break; | ||
| 390 | default: | ||
| 391 | BUG(); | ||
| 392 | break; | ||
| 393 | } | ||
| 372 | 394 | ||
| 373 | synchronize_rcu(); | 395 | synchronize_rcu(); |
| 396 | ghes_fini(ghes); | ||
| 397 | kfree(ghes); | ||
| 374 | 398 | ||
| 375 | list_for_each_entry_safe(ghes, nghes, &ghes_sci, list) { | 399 | platform_set_drvdata(ghes_dev, NULL); |
| 376 | list_del(&ghes->list); | 400 | |
| 377 | ghes_fini(ghes); | 401 | return 0; |
| 378 | kfree(ghes); | ||
| 379 | } | ||
| 380 | } | 402 | } |
| 381 | 403 | ||
| 404 | static struct platform_driver ghes_platform_driver = { | ||
| 405 | .driver = { | ||
| 406 | .name = "GHES", | ||
| 407 | .owner = THIS_MODULE, | ||
| 408 | }, | ||
| 409 | .probe = ghes_probe, | ||
| 410 | .remove = ghes_remove, | ||
| 411 | }; | ||
| 412 | |||
| 382 | static int __init ghes_init(void) | 413 | static int __init ghes_init(void) |
| 383 | { | 414 | { |
| 384 | int rc; | ||
| 385 | |||
| 386 | if (acpi_disabled) | 415 | if (acpi_disabled) |
| 387 | return -ENODEV; | 416 | return -ENODEV; |
| 388 | 417 | ||
| @@ -391,32 +420,12 @@ static int __init ghes_init(void) | |||
| 391 | return -EINVAL; | 420 | return -EINVAL; |
| 392 | } | 421 | } |
| 393 | 422 | ||
| 394 | rc = apei_hest_parse(hest_ghes_parse, NULL); | 423 | return platform_driver_register(&ghes_platform_driver); |
| 395 | if (rc) { | ||
| 396 | pr_err(GHES_PFX | ||
| 397 | "Error during parsing HEST generic hardware error sources.\n"); | ||
| 398 | goto err_cleanup; | ||
| 399 | } | ||
| 400 | |||
| 401 | if (list_empty(&ghes_sci)) { | ||
| 402 | pr_info(GHES_PFX | ||
| 403 | "No functional generic hardware error sources.\n"); | ||
| 404 | rc = -ENODEV; | ||
| 405 | goto err_cleanup; | ||
| 406 | } | ||
| 407 | |||
| 408 | pr_info(GHES_PFX | ||
| 409 | "Generic Hardware Error Source support is initialized.\n"); | ||
| 410 | |||
| 411 | return 0; | ||
| 412 | err_cleanup: | ||
| 413 | ghes_cleanup(); | ||
| 414 | return rc; | ||
| 415 | } | 424 | } |
| 416 | 425 | ||
| 417 | static void __exit ghes_exit(void) | 426 | static void __exit ghes_exit(void) |
| 418 | { | 427 | { |
| 419 | ghes_cleanup(); | 428 | platform_driver_unregister(&ghes_platform_driver); |
| 420 | } | 429 | } |
| 421 | 430 | ||
| 422 | module_init(ghes_init); | 431 | module_init(ghes_init); |
| @@ -425,3 +434,4 @@ module_exit(ghes_exit); | |||
| 425 | MODULE_AUTHOR("Huang Ying"); | 434 | MODULE_AUTHOR("Huang Ying"); |
| 426 | MODULE_DESCRIPTION("APEI Generic Hardware Error Source support"); | 435 | MODULE_DESCRIPTION("APEI Generic Hardware Error Source support"); |
| 427 | MODULE_LICENSE("GPL"); | 436 | MODULE_LICENSE("GPL"); |
| 437 | MODULE_ALIAS("platform:GHES"); | ||
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index e7f40d362cb3..343168d18266 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/kdebug.h> | 34 | #include <linux/kdebug.h> |
| 35 | #include <linux/highmem.h> | 35 | #include <linux/highmem.h> |
| 36 | #include <linux/io.h> | 36 | #include <linux/io.h> |
| 37 | #include <linux/platform_device.h> | ||
| 37 | #include <acpi/apei.h> | 38 | #include <acpi/apei.h> |
| 38 | 39 | ||
| 39 | #include "apei-internal.h" | 40 | #include "apei-internal.h" |
| @@ -47,11 +48,6 @@ EXPORT_SYMBOL_GPL(hest_disable); | |||
| 47 | 48 | ||
| 48 | static struct acpi_table_hest *hest_tab; | 49 | static struct acpi_table_hest *hest_tab; |
| 49 | 50 | ||
| 50 | static int hest_void_parse(struct acpi_hest_header *hest_hdr, void *data) | ||
| 51 | { | ||
| 52 | return 0; | ||
| 53 | } | ||
| 54 | |||
| 55 | static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { | 51 | static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { |
| 56 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ | 52 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ |
| 57 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, | 53 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, |
| @@ -125,6 +121,69 @@ int apei_hest_parse(apei_hest_func_t func, void *data) | |||
| 125 | } | 121 | } |
| 126 | EXPORT_SYMBOL_GPL(apei_hest_parse); | 122 | EXPORT_SYMBOL_GPL(apei_hest_parse); |
| 127 | 123 | ||
| 124 | struct ghes_arr { | ||
| 125 | struct platform_device **ghes_devs; | ||
| 126 | unsigned int count; | ||
| 127 | }; | ||
| 128 | |||
| 129 | static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | ||
| 130 | { | ||
| 131 | int *count = data; | ||
| 132 | |||
| 133 | if (hest_hdr->type == ACPI_HEST_TYPE_GENERIC_ERROR) | ||
| 134 | (*count)++; | ||
| 135 | return 0; | ||
| 136 | } | ||
| 137 | |||
| 138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) | ||
| 139 | { | ||
| 140 | struct acpi_hest_generic *generic; | ||
| 141 | struct platform_device *ghes_dev; | ||
| 142 | struct ghes_arr *ghes_arr = data; | ||
| 143 | int rc; | ||
| 144 | |||
| 145 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) | ||
| 146 | return 0; | ||
| 147 | generic = (struct acpi_hest_generic *)hest_hdr; | ||
| 148 | if (!generic->enabled) | ||
| 149 | return 0; | ||
| 150 | ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); | ||
| 151 | if (!ghes_dev) | ||
| 152 | return -ENOMEM; | ||
| 153 | ghes_dev->dev.platform_data = generic; | ||
| 154 | rc = platform_device_add(ghes_dev); | ||
| 155 | if (rc) | ||
| 156 | goto err; | ||
| 157 | ghes_arr->ghes_devs[ghes_arr->count++] = ghes_dev; | ||
| 158 | |||
| 159 | return 0; | ||
| 160 | err: | ||
| 161 | platform_device_put(ghes_dev); | ||
| 162 | return rc; | ||
| 163 | } | ||
| 164 | |||
| 165 | static int hest_ghes_dev_register(unsigned int ghes_count) | ||
| 166 | { | ||
| 167 | int rc, i; | ||
| 168 | struct ghes_arr ghes_arr; | ||
| 169 | |||
| 170 | ghes_arr.count = 0; | ||
| 171 | ghes_arr.ghes_devs = kmalloc(sizeof(void *) * ghes_count, GFP_KERNEL); | ||
| 172 | if (!ghes_arr.ghes_devs) | ||
| 173 | return -ENOMEM; | ||
| 174 | |||
| 175 | rc = apei_hest_parse(hest_parse_ghes, &ghes_arr); | ||
| 176 | if (rc) | ||
| 177 | goto err; | ||
| 178 | out: | ||
| 179 | kfree(ghes_arr.ghes_devs); | ||
| 180 | return rc; | ||
| 181 | err: | ||
| 182 | for (i = 0; i < ghes_arr.count; i++) | ||
| 183 | platform_device_unregister(ghes_arr.ghes_devs[i]); | ||
| 184 | goto out; | ||
| 185 | } | ||
| 186 | |||
| 128 | static int __init setup_hest_disable(char *str) | 187 | static int __init setup_hest_disable(char *str) |
| 129 | { | 188 | { |
| 130 | hest_disable = 1; | 189 | hest_disable = 1; |
| @@ -137,6 +196,7 @@ static int __init hest_init(void) | |||
| 137 | { | 196 | { |
| 138 | acpi_status status; | 197 | acpi_status status; |
| 139 | int rc = -ENODEV; | 198 | int rc = -ENODEV; |
| 199 | unsigned int ghes_count = 0; | ||
| 140 | 200 | ||
| 141 | if (acpi_disabled) | 201 | if (acpi_disabled) |
| 142 | goto err; | 202 | goto err; |
| @@ -158,7 +218,11 @@ static int __init hest_init(void) | |||
| 158 | goto err; | 218 | goto err; |
| 159 | } | 219 | } |
| 160 | 220 | ||
| 161 | rc = apei_hest_parse(hest_void_parse, NULL); | 221 | rc = apei_hest_parse(hest_parse_ghes_count, &ghes_count); |
| 222 | if (rc) | ||
| 223 | goto err; | ||
| 224 | |||
| 225 | rc = hest_ghes_dev_register(ghes_count); | ||
| 162 | if (rc) | 226 | if (rc) |
| 163 | goto err; | 227 | goto err; |
| 164 | 228 | ||
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index c1d23cd71652..5c221ab535d5 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
| @@ -1034,8 +1034,8 @@ static int __init acpi_init(void) | |||
| 1034 | acpi_scan_init(); | 1034 | acpi_scan_init(); |
| 1035 | acpi_ec_init(); | 1035 | acpi_ec_init(); |
| 1036 | acpi_power_init(); | 1036 | acpi_power_init(); |
| 1037 | acpi_system_init(); | 1037 | acpi_sysfs_init(); |
| 1038 | acpi_debug_init(); | 1038 | acpi_debugfs_init(); |
| 1039 | acpi_sleep_proc_init(); | 1039 | acpi_sleep_proc_init(); |
| 1040 | acpi_wakeup_device_init(); | 1040 | acpi_wakeup_device_init(); |
| 1041 | return result; | 1041 | return result; |
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c deleted file mode 100644 index 295dbfa2db9c..000000000000 --- a/drivers/acpi/debug.c +++ /dev/null | |||
| @@ -1,422 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * debug.c - ACPI debug interface to userspace. | ||
| 3 | */ | ||
| 4 | |||
| 5 | #include <linux/proc_fs.h> | ||
| 6 | #include <linux/seq_file.h> | ||
| 7 | #include <linux/init.h> | ||
| 8 | #include <linux/module.h> | ||
| 9 | #include <linux/kernel.h> | ||
| 10 | #include <linux/moduleparam.h> | ||
| 11 | #include <linux/debugfs.h> | ||
| 12 | #include <linux/slab.h> | ||
| 13 | #include <asm/uaccess.h> | ||
| 14 | #include <acpi/acpi_drivers.h> | ||
| 15 | |||
| 16 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | ||
| 17 | ACPI_MODULE_NAME("debug"); | ||
| 18 | |||
| 19 | struct acpi_dlayer { | ||
| 20 | const char *name; | ||
| 21 | unsigned long value; | ||
| 22 | }; | ||
| 23 | struct acpi_dlevel { | ||
| 24 | const char *name; | ||
| 25 | unsigned long value; | ||
| 26 | }; | ||
| 27 | #define ACPI_DEBUG_INIT(v) { .name = #v, .value = v } | ||
| 28 | |||
| 29 | static const struct acpi_dlayer acpi_debug_layers[] = { | ||
| 30 | ACPI_DEBUG_INIT(ACPI_UTILITIES), | ||
| 31 | ACPI_DEBUG_INIT(ACPI_HARDWARE), | ||
| 32 | ACPI_DEBUG_INIT(ACPI_EVENTS), | ||
| 33 | ACPI_DEBUG_INIT(ACPI_TABLES), | ||
| 34 | ACPI_DEBUG_INIT(ACPI_NAMESPACE), | ||
| 35 | ACPI_DEBUG_INIT(ACPI_PARSER), | ||
| 36 | ACPI_DEBUG_INIT(ACPI_DISPATCHER), | ||
| 37 | ACPI_DEBUG_INIT(ACPI_EXECUTER), | ||
| 38 | ACPI_DEBUG_INIT(ACPI_RESOURCES), | ||
| 39 | ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER), | ||
| 40 | ACPI_DEBUG_INIT(ACPI_OS_SERVICES), | ||
| 41 | ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER), | ||
| 42 | ACPI_DEBUG_INIT(ACPI_COMPILER), | ||
| 43 | ACPI_DEBUG_INIT(ACPI_TOOLS), | ||
| 44 | |||
| 45 | ACPI_DEBUG_INIT(ACPI_BUS_COMPONENT), | ||
| 46 | ACPI_DEBUG_INIT(ACPI_AC_COMPONENT), | ||
| 47 | ACPI_DEBUG_INIT(ACPI_BATTERY_COMPONENT), | ||
| 48 | ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT), | ||
| 49 | ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT), | ||
| 50 | ACPI_DEBUG_INIT(ACPI_FAN_COMPONENT), | ||
| 51 | ACPI_DEBUG_INIT(ACPI_PCI_COMPONENT), | ||
| 52 | ACPI_DEBUG_INIT(ACPI_POWER_COMPONENT), | ||
| 53 | ACPI_DEBUG_INIT(ACPI_CONTAINER_COMPONENT), | ||
| 54 | ACPI_DEBUG_INIT(ACPI_SYSTEM_COMPONENT), | ||
| 55 | ACPI_DEBUG_INIT(ACPI_THERMAL_COMPONENT), | ||
| 56 | ACPI_DEBUG_INIT(ACPI_MEMORY_DEVICE_COMPONENT), | ||
| 57 | ACPI_DEBUG_INIT(ACPI_VIDEO_COMPONENT), | ||
| 58 | ACPI_DEBUG_INIT(ACPI_PROCESSOR_COMPONENT), | ||
| 59 | }; | ||
| 60 | |||
| 61 | static const struct acpi_dlevel acpi_debug_levels[] = { | ||
| 62 | ACPI_DEBUG_INIT(ACPI_LV_INIT), | ||
| 63 | ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT), | ||
| 64 | ACPI_DEBUG_INIT(ACPI_LV_INFO), | ||
| 65 | |||
| 66 | ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES), | ||
| 67 | ACPI_DEBUG_INIT(ACPI_LV_PARSE), | ||
| 68 | ACPI_DEBUG_INIT(ACPI_LV_LOAD), | ||
| 69 | ACPI_DEBUG_INIT(ACPI_LV_DISPATCH), | ||
| 70 | ACPI_DEBUG_INIT(ACPI_LV_EXEC), | ||
| 71 | ACPI_DEBUG_INIT(ACPI_LV_NAMES), | ||
| 72 | ACPI_DEBUG_INIT(ACPI_LV_OPREGION), | ||
| 73 | ACPI_DEBUG_INIT(ACPI_LV_BFIELD), | ||
| 74 | ACPI_DEBUG_INIT(ACPI_LV_TABLES), | ||
| 75 | ACPI_DEBUG_INIT(ACPI_LV_VALUES), | ||
| 76 | ACPI_DEBUG_INIT(ACPI_LV_OBJECTS), | ||
| 77 | ACPI_DEBUG_INIT(ACPI_LV_RESOURCES), | ||
| 78 | ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS), | ||
| 79 | ACPI_DEBUG_INIT(ACPI_LV_PACKAGE), | ||
| 80 | |||
| 81 | ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS), | ||
| 82 | ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS), | ||
| 83 | ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS), | ||
| 84 | |||
| 85 | ACPI_DEBUG_INIT(ACPI_LV_MUTEX), | ||
| 86 | ACPI_DEBUG_INIT(ACPI_LV_THREADS), | ||
| 87 | ACPI_DEBUG_INIT(ACPI_LV_IO), | ||
| 88 | ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS), | ||
| 89 | |||
| 90 | ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE), | ||
| 91 | ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO), | ||
| 92 | ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES), | ||
| 93 | ACPI_DEBUG_INIT(ACPI_LV_EVENTS), | ||
| 94 | }; | ||
| 95 | |||
| 96 | /* -------------------------------------------------------------------------- | ||
| 97 | FS Interface (/sys) | ||
| 98 | -------------------------------------------------------------------------- */ | ||
| 99 | static int param_get_debug_layer(char *buffer, const struct kernel_param *kp) | ||
| 100 | { | ||
| 101 | int result = 0; | ||
| 102 | int i; | ||
| 103 | |||
| 104 | result = sprintf(buffer, "%-25s\tHex SET\n", "Description"); | ||
| 105 | |||
| 106 | for(i = 0; i <ARRAY_SIZE(acpi_debug_layers); i++) { | ||
| 107 | result += sprintf(buffer+result, "%-25s\t0x%08lX [%c]\n", | ||
| 108 | acpi_debug_layers[i].name, | ||
| 109 | acpi_debug_layers[i].value, | ||
| 110 | (acpi_dbg_layer & acpi_debug_layers[i].value) ? '*' : ' '); | ||
| 111 | } | ||
| 112 | result += sprintf(buffer+result, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", | ||
| 113 | ACPI_ALL_DRIVERS, | ||
| 114 | (acpi_dbg_layer & ACPI_ALL_DRIVERS) == | ||
| 115 | ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & | ||
| 116 | ACPI_ALL_DRIVERS) == 0 ? ' ' : '-'); | ||
| 117 | result += sprintf(buffer+result, "--\ndebug_layer = 0x%08X ( * = enabled)\n", acpi_dbg_layer); | ||
| 118 | |||
| 119 | return result; | ||
| 120 | } | ||
| 121 | |||
| 122 | static int param_get_debug_level(char *buffer, const struct kernel_param *kp) | ||
| 123 | { | ||
| 124 | int result = 0; | ||
| 125 | int i; | ||
| 126 | |||
| 127 | result = sprintf(buffer, "%-25s\tHex SET\n", "Description"); | ||
| 128 | |||
| 129 | for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { | ||
| 130 | result += sprintf(buffer+result, "%-25s\t0x%08lX [%c]\n", | ||
| 131 | acpi_debug_levels[i].name, | ||
| 132 | acpi_debug_levels[i].value, | ||
| 133 | (acpi_dbg_level & acpi_debug_levels[i]. | ||
| 134 | value) ? '*' : ' '); | ||
| 135 | } | ||
| 136 | result += sprintf(buffer+result, "--\ndebug_level = 0x%08X (* = enabled)\n", | ||
| 137 | acpi_dbg_level); | ||
| 138 | |||
| 139 | return result; | ||
| 140 | } | ||
| 141 | |||
| 142 | static struct kernel_param_ops acpi_debug_layer_ops = { | ||
| 143 | .set = param_set_uint, | ||
| 144 | .get = param_get_debug_layer, | ||
| 145 | }; | ||
| 146 | |||
| 147 | static struct kernel_param_ops acpi_debug_level_ops = { | ||
| 148 | .set = param_set_uint, | ||
| 149 | .get = param_get_debug_level, | ||
| 150 | }; | ||
| 151 | |||
| 152 | module_param_cb(debug_layer, &acpi_debug_layer_ops, &acpi_dbg_layer, 0644); | ||
| 153 | module_param_cb(debug_level, &acpi_debug_level_ops, &acpi_dbg_level, 0644); | ||
| 154 | |||
| 155 | static char trace_method_name[6]; | ||
| 156 | module_param_string(trace_method_name, trace_method_name, 6, 0644); | ||
| 157 | static unsigned int trace_debug_layer; | ||
| 158 | module_param(trace_debug_layer, uint, 0644); | ||
| 159 | static unsigned int trace_debug_level; | ||
| 160 | module_param(trace_debug_level, uint, 0644); | ||
| 161 | |||
| 162 | static int param_set_trace_state(const char *val, const struct kernel_param *kp) | ||
| 163 | { | ||
| 164 | int result = 0; | ||
| 165 | |||
| 166 | if (!strncmp(val, "enable", strlen("enable") - 1)) { | ||
| 167 | result = acpi_debug_trace(trace_method_name, trace_debug_level, | ||
| 168 | trace_debug_layer, 0); | ||
| 169 | if (result) | ||
| 170 | result = -EBUSY; | ||
| 171 | goto exit; | ||
| 172 | } | ||
| 173 | |||
| 174 | if (!strncmp(val, "disable", strlen("disable") - 1)) { | ||
| 175 | int name = 0; | ||
| 176 | result = acpi_debug_trace((char *)&name, trace_debug_level, | ||
| 177 | trace_debug_layer, 0); | ||
| 178 | if (result) | ||
| 179 | result = -EBUSY; | ||
| 180 | goto exit; | ||
| 181 | } | ||
| 182 | |||
| 183 | if (!strncmp(val, "1", 1)) { | ||
| 184 | result = acpi_debug_trace(trace_method_name, trace_debug_level, | ||
| 185 | trace_debug_layer, 1); | ||
| 186 | if (result) | ||
| 187 | result = -EBUSY; | ||
| 188 | goto exit; | ||
| 189 | } | ||
| 190 | |||
| 191 | result = -EINVAL; | ||
| 192 | exit: | ||
| 193 | return result; | ||
| 194 | } | ||
| 195 | |||
| 196 | static int param_get_trace_state(char *buffer, const struct kernel_param *kp) | ||
| 197 | { | ||
| 198 | if (!acpi_gbl_trace_method_name) | ||
| 199 | return sprintf(buffer, "disable"); | ||
| 200 | else { | ||
| 201 | if (acpi_gbl_trace_flags & 1) | ||
| 202 | return sprintf(buffer, "1"); | ||
| 203 | else | ||
| 204 | return sprintf(buffer, "enable"); | ||
| 205 | } | ||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | static struct kernel_param_ops param_ops_trace_state = { | ||
| 210 | .set = param_set_trace_state, | ||
| 211 | .get = param_get_trace_state, | ||
| 212 | }; | ||
| 213 | |||
| 214 | module_param_cb(trace_state, ¶m_ops_trace_state, NULL, 0644); | ||
| 215 | |||
| 216 | /* -------------------------------------------------------------------------- | ||
| 217 | DebugFS Interface | ||
| 218 | -------------------------------------------------------------------------- */ | ||
| 219 | |||
| 220 | static ssize_t cm_write(struct file *file, const char __user *user_buf, | ||
| 221 | size_t count, loff_t *ppos) | ||
| 222 | { | ||
| 223 | static char *buf; | ||
| 224 | static int uncopied_bytes; | ||
| 225 | struct acpi_table_header table; | ||
| 226 | acpi_status status; | ||
| 227 | |||
| 228 | if (!(*ppos)) { | ||
| 229 | /* parse the table header to get the table length */ | ||
| 230 | if (count <= sizeof(struct acpi_table_header)) | ||
| 231 | return -EINVAL; | ||
| 232 | if (copy_from_user(&table, user_buf, | ||
| 233 | sizeof(struct acpi_table_header))) | ||
| 234 | return -EFAULT; | ||
| 235 | uncopied_bytes = table.length; | ||
| 236 | buf = kzalloc(uncopied_bytes, GFP_KERNEL); | ||
| 237 | if (!buf) | ||
| 238 | return -ENOMEM; | ||
| 239 | } | ||
| 240 | |||
| 241 | if (uncopied_bytes < count) { | ||
| 242 | kfree(buf); | ||
| 243 | return -EINVAL; | ||
| 244 | } | ||
| 245 | |||
| 246 | if (copy_from_user(buf + (*ppos), user_buf, count)) { | ||
| 247 | kfree(buf); | ||
| 248 | return -EFAULT; | ||
| 249 | } | ||
| 250 | |||
| 251 | uncopied_bytes -= count; | ||
| 252 | *ppos += count; | ||
| 253 | |||
| 254 | if (!uncopied_bytes) { | ||
| 255 | status = acpi_install_method(buf); | ||
| 256 | kfree(buf); | ||
| 257 | if (ACPI_FAILURE(status)) | ||
| 258 | return -EINVAL; | ||
| 259 | add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); | ||
| 260 | } | ||
| 261 | |||
| 262 | return count; | ||
| 263 | } | ||
| 264 | |||
| 265 | static const struct file_operations cm_fops = { | ||
| 266 | .write = cm_write, | ||
| 267 | }; | ||
| 268 | |||
| 269 | static int acpi_debugfs_init(void) | ||
| 270 | { | ||
| 271 | struct dentry *acpi_dir, *cm_dentry; | ||
| 272 | |||
| 273 | acpi_dir = debugfs_create_dir("acpi", NULL); | ||
| 274 | if (!acpi_dir) | ||
| 275 | goto err; | ||
| 276 | |||
| 277 | cm_dentry = debugfs_create_file("custom_method", S_IWUGO, | ||
| 278 | acpi_dir, NULL, &cm_fops); | ||
| 279 | if (!cm_dentry) | ||
| 280 | goto err; | ||
| 281 | |||
| 282 | return 0; | ||
| 283 | |||
| 284 | err: | ||
| 285 | if (acpi_dir) | ||
| 286 | debugfs_remove(acpi_dir); | ||
| 287 | return -EINVAL; | ||
| 288 | } | ||
| 289 | |||
| 290 | /* -------------------------------------------------------------------------- | ||
| 291 | FS Interface (/proc) | ||
| 292 | -------------------------------------------------------------------------- */ | ||
| 293 | #ifdef CONFIG_ACPI_PROCFS | ||
| 294 | #define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer" | ||
| 295 | #define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level" | ||
| 296 | |||
| 297 | static int acpi_system_debug_proc_show(struct seq_file *m, void *v) | ||
| 298 | { | ||
| 299 | unsigned int i; | ||
| 300 | |||
| 301 | seq_printf(m, "%-25s\tHex SET\n", "Description"); | ||
| 302 | |||
| 303 | switch ((unsigned long)m->private) { | ||
| 304 | case 0: | ||
| 305 | for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) { | ||
| 306 | seq_printf(m, "%-25s\t0x%08lX [%c]\n", | ||
| 307 | acpi_debug_layers[i].name, | ||
| 308 | acpi_debug_layers[i].value, | ||
| 309 | (acpi_dbg_layer & acpi_debug_layers[i]. | ||
| 310 | value) ? '*' : ' '); | ||
| 311 | } | ||
| 312 | seq_printf(m, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", | ||
| 313 | ACPI_ALL_DRIVERS, | ||
| 314 | (acpi_dbg_layer & ACPI_ALL_DRIVERS) == | ||
| 315 | ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & | ||
| 316 | ACPI_ALL_DRIVERS) == | ||
| 317 | 0 ? ' ' : '-'); | ||
| 318 | seq_printf(m, | ||
| 319 | "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n", | ||
| 320 | acpi_dbg_layer); | ||
| 321 | break; | ||
| 322 | case 1: | ||
| 323 | for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { | ||
| 324 | seq_printf(m, "%-25s\t0x%08lX [%c]\n", | ||
| 325 | acpi_debug_levels[i].name, | ||
| 326 | acpi_debug_levels[i].value, | ||
| 327 | (acpi_dbg_level & acpi_debug_levels[i]. | ||
| 328 | value) ? '*' : ' '); | ||
| 329 | } | ||
| 330 | seq_printf(m, "--\ndebug_level = 0x%08X (* = enabled)\n", | ||
| 331 | acpi_dbg_level); | ||
| 332 | break; | ||
| 333 | } | ||
| 334 | return 0; | ||
| 335 | } | ||
| 336 | |||
| 337 | static int acpi_system_debug_proc_open(struct inode *inode, struct file *file) | ||
| 338 | { | ||
| 339 | return single_open(file, acpi_system_debug_proc_show, PDE(inode)->data); | ||
| 340 | } | ||
| 341 | |||
| 342 | static ssize_t acpi_system_debug_proc_write(struct file *file, | ||
| 343 | const char __user * buffer, | ||
| 344 | size_t count, loff_t *pos) | ||
| 345 | { | ||
| 346 | char debug_string[12] = { '\0' }; | ||
| 347 | |||
| 348 | |||
| 349 | if (count > sizeof(debug_string) - 1) | ||
| 350 | return -EINVAL; | ||
| 351 | |||
| 352 | if (copy_from_user(debug_string, buffer, count)) | ||
| 353 | return -EFAULT; | ||
| 354 | |||
| 355 | debug_string[count] = '\0'; | ||
| 356 | |||
| 357 | switch ((unsigned long)PDE(file->f_path.dentry->d_inode)->data) { | ||
| 358 | case 0: | ||
| 359 | acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0); | ||
| 360 | break; | ||
| 361 | case 1: | ||
| 362 | acpi_dbg_level = simple_strtoul(debug_string, NULL, 0); | ||
| 363 | break; | ||
| 364 | default: | ||
| 365 | return -EINVAL; | ||
| 366 | } | ||
| 367 | |||
| 368 | return count; | ||
| 369 | } | ||
| 370 | |||
| 371 | static const struct file_operations acpi_system_debug_proc_fops = { | ||
| 372 | .owner = THIS_MODULE, | ||
| 373 | .open = acpi_system_debug_proc_open, | ||
| 374 | .read = seq_read, | ||
| 375 | .llseek = seq_lseek, | ||
| 376 | .release = single_release, | ||
| 377 | .write = acpi_system_debug_proc_write, | ||
| 378 | }; | ||
| 379 | #endif | ||
| 380 | |||
| 381 | int __init acpi_procfs_init(void) | ||
| 382 | { | ||
| 383 | #ifdef CONFIG_ACPI_PROCFS | ||
| 384 | struct proc_dir_entry *entry; | ||
| 385 | int error = 0; | ||
| 386 | char *name; | ||
| 387 | |||
| 388 | /* 'debug_layer' [R/W] */ | ||
| 389 | name = ACPI_SYSTEM_FILE_DEBUG_LAYER; | ||
| 390 | entry = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, | ||
| 391 | acpi_root_dir, &acpi_system_debug_proc_fops, | ||
| 392 | (void *)0); | ||
| 393 | if (!entry) | ||
| 394 | goto Error; | ||
| 395 | |||
| 396 | /* 'debug_level' [R/W] */ | ||
| 397 | name = ACPI_SYSTEM_FILE_DEBUG_LEVEL; | ||
| 398 | entry = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, | ||
| 399 | acpi_root_dir, &acpi_system_debug_proc_fops, | ||
| 400 | (void *)1); | ||
| 401 | if (!entry) | ||
| 402 | goto Error; | ||
| 403 | |||
| 404 | Done: | ||
| 405 | return error; | ||
| 406 | |||
| 407 | Error: | ||
| 408 | remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, acpi_root_dir); | ||
| 409 | remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir); | ||
| 410 | error = -ENODEV; | ||
| 411 | goto Done; | ||
| 412 | #else | ||
| 413 | return 0; | ||
| 414 | #endif | ||
| 415 | } | ||
| 416 | |||
| 417 | int __init acpi_debug_init(void) | ||
| 418 | { | ||
| 419 | acpi_debugfs_init(); | ||
| 420 | acpi_procfs_init(); | ||
| 421 | return 0; | ||
| 422 | } | ||
diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c new file mode 100644 index 000000000000..7de27d49c4b9 --- /dev/null +++ b/drivers/acpi/debugfs.c | |||
| @@ -0,0 +1,93 @@ | |||
| 1 | /* | ||
| 2 | * debugfs.c - ACPI debugfs interface to userspace. | ||
| 3 | */ | ||
| 4 | |||
| 5 | #include <linux/init.h> | ||
| 6 | #include <linux/module.h> | ||
| 7 | #include <linux/kernel.h> | ||
| 8 | #include <linux/uaccess.h> | ||
| 9 | #include <linux/debugfs.h> | ||
| 10 | #include <acpi/acpi_drivers.h> | ||
| 11 | |||
| 12 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | ||
| 13 | ACPI_MODULE_NAME("debugfs"); | ||
| 14 | |||
| 15 | |||
| 16 | /* /sys/modules/acpi/parameters/aml_debug_output */ | ||
| 17 | |||
| 18 | module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object, | ||
| 19 | bool, 0644); | ||
| 20 | MODULE_PARM_DESC(aml_debug_output, | ||
| 21 | "To enable/disable the ACPI Debug Object output."); | ||
| 22 | |||
| 23 | /* /sys/kernel/debug/acpi/custom_method */ | ||
| 24 | |||
| 25 | static ssize_t cm_write(struct file *file, const char __user * user_buf, | ||
| 26 | size_t count, loff_t *ppos) | ||
| 27 | { | ||
| 28 | static char *buf; | ||
| 29 | static int uncopied_bytes; | ||
| 30 | struct acpi_table_header table; | ||
| 31 | acpi_status status; | ||
| 32 | |||
| 33 | if (!(*ppos)) { | ||
| 34 | /* parse the table header to get the table length */ | ||
| 35 | if (count <= sizeof(struct acpi_table_header)) | ||
| 36 | return -EINVAL; | ||
| 37 | if (copy_from_user(&table, user_buf, | ||
| 38 | sizeof(struct acpi_table_header))) | ||
| 39 | return -EFAULT; | ||
| 40 | uncopied_bytes = table.length; | ||
| 41 | buf = kzalloc(uncopied_bytes, GFP_KERNEL); | ||
| 42 | if (!buf) | ||
| 43 | return -ENOMEM; | ||
| 44 | } | ||
| 45 | |||
| 46 | if (uncopied_bytes < count) { | ||
| 47 | kfree(buf); | ||
| 48 | return -EINVAL; | ||
| 49 | } | ||
| 50 | |||
| 51 | if (copy_from_user(buf + (*ppos), user_buf, count)) { | ||
| 52 | kfree(buf); | ||
| 53 | return -EFAULT; | ||
| 54 | } | ||
| 55 | |||
| 56 | uncopied_bytes -= count; | ||
| 57 | *ppos += count; | ||
| 58 | |||
| 59 | if (!uncopied_bytes) { | ||
| 60 | status = acpi_install_method(buf); | ||
| 61 | kfree(buf); | ||
| 62 | if (ACPI_FAILURE(status)) | ||
| 63 | return -EINVAL; | ||
| 64 | add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); | ||
| 65 | } | ||
| 66 | |||
| 67 | return count; | ||
| 68 | } | ||
| 69 | |||
| 70 | static const struct file_operations cm_fops = { | ||
| 71 | .write = cm_write, | ||
| 72 | }; | ||
| 73 | |||
| 74 | int __init acpi_debugfs_init(void) | ||
| 75 | { | ||
| 76 | struct dentry *acpi_dir, *cm_dentry; | ||
| 77 | |||
| 78 | acpi_dir = debugfs_create_dir("acpi", NULL); | ||
| 79 | if (!acpi_dir) | ||
| 80 | goto err; | ||
| 81 | |||
| 82 | cm_dentry = debugfs_create_file("custom_method", S_IWUGO, | ||
| 83 | acpi_dir, NULL, &cm_fops); | ||
| 84 | if (!cm_dentry) | ||
| 85 | goto err; | ||
| 86 | |||
| 87 | return 0; | ||
| 88 | |||
| 89 | err: | ||
| 90 | if (acpi_dir) | ||
| 91 | debugfs_remove(acpi_dir); | ||
| 92 | return -EINVAL; | ||
| 93 | } | ||
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 4af6301601e7..78b0164c35b2 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
| @@ -100,7 +100,8 @@ do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
| 100 | 100 | ||
| 101 | status = acpi_get_object_info(handle, &info); | 101 | status = acpi_get_object_info(handle, &info); |
| 102 | if (ACPI_SUCCESS(status)) { | 102 | if (ACPI_SUCCESS(status)) { |
| 103 | if (info->address == find->address) | 103 | if ((info->address == find->address) |
| 104 | && (info->valid & ACPI_VALID_ADR)) | ||
| 104 | find->handle = handle; | 105 | find->handle = handle; |
| 105 | kfree(info); | 106 | kfree(info); |
| 106 | } | 107 | } |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 8ae27264a00e..a212bfeddf8c 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
| @@ -27,12 +27,12 @@ | |||
| 27 | 27 | ||
| 28 | int init_acpi_device_notify(void); | 28 | int init_acpi_device_notify(void); |
| 29 | int acpi_scan_init(void); | 29 | int acpi_scan_init(void); |
| 30 | int acpi_system_init(void); | 30 | int acpi_sysfs_init(void); |
| 31 | 31 | ||
| 32 | #ifdef CONFIG_ACPI_DEBUG | 32 | #ifdef CONFIG_DEBUG_FS |
| 33 | int acpi_debug_init(void); | 33 | int acpi_debugfs_init(void); |
| 34 | #else | 34 | #else |
| 35 | static inline int acpi_debug_init(void) { return 0; } | 35 | static inline int acpi_debugfs_init(void) { return 0; } |
| 36 | #endif | 36 | #endif |
| 37 | 37 | ||
| 38 | /* -------------------------------------------------------------------------- | 38 | /* -------------------------------------------------------------------------- |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index b0337d314604..5718566e00f9 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
| @@ -255,12 +255,10 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header, | |||
| 255 | 255 | ||
| 256 | static int __init acpi_parse_srat(struct acpi_table_header *table) | 256 | static int __init acpi_parse_srat(struct acpi_table_header *table) |
| 257 | { | 257 | { |
| 258 | struct acpi_table_srat *srat; | ||
| 259 | |||
| 260 | if (!table) | 258 | if (!table) |
| 261 | return -EINVAL; | 259 | return -EINVAL; |
| 262 | 260 | ||
| 263 | srat = (struct acpi_table_srat *)table; | 261 | /* Real work done in acpi_table_parse_srat below. */ |
| 264 | 262 | ||
| 265 | return 0; | 263 | return 0; |
| 266 | } | 264 | } |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index f14d3f251d26..65b25a303b86 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
| @@ -141,15 +141,14 @@ static struct osi_linux { | |||
| 141 | static void __init acpi_request_region (struct acpi_generic_address *addr, | 141 | static void __init acpi_request_region (struct acpi_generic_address *addr, |
| 142 | unsigned int length, char *desc) | 142 | unsigned int length, char *desc) |
| 143 | { | 143 | { |
| 144 | struct resource *res; | ||
| 145 | |||
| 146 | if (!addr->address || !length) | 144 | if (!addr->address || !length) |
| 147 | return; | 145 | return; |
| 148 | 146 | ||
| 147 | /* Resources are never freed */ | ||
| 149 | if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO) | 148 | if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO) |
| 150 | res = request_region(addr->address, length, desc); | 149 | request_region(addr->address, length, desc); |
| 151 | else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) | 150 | else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) |
| 152 | res = request_mem_region(addr->address, length, desc); | 151 | request_mem_region(addr->address, length, desc); |
| 153 | } | 152 | } |
| 154 | 153 | ||
| 155 | static int __init acpi_reserve_resources(void) | 154 | static int __init acpi_reserve_resources(void) |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index f74d3b31e5c9..844c155aeb0f 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
| @@ -40,8 +40,6 @@ | |||
| 40 | #include <linux/init.h> | 40 | #include <linux/init.h> |
| 41 | #include <linux/types.h> | 41 | #include <linux/types.h> |
| 42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
| 43 | #include <linux/proc_fs.h> | ||
| 44 | #include <linux/seq_file.h> | ||
| 45 | #include <acpi/acpi_bus.h> | 43 | #include <acpi/acpi_bus.h> |
| 46 | #include <acpi/acpi_drivers.h> | 44 | #include <acpi/acpi_drivers.h> |
| 47 | #include "sleep.h" | 45 | #include "sleep.h" |
| @@ -64,7 +62,6 @@ module_param_named(power_nocheck, acpi_power_nocheck, bool, 000); | |||
| 64 | static int acpi_power_add(struct acpi_device *device); | 62 | static int acpi_power_add(struct acpi_device *device); |
| 65 | static int acpi_power_remove(struct acpi_device *device, int type); | 63 | static int acpi_power_remove(struct acpi_device *device, int type); |
| 66 | static int acpi_power_resume(struct acpi_device *device); | 64 | static int acpi_power_resume(struct acpi_device *device); |
| 67 | static int acpi_power_open_fs(struct inode *inode, struct file *file); | ||
| 68 | 65 | ||
| 69 | static const struct acpi_device_id power_device_ids[] = { | 66 | static const struct acpi_device_id power_device_ids[] = { |
| 70 | {ACPI_POWER_HID, 0}, | 67 | {ACPI_POWER_HID, 0}, |
| @@ -99,14 +96,6 @@ struct acpi_power_resource { | |||
| 99 | 96 | ||
| 100 | static struct list_head acpi_power_resource_list; | 97 | static struct list_head acpi_power_resource_list; |
| 101 | 98 | ||
| 102 | static const struct file_operations acpi_power_fops = { | ||
| 103 | .owner = THIS_MODULE, | ||
| 104 | .open = acpi_power_open_fs, | ||
| 105 | .read = seq_read, | ||
| 106 | .llseek = seq_lseek, | ||
| 107 | .release = single_release, | ||
| 108 | }; | ||
| 109 | |||
| 110 | /* -------------------------------------------------------------------------- | 99 | /* -------------------------------------------------------------------------- |
| 111 | Power Resource Management | 100 | Power Resource Management |
| 112 | -------------------------------------------------------------------------- */ | 101 | -------------------------------------------------------------------------- */ |
| @@ -255,7 +244,6 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) | |||
| 255 | struct list_head *node, *next; | 244 | struct list_head *node, *next; |
| 256 | struct acpi_power_reference *ref; | 245 | struct acpi_power_reference *ref; |
| 257 | 246 | ||
| 258 | |||
| 259 | result = acpi_power_get_context(handle, &resource); | 247 | result = acpi_power_get_context(handle, &resource); |
| 260 | if (result) | 248 | if (result) |
| 261 | return result; | 249 | return result; |
| @@ -542,102 +530,6 @@ int acpi_power_transition(struct acpi_device *device, int state) | |||
| 542 | } | 530 | } |
| 543 | 531 | ||
| 544 | /* -------------------------------------------------------------------------- | 532 | /* -------------------------------------------------------------------------- |
| 545 | FS Interface (/proc) | ||
| 546 | -------------------------------------------------------------------------- */ | ||
| 547 | |||
| 548 | static struct proc_dir_entry *acpi_power_dir; | ||
| 549 | |||
| 550 | static int acpi_power_seq_show(struct seq_file *seq, void *offset) | ||
| 551 | { | ||
| 552 | int count = 0; | ||
| 553 | int result = 0, state; | ||
| 554 | struct acpi_power_resource *resource = NULL; | ||
| 555 | struct list_head *node, *next; | ||
| 556 | struct acpi_power_reference *ref; | ||
| 557 | |||
| 558 | |||
| 559 | resource = seq->private; | ||
| 560 | |||
| 561 | if (!resource) | ||
| 562 | goto end; | ||
| 563 | |||
| 564 | result = acpi_power_get_state(resource->device->handle, &state); | ||
| 565 | if (result) | ||
| 566 | goto end; | ||
| 567 | |||
| 568 | seq_puts(seq, "state: "); | ||
| 569 | switch (state) { | ||
| 570 | case ACPI_POWER_RESOURCE_STATE_ON: | ||
| 571 | seq_puts(seq, "on\n"); | ||
| 572 | break; | ||
| 573 | case ACPI_POWER_RESOURCE_STATE_OFF: | ||
| 574 | seq_puts(seq, "off\n"); | ||
| 575 | break; | ||
| 576 | default: | ||
| 577 | seq_puts(seq, "unknown\n"); | ||
| 578 | break; | ||
| 579 | } | ||
| 580 | |||
| 581 | mutex_lock(&resource->resource_lock); | ||
| 582 | list_for_each_safe(node, next, &resource->reference) { | ||
| 583 | ref = container_of(node, struct acpi_power_reference, node); | ||
| 584 | count++; | ||
| 585 | } | ||
| 586 | mutex_unlock(&resource->resource_lock); | ||
| 587 | |||
| 588 | seq_printf(seq, "system level: S%d\n" | ||
| 589 | "order: %d\n" | ||
| 590 | "reference count: %d\n", | ||
| 591 | resource->system_level, | ||
| 592 | resource->order, count); | ||
| 593 | |||
| 594 | end: | ||
| 595 | return 0; | ||
| 596 | } | ||
| 597 | |||
| 598 | static int acpi_power_open_fs(struct inode *inode, struct file *file) | ||
| 599 | { | ||
| 600 | return single_open(file, acpi_power_seq_show, PDE(inode)->data); | ||
| 601 | } | ||
| 602 | |||
| 603 | static int acpi_power_add_fs(struct acpi_device *device) | ||
| 604 | { | ||
| 605 | struct proc_dir_entry *entry = NULL; | ||
| 606 | |||
| 607 | |||
| 608 | if (!device) | ||
| 609 | return -EINVAL; | ||
| 610 | |||
| 611 | if (!acpi_device_dir(device)) { | ||
| 612 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
| 613 | acpi_power_dir); | ||
| 614 | if (!acpi_device_dir(device)) | ||
| 615 | return -ENODEV; | ||
| 616 | } | ||
| 617 | |||
| 618 | /* 'status' [R] */ | ||
| 619 | entry = proc_create_data(ACPI_POWER_FILE_STATUS, | ||
| 620 | S_IRUGO, acpi_device_dir(device), | ||
| 621 | &acpi_power_fops, acpi_driver_data(device)); | ||
| 622 | if (!entry) | ||
| 623 | return -EIO; | ||
| 624 | return 0; | ||
| 625 | } | ||
| 626 | |||
| 627 | static int acpi_power_remove_fs(struct acpi_device *device) | ||
| 628 | { | ||
| 629 | |||
| 630 | if (acpi_device_dir(device)) { | ||
| 631 | remove_proc_entry(ACPI_POWER_FILE_STATUS, | ||
| 632 | acpi_device_dir(device)); | ||
| 633 | remove_proc_entry(acpi_device_bid(device), acpi_power_dir); | ||
| 634 | acpi_device_dir(device) = NULL; | ||
| 635 | } | ||
| 636 | |||
| 637 | return 0; | ||
| 638 | } | ||
| 639 | |||
| 640 | /* -------------------------------------------------------------------------- | ||
| 641 | Driver Interface | 533 | Driver Interface |
| 642 | -------------------------------------------------------------------------- */ | 534 | -------------------------------------------------------------------------- */ |
| 643 | 535 | ||
| @@ -690,10 +582,6 @@ static int acpi_power_add(struct acpi_device *device) | |||
| 690 | break; | 582 | break; |
| 691 | } | 583 | } |
| 692 | 584 | ||
| 693 | result = acpi_power_add_fs(device); | ||
| 694 | if (result) | ||
| 695 | goto end; | ||
| 696 | |||
| 697 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), | 585 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), |
| 698 | acpi_device_bid(device), state ? "on" : "off"); | 586 | acpi_device_bid(device), state ? "on" : "off"); |
| 699 | 587 | ||
| @@ -715,8 +603,6 @@ static int acpi_power_remove(struct acpi_device *device, int type) | |||
| 715 | 603 | ||
| 716 | resource = acpi_driver_data(device); | 604 | resource = acpi_driver_data(device); |
| 717 | 605 | ||
| 718 | acpi_power_remove_fs(device); | ||
| 719 | |||
| 720 | mutex_lock(&resource->resource_lock); | 606 | mutex_lock(&resource->resource_lock); |
| 721 | list_for_each_safe(node, next, &resource->reference) { | 607 | list_for_each_safe(node, next, &resource->reference) { |
| 722 | struct acpi_power_reference *ref = container_of(node, struct acpi_power_reference, node); | 608 | 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) | |||
| 760 | 646 | ||
| 761 | int __init acpi_power_init(void) | 647 | int __init acpi_power_init(void) |
| 762 | { | 648 | { |
| 763 | int result = 0; | ||
| 764 | |||
| 765 | INIT_LIST_HEAD(&acpi_power_resource_list); | 649 | INIT_LIST_HEAD(&acpi_power_resource_list); |
| 766 | 650 | return acpi_bus_register_driver(&acpi_power_driver); | |
| 767 | acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir); | ||
| 768 | if (!acpi_power_dir) | ||
| 769 | return -ENODEV; | ||
| 770 | |||
| 771 | result = acpi_bus_register_driver(&acpi_power_driver); | ||
| 772 | if (result < 0) { | ||
| 773 | remove_proc_entry(ACPI_POWER_CLASS, acpi_root_dir); | ||
| 774 | return -ENODEV; | ||
| 775 | } | ||
| 776 | |||
| 777 | return 0; | ||
| 778 | } | 651 | } |
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 1ac678d2c51c..afad67769db6 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
| @@ -17,64 +17,11 @@ | |||
| 17 | 17 | ||
| 18 | /* | 18 | /* |
| 19 | * this file provides support for: | 19 | * this file provides support for: |
| 20 | * /proc/acpi/sleep | ||
| 21 | * /proc/acpi/alarm | 20 | * /proc/acpi/alarm |
| 22 | * /proc/acpi/wakeup | 21 | * /proc/acpi/wakeup |
| 23 | */ | 22 | */ |
| 24 | 23 | ||
| 25 | ACPI_MODULE_NAME("sleep") | 24 | ACPI_MODULE_NAME("sleep") |
| 26 | #ifdef CONFIG_ACPI_PROCFS | ||
| 27 | static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset) | ||
| 28 | { | ||
| 29 | int i; | ||
| 30 | |||
| 31 | for (i = 0; i <= ACPI_STATE_S5; i++) { | ||
| 32 | if (sleep_states[i]) { | ||
| 33 | seq_printf(seq, "S%d ", i); | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 37 | seq_puts(seq, "\n"); | ||
| 38 | |||
| 39 | return 0; | ||
| 40 | } | ||
| 41 | |||
| 42 | static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file) | ||
| 43 | { | ||
| 44 | return single_open(file, acpi_system_sleep_seq_show, PDE(inode)->data); | ||
| 45 | } | ||
| 46 | |||
| 47 | static ssize_t | ||
| 48 | acpi_system_write_sleep(struct file *file, | ||
| 49 | const char __user * buffer, size_t count, loff_t * ppos) | ||
| 50 | { | ||
| 51 | char str[12]; | ||
| 52 | u32 state = 0; | ||
| 53 | int error = 0; | ||
| 54 | |||
| 55 | if (count > sizeof(str) - 1) | ||
| 56 | goto Done; | ||
| 57 | memset(str, 0, sizeof(str)); | ||
| 58 | if (copy_from_user(str, buffer, count)) | ||
| 59 | return -EFAULT; | ||
| 60 | |||
| 61 | /* Check for S4 bios request */ | ||
| 62 | if (!strcmp(str, "4b")) { | ||
| 63 | error = acpi_suspend(4); | ||
| 64 | goto Done; | ||
| 65 | } | ||
| 66 | state = simple_strtoul(str, NULL, 0); | ||
| 67 | #ifdef CONFIG_HIBERNATION | ||
| 68 | if (state == 4) { | ||
| 69 | error = hibernate(); | ||
| 70 | goto Done; | ||
| 71 | } | ||
| 72 | #endif | ||
| 73 | error = acpi_suspend(state); | ||
| 74 | Done: | ||
| 75 | return error ? error : count; | ||
| 76 | } | ||
| 77 | #endif /* CONFIG_ACPI_PROCFS */ | ||
| 78 | 25 | ||
| 79 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86) | 26 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86) |
| 80 | /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ | 27 | /* 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 = { | |||
| 463 | .release = single_release, | 410 | .release = single_release, |
| 464 | }; | 411 | }; |
| 465 | 412 | ||
| 466 | #ifdef CONFIG_ACPI_PROCFS | ||
| 467 | static const struct file_operations acpi_system_sleep_fops = { | ||
| 468 | .owner = THIS_MODULE, | ||
| 469 | .open = acpi_system_sleep_open_fs, | ||
| 470 | .read = seq_read, | ||
| 471 | .write = acpi_system_write_sleep, | ||
| 472 | .llseek = seq_lseek, | ||
| 473 | .release = single_release, | ||
| 474 | }; | ||
| 475 | #endif /* CONFIG_ACPI_PROCFS */ | ||
| 476 | |||
| 477 | #ifdef HAVE_ACPI_LEGACY_ALARM | 413 | #ifdef HAVE_ACPI_LEGACY_ALARM |
| 478 | static const struct file_operations acpi_system_alarm_fops = { | 414 | static const struct file_operations acpi_system_alarm_fops = { |
| 479 | .owner = THIS_MODULE, | 415 | .owner = THIS_MODULE, |
| @@ -495,12 +431,6 @@ static u32 rtc_handler(void *context) | |||
| 495 | 431 | ||
| 496 | int __init acpi_sleep_proc_init(void) | 432 | int __init acpi_sleep_proc_init(void) |
| 497 | { | 433 | { |
| 498 | #ifdef CONFIG_ACPI_PROCFS | ||
| 499 | /* 'sleep' [R/W] */ | ||
| 500 | proc_create("sleep", S_IFREG | S_IRUGO | S_IWUSR, | ||
| 501 | acpi_root_dir, &acpi_system_sleep_fops); | ||
| 502 | #endif /* CONFIG_ACPI_PROCFS */ | ||
| 503 | |||
| 504 | #ifdef HAVE_ACPI_LEGACY_ALARM | 434 | #ifdef HAVE_ACPI_LEGACY_ALARM |
| 505 | /* 'alarm' [R/W] */ | 435 | /* 'alarm' [R/W] */ |
| 506 | proc_create("alarm", S_IFREG | S_IRUGO | S_IWUSR, | 436 | proc_create("alarm", S_IFREG | S_IRUGO | S_IWUSR, |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 38ea0cc6dc49..156021892389 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
| @@ -83,9 +83,6 @@ MODULE_LICENSE("GPL"); | |||
| 83 | 83 | ||
| 84 | static int acpi_processor_add(struct acpi_device *device); | 84 | static int acpi_processor_add(struct acpi_device *device); |
| 85 | static int acpi_processor_remove(struct acpi_device *device, int type); | 85 | static int acpi_processor_remove(struct acpi_device *device, int type); |
| 86 | #ifdef CONFIG_ACPI_PROCFS | ||
| 87 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); | ||
| 88 | #endif | ||
| 89 | static void acpi_processor_notify(struct acpi_device *device, u32 event); | 86 | static void acpi_processor_notify(struct acpi_device *device, u32 event); |
| 90 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); | 87 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); |
| 91 | static int acpi_processor_handle_eject(struct acpi_processor *pr); | 88 | static int acpi_processor_handle_eject(struct acpi_processor *pr); |
| @@ -113,15 +110,6 @@ static struct acpi_driver acpi_processor_driver = { | |||
| 113 | 110 | ||
| 114 | #define INSTALL_NOTIFY_HANDLER 1 | 111 | #define INSTALL_NOTIFY_HANDLER 1 |
| 115 | #define UNINSTALL_NOTIFY_HANDLER 2 | 112 | #define UNINSTALL_NOTIFY_HANDLER 2 |
| 116 | #ifdef CONFIG_ACPI_PROCFS | ||
| 117 | static const struct file_operations acpi_processor_info_fops = { | ||
| 118 | .owner = THIS_MODULE, | ||
| 119 | .open = acpi_processor_info_open_fs, | ||
| 120 | .read = seq_read, | ||
| 121 | .llseek = seq_lseek, | ||
| 122 | .release = single_release, | ||
| 123 | }; | ||
| 124 | #endif | ||
| 125 | 113 | ||
| 126 | DEFINE_PER_CPU(struct acpi_processor *, processors); | 114 | DEFINE_PER_CPU(struct acpi_processor *, processors); |
| 127 | EXPORT_PER_CPU_SYMBOL(processors); | 115 | EXPORT_PER_CPU_SYMBOL(processors); |
| @@ -256,44 +244,8 @@ static int acpi_processor_errata(struct acpi_processor *pr) | |||
| 256 | return result; | 244 | return result; |
| 257 | } | 245 | } |
| 258 | 246 | ||
| 259 | /* -------------------------------------------------------------------------- | ||
| 260 | FS Interface (/proc) | ||
| 261 | -------------------------------------------------------------------------- */ | ||
| 262 | |||
| 263 | #ifdef CONFIG_ACPI_PROCFS | ||
| 264 | static struct proc_dir_entry *acpi_processor_dir = NULL; | 247 | static struct proc_dir_entry *acpi_processor_dir = NULL; |
| 265 | 248 | ||
| 266 | static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) | ||
| 267 | { | ||
| 268 | struct acpi_processor *pr = seq->private; | ||
| 269 | |||
| 270 | |||
| 271 | if (!pr) | ||
| 272 | goto end; | ||
| 273 | |||
| 274 | seq_printf(seq, "processor id: %d\n" | ||
| 275 | "acpi id: %d\n" | ||
| 276 | "bus mastering control: %s\n" | ||
| 277 | "power management: %s\n" | ||
| 278 | "throttling control: %s\n" | ||
| 279 | "limit interface: %s\n", | ||
| 280 | pr->id, | ||
| 281 | pr->acpi_id, | ||
| 282 | pr->flags.bm_control ? "yes" : "no", | ||
| 283 | pr->flags.power ? "yes" : "no", | ||
| 284 | pr->flags.throttling ? "yes" : "no", | ||
| 285 | pr->flags.limit ? "yes" : "no"); | ||
| 286 | |||
| 287 | end: | ||
| 288 | return 0; | ||
| 289 | } | ||
| 290 | |||
| 291 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file) | ||
| 292 | { | ||
| 293 | return single_open(file, acpi_processor_info_seq_show, | ||
| 294 | PDE(inode)->data); | ||
| 295 | } | ||
| 296 | |||
| 297 | static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) | 249 | static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) |
| 298 | { | 250 | { |
| 299 | struct proc_dir_entry *entry = NULL; | 251 | struct proc_dir_entry *entry = NULL; |
| @@ -306,14 +258,6 @@ static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) | |||
| 306 | return -ENODEV; | 258 | return -ENODEV; |
| 307 | } | 259 | } |
| 308 | 260 | ||
| 309 | /* 'info' [R] */ | ||
| 310 | entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO, | ||
| 311 | S_IRUGO, acpi_device_dir(device), | ||
| 312 | &acpi_processor_info_fops, | ||
| 313 | acpi_driver_data(device)); | ||
| 314 | if (!entry) | ||
| 315 | return -EIO; | ||
| 316 | |||
| 317 | /* 'throttling' [R/W] */ | 261 | /* 'throttling' [R/W] */ |
| 318 | entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING, | 262 | entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING, |
| 319 | S_IFREG | S_IRUGO | S_IWUSR, | 263 | S_IFREG | S_IRUGO | S_IWUSR, |
| @@ -322,43 +266,20 @@ static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) | |||
| 322 | acpi_driver_data(device)); | 266 | acpi_driver_data(device)); |
| 323 | if (!entry) | 267 | if (!entry) |
| 324 | return -EIO; | 268 | return -EIO; |
| 325 | |||
| 326 | /* 'limit' [R/W] */ | ||
| 327 | entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT, | ||
| 328 | S_IFREG | S_IRUGO | S_IWUSR, | ||
| 329 | acpi_device_dir(device), | ||
| 330 | &acpi_processor_limit_fops, | ||
| 331 | acpi_driver_data(device)); | ||
| 332 | if (!entry) | ||
| 333 | return -EIO; | ||
| 334 | return 0; | 269 | return 0; |
| 335 | } | 270 | } |
| 336 | static int acpi_processor_remove_fs(struct acpi_device *device) | 271 | static int acpi_processor_remove_fs(struct acpi_device *device) |
| 337 | { | 272 | { |
| 338 | 273 | ||
| 339 | if (acpi_device_dir(device)) { | 274 | if (acpi_device_dir(device)) { |
| 340 | remove_proc_entry(ACPI_PROCESSOR_FILE_INFO, | ||
| 341 | acpi_device_dir(device)); | ||
| 342 | remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, | 275 | remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, |
| 343 | acpi_device_dir(device)); | 276 | acpi_device_dir(device)); |
| 344 | remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT, | ||
| 345 | acpi_device_dir(device)); | ||
| 346 | remove_proc_entry(acpi_device_bid(device), acpi_processor_dir); | 277 | remove_proc_entry(acpi_device_bid(device), acpi_processor_dir); |
| 347 | acpi_device_dir(device) = NULL; | 278 | acpi_device_dir(device) = NULL; |
| 348 | } | 279 | } |
| 349 | 280 | ||
| 350 | return 0; | 281 | return 0; |
| 351 | } | 282 | } |
| 352 | #else | ||
| 353 | static inline int acpi_processor_add_fs(struct acpi_device *device) | ||
| 354 | { | ||
| 355 | return 0; | ||
| 356 | } | ||
| 357 | static inline int acpi_processor_remove_fs(struct acpi_device *device) | ||
| 358 | { | ||
| 359 | return 0; | ||
| 360 | } | ||
| 361 | #endif | ||
| 362 | 283 | ||
| 363 | /* -------------------------------------------------------------------------- | 284 | /* -------------------------------------------------------------------------- |
| 364 | Driver Interface | 285 | Driver Interface |
| @@ -921,11 +842,9 @@ static int __init acpi_processor_init(void) | |||
| 921 | 842 | ||
| 922 | memset(&errata, 0, sizeof(errata)); | 843 | memset(&errata, 0, sizeof(errata)); |
| 923 | 844 | ||
| 924 | #ifdef CONFIG_ACPI_PROCFS | ||
| 925 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 845 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
| 926 | if (!acpi_processor_dir) | 846 | if (!acpi_processor_dir) |
| 927 | return -ENOMEM; | 847 | return -ENOMEM; |
| 928 | #endif | ||
| 929 | 848 | ||
| 930 | if (!cpuidle_register_driver(&acpi_idle_driver)) { | 849 | if (!cpuidle_register_driver(&acpi_idle_driver)) { |
| 931 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", | 850 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", |
| @@ -952,9 +871,7 @@ static int __init acpi_processor_init(void) | |||
| 952 | out_cpuidle: | 871 | out_cpuidle: |
| 953 | cpuidle_unregister_driver(&acpi_idle_driver); | 872 | cpuidle_unregister_driver(&acpi_idle_driver); |
| 954 | 873 | ||
| 955 | #ifdef CONFIG_ACPI_PROCFS | ||
| 956 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 874 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
| 957 | #endif | ||
| 958 | 875 | ||
| 959 | return result; | 876 | return result; |
| 960 | } | 877 | } |
| @@ -974,9 +891,7 @@ static void __exit acpi_processor_exit(void) | |||
| 974 | 891 | ||
| 975 | cpuidle_unregister_driver(&acpi_idle_driver); | 892 | cpuidle_unregister_driver(&acpi_idle_driver); |
| 976 | 893 | ||
| 977 | #ifdef CONFIG_ACPI_PROCFS | ||
| 978 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 894 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
| 979 | #endif | ||
| 980 | 895 | ||
| 981 | return; | 896 | return; |
| 982 | } | 897 | } |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index b4c2f3bdadeb..f4428e82b352 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
| @@ -33,8 +33,6 @@ | |||
| 33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
| 34 | #include <linux/cpufreq.h> | 34 | #include <linux/cpufreq.h> |
| 35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| 36 | #include <linux/proc_fs.h> | ||
| 37 | #include <linux/seq_file.h> | ||
| 38 | #include <linux/acpi.h> | 36 | #include <linux/acpi.h> |
| 39 | #include <linux/dmi.h> | 37 | #include <linux/dmi.h> |
| 40 | #include <linux/moduleparam.h> | 38 | #include <linux/moduleparam.h> |
| @@ -82,13 +80,6 @@ module_param(bm_check_disable, uint, 0000); | |||
| 82 | static unsigned int latency_factor __read_mostly = 2; | 80 | static unsigned int latency_factor __read_mostly = 2; |
| 83 | module_param(latency_factor, uint, 0644); | 81 | module_param(latency_factor, uint, 0644); |
| 84 | 82 | ||
| 85 | #ifdef CONFIG_ACPI_PROCFS | ||
| 86 | static u64 us_to_pm_timer_ticks(s64 t) | ||
| 87 | { | ||
| 88 | return div64_u64(t * PM_TIMER_FREQUENCY, 1000000); | ||
| 89 | } | ||
| 90 | #endif | ||
| 91 | |||
| 92 | /* | 83 | /* |
| 93 | * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. | 84 | * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. |
| 94 | * For now disable this. Probably a bug somewhere else. | 85 | * For now disable this. Probably a bug somewhere else. |
| @@ -689,78 +680,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) | |||
| 689 | return 0; | 680 | return 0; |
| 690 | } | 681 | } |
| 691 | 682 | ||
| 692 | #ifdef CONFIG_ACPI_PROCFS | ||
| 693 | static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) | ||
| 694 | { | ||
| 695 | struct acpi_processor *pr = seq->private; | ||
| 696 | unsigned int i; | ||
| 697 | |||
| 698 | |||
| 699 | if (!pr) | ||
| 700 | goto end; | ||
| 701 | |||
| 702 | seq_printf(seq, "active state: C%zd\n" | ||
| 703 | "max_cstate: C%d\n" | ||
| 704 | "maximum allowed latency: %d usec\n", | ||
| 705 | pr->power.state ? pr->power.state - pr->power.states : 0, | ||
| 706 | max_cstate, pm_qos_request(PM_QOS_CPU_DMA_LATENCY)); | ||
| 707 | |||
| 708 | seq_puts(seq, "states:\n"); | ||
| 709 | |||
| 710 | for (i = 1; i <= pr->power.count; i++) { | ||
| 711 | seq_printf(seq, " %cC%d: ", | ||
| 712 | (&pr->power.states[i] == | ||
| 713 | pr->power.state ? '*' : ' '), i); | ||
| 714 | |||
| 715 | if (!pr->power.states[i].valid) { | ||
| 716 | seq_puts(seq, "<not supported>\n"); | ||
| 717 | continue; | ||
| 718 | } | ||
| 719 | |||
| 720 | switch (pr->power.states[i].type) { | ||
| 721 | case ACPI_STATE_C1: | ||
| 722 | seq_printf(seq, "type[C1] "); | ||
| 723 | break; | ||
| 724 | case ACPI_STATE_C2: | ||
| 725 | seq_printf(seq, "type[C2] "); | ||
| 726 | break; | ||
| 727 | case ACPI_STATE_C3: | ||
| 728 | seq_printf(seq, "type[C3] "); | ||
| 729 | break; | ||
| 730 | default: | ||
| 731 | seq_printf(seq, "type[--] "); | ||
| 732 | break; | ||
| 733 | } | ||
| 734 | |||
| 735 | seq_puts(seq, "promotion[--] "); | ||
| 736 | |||
| 737 | seq_puts(seq, "demotion[--] "); | ||
| 738 | |||
| 739 | seq_printf(seq, "latency[%03d] usage[%08d] duration[%020Lu]\n", | ||
| 740 | pr->power.states[i].latency, | ||
| 741 | pr->power.states[i].usage, | ||
| 742 | us_to_pm_timer_ticks(pr->power.states[i].time)); | ||
| 743 | } | ||
| 744 | |||
| 745 | end: | ||
| 746 | return 0; | ||
| 747 | } | ||
| 748 | |||
| 749 | static int acpi_processor_power_open_fs(struct inode *inode, struct file *file) | ||
| 750 | { | ||
| 751 | return single_open(file, acpi_processor_power_seq_show, | ||
| 752 | PDE(inode)->data); | ||
| 753 | } | ||
| 754 | |||
| 755 | static const struct file_operations acpi_processor_power_fops = { | ||
| 756 | .owner = THIS_MODULE, | ||
| 757 | .open = acpi_processor_power_open_fs, | ||
| 758 | .read = seq_read, | ||
| 759 | .llseek = seq_lseek, | ||
| 760 | .release = single_release, | ||
| 761 | }; | ||
| 762 | #endif | ||
| 763 | |||
| 764 | /** | 683 | /** |
| 765 | * acpi_idle_bm_check - checks if bus master activity was detected | 684 | * acpi_idle_bm_check - checks if bus master activity was detected |
| 766 | */ | 685 | */ |
| @@ -803,13 +722,12 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) | |||
| 803 | } else if (cx->entry_method == ACPI_CSTATE_HALT) { | 722 | } else if (cx->entry_method == ACPI_CSTATE_HALT) { |
| 804 | acpi_safe_halt(); | 723 | acpi_safe_halt(); |
| 805 | } else { | 724 | } else { |
| 806 | int unused; | ||
| 807 | /* IO port based C-state */ | 725 | /* IO port based C-state */ |
| 808 | inb(cx->address); | 726 | inb(cx->address); |
| 809 | /* Dummy wait op - must do something useless after P_LVL2 read | 727 | /* Dummy wait op - must do something useless after P_LVL2 read |
| 810 | because chipsets cannot guarantee that STPCLK# signal | 728 | because chipsets cannot guarantee that STPCLK# signal |
| 811 | gets asserted in time to freeze execution properly. */ | 729 | gets asserted in time to freeze execution properly. */ |
| 812 | unused = inl(acpi_gbl_FADT.xpm_timer_block.address); | 730 | inl(acpi_gbl_FADT.xpm_timer_block.address); |
| 813 | } | 731 | } |
| 814 | start_critical_timings(); | 732 | start_critical_timings(); |
| 815 | } | 733 | } |
| @@ -1172,9 +1090,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
| 1172 | { | 1090 | { |
| 1173 | acpi_status status = 0; | 1091 | acpi_status status = 0; |
| 1174 | static int first_run; | 1092 | static int first_run; |
| 1175 | #ifdef CONFIG_ACPI_PROCFS | ||
| 1176 | struct proc_dir_entry *entry = NULL; | ||
| 1177 | #endif | ||
| 1178 | 1093 | ||
| 1179 | if (boot_option_idle_override) | 1094 | if (boot_option_idle_override) |
| 1180 | return 0; | 1095 | return 0; |
| @@ -1223,15 +1138,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
| 1223 | if (cpuidle_register_device(&pr->power.dev)) | 1138 | if (cpuidle_register_device(&pr->power.dev)) |
| 1224 | return -EIO; | 1139 | return -EIO; |
| 1225 | } | 1140 | } |
| 1226 | #ifdef CONFIG_ACPI_PROCFS | ||
| 1227 | /* 'power' [R] */ | ||
| 1228 | entry = proc_create_data(ACPI_PROCESSOR_FILE_POWER, | ||
| 1229 | S_IRUGO, acpi_device_dir(device), | ||
| 1230 | &acpi_processor_power_fops, | ||
| 1231 | acpi_driver_data(device)); | ||
| 1232 | if (!entry) | ||
| 1233 | return -EIO; | ||
| 1234 | #endif | ||
| 1235 | return 0; | 1141 | return 0; |
| 1236 | } | 1142 | } |
| 1237 | 1143 | ||
| @@ -1244,11 +1150,5 @@ int acpi_processor_power_exit(struct acpi_processor *pr, | |||
| 1244 | cpuidle_unregister_device(&pr->power.dev); | 1150 | cpuidle_unregister_device(&pr->power.dev); |
| 1245 | pr->flags.power_setup_done = 0; | 1151 | pr->flags.power_setup_done = 0; |
| 1246 | 1152 | ||
| 1247 | #ifdef CONFIG_ACPI_PROCFS | ||
| 1248 | if (acpi_device_dir(device)) | ||
| 1249 | remove_proc_entry(ACPI_PROCESSOR_FILE_POWER, | ||
| 1250 | acpi_device_dir(device)); | ||
| 1251 | #endif | ||
| 1252 | |||
| 1253 | return 0; | 1153 | return 0; |
| 1254 | } | 1154 | } |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 6deafb4aa0da..953b25fb9869 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
| @@ -30,8 +30,6 @@ | |||
| 30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
| 32 | #include <linux/cpufreq.h> | 32 | #include <linux/cpufreq.h> |
| 33 | #include <linux/proc_fs.h> | ||
| 34 | #include <linux/seq_file.h> | ||
| 35 | #include <linux/sysdev.h> | 33 | #include <linux/sysdev.h> |
| 36 | 34 | ||
| 37 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
| @@ -438,84 +436,3 @@ struct thermal_cooling_device_ops processor_cooling_ops = { | |||
| 438 | .get_cur_state = processor_get_cur_state, | 436 | .get_cur_state = processor_get_cur_state, |
| 439 | .set_cur_state = processor_set_cur_state, | 437 | .set_cur_state = processor_set_cur_state, |
| 440 | }; | 438 | }; |
| 441 | |||
| 442 | /* /proc interface */ | ||
| 443 | #ifdef CONFIG_ACPI_PROCFS | ||
| 444 | static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset) | ||
| 445 | { | ||
| 446 | struct acpi_processor *pr = seq->private; | ||
| 447 | |||
| 448 | if (!pr) | ||
| 449 | goto end; | ||
| 450 | |||
| 451 | if (!pr->flags.limit) { | ||
| 452 | seq_puts(seq, "<not supported>\n"); | ||
| 453 | goto end; | ||
| 454 | } | ||
| 455 | |||
| 456 | seq_printf(seq, "active limit: P%d:T%d\n" | ||
| 457 | "user limit: P%d:T%d\n" | ||
| 458 | "thermal limit: P%d:T%d\n", | ||
| 459 | pr->limit.state.px, pr->limit.state.tx, | ||
| 460 | pr->limit.user.px, pr->limit.user.tx, | ||
| 461 | pr->limit.thermal.px, pr->limit.thermal.tx); | ||
| 462 | |||
| 463 | end: | ||
| 464 | return 0; | ||
| 465 | } | ||
| 466 | |||
| 467 | static int acpi_processor_limit_open_fs(struct inode *inode, struct file *file) | ||
| 468 | { | ||
| 469 | return single_open(file, acpi_processor_limit_seq_show, | ||
| 470 | PDE(inode)->data); | ||
| 471 | } | ||
| 472 | |||
| 473 | static ssize_t acpi_processor_write_limit(struct file * file, | ||
| 474 | const char __user * buffer, | ||
| 475 | size_t count, loff_t * data) | ||
| 476 | { | ||
| 477 | int result = 0; | ||
| 478 | struct seq_file *m = file->private_data; | ||
| 479 | struct acpi_processor *pr = m->private; | ||
| 480 | char limit_string[25] = { '\0' }; | ||
| 481 | int px = 0; | ||
| 482 | int tx = 0; | ||
| 483 | |||
| 484 | |||
| 485 | if (!pr || (count > sizeof(limit_string) - 1)) { | ||
| 486 | return -EINVAL; | ||
| 487 | } | ||
| 488 | |||
| 489 | if (copy_from_user(limit_string, buffer, count)) { | ||
| 490 | return -EFAULT; | ||
| 491 | } | ||
| 492 | |||
| 493 | limit_string[count] = '\0'; | ||
| 494 | |||
| 495 | if (sscanf(limit_string, "%d:%d", &px, &tx) != 2) { | ||
| 496 | printk(KERN_ERR PREFIX "Invalid data format\n"); | ||
| 497 | return -EINVAL; | ||
| 498 | } | ||
| 499 | |||
| 500 | if (pr->flags.throttling) { | ||
| 501 | if ((tx < 0) || (tx > (pr->throttling.state_count - 1))) { | ||
| 502 | printk(KERN_ERR PREFIX "Invalid tx\n"); | ||
| 503 | return -EINVAL; | ||
| 504 | } | ||
| 505 | pr->limit.user.tx = tx; | ||
| 506 | } | ||
| 507 | |||
| 508 | result = acpi_processor_apply_limit(pr); | ||
| 509 | |||
| 510 | return count; | ||
| 511 | } | ||
| 512 | |||
| 513 | const struct file_operations acpi_processor_limit_fops = { | ||
| 514 | .owner = THIS_MODULE, | ||
| 515 | .open = acpi_processor_limit_open_fs, | ||
| 516 | .read = seq_read, | ||
| 517 | .write = acpi_processor_write_limit, | ||
| 518 | .llseek = seq_lseek, | ||
| 519 | .release = single_release, | ||
| 520 | }; | ||
| 521 | #endif | ||
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 9ade1a5b32ed..730863855ed5 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
| @@ -1215,7 +1215,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) | |||
| 1215 | } | 1215 | } |
| 1216 | 1216 | ||
| 1217 | /* proc interface */ | 1217 | /* proc interface */ |
| 1218 | #ifdef CONFIG_ACPI_PROCFS | ||
| 1219 | static int acpi_processor_throttling_seq_show(struct seq_file *seq, | 1218 | static int acpi_processor_throttling_seq_show(struct seq_file *seq, |
| 1220 | void *offset) | 1219 | void *offset) |
| 1221 | { | 1220 | { |
| @@ -1323,4 +1322,3 @@ const struct file_operations acpi_processor_throttling_fops = { | |||
| 1323 | .llseek = seq_lseek, | 1322 | .llseek = seq_lseek, |
| 1324 | .release = single_release, | 1323 | .release = single_release, |
| 1325 | }; | 1324 | }; |
| 1326 | #endif | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index e143203254a4..cf82989ae756 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
| @@ -70,10 +70,10 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
| 70 | 70 | ||
| 71 | } | 71 | } |
| 72 | ACPI_FLUSH_CPU_CACHE(); | 72 | ACPI_FLUSH_CPU_CACHE(); |
| 73 | acpi_enable_wakeup_device_prep(acpi_state); | ||
| 74 | #endif | 73 | #endif |
| 75 | printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n", | 74 | printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n", |
| 76 | acpi_state); | 75 | acpi_state); |
| 76 | acpi_enable_wakeup_devices(acpi_state); | ||
| 77 | acpi_enter_sleep_state_prep(acpi_state); | 77 | acpi_enter_sleep_state_prep(acpi_state); |
| 78 | return 0; | 78 | return 0; |
| 79 | } | 79 | } |
| @@ -119,6 +119,16 @@ static int acpi_pm_freeze(void) | |||
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | /** | 121 | /** |
| 122 | * acpi_pre_suspend - Enable wakeup devices, "freeze" EC and save NVS. | ||
| 123 | */ | ||
| 124 | static int acpi_pm_pre_suspend(void) | ||
| 125 | { | ||
| 126 | acpi_pm_freeze(); | ||
| 127 | suspend_nvs_save(); | ||
| 128 | return 0; | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 122 | * __acpi_pm_prepare - Prepare the platform to enter the target state. | 132 | * __acpi_pm_prepare - Prepare the platform to enter the target state. |
| 123 | * | 133 | * |
| 124 | * If necessary, set the firmware waking vector and do arch-specific | 134 | * If necessary, set the firmware waking vector and do arch-specific |
| @@ -127,11 +137,9 @@ static int acpi_pm_freeze(void) | |||
| 127 | static int __acpi_pm_prepare(void) | 137 | static int __acpi_pm_prepare(void) |
| 128 | { | 138 | { |
| 129 | int error = acpi_sleep_prepare(acpi_target_sleep_state); | 139 | int error = acpi_sleep_prepare(acpi_target_sleep_state); |
| 130 | |||
| 131 | suspend_nvs_save(); | ||
| 132 | |||
| 133 | if (error) | 140 | if (error) |
| 134 | acpi_target_sleep_state = ACPI_STATE_S0; | 141 | acpi_target_sleep_state = ACPI_STATE_S0; |
| 142 | |||
| 135 | return error; | 143 | return error; |
| 136 | } | 144 | } |
| 137 | 145 | ||
| @@ -142,9 +150,8 @@ static int __acpi_pm_prepare(void) | |||
| 142 | static int acpi_pm_prepare(void) | 150 | static int acpi_pm_prepare(void) |
| 143 | { | 151 | { |
| 144 | int error = __acpi_pm_prepare(); | 152 | int error = __acpi_pm_prepare(); |
| 145 | |||
| 146 | if (!error) | 153 | if (!error) |
| 147 | acpi_pm_freeze(); | 154 | acpi_pm_pre_suspend(); |
| 148 | 155 | ||
| 149 | return error; | 156 | return error; |
| 150 | } | 157 | } |
| @@ -159,7 +166,6 @@ static void acpi_pm_finish(void) | |||
| 159 | { | 166 | { |
| 160 | u32 acpi_state = acpi_target_sleep_state; | 167 | u32 acpi_state = acpi_target_sleep_state; |
| 161 | 168 | ||
| 162 | suspend_nvs_free(); | ||
| 163 | acpi_ec_unblock_transactions(); | 169 | acpi_ec_unblock_transactions(); |
| 164 | 170 | ||
| 165 | if (acpi_state == ACPI_STATE_S0) | 171 | if (acpi_state == ACPI_STATE_S0) |
| @@ -167,7 +173,7 @@ static void acpi_pm_finish(void) | |||
| 167 | 173 | ||
| 168 | printk(KERN_INFO PREFIX "Waking up from system sleep state S%d\n", | 174 | printk(KERN_INFO PREFIX "Waking up from system sleep state S%d\n", |
| 169 | acpi_state); | 175 | acpi_state); |
| 170 | acpi_disable_wakeup_device(acpi_state); | 176 | acpi_disable_wakeup_devices(acpi_state); |
| 171 | acpi_leave_sleep_state(acpi_state); | 177 | acpi_leave_sleep_state(acpi_state); |
| 172 | 178 | ||
| 173 | /* reset firmware waking vector */ | 179 | /* reset firmware waking vector */ |
| @@ -181,6 +187,7 @@ static void acpi_pm_finish(void) | |||
| 181 | */ | 187 | */ |
| 182 | static void acpi_pm_end(void) | 188 | static void acpi_pm_end(void) |
| 183 | { | 189 | { |
| 190 | suspend_nvs_free(); | ||
| 184 | /* | 191 | /* |
| 185 | * This is necessary in case acpi_pm_finish() is not called during a | 192 | * This is necessary in case acpi_pm_finish() is not called during a |
| 186 | * failing transition to a sleep state. | 193 | * failing transition to a sleep state. |
| @@ -251,7 +258,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
| 251 | } | 258 | } |
| 252 | 259 | ||
| 253 | local_irq_save(flags); | 260 | local_irq_save(flags); |
| 254 | acpi_enable_wakeup_device(acpi_state); | ||
| 255 | switch (acpi_state) { | 261 | switch (acpi_state) { |
| 256 | case ACPI_STATE_S1: | 262 | case ACPI_STATE_S1: |
| 257 | barrier(); | 263 | barrier(); |
| @@ -297,11 +303,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
| 297 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 303 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
| 298 | } | 304 | } |
| 299 | 305 | ||
| 300 | static void acpi_suspend_finish(void) | ||
| 301 | { | ||
| 302 | acpi_pm_finish(); | ||
| 303 | } | ||
| 304 | |||
| 305 | static int acpi_suspend_state_valid(suspend_state_t pm_state) | 306 | static int acpi_suspend_state_valid(suspend_state_t pm_state) |
| 306 | { | 307 | { |
| 307 | u32 acpi_state; | 308 | u32 acpi_state; |
| @@ -323,7 +324,7 @@ static struct platform_suspend_ops acpi_suspend_ops = { | |||
| 323 | .begin = acpi_suspend_begin, | 324 | .begin = acpi_suspend_begin, |
| 324 | .prepare_late = acpi_pm_prepare, | 325 | .prepare_late = acpi_pm_prepare, |
| 325 | .enter = acpi_suspend_enter, | 326 | .enter = acpi_suspend_enter, |
| 326 | .wake = acpi_suspend_finish, | 327 | .wake = acpi_pm_finish, |
| 327 | .end = acpi_pm_end, | 328 | .end = acpi_pm_end, |
| 328 | }; | 329 | }; |
| 329 | 330 | ||
| @@ -336,9 +337,9 @@ static struct platform_suspend_ops acpi_suspend_ops = { | |||
| 336 | static int acpi_suspend_begin_old(suspend_state_t pm_state) | 337 | static int acpi_suspend_begin_old(suspend_state_t pm_state) |
| 337 | { | 338 | { |
| 338 | int error = acpi_suspend_begin(pm_state); | 339 | int error = acpi_suspend_begin(pm_state); |
| 339 | |||
| 340 | if (!error) | 340 | if (!error) |
| 341 | error = __acpi_pm_prepare(); | 341 | error = __acpi_pm_prepare(); |
| 342 | |||
| 342 | return error; | 343 | return error; |
| 343 | } | 344 | } |
| 344 | 345 | ||
| @@ -349,9 +350,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state) | |||
| 349 | static struct platform_suspend_ops acpi_suspend_ops_old = { | 350 | static struct platform_suspend_ops acpi_suspend_ops_old = { |
| 350 | .valid = acpi_suspend_state_valid, | 351 | .valid = acpi_suspend_state_valid, |
| 351 | .begin = acpi_suspend_begin_old, | 352 | .begin = acpi_suspend_begin_old, |
| 352 | .prepare_late = acpi_pm_freeze, | 353 | .prepare_late = acpi_pm_pre_suspend, |
| 353 | .enter = acpi_suspend_enter, | 354 | .enter = acpi_suspend_enter, |
| 354 | .wake = acpi_suspend_finish, | 355 | .wake = acpi_pm_finish, |
| 355 | .end = acpi_pm_end, | 356 | .end = acpi_pm_end, |
| 356 | .recover = acpi_pm_finish, | 357 | .recover = acpi_pm_finish, |
| 357 | }; | 358 | }; |
| @@ -423,16 +424,6 @@ static int acpi_hibernation_begin(void) | |||
| 423 | return error; | 424 | return error; |
| 424 | } | 425 | } |
| 425 | 426 | ||
| 426 | static int acpi_hibernation_pre_snapshot(void) | ||
| 427 | { | ||
| 428 | int error = acpi_pm_prepare(); | ||
| 429 | |||
| 430 | if (!error) | ||
| 431 | suspend_nvs_save(); | ||
| 432 | |||
| 433 | return error; | ||
| 434 | } | ||
| 435 | |||
| 436 | static int acpi_hibernation_enter(void) | 427 | static int acpi_hibernation_enter(void) |
| 437 | { | 428 | { |
| 438 | acpi_status status = AE_OK; | 429 | acpi_status status = AE_OK; |
| @@ -441,7 +432,6 @@ static int acpi_hibernation_enter(void) | |||
| 441 | ACPI_FLUSH_CPU_CACHE(); | 432 | ACPI_FLUSH_CPU_CACHE(); |
| 442 | 433 | ||
| 443 | local_irq_save(flags); | 434 | local_irq_save(flags); |
| 444 | acpi_enable_wakeup_device(ACPI_STATE_S4); | ||
| 445 | /* This shouldn't return. If it returns, we have a problem */ | 435 | /* This shouldn't return. If it returns, we have a problem */ |
| 446 | status = acpi_enter_sleep_state(ACPI_STATE_S4); | 436 | status = acpi_enter_sleep_state(ACPI_STATE_S4); |
| 447 | /* Reprogram control registers and execute _BFS */ | 437 | /* Reprogram control registers and execute _BFS */ |
| @@ -481,7 +471,7 @@ static void acpi_pm_thaw(void) | |||
| 481 | static struct platform_hibernation_ops acpi_hibernation_ops = { | 471 | static struct platform_hibernation_ops acpi_hibernation_ops = { |
| 482 | .begin = acpi_hibernation_begin, | 472 | .begin = acpi_hibernation_begin, |
| 483 | .end = acpi_pm_end, | 473 | .end = acpi_pm_end, |
| 484 | .pre_snapshot = acpi_hibernation_pre_snapshot, | 474 | .pre_snapshot = acpi_pm_prepare, |
| 485 | .finish = acpi_pm_finish, | 475 | .finish = acpi_pm_finish, |
| 486 | .prepare = acpi_pm_prepare, | 476 | .prepare = acpi_pm_prepare, |
| 487 | .enter = acpi_hibernation_enter, | 477 | .enter = acpi_hibernation_enter, |
| @@ -517,13 +507,6 @@ static int acpi_hibernation_begin_old(void) | |||
| 517 | return error; | 507 | return error; |
| 518 | } | 508 | } |
| 519 | 509 | ||
| 520 | static int acpi_hibernation_pre_snapshot_old(void) | ||
| 521 | { | ||
| 522 | acpi_pm_freeze(); | ||
| 523 | suspend_nvs_save(); | ||
| 524 | return 0; | ||
| 525 | } | ||
| 526 | |||
| 527 | /* | 510 | /* |
| 528 | * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has | 511 | * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has |
| 529 | * been requested. | 512 | * been requested. |
| @@ -531,7 +514,7 @@ static int acpi_hibernation_pre_snapshot_old(void) | |||
| 531 | static struct platform_hibernation_ops acpi_hibernation_ops_old = { | 514 | static struct platform_hibernation_ops acpi_hibernation_ops_old = { |
| 532 | .begin = acpi_hibernation_begin_old, | 515 | .begin = acpi_hibernation_begin_old, |
| 533 | .end = acpi_pm_end, | 516 | .end = acpi_pm_end, |
| 534 | .pre_snapshot = acpi_hibernation_pre_snapshot_old, | 517 | .pre_snapshot = acpi_pm_pre_suspend, |
| 535 | .prepare = acpi_pm_freeze, | 518 | .prepare = acpi_pm_freeze, |
| 536 | .finish = acpi_pm_finish, | 519 | .finish = acpi_pm_finish, |
| 537 | .enter = acpi_hibernation_enter, | 520 | .enter = acpi_hibernation_enter, |
| @@ -686,7 +669,6 @@ static void acpi_power_off(void) | |||
| 686 | /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ | 669 | /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ |
| 687 | printk(KERN_DEBUG "%s called\n", __func__); | 670 | printk(KERN_DEBUG "%s called\n", __func__); |
| 688 | local_irq_disable(); | 671 | local_irq_disable(); |
| 689 | acpi_enable_wakeup_device(ACPI_STATE_S5); | ||
| 690 | acpi_enter_sleep_state(ACPI_STATE_S5); | 672 | acpi_enter_sleep_state(ACPI_STATE_S5); |
| 691 | } | 673 | } |
| 692 | 674 | ||
diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h index 25b8bd149284..d8821805c3bc 100644 --- a/drivers/acpi/sleep.h +++ b/drivers/acpi/sleep.h | |||
| @@ -2,9 +2,8 @@ | |||
| 2 | extern u8 sleep_states[]; | 2 | extern u8 sleep_states[]; |
| 3 | extern int acpi_suspend(u32 state); | 3 | extern int acpi_suspend(u32 state); |
| 4 | 4 | ||
| 5 | extern void acpi_enable_wakeup_device_prep(u8 sleep_state); | 5 | extern void acpi_enable_wakeup_devices(u8 sleep_state); |
| 6 | extern void acpi_enable_wakeup_device(u8 sleep_state); | 6 | extern void acpi_disable_wakeup_devices(u8 sleep_state); |
| 7 | extern void acpi_disable_wakeup_device(u8 sleep_state); | ||
| 8 | 7 | ||
| 9 | extern struct list_head acpi_wakeup_device_list; | 8 | extern struct list_head acpi_wakeup_device_list; |
| 10 | extern struct mutex acpi_device_lock; | 9 | extern struct mutex acpi_device_lock; |
diff --git a/drivers/acpi/system.c b/drivers/acpi/sysfs.c index 5981bd07e20e..68e2e4582fa2 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/sysfs.c | |||
| @@ -1,51 +1,218 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * acpi_system.c - ACPI System Driver ($Revision: 63 $) | 2 | * sysfs.c - ACPI sysfs interface to userspace. |
| 3 | * | ||
| 4 | * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> | ||
| 5 | * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> | ||
| 6 | * | ||
| 7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or (at | ||
| 12 | * your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, but | ||
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 17 | * General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License along | ||
| 20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 21 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
| 22 | * | ||
| 23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 24 | */ | 3 | */ |
| 25 | 4 | ||
| 26 | #include <linux/proc_fs.h> | ||
| 27 | #include <linux/seq_file.h> | ||
| 28 | #include <linux/slab.h> | ||
| 29 | #include <linux/init.h> | 5 | #include <linux/init.h> |
| 30 | #include <linux/string.h> | 6 | #include <linux/kernel.h> |
| 31 | #include <asm/uaccess.h> | 7 | #include <linux/moduleparam.h> |
| 32 | |||
| 33 | #include <acpi/acpi_drivers.h> | 8 | #include <acpi/acpi_drivers.h> |
| 34 | 9 | ||
| 35 | #define PREFIX "ACPI: " | ||
| 36 | |||
| 37 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 10 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
| 38 | ACPI_MODULE_NAME("system"); | 11 | ACPI_MODULE_NAME("sysfs"); |
| 39 | |||
| 40 | #define ACPI_SYSTEM_CLASS "system" | ||
| 41 | #define ACPI_SYSTEM_DEVICE_NAME "System" | ||
| 42 | 12 | ||
| 43 | u32 acpi_irq_handled; | 13 | #define PREFIX "ACPI: " |
| 44 | u32 acpi_irq_not_handled; | ||
| 45 | 14 | ||
| 15 | #ifdef CONFIG_ACPI_DEBUG | ||
| 46 | /* | 16 | /* |
| 47 | * Make ACPICA version work as module param | 17 | * ACPI debug sysfs I/F, including: |
| 18 | * /sys/modules/acpi/parameters/debug_layer | ||
| 19 | * /sys/modules/acpi/parameters/debug_level | ||
| 20 | * /sys/modules/acpi/parameters/trace_method_name | ||
| 21 | * /sys/modules/acpi/parameters/trace_state | ||
| 22 | * /sys/modules/acpi/parameters/trace_debug_layer | ||
| 23 | * /sys/modules/acpi/parameters/trace_debug_level | ||
| 48 | */ | 24 | */ |
| 25 | |||
| 26 | struct acpi_dlayer { | ||
| 27 | const char *name; | ||
| 28 | unsigned long value; | ||
| 29 | }; | ||
| 30 | struct acpi_dlevel { | ||
| 31 | const char *name; | ||
| 32 | unsigned long value; | ||
| 33 | }; | ||
| 34 | #define ACPI_DEBUG_INIT(v) { .name = #v, .value = v } | ||
| 35 | |||
| 36 | static const struct acpi_dlayer acpi_debug_layers[] = { | ||
| 37 | ACPI_DEBUG_INIT(ACPI_UTILITIES), | ||
| 38 | ACPI_DEBUG_INIT(ACPI_HARDWARE), | ||
| 39 | ACPI_DEBUG_INIT(ACPI_EVENTS), | ||
| 40 | ACPI_DEBUG_INIT(ACPI_TABLES), | ||
| 41 | ACPI_DEBUG_INIT(ACPI_NAMESPACE), | ||
| 42 | ACPI_DEBUG_INIT(ACPI_PARSER), | ||
| 43 | ACPI_DEBUG_INIT(ACPI_DISPATCHER), | ||
| 44 | ACPI_DEBUG_INIT(ACPI_EXECUTER), | ||
| 45 | ACPI_DEBUG_INIT(ACPI_RESOURCES), | ||
| 46 | ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER), | ||
| 47 | ACPI_DEBUG_INIT(ACPI_OS_SERVICES), | ||
| 48 | ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER), | ||
| 49 | ACPI_DEBUG_INIT(ACPI_COMPILER), | ||
| 50 | ACPI_DEBUG_INIT(ACPI_TOOLS), | ||
| 51 | |||
| 52 | ACPI_DEBUG_INIT(ACPI_BUS_COMPONENT), | ||
| 53 | ACPI_DEBUG_INIT(ACPI_AC_COMPONENT), | ||
| 54 | ACPI_DEBUG_INIT(ACPI_BATTERY_COMPONENT), | ||
| 55 | ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT), | ||
| 56 | ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT), | ||
| 57 | ACPI_DEBUG_INIT(ACPI_FAN_COMPONENT), | ||
| 58 | ACPI_DEBUG_INIT(ACPI_PCI_COMPONENT), | ||
| 59 | ACPI_DEBUG_INIT(ACPI_POWER_COMPONENT), | ||
| 60 | ACPI_DEBUG_INIT(ACPI_CONTAINER_COMPONENT), | ||
| 61 | ACPI_DEBUG_INIT(ACPI_SYSTEM_COMPONENT), | ||
| 62 | ACPI_DEBUG_INIT(ACPI_THERMAL_COMPONENT), | ||
| 63 | ACPI_DEBUG_INIT(ACPI_MEMORY_DEVICE_COMPONENT), | ||
| 64 | ACPI_DEBUG_INIT(ACPI_VIDEO_COMPONENT), | ||
| 65 | ACPI_DEBUG_INIT(ACPI_PROCESSOR_COMPONENT), | ||
| 66 | }; | ||
| 67 | |||
| 68 | static const struct acpi_dlevel acpi_debug_levels[] = { | ||
| 69 | ACPI_DEBUG_INIT(ACPI_LV_INIT), | ||
| 70 | ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT), | ||
| 71 | ACPI_DEBUG_INIT(ACPI_LV_INFO), | ||
| 72 | |||
| 73 | ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES), | ||
| 74 | ACPI_DEBUG_INIT(ACPI_LV_PARSE), | ||
| 75 | ACPI_DEBUG_INIT(ACPI_LV_LOAD), | ||
| 76 | ACPI_DEBUG_INIT(ACPI_LV_DISPATCH), | ||
| 77 | ACPI_DEBUG_INIT(ACPI_LV_EXEC), | ||
| 78 | ACPI_DEBUG_INIT(ACPI_LV_NAMES), | ||
| 79 | ACPI_DEBUG_INIT(ACPI_LV_OPREGION), | ||
| 80 | ACPI_DEBUG_INIT(ACPI_LV_BFIELD), | ||
| 81 | ACPI_DEBUG_INIT(ACPI_LV_TABLES), | ||
| 82 | ACPI_DEBUG_INIT(ACPI_LV_VALUES), | ||
| 83 | ACPI_DEBUG_INIT(ACPI_LV_OBJECTS), | ||
| 84 | ACPI_DEBUG_INIT(ACPI_LV_RESOURCES), | ||
| 85 | ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS), | ||
| 86 | ACPI_DEBUG_INIT(ACPI_LV_PACKAGE), | ||
| 87 | |||
| 88 | ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS), | ||
| 89 | ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS), | ||
| 90 | ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS), | ||
| 91 | |||
| 92 | ACPI_DEBUG_INIT(ACPI_LV_MUTEX), | ||
| 93 | ACPI_DEBUG_INIT(ACPI_LV_THREADS), | ||
| 94 | ACPI_DEBUG_INIT(ACPI_LV_IO), | ||
| 95 | ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS), | ||
| 96 | |||
| 97 | ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE), | ||
| 98 | ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO), | ||
| 99 | ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES), | ||
| 100 | ACPI_DEBUG_INIT(ACPI_LV_EVENTS), | ||
| 101 | }; | ||
| 102 | |||
| 103 | static int param_get_debug_layer(char *buffer, struct kernel_param *kp) | ||
| 104 | { | ||
| 105 | int result = 0; | ||
| 106 | int i; | ||
| 107 | |||
| 108 | result = sprintf(buffer, "%-25s\tHex SET\n", "Description"); | ||
| 109 | |||
| 110 | for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) { | ||
| 111 | result += sprintf(buffer + result, "%-25s\t0x%08lX [%c]\n", | ||
| 112 | acpi_debug_layers[i].name, | ||
| 113 | acpi_debug_layers[i].value, | ||
| 114 | (acpi_dbg_layer & acpi_debug_layers[i].value) | ||
| 115 | ? '*' : ' '); | ||
| 116 | } | ||
| 117 | result += | ||
| 118 | sprintf(buffer + result, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", | ||
| 119 | ACPI_ALL_DRIVERS, | ||
| 120 | (acpi_dbg_layer & ACPI_ALL_DRIVERS) == | ||
| 121 | ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & ACPI_ALL_DRIVERS) | ||
| 122 | == 0 ? ' ' : '-'); | ||
| 123 | result += | ||
| 124 | sprintf(buffer + result, | ||
| 125 | "--\ndebug_layer = 0x%08X ( * = enabled)\n", | ||
| 126 | acpi_dbg_layer); | ||
| 127 | |||
| 128 | return result; | ||
| 129 | } | ||
| 130 | |||
| 131 | static int param_get_debug_level(char *buffer, struct kernel_param *kp) | ||
| 132 | { | ||
| 133 | int result = 0; | ||
| 134 | int i; | ||
| 135 | |||
| 136 | result = sprintf(buffer, "%-25s\tHex SET\n", "Description"); | ||
| 137 | |||
| 138 | for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { | ||
| 139 | result += sprintf(buffer + result, "%-25s\t0x%08lX [%c]\n", | ||
| 140 | acpi_debug_levels[i].name, | ||
| 141 | acpi_debug_levels[i].value, | ||
| 142 | (acpi_dbg_level & acpi_debug_levels[i].value) | ||
| 143 | ? '*' : ' '); | ||
| 144 | } | ||
| 145 | result += | ||
| 146 | sprintf(buffer + result, "--\ndebug_level = 0x%08X (* = enabled)\n", | ||
| 147 | acpi_dbg_level); | ||
| 148 | |||
| 149 | return result; | ||
| 150 | } | ||
| 151 | |||
| 152 | module_param_call(debug_layer, param_set_uint, param_get_debug_layer, | ||
| 153 | &acpi_dbg_layer, 0644); | ||
| 154 | module_param_call(debug_level, param_set_uint, param_get_debug_level, | ||
| 155 | &acpi_dbg_level, 0644); | ||
| 156 | |||
| 157 | static char trace_method_name[6]; | ||
| 158 | module_param_string(trace_method_name, trace_method_name, 6, 0644); | ||
| 159 | static unsigned int trace_debug_layer; | ||
| 160 | module_param(trace_debug_layer, uint, 0644); | ||
| 161 | static unsigned int trace_debug_level; | ||
| 162 | module_param(trace_debug_level, uint, 0644); | ||
| 163 | |||
| 164 | static int param_set_trace_state(const char *val, struct kernel_param *kp) | ||
| 165 | { | ||
| 166 | int result = 0; | ||
| 167 | |||
| 168 | if (!strncmp(val, "enable", strlen("enable") - 1)) { | ||
| 169 | result = acpi_debug_trace(trace_method_name, trace_debug_level, | ||
| 170 | trace_debug_layer, 0); | ||
| 171 | if (result) | ||
| 172 | result = -EBUSY; | ||
| 173 | goto exit; | ||
| 174 | } | ||
| 175 | |||
| 176 | if (!strncmp(val, "disable", strlen("disable") - 1)) { | ||
| 177 | int name = 0; | ||
| 178 | result = acpi_debug_trace((char *)&name, trace_debug_level, | ||
| 179 | trace_debug_layer, 0); | ||
| 180 | if (result) | ||
| 181 | result = -EBUSY; | ||
| 182 | goto exit; | ||
| 183 | } | ||
| 184 | |||
| 185 | if (!strncmp(val, "1", 1)) { | ||
| 186 | result = acpi_debug_trace(trace_method_name, trace_debug_level, | ||
| 187 | trace_debug_layer, 1); | ||
| 188 | if (result) | ||
| 189 | result = -EBUSY; | ||
| 190 | goto exit; | ||
| 191 | } | ||
| 192 | |||
| 193 | result = -EINVAL; | ||
| 194 | exit: | ||
| 195 | return result; | ||
| 196 | } | ||
| 197 | |||
| 198 | static int param_get_trace_state(char *buffer, struct kernel_param *kp) | ||
| 199 | { | ||
| 200 | if (!acpi_gbl_trace_method_name) | ||
| 201 | return sprintf(buffer, "disable"); | ||
| 202 | else { | ||
| 203 | if (acpi_gbl_trace_flags & 1) | ||
| 204 | return sprintf(buffer, "1"); | ||
| 205 | else | ||
| 206 | return sprintf(buffer, "enable"); | ||
| 207 | } | ||
| 208 | return 0; | ||
| 209 | } | ||
| 210 | |||
| 211 | module_param_call(trace_state, param_set_trace_state, param_get_trace_state, | ||
| 212 | NULL, 0644); | ||
| 213 | #endif /* CONFIG_ACPI_DEBUG */ | ||
| 214 | |||
| 215 | /* /sys/module/acpi/parameters/acpica_version */ | ||
| 49 | static int param_get_acpica_version(char *buffer, struct kernel_param *kp) | 216 | static int param_get_acpica_version(char *buffer, struct kernel_param *kp) |
| 50 | { | 217 | { |
| 51 | int result; | 218 | int result; |
| @@ -57,9 +224,12 @@ static int param_get_acpica_version(char *buffer, struct kernel_param *kp) | |||
| 57 | 224 | ||
| 58 | module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); | 225 | module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); |
| 59 | 226 | ||
| 60 | /* -------------------------------------------------------------------------- | 227 | /* |
| 61 | FS Interface (/sys) | 228 | * ACPI table sysfs I/F: |
| 62 | -------------------------------------------------------------------------- */ | 229 | * /sys/firmware/acpi/tables/ |
| 230 | * /sys/firmware/acpi/tables/dynamic/ | ||
| 231 | */ | ||
| 232 | |||
| 63 | static LIST_HEAD(acpi_table_attr_list); | 233 | static LIST_HEAD(acpi_table_attr_list); |
| 64 | static struct kobject *tables_kobj; | 234 | static struct kobject *tables_kobj; |
| 65 | static struct kobject *dynamic_tables_kobj; | 235 | static struct kobject *dynamic_tables_kobj; |
| @@ -86,14 +256,12 @@ static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj, | |||
| 86 | else | 256 | else |
| 87 | memcpy(name, "\0\0\0\0", 4); | 257 | memcpy(name, "\0\0\0\0", 4); |
| 88 | 258 | ||
| 89 | status = | 259 | status = acpi_get_table(name, table_attr->instance, &table_header); |
| 90 | acpi_get_table(name, table_attr->instance, | ||
| 91 | &table_header); | ||
| 92 | if (ACPI_FAILURE(status)) | 260 | if (ACPI_FAILURE(status)) |
| 93 | return -ENODEV; | 261 | return -ENODEV; |
| 94 | 262 | ||
| 95 | return memory_read_from_buffer(buf, count, &offset, | 263 | return memory_read_from_buffer(buf, count, &offset, |
| 96 | table_header, table_header->length); | 264 | table_header, table_header->length); |
| 97 | } | 265 | } |
| 98 | 266 | ||
| 99 | static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | 267 | 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, | |||
| 105 | sysfs_attr_init(&table_attr->attr.attr); | 273 | sysfs_attr_init(&table_attr->attr.attr); |
| 106 | if (table_header->signature[0] != '\0') | 274 | if (table_header->signature[0] != '\0') |
| 107 | memcpy(table_attr->name, table_header->signature, | 275 | memcpy(table_attr->name, table_header->signature, |
| 108 | ACPI_NAME_SIZE); | 276 | ACPI_NAME_SIZE); |
| 109 | else | 277 | else |
| 110 | memcpy(table_attr->name, "NULL", 4); | 278 | memcpy(table_attr->name, "NULL", 4); |
| 111 | 279 | ||
| @@ -117,8 +285,8 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | |||
| 117 | table_attr->instance++; | 285 | table_attr->instance++; |
| 118 | 286 | ||
| 119 | if (table_attr->instance > 1 || (table_attr->instance == 1 && | 287 | if (table_attr->instance > 1 || (table_attr->instance == 1 && |
| 120 | !acpi_get_table | 288 | !acpi_get_table |
| 121 | (table_header->signature, 2, &header))) | 289 | (table_header->signature, 2, &header))) |
| 122 | sprintf(table_attr->name + ACPI_NAME_SIZE, "%d", | 290 | sprintf(table_attr->name + ACPI_NAME_SIZE, "%d", |
| 123 | table_attr->instance); | 291 | table_attr->instance); |
| 124 | 292 | ||
| @@ -138,18 +306,17 @@ acpi_sysfs_table_handler(u32 event, void *table, void *context) | |||
| 138 | switch (event) { | 306 | switch (event) { |
| 139 | case ACPI_TABLE_EVENT_LOAD: | 307 | case ACPI_TABLE_EVENT_LOAD: |
| 140 | table_attr = | 308 | table_attr = |
| 141 | kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); | 309 | kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); |
| 142 | if (!table_attr) | 310 | if (!table_attr) |
| 143 | return AE_NO_MEMORY; | 311 | return AE_NO_MEMORY; |
| 144 | 312 | ||
| 145 | acpi_table_attr_init(table_attr, table); | 313 | acpi_table_attr_init(table_attr, table); |
| 146 | if (sysfs_create_bin_file(dynamic_tables_kobj, | 314 | if (sysfs_create_bin_file(dynamic_tables_kobj, |
| 147 | &table_attr->attr)) { | 315 | &table_attr->attr)) { |
| 148 | kfree(table_attr); | 316 | kfree(table_attr); |
| 149 | return AE_ERROR; | 317 | return AE_ERROR; |
| 150 | } else | 318 | } else |
| 151 | list_add_tail(&table_attr->node, | 319 | list_add_tail(&table_attr->node, &acpi_table_attr_list); |
| 152 | &acpi_table_attr_list); | ||
| 153 | break; | 320 | break; |
| 154 | case ACPI_TABLE_EVENT_UNLOAD: | 321 | case ACPI_TABLE_EVENT_UNLOAD: |
| 155 | /* | 322 | /* |
| @@ -164,7 +331,7 @@ acpi_sysfs_table_handler(u32 event, void *table, void *context) | |||
| 164 | return AE_OK; | 331 | return AE_OK; |
| 165 | } | 332 | } |
| 166 | 333 | ||
| 167 | static int acpi_system_sysfs_init(void) | 334 | static int acpi_tables_sysfs_init(void) |
| 168 | { | 335 | { |
| 169 | struct acpi_table_attr *table_attr; | 336 | struct acpi_table_attr *table_attr; |
| 170 | struct acpi_table_header *table_header = NULL; | 337 | struct acpi_table_header *table_header = NULL; |
| @@ -213,14 +380,17 @@ err: | |||
| 213 | } | 380 | } |
| 214 | 381 | ||
| 215 | /* | 382 | /* |
| 216 | * Detailed ACPI IRQ counters in /sys/firmware/acpi/interrupts/ | 383 | * Detailed ACPI IRQ counters: |
| 217 | * See Documentation/ABI/testing/sysfs-firmware-acpi | 384 | * /sys/firmware/acpi/interrupts/ |
| 218 | */ | 385 | */ |
| 219 | 386 | ||
| 387 | u32 acpi_irq_handled; | ||
| 388 | u32 acpi_irq_not_handled; | ||
| 389 | |||
| 220 | #define COUNT_GPE 0 | 390 | #define COUNT_GPE 0 |
| 221 | #define COUNT_SCI 1 /* acpi_irq_handled */ | 391 | #define COUNT_SCI 1 /* acpi_irq_handled */ |
| 222 | #define COUNT_SCI_NOT 2 /* acpi_irq_not_handled */ | 392 | #define COUNT_SCI_NOT 2 /* acpi_irq_not_handled */ |
| 223 | #define COUNT_ERROR 3 /* other */ | 393 | #define COUNT_ERROR 3 /* other */ |
| 224 | #define NUM_COUNTERS_EXTRA 4 | 394 | #define NUM_COUNTERS_EXTRA 4 |
| 225 | 395 | ||
| 226 | struct event_counter { | 396 | struct event_counter { |
| @@ -237,6 +407,7 @@ static u32 acpi_gpe_count; | |||
| 237 | static struct attribute_group interrupt_stats_attr_group = { | 407 | static struct attribute_group interrupt_stats_attr_group = { |
| 238 | .name = "interrupts", | 408 | .name = "interrupts", |
| 239 | }; | 409 | }; |
| 410 | |||
| 240 | static struct kobj_attribute *counter_attrs; | 411 | static struct kobj_attribute *counter_attrs; |
| 241 | 412 | ||
| 242 | static void delete_gpe_attr_array(void) | 413 | static void delete_gpe_attr_array(void) |
| @@ -269,8 +440,8 @@ void acpi_os_gpe_count(u32 gpe_number) | |||
| 269 | if (gpe_number < num_gpes) | 440 | if (gpe_number < num_gpes) |
| 270 | all_counters[gpe_number].count++; | 441 | all_counters[gpe_number].count++; |
| 271 | else | 442 | else |
| 272 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]. | 443 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + |
| 273 | count++; | 444 | COUNT_ERROR].count++; |
| 274 | 445 | ||
| 275 | return; | 446 | return; |
| 276 | } | 447 | } |
| @@ -283,13 +454,14 @@ void acpi_os_fixed_event_count(u32 event_number) | |||
| 283 | if (event_number < ACPI_NUM_FIXED_EVENTS) | 454 | if (event_number < ACPI_NUM_FIXED_EVENTS) |
| 284 | all_counters[num_gpes + event_number].count++; | 455 | all_counters[num_gpes + event_number].count++; |
| 285 | else | 456 | else |
| 286 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]. | 457 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + |
| 287 | count++; | 458 | COUNT_ERROR].count++; |
| 288 | 459 | ||
| 289 | return; | 460 | return; |
| 290 | } | 461 | } |
| 291 | 462 | ||
| 292 | static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) | 463 | static int get_status(u32 index, acpi_event_status *status, |
| 464 | acpi_handle *handle) | ||
| 293 | { | 465 | { |
| 294 | int result = 0; | 466 | int result = 0; |
| 295 | 467 | ||
| @@ -300,7 +472,7 @@ static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) | |||
| 300 | result = acpi_get_gpe_device(index, handle); | 472 | result = acpi_get_gpe_device(index, handle); |
| 301 | if (result) { | 473 | if (result) { |
| 302 | ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND, | 474 | ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND, |
| 303 | "Invalid GPE 0x%x\n", index)); | 475 | "Invalid GPE 0x%x\n", index)); |
| 304 | goto end; | 476 | goto end; |
| 305 | } | 477 | } |
| 306 | result = acpi_get_gpe_status(*handle, index, status); | 478 | result = acpi_get_gpe_status(*handle, index, status); |
| @@ -312,7 +484,7 @@ end: | |||
| 312 | } | 484 | } |
| 313 | 485 | ||
| 314 | static ssize_t counter_show(struct kobject *kobj, | 486 | static ssize_t counter_show(struct kobject *kobj, |
| 315 | struct kobj_attribute *attr, char *buf) | 487 | struct kobj_attribute *attr, char *buf) |
| 316 | { | 488 | { |
| 317 | int index = attr - counter_attrs; | 489 | int index = attr - counter_attrs; |
| 318 | int size; | 490 | int size; |
| @@ -321,12 +493,11 @@ static ssize_t counter_show(struct kobject *kobj, | |||
| 321 | int result = 0; | 493 | int result = 0; |
| 322 | 494 | ||
| 323 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count = | 495 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count = |
| 324 | acpi_irq_handled; | 496 | acpi_irq_handled; |
| 325 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count = | 497 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count = |
| 326 | acpi_irq_not_handled; | 498 | acpi_irq_not_handled; |
| 327 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count = | 499 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count = |
| 328 | acpi_gpe_count; | 500 | acpi_gpe_count; |
| 329 | |||
| 330 | size = sprintf(buf, "%8d", all_counters[index].count); | 501 | size = sprintf(buf, "%8d", all_counters[index].count); |
| 331 | 502 | ||
| 332 | /* "gpe_all" or "sci" */ | 503 | /* "gpe_all" or "sci" */ |
| @@ -338,13 +509,13 @@ static ssize_t counter_show(struct kobject *kobj, | |||
| 338 | goto end; | 509 | goto end; |
| 339 | 510 | ||
| 340 | if (!(status & ACPI_EVENT_FLAG_HANDLE)) | 511 | if (!(status & ACPI_EVENT_FLAG_HANDLE)) |
| 341 | size += sprintf(buf + size, " invalid"); | 512 | size += sprintf(buf + size, " invalid"); |
| 342 | else if (status & ACPI_EVENT_FLAG_ENABLED) | 513 | else if (status & ACPI_EVENT_FLAG_ENABLED) |
| 343 | size += sprintf(buf + size, " enabled"); | 514 | size += sprintf(buf + size, " enabled"); |
| 344 | else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED) | 515 | else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED) |
| 345 | size += sprintf(buf + size, " wake_enabled"); | 516 | size += sprintf(buf + size, " wake_enabled"); |
| 346 | else | 517 | else |
| 347 | size += sprintf(buf + size, " disabled"); | 518 | size += sprintf(buf + size, " disabled"); |
| 348 | 519 | ||
| 349 | end: | 520 | end: |
| 350 | size += sprintf(buf + size, "\n"); | 521 | size += sprintf(buf + size, "\n"); |
| @@ -357,7 +528,8 @@ end: | |||
| 357 | * enable/disable/clear a gpe/fixed event in user space. | 528 | * enable/disable/clear a gpe/fixed event in user space. |
| 358 | */ | 529 | */ |
| 359 | static ssize_t counter_set(struct kobject *kobj, | 530 | static ssize_t counter_set(struct kobject *kobj, |
| 360 | struct kobj_attribute *attr, const char *buf, size_t size) | 531 | struct kobj_attribute *attr, const char *buf, |
| 532 | size_t size) | ||
| 361 | { | 533 | { |
| 362 | int index = attr - counter_attrs; | 534 | int index = attr - counter_attrs; |
| 363 | acpi_event_status status; | 535 | acpi_event_status status; |
| @@ -381,32 +553,32 @@ static ssize_t counter_set(struct kobject *kobj, | |||
| 381 | 553 | ||
| 382 | if (!(status & ACPI_EVENT_FLAG_HANDLE)) { | 554 | if (!(status & ACPI_EVENT_FLAG_HANDLE)) { |
| 383 | printk(KERN_WARNING PREFIX | 555 | printk(KERN_WARNING PREFIX |
| 384 | "Can not change Invalid GPE/Fixed Event status\n"); | 556 | "Can not change Invalid GPE/Fixed Event status\n"); |
| 385 | return -EINVAL; | 557 | return -EINVAL; |
| 386 | } | 558 | } |
| 387 | 559 | ||
| 388 | if (index < num_gpes) { | 560 | if (index < num_gpes) { |
| 389 | if (!strcmp(buf, "disable\n") && | 561 | if (!strcmp(buf, "disable\n") && |
| 390 | (status & ACPI_EVENT_FLAG_ENABLED)) | 562 | (status & ACPI_EVENT_FLAG_ENABLED)) |
| 391 | result = acpi_disable_gpe(handle, index); | 563 | result = acpi_disable_gpe(handle, index); |
| 392 | else if (!strcmp(buf, "enable\n") && | 564 | else if (!strcmp(buf, "enable\n") && |
| 393 | !(status & ACPI_EVENT_FLAG_ENABLED)) | 565 | !(status & ACPI_EVENT_FLAG_ENABLED)) |
| 394 | result = acpi_enable_gpe(handle, index); | 566 | result = acpi_enable_gpe(handle, index); |
| 395 | else if (!strcmp(buf, "clear\n") && | 567 | else if (!strcmp(buf, "clear\n") && |
| 396 | (status & ACPI_EVENT_FLAG_SET)) | 568 | (status & ACPI_EVENT_FLAG_SET)) |
| 397 | result = acpi_clear_gpe(handle, index); | 569 | result = acpi_clear_gpe(handle, index); |
| 398 | else | 570 | else |
| 399 | all_counters[index].count = strtoul(buf, NULL, 0); | 571 | all_counters[index].count = strtoul(buf, NULL, 0); |
| 400 | } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { | 572 | } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { |
| 401 | int event = index - num_gpes; | 573 | int event = index - num_gpes; |
| 402 | if (!strcmp(buf, "disable\n") && | 574 | if (!strcmp(buf, "disable\n") && |
| 403 | (status & ACPI_EVENT_FLAG_ENABLED)) | 575 | (status & ACPI_EVENT_FLAG_ENABLED)) |
| 404 | result = acpi_disable_event(event, ACPI_NOT_ISR); | 576 | result = acpi_disable_event(event, ACPI_NOT_ISR); |
| 405 | else if (!strcmp(buf, "enable\n") && | 577 | else if (!strcmp(buf, "enable\n") && |
| 406 | !(status & ACPI_EVENT_FLAG_ENABLED)) | 578 | !(status & ACPI_EVENT_FLAG_ENABLED)) |
| 407 | result = acpi_enable_event(event, ACPI_NOT_ISR); | 579 | result = acpi_enable_event(event, ACPI_NOT_ISR); |
| 408 | else if (!strcmp(buf, "clear\n") && | 580 | else if (!strcmp(buf, "clear\n") && |
| 409 | (status & ACPI_EVENT_FLAG_SET)) | 581 | (status & ACPI_EVENT_FLAG_SET)) |
| 410 | result = acpi_clear_event(event); | 582 | result = acpi_clear_event(event); |
| 411 | else | 583 | else |
| 412 | all_counters[index].count = strtoul(buf, NULL, 0); | 584 | all_counters[index].count = strtoul(buf, NULL, 0); |
| @@ -430,17 +602,17 @@ void acpi_irq_stats_init(void) | |||
| 430 | num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA; | 602 | num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA; |
| 431 | 603 | ||
| 432 | all_attrs = kzalloc(sizeof(struct attribute *) * (num_counters + 1), | 604 | all_attrs = kzalloc(sizeof(struct attribute *) * (num_counters + 1), |
| 433 | GFP_KERNEL); | 605 | GFP_KERNEL); |
| 434 | if (all_attrs == NULL) | 606 | if (all_attrs == NULL) |
| 435 | return; | 607 | return; |
| 436 | 608 | ||
| 437 | all_counters = kzalloc(sizeof(struct event_counter) * (num_counters), | 609 | all_counters = kzalloc(sizeof(struct event_counter) * (num_counters), |
| 438 | GFP_KERNEL); | 610 | GFP_KERNEL); |
| 439 | if (all_counters == NULL) | 611 | if (all_counters == NULL) |
| 440 | goto fail; | 612 | goto fail; |
| 441 | 613 | ||
| 442 | counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), | 614 | counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), |
| 443 | GFP_KERNEL); | 615 | GFP_KERNEL); |
| 444 | if (counter_attrs == NULL) | 616 | if (counter_attrs == NULL) |
| 445 | goto fail; | 617 | goto fail; |
| 446 | 618 | ||
| @@ -503,135 +675,11 @@ static void __exit interrupt_stats_exit(void) | |||
| 503 | return; | 675 | return; |
| 504 | } | 676 | } |
| 505 | 677 | ||
| 506 | /* -------------------------------------------------------------------------- | 678 | int __init acpi_sysfs_init(void) |
| 507 | FS Interface (/proc) | ||
| 508 | -------------------------------------------------------------------------- */ | ||
| 509 | #ifdef CONFIG_ACPI_PROCFS | ||
| 510 | #define ACPI_SYSTEM_FILE_INFO "info" | ||
| 511 | #define ACPI_SYSTEM_FILE_EVENT "event" | ||
| 512 | #define ACPI_SYSTEM_FILE_DSDT "dsdt" | ||
| 513 | #define ACPI_SYSTEM_FILE_FADT "fadt" | ||
| 514 | |||
| 515 | static int acpi_system_read_info(struct seq_file *seq, void *offset) | ||
| 516 | { | ||
| 517 | |||
| 518 | seq_printf(seq, "version: %x\n", ACPI_CA_VERSION); | ||
| 519 | return 0; | ||
| 520 | } | ||
| 521 | |||
| 522 | static int acpi_system_info_open_fs(struct inode *inode, struct file *file) | ||
| 523 | { | ||
| 524 | return single_open(file, acpi_system_read_info, PDE(inode)->data); | ||
| 525 | } | ||
| 526 | |||
| 527 | static const struct file_operations acpi_system_info_ops = { | ||
| 528 | .owner = THIS_MODULE, | ||
| 529 | .open = acpi_system_info_open_fs, | ||
| 530 | .read = seq_read, | ||
| 531 | .llseek = seq_lseek, | ||
| 532 | .release = single_release, | ||
| 533 | }; | ||
| 534 | |||
| 535 | static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t, | ||
| 536 | loff_t *); | ||
| 537 | |||
| 538 | static const struct file_operations acpi_system_dsdt_ops = { | ||
| 539 | .owner = THIS_MODULE, | ||
| 540 | .read = acpi_system_read_dsdt, | ||
| 541 | }; | ||
| 542 | |||
| 543 | static ssize_t | ||
| 544 | acpi_system_read_dsdt(struct file *file, | ||
| 545 | char __user * buffer, size_t count, loff_t * ppos) | ||
| 546 | { | ||
| 547 | acpi_status status = AE_OK; | ||
| 548 | struct acpi_table_header *dsdt = NULL; | ||
| 549 | ssize_t res; | ||
| 550 | |||
| 551 | status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt); | ||
| 552 | if (ACPI_FAILURE(status)) | ||
| 553 | return -ENODEV; | ||
| 554 | |||
| 555 | res = simple_read_from_buffer(buffer, count, ppos, dsdt, dsdt->length); | ||
| 556 | |||
| 557 | return res; | ||
| 558 | } | ||
| 559 | |||
| 560 | static ssize_t acpi_system_read_fadt(struct file *, char __user *, size_t, | ||
| 561 | loff_t *); | ||
| 562 | |||
| 563 | static const struct file_operations acpi_system_fadt_ops = { | ||
| 564 | .owner = THIS_MODULE, | ||
| 565 | .read = acpi_system_read_fadt, | ||
| 566 | }; | ||
| 567 | |||
| 568 | static ssize_t | ||
| 569 | acpi_system_read_fadt(struct file *file, | ||
| 570 | char __user * buffer, size_t count, loff_t * ppos) | ||
| 571 | { | ||
| 572 | acpi_status status = AE_OK; | ||
| 573 | struct acpi_table_header *fadt = NULL; | ||
| 574 | ssize_t res; | ||
| 575 | |||
| 576 | status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt); | ||
| 577 | if (ACPI_FAILURE(status)) | ||
| 578 | return -ENODEV; | ||
| 579 | |||
| 580 | res = simple_read_from_buffer(buffer, count, ppos, fadt, fadt->length); | ||
| 581 | |||
| 582 | return res; | ||
| 583 | } | ||
| 584 | |||
| 585 | static int acpi_system_procfs_init(void) | ||
| 586 | { | ||
| 587 | struct proc_dir_entry *entry; | ||
| 588 | int error = 0; | ||
| 589 | |||
| 590 | /* 'info' [R] */ | ||
| 591 | entry = proc_create(ACPI_SYSTEM_FILE_INFO, S_IRUGO, acpi_root_dir, | ||
| 592 | &acpi_system_info_ops); | ||
| 593 | if (!entry) | ||
| 594 | goto Error; | ||
| 595 | |||
| 596 | /* 'dsdt' [R] */ | ||
| 597 | entry = proc_create(ACPI_SYSTEM_FILE_DSDT, S_IRUSR, acpi_root_dir, | ||
| 598 | &acpi_system_dsdt_ops); | ||
| 599 | if (!entry) | ||
| 600 | goto Error; | ||
| 601 | |||
| 602 | /* 'fadt' [R] */ | ||
| 603 | entry = proc_create(ACPI_SYSTEM_FILE_FADT, S_IRUSR, acpi_root_dir, | ||
| 604 | &acpi_system_fadt_ops); | ||
| 605 | if (!entry) | ||
| 606 | goto Error; | ||
| 607 | |||
| 608 | Done: | ||
| 609 | return error; | ||
| 610 | |||
| 611 | Error: | ||
| 612 | remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir); | ||
| 613 | remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir); | ||
| 614 | remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir); | ||
| 615 | |||
| 616 | error = -EFAULT; | ||
| 617 | goto Done; | ||
| 618 | } | ||
| 619 | #else | ||
| 620 | static int acpi_system_procfs_init(void) | ||
| 621 | { | ||
| 622 | return 0; | ||
| 623 | } | ||
| 624 | #endif | ||
| 625 | |||
| 626 | int __init acpi_system_init(void) | ||
| 627 | { | 679 | { |
| 628 | int result; | 680 | int result; |
| 629 | 681 | ||
| 630 | result = acpi_system_procfs_init(); | 682 | result = acpi_tables_sysfs_init(); |
| 631 | if (result) | ||
| 632 | return result; | ||
| 633 | |||
| 634 | result = acpi_system_sysfs_init(); | ||
| 635 | 683 | ||
| 636 | return result; | 684 | return result; |
| 637 | } | 685 | } |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index efad1f33aeb5..2f8f17131d9f 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
| @@ -37,10 +37,14 @@ | |||
| 37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
| 38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
| 39 | #include <linux/types.h> | 39 | #include <linux/types.h> |
| 40 | |||
| 41 | #ifdef CONFIG_ACPI_PROCFS | ||
| 40 | #include <linux/proc_fs.h> | 42 | #include <linux/proc_fs.h> |
| 43 | #include <linux/seq_file.h> | ||
| 44 | #endif | ||
| 45 | |||
| 41 | #include <linux/jiffies.h> | 46 | #include <linux/jiffies.h> |
| 42 | #include <linux/kmod.h> | 47 | #include <linux/kmod.h> |
| 43 | #include <linux/seq_file.h> | ||
| 44 | #include <linux/reboot.h> | 48 | #include <linux/reboot.h> |
| 45 | #include <linux/device.h> | 49 | #include <linux/device.h> |
| 46 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
| @@ -102,16 +106,6 @@ static int acpi_thermal_add(struct acpi_device *device); | |||
| 102 | static int acpi_thermal_remove(struct acpi_device *device, int type); | 106 | static int acpi_thermal_remove(struct acpi_device *device, int type); |
| 103 | static int acpi_thermal_resume(struct acpi_device *device); | 107 | static int acpi_thermal_resume(struct acpi_device *device); |
| 104 | static void acpi_thermal_notify(struct acpi_device *device, u32 event); | 108 | static void acpi_thermal_notify(struct acpi_device *device, u32 event); |
| 105 | static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); | ||
| 106 | static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); | ||
| 107 | static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); | ||
| 108 | static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); | ||
| 109 | static ssize_t acpi_thermal_write_cooling_mode(struct file *, | ||
| 110 | const char __user *, size_t, | ||
| 111 | loff_t *); | ||
| 112 | static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); | ||
| 113 | static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, | ||
| 114 | size_t, loff_t *); | ||
| 115 | 109 | ||
| 116 | static const struct acpi_device_id thermal_device_ids[] = { | 110 | static const struct acpi_device_id thermal_device_ids[] = { |
| 117 | {ACPI_THERMAL_HID, 0}, | 111 | {ACPI_THERMAL_HID, 0}, |
| @@ -201,6 +195,18 @@ struct acpi_thermal { | |||
| 201 | struct mutex lock; | 195 | struct mutex lock; |
| 202 | }; | 196 | }; |
| 203 | 197 | ||
| 198 | #ifdef CONFIG_ACPI_PROCFS | ||
| 199 | static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); | ||
| 200 | static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); | ||
| 201 | static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); | ||
| 202 | static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); | ||
| 203 | static ssize_t acpi_thermal_write_cooling_mode(struct file *, | ||
| 204 | const char __user *, size_t, | ||
| 205 | loff_t *); | ||
| 206 | static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); | ||
| 207 | static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, | ||
| 208 | size_t, loff_t *); | ||
| 209 | |||
| 204 | static const struct file_operations acpi_thermal_state_fops = { | 210 | static const struct file_operations acpi_thermal_state_fops = { |
| 205 | .owner = THIS_MODULE, | 211 | .owner = THIS_MODULE, |
| 206 | .open = acpi_thermal_state_open_fs, | 212 | .open = acpi_thermal_state_open_fs, |
| @@ -242,6 +248,7 @@ static const struct file_operations acpi_thermal_polling_fops = { | |||
| 242 | .llseek = seq_lseek, | 248 | .llseek = seq_lseek, |
| 243 | .release = single_release, | 249 | .release = single_release, |
| 244 | }; | 250 | }; |
| 251 | #endif /* CONFIG_ACPI_PROCFS*/ | ||
| 245 | 252 | ||
| 246 | /* -------------------------------------------------------------------------- | 253 | /* -------------------------------------------------------------------------- |
| 247 | Thermal Zone Management | 254 | Thermal Zone Management |
| @@ -287,26 +294,6 @@ static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) | |||
| 287 | return 0; | 294 | return 0; |
| 288 | } | 295 | } |
| 289 | 296 | ||
| 290 | static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) | ||
| 291 | { | ||
| 292 | |||
| 293 | if (!tz) | ||
| 294 | return -EINVAL; | ||
| 295 | |||
| 296 | tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */ | ||
| 297 | |||
| 298 | tz->thermal_zone->polling_delay = seconds * 1000; | ||
| 299 | |||
| 300 | if (tz->tz_enabled) | ||
| 301 | thermal_zone_device_update(tz->thermal_zone); | ||
| 302 | |||
| 303 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
| 304 | "Polling frequency set to %lu seconds\n", | ||
| 305 | tz->polling_frequency/10)); | ||
| 306 | |||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | |||
| 310 | static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) | 297 | static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) |
| 311 | { | 298 | { |
| 312 | acpi_status status = AE_OK; | 299 | acpi_status status = AE_OK; |
| @@ -973,7 +960,7 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) | |||
| 973 | /* -------------------------------------------------------------------------- | 960 | /* -------------------------------------------------------------------------- |
| 974 | FS Interface (/proc) | 961 | FS Interface (/proc) |
| 975 | -------------------------------------------------------------------------- */ | 962 | -------------------------------------------------------------------------- */ |
| 976 | 963 | #ifdef CONFIG_ACPI_PROCFS | |
| 977 | static struct proc_dir_entry *acpi_thermal_dir; | 964 | static struct proc_dir_entry *acpi_thermal_dir; |
| 978 | 965 | ||
| 979 | static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) | 966 | 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) | |||
| 1187 | PDE(inode)->data); | 1174 | PDE(inode)->data); |
| 1188 | } | 1175 | } |
| 1189 | 1176 | ||
| 1177 | static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) | ||
| 1178 | { | ||
| 1179 | if (!tz) | ||
| 1180 | return -EINVAL; | ||
| 1181 | |||
| 1182 | /* Convert value to deci-seconds */ | ||
| 1183 | tz->polling_frequency = seconds * 10; | ||
| 1184 | |||
| 1185 | tz->thermal_zone->polling_delay = seconds * 1000; | ||
| 1186 | |||
| 1187 | if (tz->tz_enabled) | ||
| 1188 | thermal_zone_device_update(tz->thermal_zone); | ||
| 1189 | |||
| 1190 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
| 1191 | "Polling frequency set to %lu seconds\n", | ||
| 1192 | tz->polling_frequency/10)); | ||
| 1193 | |||
| 1194 | return 0; | ||
| 1195 | } | ||
| 1196 | |||
| 1190 | static ssize_t | 1197 | static ssize_t |
| 1191 | acpi_thermal_write_polling(struct file *file, | 1198 | acpi_thermal_write_polling(struct file *file, |
| 1192 | const char __user * buffer, | 1199 | const char __user * buffer, |
| @@ -1295,7 +1302,13 @@ static int acpi_thermal_remove_fs(struct acpi_device *device) | |||
| 1295 | 1302 | ||
| 1296 | return 0; | 1303 | return 0; |
| 1297 | } | 1304 | } |
| 1298 | 1305 | #else | |
| 1306 | static inline int acpi_thermal_add_fs(struct acpi_device *device) { return 0; } | ||
| 1307 | static inline int acpi_thermal_remove_fs(struct acpi_device *device) | ||
| 1308 | { | ||
| 1309 | return 0; | ||
| 1310 | } | ||
| 1311 | #endif /* CONFIG_ACPI_PROCFS */ | ||
| 1299 | /* -------------------------------------------------------------------------- | 1312 | /* -------------------------------------------------------------------------- |
| 1300 | Driver Interface | 1313 | Driver Interface |
| 1301 | -------------------------------------------------------------------------- */ | 1314 | -------------------------------------------------------------------------- */ |
| @@ -1566,13 +1579,18 @@ static int __init acpi_thermal_init(void) | |||
| 1566 | printk(KERN_NOTICE "ACPI: thermal control disabled\n"); | 1579 | printk(KERN_NOTICE "ACPI: thermal control disabled\n"); |
| 1567 | return -ENODEV; | 1580 | return -ENODEV; |
| 1568 | } | 1581 | } |
| 1582 | |||
| 1583 | #ifdef CONFIG_ACPI_PROCFS | ||
| 1569 | acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); | 1584 | acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); |
| 1570 | if (!acpi_thermal_dir) | 1585 | if (!acpi_thermal_dir) |
| 1571 | return -ENODEV; | 1586 | return -ENODEV; |
| 1587 | #endif | ||
| 1572 | 1588 | ||
| 1573 | result = acpi_bus_register_driver(&acpi_thermal_driver); | 1589 | result = acpi_bus_register_driver(&acpi_thermal_driver); |
| 1574 | if (result < 0) { | 1590 | if (result < 0) { |
| 1591 | #ifdef CONFIG_ACPI_PROCFS | ||
| 1575 | remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); | 1592 | remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); |
| 1593 | #endif | ||
| 1576 | return -ENODEV; | 1594 | return -ENODEV; |
| 1577 | } | 1595 | } |
| 1578 | 1596 | ||
| @@ -1584,7 +1602,9 @@ static void __exit acpi_thermal_exit(void) | |||
| 1584 | 1602 | ||
| 1585 | acpi_bus_unregister_driver(&acpi_thermal_driver); | 1603 | acpi_bus_unregister_driver(&acpi_thermal_driver); |
| 1586 | 1604 | ||
| 1605 | #ifdef CONFIG_ACPI_PROCFS | ||
| 1587 | remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); | 1606 | remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); |
| 1607 | #endif | ||
| 1588 | 1608 | ||
| 1589 | return; | 1609 | return; |
| 1590 | } | 1610 | } |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 9865d46f49a8..67dec0c675aa 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
| @@ -152,7 +152,9 @@ struct acpi_video_bus { | |||
| 152 | struct acpi_video_bus_flags flags; | 152 | struct acpi_video_bus_flags flags; |
| 153 | struct list_head video_device_list; | 153 | struct list_head video_device_list; |
| 154 | struct mutex device_list_lock; /* protects video_device_list */ | 154 | struct mutex device_list_lock; /* protects video_device_list */ |
| 155 | #ifdef CONFIG_ACPI_PROCFS | ||
| 155 | struct proc_dir_entry *dir; | 156 | struct proc_dir_entry *dir; |
| 157 | #endif | ||
| 156 | struct input_dev *input; | 158 | struct input_dev *input; |
| 157 | char phys[32]; /* for input device */ | 159 | char phys[32]; /* for input device */ |
| 158 | struct notifier_block pm_nb; | 160 | struct notifier_block pm_nb; |
| @@ -208,6 +210,7 @@ struct acpi_video_device { | |||
| 208 | struct output_device *output_dev; | 210 | struct output_device *output_dev; |
| 209 | }; | 211 | }; |
| 210 | 212 | ||
| 213 | #ifdef CONFIG_ACPI_PROCFS | ||
| 211 | /* bus */ | 214 | /* bus */ |
| 212 | static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file); | 215 | static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file); |
| 213 | static const struct file_operations acpi_video_bus_info_fops = { | 216 | static const struct file_operations acpi_video_bus_info_fops = { |
| @@ -307,6 +310,7 @@ static const struct file_operations acpi_video_device_EDID_fops = { | |||
| 307 | .llseek = seq_lseek, | 310 | .llseek = seq_lseek, |
| 308 | .release = single_release, | 311 | .release = single_release, |
| 309 | }; | 312 | }; |
| 313 | #endif /* CONFIG_ACPI_PROCFS */ | ||
| 310 | 314 | ||
| 311 | static const char device_decode[][30] = { | 315 | static const char device_decode[][30] = { |
| 312 | "motherboard VGA device", | 316 | "motherboard VGA device", |
| @@ -450,16 +454,6 @@ static struct thermal_cooling_device_ops video_cooling_ops = { | |||
| 450 | /* device */ | 454 | /* device */ |
| 451 | 455 | ||
| 452 | static int | 456 | static int |
| 453 | acpi_video_device_query(struct acpi_video_device *device, unsigned long long *state) | ||
| 454 | { | ||
| 455 | int status; | ||
| 456 | |||
| 457 | status = acpi_evaluate_integer(device->dev->handle, "_DGS", NULL, state); | ||
| 458 | |||
| 459 | return status; | ||
| 460 | } | ||
| 461 | |||
| 462 | static int | ||
| 463 | acpi_video_device_get_state(struct acpi_video_device *device, | 457 | acpi_video_device_get_state(struct acpi_video_device *device, |
| 464 | unsigned long long *state) | 458 | unsigned long long *state) |
| 465 | { | 459 | { |
| @@ -698,46 +692,6 @@ acpi_video_device_EDID(struct acpi_video_device *device, | |||
| 698 | 692 | ||
| 699 | /* bus */ | 693 | /* bus */ |
| 700 | 694 | ||
| 701 | static int | ||
| 702 | acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option) | ||
| 703 | { | ||
| 704 | int status; | ||
| 705 | unsigned long long tmp; | ||
| 706 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
| 707 | struct acpi_object_list args = { 1, &arg0 }; | ||
| 708 | |||
| 709 | |||
| 710 | arg0.integer.value = option; | ||
| 711 | |||
| 712 | status = acpi_evaluate_integer(video->device->handle, "_SPD", &args, &tmp); | ||
| 713 | if (ACPI_SUCCESS(status)) | ||
| 714 | status = tmp ? (-EINVAL) : (AE_OK); | ||
| 715 | |||
| 716 | return status; | ||
| 717 | } | ||
| 718 | |||
| 719 | static int | ||
| 720 | acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id) | ||
| 721 | { | ||
| 722 | int status; | ||
| 723 | |||
| 724 | status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id); | ||
| 725 | |||
| 726 | return status; | ||
| 727 | } | ||
| 728 | |||
| 729 | static int | ||
| 730 | acpi_video_bus_POST_options(struct acpi_video_bus *video, | ||
| 731 | unsigned long long *options) | ||
| 732 | { | ||
| 733 | int status; | ||
| 734 | |||
| 735 | status = acpi_evaluate_integer(video->device->handle, "_VPO", NULL, options); | ||
| 736 | *options &= 3; | ||
| 737 | |||
| 738 | return status; | ||
| 739 | } | ||
| 740 | |||
| 741 | /* | 695 | /* |
| 742 | * Arg: | 696 | * Arg: |
| 743 | * video : video bus device pointer | 697 | * video : video bus device pointer |
| @@ -1159,6 +1113,7 @@ static int acpi_video_bus_check(struct acpi_video_bus *video) | |||
| 1159 | /* -------------------------------------------------------------------------- | 1113 | /* -------------------------------------------------------------------------- |
| 1160 | FS Interface (/proc) | 1114 | FS Interface (/proc) |
| 1161 | -------------------------------------------------------------------------- */ | 1115 | -------------------------------------------------------------------------- */ |
| 1116 | #ifdef CONFIG_ACPI_PROCFS | ||
| 1162 | 1117 | ||
| 1163 | static struct proc_dir_entry *acpi_video_dir; | 1118 | static struct proc_dir_entry *acpi_video_dir; |
| 1164 | 1119 | ||
| @@ -1198,6 +1153,18 @@ acpi_video_device_info_open_fs(struct inode *inode, struct file *file) | |||
| 1198 | PDE(inode)->data); | 1153 | PDE(inode)->data); |
| 1199 | } | 1154 | } |
| 1200 | 1155 | ||
| 1156 | static int | ||
| 1157 | acpi_video_device_query(struct acpi_video_device *device, | ||
| 1158 | unsigned long long *state) | ||
| 1159 | { | ||
| 1160 | int status; | ||
| 1161 | |||
| 1162 | status = acpi_evaluate_integer(device->dev->handle, "_DGS", | ||
| 1163 | NULL, state); | ||
| 1164 | |||
| 1165 | return status; | ||
| 1166 | } | ||
| 1167 | |||
| 1201 | static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) | 1168 | static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) |
| 1202 | { | 1169 | { |
| 1203 | int status; | 1170 | int status; |
| @@ -1492,6 +1459,19 @@ static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file) | |||
| 1492 | return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data); | 1459 | return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data); |
| 1493 | } | 1460 | } |
| 1494 | 1461 | ||
| 1462 | static int | ||
| 1463 | acpi_video_bus_POST_options(struct acpi_video_bus *video, | ||
| 1464 | unsigned long long *options) | ||
| 1465 | { | ||
| 1466 | int status; | ||
| 1467 | |||
| 1468 | status = acpi_evaluate_integer(video->device->handle, "_VPO", | ||
| 1469 | NULL, options); | ||
| 1470 | *options &= 3; | ||
| 1471 | |||
| 1472 | return status; | ||
| 1473 | } | ||
| 1474 | |||
| 1495 | static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) | 1475 | static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) |
| 1496 | { | 1476 | { |
| 1497 | struct acpi_video_bus *video = seq->private; | 1477 | struct acpi_video_bus *video = seq->private; |
| @@ -1530,6 +1510,16 @@ acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file) | |||
| 1530 | PDE(inode)->data); | 1510 | PDE(inode)->data); |
| 1531 | } | 1511 | } |
| 1532 | 1512 | ||
| 1513 | static int | ||
| 1514 | acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id) | ||
| 1515 | { | ||
| 1516 | int status; | ||
| 1517 | |||
| 1518 | status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id); | ||
| 1519 | |||
| 1520 | return status; | ||
| 1521 | } | ||
| 1522 | |||
| 1533 | static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) | 1523 | static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) |
| 1534 | { | 1524 | { |
| 1535 | struct acpi_video_bus *video = seq->private; | 1525 | 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) | |||
| 1572 | return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data); | 1562 | return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data); |
| 1573 | } | 1563 | } |
| 1574 | 1564 | ||
| 1565 | static int | ||
| 1566 | acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option) | ||
| 1567 | { | ||
| 1568 | int status; | ||
| 1569 | unsigned long long tmp; | ||
| 1570 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
| 1571 | struct acpi_object_list args = { 1, &arg0 }; | ||
| 1572 | |||
| 1573 | |||
| 1574 | arg0.integer.value = option; | ||
| 1575 | |||
| 1576 | status = acpi_evaluate_integer(video->device->handle, "_SPD", | ||
| 1577 | &args, &tmp); | ||
| 1578 | if (ACPI_SUCCESS(status)) | ||
| 1579 | status = tmp ? (-EINVAL) : (AE_OK); | ||
| 1580 | |||
| 1581 | return status; | ||
| 1582 | } | ||
| 1583 | |||
| 1575 | static ssize_t | 1584 | static ssize_t |
| 1576 | acpi_video_bus_write_POST(struct file *file, | 1585 | acpi_video_bus_write_POST(struct file *file, |
| 1577 | const char __user * buffer, | 1586 | const char __user * buffer, |
| @@ -1722,6 +1731,24 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device) | |||
| 1722 | 1731 | ||
| 1723 | return 0; | 1732 | return 0; |
| 1724 | } | 1733 | } |
| 1734 | #else | ||
| 1735 | static inline int acpi_video_device_add_fs(struct acpi_device *device) | ||
| 1736 | { | ||
| 1737 | return 0; | ||
| 1738 | } | ||
| 1739 | static inline int acpi_video_device_remove_fs(struct acpi_device *device) | ||
| 1740 | { | ||
| 1741 | return 0; | ||
| 1742 | } | ||
| 1743 | static inline int acpi_video_bus_add_fs(struct acpi_device *device) | ||
| 1744 | { | ||
| 1745 | return 0; | ||
| 1746 | } | ||
| 1747 | static inline int acpi_video_bus_remove_fs(struct acpi_device *device) | ||
| 1748 | { | ||
| 1749 | return 0; | ||
| 1750 | } | ||
| 1751 | #endif /* CONFIG_ACPI_PROCFS */ | ||
| 1725 | 1752 | ||
| 1726 | /* -------------------------------------------------------------------------- | 1753 | /* -------------------------------------------------------------------------- |
| 1727 | Driver Interface | 1754 | Driver Interface |
| @@ -2140,7 +2167,7 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, | |||
| 2140 | status = acpi_video_bus_get_one_device(dev, video); | 2167 | status = acpi_video_bus_get_one_device(dev, video); |
| 2141 | if (ACPI_FAILURE(status)) { | 2168 | if (ACPI_FAILURE(status)) { |
| 2142 | printk(KERN_WARNING PREFIX | 2169 | printk(KERN_WARNING PREFIX |
| 2143 | "Cant attach device"); | 2170 | "Cant attach device\n"); |
| 2144 | continue; | 2171 | continue; |
| 2145 | } | 2172 | } |
| 2146 | } | 2173 | } |
| @@ -2150,19 +2177,19 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, | |||
| 2150 | static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | 2177 | static int acpi_video_bus_put_one_device(struct acpi_video_device *device) |
| 2151 | { | 2178 | { |
| 2152 | acpi_status status; | 2179 | acpi_status status; |
| 2153 | struct acpi_video_bus *video; | ||
| 2154 | |||
| 2155 | 2180 | ||
| 2156 | if (!device || !device->video) | 2181 | if (!device || !device->video) |
| 2157 | return -ENOENT; | 2182 | return -ENOENT; |
| 2158 | 2183 | ||
| 2159 | video = device->video; | ||
| 2160 | |||
| 2161 | acpi_video_device_remove_fs(device->dev); | 2184 | acpi_video_device_remove_fs(device->dev); |
| 2162 | 2185 | ||
| 2163 | status = acpi_remove_notify_handler(device->dev->handle, | 2186 | status = acpi_remove_notify_handler(device->dev->handle, |
| 2164 | ACPI_DEVICE_NOTIFY, | 2187 | ACPI_DEVICE_NOTIFY, |
| 2165 | acpi_video_device_notify); | 2188 | acpi_video_device_notify); |
| 2189 | if (ACPI_FAILURE(status)) { | ||
| 2190 | printk(KERN_WARNING PREFIX | ||
| 2191 | "Cant remove video notify handler\n"); | ||
| 2192 | } | ||
| 2166 | if (device->backlight) { | 2193 | if (device->backlight) { |
| 2167 | sysfs_remove_link(&device->backlight->dev.kobj, "device"); | 2194 | sysfs_remove_link(&device->backlight->dev.kobj, "device"); |
| 2168 | backlight_device_unregister(device->backlight); | 2195 | backlight_device_unregister(device->backlight); |
| @@ -2557,9 +2584,11 @@ int acpi_video_register(void) | |||
| 2557 | return 0; | 2584 | return 0; |
| 2558 | } | 2585 | } |
| 2559 | 2586 | ||
| 2587 | #ifdef CONFIG_ACPI_PROCFS | ||
| 2560 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); | 2588 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); |
| 2561 | if (!acpi_video_dir) | 2589 | if (!acpi_video_dir) |
| 2562 | return -ENODEV; | 2590 | return -ENODEV; |
| 2591 | #endif | ||
| 2563 | 2592 | ||
| 2564 | result = acpi_bus_register_driver(&acpi_video_bus); | 2593 | result = acpi_bus_register_driver(&acpi_video_bus); |
| 2565 | if (result < 0) { | 2594 | if (result < 0) { |
| @@ -2588,7 +2617,9 @@ void acpi_video_unregister(void) | |||
| 2588 | } | 2617 | } |
| 2589 | acpi_bus_unregister_driver(&acpi_video_bus); | 2618 | acpi_bus_unregister_driver(&acpi_video_bus); |
| 2590 | 2619 | ||
| 2620 | #ifdef CONFIG_ACPI_PROCFS | ||
| 2591 | remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); | 2621 | remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); |
| 2622 | #endif | ||
| 2592 | 2623 | ||
| 2593 | register_count = 0; | 2624 | register_count = 0; |
| 2594 | 2625 | ||
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index c80537bc3234..f62a50c3ed34 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c | |||
| @@ -21,46 +21,18 @@ | |||
| 21 | ACPI_MODULE_NAME("wakeup_devices") | 21 | ACPI_MODULE_NAME("wakeup_devices") |
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | * acpi_enable_wakeup_device_prep - Prepare wake-up devices. | 24 | * acpi_enable_wakeup_devices - Enable wake-up device GPEs. |
| 25 | * @sleep_state: ACPI system sleep state. | 25 | * @sleep_state: ACPI system sleep state. |
| 26 | * | 26 | * |
| 27 | * Enable all wake-up devices' power, unless the requested system sleep state is | 27 | * Enable wakeup device power of devices with the state.enable flag set and set |
| 28 | * too deep. | 28 | * the wakeup enable mask bits in the GPE registers that correspond to wakeup |
| 29 | * devices. | ||
| 29 | */ | 30 | */ |
| 30 | void acpi_enable_wakeup_device_prep(u8 sleep_state) | 31 | void acpi_enable_wakeup_devices(u8 sleep_state) |
| 31 | { | 32 | { |
| 32 | struct list_head *node, *next; | 33 | struct list_head *node, *next; |
| 33 | 34 | ||
| 34 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { | 35 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { |
| 35 | struct acpi_device *dev = container_of(node, | ||
| 36 | struct acpi_device, | ||
| 37 | wakeup_list); | ||
| 38 | |||
| 39 | if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled | ||
| 40 | || (sleep_state > (u32) dev->wakeup.sleep_state)) | ||
| 41 | continue; | ||
| 42 | |||
| 43 | acpi_enable_wakeup_device_power(dev, sleep_state); | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | /** | ||
| 48 | * acpi_enable_wakeup_device - Enable wake-up device GPEs. | ||
| 49 | * @sleep_state: ACPI system sleep state. | ||
| 50 | * | ||
| 51 | * Enable all wake-up devices' GPEs, with the assumption that | ||
| 52 | * acpi_disable_all_gpes() was executed before, so we don't need to disable any | ||
| 53 | * GPEs here. | ||
| 54 | */ | ||
| 55 | void acpi_enable_wakeup_device(u8 sleep_state) | ||
| 56 | { | ||
| 57 | struct list_head *node, *next; | ||
| 58 | |||
| 59 | /* | ||
| 60 | * Caution: this routine must be invoked when interrupt is disabled | ||
| 61 | * Refer ACPI2.0: P212 | ||
| 62 | */ | ||
| 63 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { | ||
| 64 | struct acpi_device *dev = | 36 | struct acpi_device *dev = |
| 65 | container_of(node, struct acpi_device, wakeup_list); | 37 | container_of(node, struct acpi_device, wakeup_list); |
| 66 | 38 | ||
| @@ -69,6 +41,9 @@ void acpi_enable_wakeup_device(u8 sleep_state) | |||
| 69 | || sleep_state > (u32) dev->wakeup.sleep_state) | 41 | || sleep_state > (u32) dev->wakeup.sleep_state) |
| 70 | continue; | 42 | continue; |
| 71 | 43 | ||
| 44 | if (dev->wakeup.state.enabled) | ||
| 45 | acpi_enable_wakeup_device_power(dev, sleep_state); | ||
| 46 | |||
| 72 | /* The wake-up power should have been enabled already. */ | 47 | /* The wake-up power should have been enabled already. */ |
| 73 | acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, | 48 | acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, |
| 74 | ACPI_GPE_ENABLE); | 49 | ACPI_GPE_ENABLE); |
| @@ -76,13 +51,10 @@ void acpi_enable_wakeup_device(u8 sleep_state) | |||
| 76 | } | 51 | } |
| 77 | 52 | ||
| 78 | /** | 53 | /** |
| 79 | * acpi_disable_wakeup_device - Disable devices' wakeup capability. | 54 | * acpi_disable_wakeup_devices - Disable devices' wakeup capability. |
| 80 | * @sleep_state: ACPI system sleep state. | 55 | * @sleep_state: ACPI system sleep state. |
| 81 | * | ||
| 82 | * This function only affects devices with wakeup.state.enabled set, which means | ||
| 83 | * that it reverses the changes made by acpi_enable_wakeup_device_prep(). | ||
| 84 | */ | 56 | */ |
| 85 | void acpi_disable_wakeup_device(u8 sleep_state) | 57 | void acpi_disable_wakeup_devices(u8 sleep_state) |
| 86 | { | 58 | { |
| 87 | struct list_head *node, *next; | 59 | struct list_head *node, *next; |
| 88 | 60 | ||
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 7b5eea7e01dc..8b5ea399a4f4 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c | |||
| @@ -145,12 +145,6 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, | |||
| 145 | struct ata_eh_info *ehi = &ap->link.eh_info; | 145 | struct ata_eh_info *ehi = &ap->link.eh_info; |
| 146 | int wait = 0; | 146 | int wait = 0; |
| 147 | unsigned long flags; | 147 | unsigned long flags; |
| 148 | acpi_handle handle; | ||
| 149 | |||
| 150 | if (dev) | ||
| 151 | handle = dev->acpi_handle; | ||
| 152 | else | ||
| 153 | handle = ap->acpi_handle; | ||
| 154 | 148 | ||
| 155 | spin_lock_irqsave(ap->lock, flags); | 149 | spin_lock_irqsave(ap->lock, flags); |
| 156 | /* | 150 | /* |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 81d4f3d4b9fd..c0786d446a00 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
| @@ -66,7 +66,7 @@ extern u8 acpi_gbl_create_osi_method; | |||
| 66 | extern u8 acpi_gbl_use_default_register_widths; | 66 | extern u8 acpi_gbl_use_default_register_widths; |
| 67 | extern acpi_name acpi_gbl_trace_method_name; | 67 | extern acpi_name acpi_gbl_trace_method_name; |
| 68 | extern u32 acpi_gbl_trace_flags; | 68 | extern u32 acpi_gbl_trace_flags; |
| 69 | extern u8 acpi_gbl_enable_aml_debug_object; | 69 | extern u32 acpi_gbl_enable_aml_debug_object; |
| 70 | extern u8 acpi_gbl_copy_dsdt_locally; | 70 | extern u8 acpi_gbl_copy_dsdt_locally; |
| 71 | extern u8 acpi_gbl_truncate_io_addresses; | 71 | extern u8 acpi_gbl_truncate_io_addresses; |
| 72 | 72 | ||
diff --git a/include/acpi/processor.h b/include/acpi/processor.h index a68ca8a11a53..1b62102fbb67 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h | |||
| @@ -338,7 +338,6 @@ extern struct cpuidle_driver acpi_idle_driver; | |||
| 338 | 338 | ||
| 339 | /* in processor_thermal.c */ | 339 | /* in processor_thermal.c */ |
| 340 | int acpi_processor_get_limit_info(struct acpi_processor *pr); | 340 | int acpi_processor_get_limit_info(struct acpi_processor *pr); |
| 341 | extern const struct file_operations acpi_processor_limit_fops; | ||
| 342 | extern struct thermal_cooling_device_ops processor_cooling_ops; | 341 | extern struct thermal_cooling_device_ops processor_cooling_ops; |
| 343 | #ifdef CONFIG_CPU_FREQ | 342 | #ifdef CONFIG_CPU_FREQ |
| 344 | void acpi_thermal_cpufreq_init(void); | 343 | void acpi_thermal_cpufreq_init(void); |
diff --git a/include/linux/cper.h b/include/linux/cper.h index 4b38f905b705..bf972f81e2a7 100644 --- a/include/linux/cper.h +++ b/include/linux/cper.h | |||
| @@ -39,10 +39,10 @@ | |||
| 39 | * Severity difinition for error_severity in struct cper_record_header | 39 | * Severity difinition for error_severity in struct cper_record_header |
| 40 | * and section_severity in struct cper_section_descriptor | 40 | * and section_severity in struct cper_section_descriptor |
| 41 | */ | 41 | */ |
| 42 | #define CPER_SER_RECOVERABLE 0x0 | 42 | #define CPER_SEV_RECOVERABLE 0x0 |
| 43 | #define CPER_SER_FATAL 0x1 | 43 | #define CPER_SEV_FATAL 0x1 |
| 44 | #define CPER_SER_CORRECTED 0x2 | 44 | #define CPER_SEV_CORRECTED 0x2 |
| 45 | #define CPER_SER_INFORMATIONAL 0x3 | 45 | #define CPER_SEV_INFORMATIONAL 0x3 |
| 46 | 46 | ||
| 47 | /* | 47 | /* |
| 48 | * Validation bits difinition for validation_bits in struct | 48 | * Validation bits difinition for validation_bits in struct |
