aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig11
-rw-r--r--drivers/acpi/Makefile5
-rw-r--r--drivers/acpi/acpica/acevents.h4
-rw-r--r--drivers/acpi/acpica/acglobal.h2
-rw-r--r--drivers/acpi/acpica/aclocal.h1
-rw-r--r--drivers/acpi/acpica/evgpe.c73
-rw-r--r--drivers/acpi/acpica/evxface.c77
-rw-r--r--drivers/acpi/acpica/evxfevnt.c62
-rw-r--r--drivers/acpi/acpica/utmutex.c5
-rw-r--r--drivers/acpi/apei/Kconfig9
-rw-r--r--drivers/acpi/apei/Makefile1
-rw-r--r--drivers/acpi/apei/apei-base.c4
-rw-r--r--drivers/acpi/apei/erst-dbg.c207
-rw-r--r--drivers/acpi/apei/ghes.c172
-rw-r--r--drivers/acpi/apei/hest.c76
-rw-r--r--drivers/acpi/bus.c4
-rw-r--r--drivers/acpi/debug.c422
-rw-r--r--drivers/acpi/debugfs.c93
-rw-r--r--drivers/acpi/glue.c3
-rw-r--r--drivers/acpi/internal.h8
-rw-r--r--drivers/acpi/numa.c4
-rw-r--r--drivers/acpi/osl.c7
-rw-r--r--drivers/acpi/power.c129
-rw-r--r--drivers/acpi/proc.c70
-rw-r--r--drivers/acpi/processor_driver.c85
-rw-r--r--drivers/acpi/processor_idle.c102
-rw-r--r--drivers/acpi/processor_thermal.c83
-rw-r--r--drivers/acpi/processor_throttling.c2
-rw-r--r--drivers/acpi/sleep.c60
-rw-r--r--drivers/acpi/sleep.h5
-rw-r--r--drivers/acpi/sysfs.c (renamed from drivers/acpi/system.c)466
-rw-r--r--drivers/acpi/thermal.c86
-rw-r--r--drivers/acpi/video.c141
-rw-r--r--drivers/acpi/wakeup.c48
34 files changed, 1062 insertions, 1465 deletions
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
37acpi-$(CONFIG_ACPI_DOCK) += dock.o 37acpi-$(CONFIG_ACPI_DOCK) += dock.o
38acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o 38acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
39acpi-y += power.o 39acpi-y += power.o
40acpi-y += system.o event.o 40acpi-y += event.o
41acpi-$(CONFIG_ACPI_DEBUG) += debug.o 41acpi-y += sysfs.o
42acpi-$(CONFIG_DEBUG_FS) += debugfs.o
42acpi-$(CONFIG_ACPI_NUMA) += numa.o 43acpi-$(CONFIG_ACPI_NUMA) += numa.o
43acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o 44acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
44ifdef CONFIG_ACPI_VIDEO 45ifdef 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
83acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); 83acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
84 84
85acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
86
87acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
88
85struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, 89struct 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 */
111u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); 111u32 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
417union acpi_gpe_dispatch_info { 418union 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
151acpi_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
187acpi_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,
735unlock_and_exit: 751unlock_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
755free_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
740ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler) 761ACPI_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: 853unlock_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 ******************************************************************************/
295acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) 295acpi_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
329unlock_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 ******************************************************************************/
349acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) 331acpi_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
387unlock_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
436unlock_and_exit: 396unlock_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}
444ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake) 400ACPI_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
280acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) 280acpi_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
32config 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 @@
1obj-$(CONFIG_ACPI_APEI) += apei.o 1obj-$(CONFIG_ACPI_APEI) += apei.o
2obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o 2obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o
3obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o 3obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o
4obj-$(CONFIG_ACPI_APEI_ERST_DEBUG) += erst-dbg.o
4 5
5apei-y := apei-base.o hest.o cper.o erst.o 6apei-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;
488err_unmap_iomem: 488err_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
38static void *erst_dbg_buf;
39static unsigned int erst_dbg_buf_len;
40
41/* Prevent erst_dbg_read/write from being invoked concurrently */
42static DEFINE_MUTEX(erst_dbg_mutex);
43
44static 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
52static 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
79static 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
92retry_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;
99retry:
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;
131out:
132 mutex_unlock(&erst_dbg_mutex);
133 return rc ? rc : len;
134}
135
136static 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
172out:
173 mutex_unlock(&erst_dbg_mutex);
174 return rc < 0 ? rc : usize;
175}
176
177static 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
185static struct miscdevice erst_dbg_dev = {
186 .minor = MISC_DYNAMIC_MINOR,
187 .name = "erst_dbg",
188 .fops = &erst_dbg_ops,
189};
190
191static __init int erst_dbg_init(void)
192{
193 return misc_register(&erst_dbg_dev);
194}
195
196static __exit void erst_dbg_exit(void)
197{
198 misc_deregister(&erst_dbg_dev);
199 kfree(erst_dbg_buf);
200}
201
202module_init(erst_dbg_init);
203module_exit(erst_dbg_exit);
204
205MODULE_AUTHOR("Huang Ying");
206MODULE_DESCRIPTION("APEI Error Record Serialization Table debug support");
207MODULE_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 */
89static LIST_HEAD(ghes_sci); 91static LIST_HEAD(ghes_sci);
92static DEFINE_MUTEX(ghes_list_mutex);
90 93
91static struct ghes *ghes_new(struct acpi_hest_generic *generic) 94static 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
134enum { 137enum {
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
141static inline int ghes_severity(int severity) 144static 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
238static void ghes_do_proc(struct ghes *ghes) 241static 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
296static int hest_ghes_parse(struct acpi_hest_header *hest_hdr, void *data) 299static 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;
360err: 366err:
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
366static void ghes_cleanup(void) 374static 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
404static 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
382static int __init ghes_init(void) 413static 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;
412err_cleanup:
413 ghes_cleanup();
414 return rc;
415} 424}
416 425
417static void __exit ghes_exit(void) 426static void __exit ghes_exit(void)
418{ 427{
419 ghes_cleanup(); 428 platform_driver_unregister(&ghes_platform_driver);
420} 429}
421 430
422module_init(ghes_init); 431module_init(ghes_init);
@@ -425,3 +434,4 @@ module_exit(ghes_exit);
425MODULE_AUTHOR("Huang Ying"); 434MODULE_AUTHOR("Huang Ying");
426MODULE_DESCRIPTION("APEI Generic Hardware Error Source support"); 435MODULE_DESCRIPTION("APEI Generic Hardware Error Source support");
427MODULE_LICENSE("GPL"); 436MODULE_LICENSE("GPL");
437MODULE_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
48static struct acpi_table_hest *hest_tab; 49static struct acpi_table_hest *hest_tab;
49 50
50static int hest_void_parse(struct acpi_hest_header *hest_hdr, void *data)
51{
52 return 0;
53}
54
55static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { 51static 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}
126EXPORT_SYMBOL_GPL(apei_hest_parse); 122EXPORT_SYMBOL_GPL(apei_hest_parse);
127 123
124struct ghes_arr {
125 struct platform_device **ghes_devs;
126 unsigned int count;
127};
128
129static 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
138static 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;
160err:
161 platform_device_put(ghes_dev);
162 return rc;
163}
164
165static 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;
178out:
179 kfree(ghes_arr.ghes_devs);
180 return rc;
181err:
182 for (i = 0; i < ghes_arr.count; i++)
183 platform_device_unregister(ghes_arr.ghes_devs[i]);
184 goto out;
185}
186
128static int __init setup_hest_disable(char *str) 187static 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
17ACPI_MODULE_NAME("debug");
18
19struct acpi_dlayer {
20 const char *name;
21 unsigned long value;
22};
23struct acpi_dlevel {
24 const char *name;
25 unsigned long value;
26};
27#define ACPI_DEBUG_INIT(v) { .name = #v, .value = v }
28
29static 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
61static 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 -------------------------------------------------------------------------- */
99static 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
122static 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
142static struct kernel_param_ops acpi_debug_layer_ops = {
143 .set = param_set_uint,
144 .get = param_get_debug_layer,
145};
146
147static struct kernel_param_ops acpi_debug_level_ops = {
148 .set = param_set_uint,
149 .get = param_get_debug_level,
150};
151
152module_param_cb(debug_layer, &acpi_debug_layer_ops, &acpi_dbg_layer, 0644);
153module_param_cb(debug_level, &acpi_debug_level_ops, &acpi_dbg_level, 0644);
154
155static char trace_method_name[6];
156module_param_string(trace_method_name, trace_method_name, 6, 0644);
157static unsigned int trace_debug_layer;
158module_param(trace_debug_layer, uint, 0644);
159static unsigned int trace_debug_level;
160module_param(trace_debug_level, uint, 0644);
161
162static 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;
192exit:
193 return result;
194}
195
196static 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
209static struct kernel_param_ops param_ops_trace_state = {
210 .set = param_set_trace_state,
211 .get = param_get_trace_state,
212};
213
214module_param_cb(trace_state, &param_ops_trace_state, NULL, 0644);
215
216/* --------------------------------------------------------------------------
217 DebugFS Interface
218 -------------------------------------------------------------------------- */
219
220static 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
265static const struct file_operations cm_fops = {
266 .write = cm_write,
267};
268
269static 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
284err:
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
297static 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
337static 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
342static 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
371static 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
381int __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
417int __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
13ACPI_MODULE_NAME("debugfs");
14
15
16/* /sys/modules/acpi/parameters/aml_debug_output */
17
18module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object,
19 bool, 0644);
20MODULE_PARM_DESC(aml_debug_output,
21 "To enable/disable the ACPI Debug Object output.");
22
23/* /sys/kernel/debug/acpi/custom_method */
24
25static 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
70static const struct file_operations cm_fops = {
71 .write = cm_write,
72};
73
74int __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
89err:
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
28int init_acpi_device_notify(void); 28int init_acpi_device_notify(void);
29int acpi_scan_init(void); 29int acpi_scan_init(void);
30int acpi_system_init(void); 30int acpi_sysfs_init(void);
31 31
32#ifdef CONFIG_ACPI_DEBUG 32#ifdef CONFIG_DEBUG_FS
33int acpi_debug_init(void); 33int acpi_debugfs_init(void);
34#else 34#else
35static inline int acpi_debug_init(void) { return 0; } 35static 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
256static int __init acpi_parse_srat(struct acpi_table_header *table) 256static 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 {
141static void __init acpi_request_region (struct acpi_generic_address *addr, 141static 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
155static int __init acpi_reserve_resources(void) 154static 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);
64static int acpi_power_add(struct acpi_device *device); 62static int acpi_power_add(struct acpi_device *device);
65static int acpi_power_remove(struct acpi_device *device, int type); 63static int acpi_power_remove(struct acpi_device *device, int type);
66static int acpi_power_resume(struct acpi_device *device); 64static int acpi_power_resume(struct acpi_device *device);
67static int acpi_power_open_fs(struct inode *inode, struct file *file);
68 65
69static const struct acpi_device_id power_device_ids[] = { 66static 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
100static struct list_head acpi_power_resource_list; 97static struct list_head acpi_power_resource_list;
101 98
102static 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
548static struct proc_dir_entry *acpi_power_dir;
549
550static 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
598static 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
603static 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
627static 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
761int __init acpi_power_init(void) 647int __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
25ACPI_MODULE_NAME("sleep") 24ACPI_MODULE_NAME("sleep")
26#ifdef CONFIG_ACPI_PROCFS
27static 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
42static 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
47static ssize_t
48acpi_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
467static 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
478static const struct file_operations acpi_system_alarm_fops = { 414static 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
496int __init acpi_sleep_proc_init(void) 432int __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
84static int acpi_processor_add(struct acpi_device *device); 84static int acpi_processor_add(struct acpi_device *device);
85static int acpi_processor_remove(struct acpi_device *device, int type); 85static int acpi_processor_remove(struct acpi_device *device, int type);
86#ifdef CONFIG_ACPI_PROCFS
87static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
88#endif
89static void acpi_processor_notify(struct acpi_device *device, u32 event); 86static void acpi_processor_notify(struct acpi_device *device, u32 event);
90static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); 87static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
91static int acpi_processor_handle_eject(struct acpi_processor *pr); 88static 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
117static 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
126DEFINE_PER_CPU(struct acpi_processor *, processors); 114DEFINE_PER_CPU(struct acpi_processor *, processors);
127EXPORT_PER_CPU_SYMBOL(processors); 115EXPORT_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
264static struct proc_dir_entry *acpi_processor_dir = NULL; 247static struct proc_dir_entry *acpi_processor_dir = NULL;
265 248
266static 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
291static 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
297static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) 249static 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}
336static int acpi_processor_remove_fs(struct acpi_device *device) 271static 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
353static inline int acpi_processor_add_fs(struct acpi_device *device)
354{
355 return 0;
356}
357static 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)
952out_cpuidle: 871out_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);
82static unsigned int latency_factor __read_mostly = 2; 80static unsigned int latency_factor __read_mostly = 2;
83module_param(latency_factor, uint, 0644); 81module_param(latency_factor, uint, 0644);
84 82
85#ifdef CONFIG_ACPI_PROCFS
86static 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
693static 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
749static 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
755static 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
444static 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
467static 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
473static 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
513const 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
1219static int acpi_processor_throttling_seq_show(struct seq_file *seq, 1218static 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 */
124static 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)
127static int __acpi_pm_prepare(void) 137static 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)
142static int acpi_pm_prepare(void) 150static 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 */
182static void acpi_pm_end(void) 188static 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
300static void acpi_suspend_finish(void)
301{
302 acpi_pm_finish();
303}
304
305static int acpi_suspend_state_valid(suspend_state_t pm_state) 306static 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 = {
336static int acpi_suspend_begin_old(suspend_state_t pm_state) 337static 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)
349static struct platform_suspend_ops acpi_suspend_ops_old = { 350static 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
426static 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
436static int acpi_hibernation_enter(void) 427static 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)
481static struct platform_hibernation_ops acpi_hibernation_ops = { 471static 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
520static 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)
531static struct platform_hibernation_ops acpi_hibernation_ops_old = { 514static 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 @@
2extern u8 sleep_states[]; 2extern u8 sleep_states[];
3extern int acpi_suspend(u32 state); 3extern int acpi_suspend(u32 state);
4 4
5extern void acpi_enable_wakeup_device_prep(u8 sleep_state); 5extern void acpi_enable_wakeup_devices(u8 sleep_state);
6extern void acpi_enable_wakeup_device(u8 sleep_state); 6extern void acpi_disable_wakeup_devices(u8 sleep_state);
7extern void acpi_disable_wakeup_device(u8 sleep_state);
8 7
9extern struct list_head acpi_wakeup_device_list; 8extern struct list_head acpi_wakeup_device_list;
10extern struct mutex acpi_device_lock; 9extern 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
38ACPI_MODULE_NAME("system"); 11ACPI_MODULE_NAME("sysfs");
39
40#define ACPI_SYSTEM_CLASS "system"
41#define ACPI_SYSTEM_DEVICE_NAME "System"
42 12
43u32 acpi_irq_handled; 13#define PREFIX "ACPI: "
44u32 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
26struct acpi_dlayer {
27 const char *name;
28 unsigned long value;
29};
30struct acpi_dlevel {
31 const char *name;
32 unsigned long value;
33};
34#define ACPI_DEBUG_INIT(v) { .name = #v, .value = v }
35
36static 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
68static 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
103static 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
131static 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
152module_param_call(debug_layer, param_set_uint, param_get_debug_layer,
153 &acpi_dbg_layer, 0644);
154module_param_call(debug_level, param_set_uint, param_get_debug_level,
155 &acpi_dbg_level, 0644);
156
157static char trace_method_name[6];
158module_param_string(trace_method_name, trace_method_name, 6, 0644);
159static unsigned int trace_debug_layer;
160module_param(trace_debug_layer, uint, 0644);
161static unsigned int trace_debug_level;
162module_param(trace_debug_level, uint, 0644);
163
164static 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;
194exit:
195 return result;
196}
197
198static 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
211module_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 */
49static int param_get_acpica_version(char *buffer, struct kernel_param *kp) 216static 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
58module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); 225module_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
63static LIST_HEAD(acpi_table_attr_list); 233static LIST_HEAD(acpi_table_attr_list);
64static struct kobject *tables_kobj; 234static struct kobject *tables_kobj;
65static struct kobject *dynamic_tables_kobj; 235static 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
99static void acpi_table_attr_init(struct acpi_table_attr *table_attr, 267static 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
167static int acpi_system_sysfs_init(void) 334static 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
387u32 acpi_irq_handled;
388u32 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
226struct event_counter { 396struct event_counter {
@@ -237,6 +407,7 @@ static u32 acpi_gpe_count;
237static struct attribute_group interrupt_stats_attr_group = { 407static struct attribute_group interrupt_stats_attr_group = {
238 .name = "interrupts", 408 .name = "interrupts",
239}; 409};
410
240static struct kobj_attribute *counter_attrs; 411static struct kobj_attribute *counter_attrs;
241 412
242static void delete_gpe_attr_array(void) 413static 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
292static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) 463static 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
314static ssize_t counter_show(struct kobject *kobj, 486static 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
349end: 520end:
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 */
359static ssize_t counter_set(struct kobject *kobj, 530static 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/* -------------------------------------------------------------------------- 678int __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
515static 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
522static 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
527static 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
535static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
536 loff_t *);
537
538static const struct file_operations acpi_system_dsdt_ops = {
539 .owner = THIS_MODULE,
540 .read = acpi_system_read_dsdt,
541};
542
543static ssize_t
544acpi_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
560static ssize_t acpi_system_read_fadt(struct file *, char __user *, size_t,
561 loff_t *);
562
563static const struct file_operations acpi_system_fadt_ops = {
564 .owner = THIS_MODULE,
565 .read = acpi_system_read_fadt,
566};
567
568static ssize_t
569acpi_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
585static 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
620static int acpi_system_procfs_init(void)
621{
622 return 0;
623}
624#endif
625
626int __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);
102static int acpi_thermal_remove(struct acpi_device *device, int type); 106static int acpi_thermal_remove(struct acpi_device *device, int type);
103static int acpi_thermal_resume(struct acpi_device *device); 107static int acpi_thermal_resume(struct acpi_device *device);
104static void acpi_thermal_notify(struct acpi_device *device, u32 event); 108static void acpi_thermal_notify(struct acpi_device *device, u32 event);
105static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
106static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
107static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
108static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file);
109static ssize_t acpi_thermal_write_cooling_mode(struct file *,
110 const char __user *, size_t,
111 loff_t *);
112static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file);
113static ssize_t acpi_thermal_write_polling(struct file *, const char __user *,
114 size_t, loff_t *);
115 109
116static const struct acpi_device_id thermal_device_ids[] = { 110static 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
199static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
200static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
201static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
202static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file);
203static ssize_t acpi_thermal_write_cooling_mode(struct file *,
204 const char __user *, size_t,
205 loff_t *);
206static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file);
207static ssize_t acpi_thermal_write_polling(struct file *, const char __user *,
208 size_t, loff_t *);
209
204static const struct file_operations acpi_thermal_state_fops = { 210static 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
290static 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
310static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) 297static 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
977static struct proc_dir_entry *acpi_thermal_dir; 964static struct proc_dir_entry *acpi_thermal_dir;
978 965
979static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) 966static 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
1177static 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
1190static ssize_t 1197static ssize_t
1191acpi_thermal_write_polling(struct file *file, 1198acpi_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
1306static inline int acpi_thermal_add_fs(struct acpi_device *device) { return 0; }
1307static 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 */
212static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file); 215static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
213static const struct file_operations acpi_video_bus_info_fops = { 216static 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
311static const char device_decode[][30] = { 315static 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
452static int 456static int
453acpi_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
462static int
463acpi_video_device_get_state(struct acpi_video_device *device, 457acpi_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
701static int
702acpi_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
719static int
720acpi_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
729static int
730acpi_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
1163static struct proc_dir_entry *acpi_video_dir; 1118static 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
1156static int
1157acpi_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
1201static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) 1168static 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
1462static int
1463acpi_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
1495static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) 1475static 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
1513static int
1514acpi_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
1533static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) 1523static 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
1565static int
1566acpi_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
1575static ssize_t 1584static ssize_t
1576acpi_video_bus_write_POST(struct file *file, 1585acpi_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
1735static inline int acpi_video_device_add_fs(struct acpi_device *device)
1736{
1737 return 0;
1738}
1739static inline int acpi_video_device_remove_fs(struct acpi_device *device)
1740{
1741 return 0;
1742}
1743static inline int acpi_video_bus_add_fs(struct acpi_device *device)
1744{
1745 return 0;
1746}
1747static 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,
2150static int acpi_video_bus_put_one_device(struct acpi_video_device *device) 2177static 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 @@
21ACPI_MODULE_NAME("wakeup_devices") 21ACPI_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 */
30void acpi_enable_wakeup_device_prep(u8 sleep_state) 31void 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 */
55void 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 */
85void acpi_disable_wakeup_device(u8 sleep_state) 57void acpi_disable_wakeup_devices(u8 sleep_state)
86{ 58{
87 struct list_head *node, *next; 59 struct list_head *node, *next;
88 60