diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-08-16 13:42:58 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-08-16 13:42:58 -0400 |
commit | e4862f2f6f5653dfb67f3ba2b6f0bc74516ed51a (patch) | |
tree | 1db5a0540a4eecfad9b7daee476b985e82ddc810 /drivers/acpi | |
parent | ec62dbd7eb8e3dddb221da89ecbcea0fc3dee8c1 (diff) | |
parent | b2c1e07b81a126e5846dfc3d36f559d861df59f4 (diff) |
Merge branch 'for-2.6.36' into for-2.6.37
Fairly simple conflicts, the most serious ones are the i.MX ones which I
suspect now need another rename.
Conflicts:
arch/arm/mach-mx2/clock_imx27.c
arch/arm/mach-mx2/devices.c
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/board-zoom2.c
sound/soc/fsl/mpc5200_dma.c
sound/soc/fsl/mpc5200_dma.h
sound/soc/fsl/mpc8610_hpcd.c
sound/soc/pxa/spitz.c
Diffstat (limited to 'drivers/acpi')
85 files changed, 1853 insertions, 2512 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 746411518802..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 | ||
@@ -104,6 +97,24 @@ config ACPI_SYSFS_POWER | |||
104 | help | 97 | help |
105 | Say N to disable power /sys interface | 98 | Say N to disable power /sys interface |
106 | 99 | ||
100 | config ACPI_EC_DEBUGFS | ||
101 | tristate "EC read/write access through /sys/kernel/debug/ec" | ||
102 | default n | ||
103 | help | ||
104 | Say N to disable Embedded Controller /sys/kernel/debug interface | ||
105 | |||
106 | Be aware that using this interface can confuse your Embedded | ||
107 | Controller in a way that a normal reboot is not enough. You then | ||
108 | have to power of your system, and remove the laptop battery for | ||
109 | some seconds. | ||
110 | An Embedded Controller typically is available on laptops and reads | ||
111 | sensor values like battery state and temperature. | ||
112 | The kernel accesses the EC through ACPI parsed code provided by BIOS | ||
113 | tables. This option allows to access the EC directly without ACPI | ||
114 | code being involved. | ||
115 | Thus this option is a debug option that helps to write ACPI drivers | ||
116 | and can be used to identify ACPI code or EC firmware bugs. | ||
117 | |||
107 | config ACPI_PROC_EVENT | 118 | config ACPI_PROC_EVENT |
108 | bool "Deprecated /proc/acpi/event support" | 119 | bool "Deprecated /proc/acpi/event support" |
109 | depends on PROC_FS | 120 | depends on PROC_FS |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 6ee33169e1dc..3d031d02e54b 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -37,8 +37,9 @@ acpi-y += ec.o | |||
37 | acpi-$(CONFIG_ACPI_DOCK) += dock.o | 37 | acpi-$(CONFIG_ACPI_DOCK) += dock.o |
38 | acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o | 38 | acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o |
39 | acpi-y += power.o | 39 | acpi-y += power.o |
40 | acpi-y += system.o event.o | 40 | acpi-y += event.o |
41 | acpi-$(CONFIG_ACPI_DEBUG) += debug.o | 41 | acpi-y += sysfs.o |
42 | acpi-$(CONFIG_DEBUG_FS) += debugfs.o | ||
42 | acpi-$(CONFIG_ACPI_NUMA) += numa.o | 43 | acpi-$(CONFIG_ACPI_NUMA) += numa.o |
43 | acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o | 44 | acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o |
44 | ifdef CONFIG_ACPI_VIDEO | 45 | ifdef CONFIG_ACPI_VIDEO |
@@ -60,6 +61,7 @@ obj-$(CONFIG_ACPI_SBS) += sbshc.o | |||
60 | obj-$(CONFIG_ACPI_SBS) += sbs.o | 61 | obj-$(CONFIG_ACPI_SBS) += sbs.o |
61 | obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o | 62 | obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o |
62 | obj-$(CONFIG_ACPI_HED) += hed.o | 63 | obj-$(CONFIG_ACPI_HED) += hed.o |
64 | obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o | ||
63 | 65 | ||
64 | # processor has its own "processor." module_param namespace | 66 | # processor has its own "processor." module_param namespace |
65 | processor-y := processor_driver.o processor_throttling.o | 67 | processor-y := processor_driver.o processor_throttling.o |
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index d269a8f3329c..b76848c80be3 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
@@ -46,6 +46,8 @@ static unsigned long power_saving_mwait_eax; | |||
46 | 46 | ||
47 | static unsigned char tsc_detected_unstable; | 47 | static unsigned char tsc_detected_unstable; |
48 | static unsigned char tsc_marked_unstable; | 48 | static unsigned char tsc_marked_unstable; |
49 | static unsigned char lapic_detected_unstable; | ||
50 | static unsigned char lapic_marked_unstable; | ||
49 | 51 | ||
50 | static void power_saving_mwait_init(void) | 52 | static void power_saving_mwait_init(void) |
51 | { | 53 | { |
@@ -75,10 +77,7 @@ static void power_saving_mwait_init(void) | |||
75 | power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | | 77 | power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | |
76 | (highest_subcstate - 1); | 78 | (highest_subcstate - 1); |
77 | 79 | ||
78 | for_each_online_cpu(i) | 80 | #if defined(CONFIG_X86) |
79 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &i); | ||
80 | |||
81 | #if defined(CONFIG_GENERIC_TIME) && defined(CONFIG_X86) | ||
82 | switch (boot_cpu_data.x86_vendor) { | 81 | switch (boot_cpu_data.x86_vendor) { |
83 | case X86_VENDOR_AMD: | 82 | case X86_VENDOR_AMD: |
84 | case X86_VENDOR_INTEL: | 83 | case X86_VENDOR_INTEL: |
@@ -86,13 +85,15 @@ static void power_saving_mwait_init(void) | |||
86 | * AMD Fam10h TSC will tick in all | 85 | * AMD Fam10h TSC will tick in all |
87 | * C/P/S0/S1 states when this bit is set. | 86 | * C/P/S0/S1 states when this bit is set. |
88 | */ | 87 | */ |
89 | if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) | 88 | if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) |
90 | return; | 89 | tsc_detected_unstable = 1; |
91 | 90 | if (!boot_cpu_has(X86_FEATURE_ARAT)) | |
92 | /*FALL THROUGH*/ | 91 | lapic_detected_unstable = 1; |
92 | break; | ||
93 | default: | 93 | default: |
94 | /* TSC could halt in idle */ | 94 | /* TSC & LAPIC could halt in idle */ |
95 | tsc_detected_unstable = 1; | 95 | tsc_detected_unstable = 1; |
96 | lapic_detected_unstable = 1; | ||
96 | } | 97 | } |
97 | #endif | 98 | #endif |
98 | } | 99 | } |
@@ -180,10 +181,20 @@ static int power_saving_thread(void *data) | |||
180 | mark_tsc_unstable("TSC halts in idle"); | 181 | mark_tsc_unstable("TSC halts in idle"); |
181 | tsc_marked_unstable = 1; | 182 | tsc_marked_unstable = 1; |
182 | } | 183 | } |
184 | if (lapic_detected_unstable && !lapic_marked_unstable) { | ||
185 | int i; | ||
186 | /* LAPIC could halt in idle, so notify users */ | ||
187 | for_each_online_cpu(i) | ||
188 | clockevents_notify( | ||
189 | CLOCK_EVT_NOTIFY_BROADCAST_ON, | ||
190 | &i); | ||
191 | lapic_marked_unstable = 1; | ||
192 | } | ||
183 | local_irq_disable(); | 193 | local_irq_disable(); |
184 | cpu = smp_processor_id(); | 194 | cpu = smp_processor_id(); |
185 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, | 195 | if (lapic_marked_unstable) |
186 | &cpu); | 196 | clockevents_notify( |
197 | CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); | ||
187 | stop_critical_timings(); | 198 | stop_critical_timings(); |
188 | 199 | ||
189 | __monitor((void *)¤t_thread_info()->flags, 0, 0); | 200 | __monitor((void *)¤t_thread_info()->flags, 0, 0); |
@@ -192,8 +203,9 @@ static int power_saving_thread(void *data) | |||
192 | __mwait(power_saving_mwait_eax, 1); | 203 | __mwait(power_saving_mwait_eax, 1); |
193 | 204 | ||
194 | start_critical_timings(); | 205 | start_critical_timings(); |
195 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, | 206 | if (lapic_marked_unstable) |
196 | &cpu); | 207 | clockevents_notify( |
208 | CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); | ||
197 | local_irq_enable(); | 209 | local_irq_enable(); |
198 | 210 | ||
199 | if (jiffies > expire_time) { | 211 | if (jiffies > expire_time) { |
diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index 33181ad350d5..b17d8de9f6ff 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h | |||
@@ -119,6 +119,10 @@ | |||
119 | 119 | ||
120 | #define ACPI_MAX_LOOP_ITERATIONS 0xFFFF | 120 | #define ACPI_MAX_LOOP_ITERATIONS 0xFFFF |
121 | 121 | ||
122 | /* Maximum sleep allowed via Sleep() operator */ | ||
123 | |||
124 | #define ACPI_MAX_SLEEP 20000 /* Two seconds */ | ||
125 | |||
122 | /****************************************************************************** | 126 | /****************************************************************************** |
123 | * | 127 | * |
124 | * ACPI Specification constants (Do not change unless the specification changes) | 128 | * ACPI Specification constants (Do not change unless the specification changes) |
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 64d1e5c2d4ae..36867cd70eac 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -78,11 +78,13 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node *node, | |||
78 | u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); | 78 | u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); |
79 | 79 | ||
80 | acpi_status | 80 | acpi_status |
81 | acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info); | 81 | acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info); |
82 | 82 | ||
83 | acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); | 83 | acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); |
84 | 84 | ||
85 | acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); | 85 | acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); |
86 | |||
87 | acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); | ||
86 | 88 | ||
87 | struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, | 89 | struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, |
88 | u32 gpe_number); | 90 | u32 gpe_number); |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 9070f1fe8f17..1d192142c691 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -100,13 +100,6 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_all_methods_serialized, FALSE); | |||
100 | u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE); | 100 | u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE); |
101 | 101 | ||
102 | /* | 102 | /* |
103 | * Disable wakeup GPEs during runtime? Default is TRUE because WAKE and | ||
104 | * RUNTIME GPEs should never be shared, and WAKE GPEs should typically only | ||
105 | * be enabled just before going to sleep. | ||
106 | */ | ||
107 | u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE); | ||
108 | |||
109 | /* | ||
110 | * Optionally use default values for the ACPI register widths. Set this to | 103 | * Optionally use default values for the ACPI register widths. Set this to |
111 | * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. | 104 | * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. |
112 | */ | 105 | */ |
@@ -115,7 +108,7 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE); | |||
115 | /* | 108 | /* |
116 | * Optionally enable output from the AML Debug Object. | 109 | * Optionally enable output from the AML Debug Object. |
117 | */ | 110 | */ |
118 | u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); | 111 | u32 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); |
119 | 112 | ||
120 | /* | 113 | /* |
121 | * Optionally copy the entire DSDT to local memory (instead of simply | 114 | * Optionally copy the entire DSDT to local memory (instead of simply |
@@ -125,6 +118,14 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); | |||
125 | */ | 118 | */ |
126 | u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE); | 119 | u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE); |
127 | 120 | ||
121 | /* | ||
122 | * Optionally truncate I/O addresses to 16 bits. Provides compatibility | ||
123 | * with other ACPI implementations. NOTE: During ACPICA initialization, | ||
124 | * this value is set to TRUE if any Windows OSI strings have been | ||
125 | * requested by the BIOS. | ||
126 | */ | ||
127 | u8 ACPI_INIT_GLOBAL(acpi_gbl_truncate_io_addresses, FALSE); | ||
128 | |||
128 | /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ | 129 | /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ |
129 | 130 | ||
130 | struct acpi_table_fadt acpi_gbl_FADT; | 131 | struct acpi_table_fadt acpi_gbl_FADT; |
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 5900f135dc6d..120b3af56596 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h | |||
@@ -90,10 +90,11 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width); | |||
90 | /* | 90 | /* |
91 | * hwgpe - GPE support | 91 | * hwgpe - GPE support |
92 | */ | 92 | */ |
93 | acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); | 93 | u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, |
94 | struct acpi_gpe_register_info *gpe_register_info); | ||
94 | 95 | ||
95 | acpi_status | 96 | acpi_status |
96 | acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info); | 97 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action); |
97 | 98 | ||
98 | acpi_status | 99 | acpi_status |
99 | acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 100 | acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 147a7e6bd38f..df85b53a674f 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -184,8 +184,9 @@ struct acpi_namespace_node { | |||
184 | u8 flags; /* Miscellaneous flags */ | 184 | u8 flags; /* Miscellaneous flags */ |
185 | acpi_owner_id owner_id; /* Node creator */ | 185 | acpi_owner_id owner_id; /* Node creator */ |
186 | union acpi_name_union name; /* ACPI Name, always 4 chars per ACPI spec */ | 186 | union acpi_name_union name; /* ACPI Name, always 4 chars per ACPI spec */ |
187 | struct acpi_namespace_node *parent; /* Parent node */ | ||
187 | struct acpi_namespace_node *child; /* First child */ | 188 | struct acpi_namespace_node *child; /* First child */ |
188 | struct acpi_namespace_node *peer; /* Peer. Parent if ANOBJ_END_OF_PEER_LIST set */ | 189 | struct acpi_namespace_node *peer; /* First peer */ |
189 | 190 | ||
190 | /* | 191 | /* |
191 | * The following fields are used by the ASL compiler and disassembler only | 192 | * The following fields are used by the ASL compiler and disassembler only |
@@ -199,7 +200,7 @@ struct acpi_namespace_node { | |||
199 | 200 | ||
200 | /* Namespace Node flags */ | 201 | /* Namespace Node flags */ |
201 | 202 | ||
202 | #define ANOBJ_END_OF_PEER_LIST 0x01 /* End-of-list, Peer field points to parent */ | 203 | #define ANOBJ_RESERVED 0x01 /* Available for use */ |
203 | #define ANOBJ_TEMPORARY 0x02 /* Node is create by a method and is temporary */ | 204 | #define ANOBJ_TEMPORARY 0x02 /* Node is create by a method and is temporary */ |
204 | #define ANOBJ_METHOD_ARG 0x04 /* Node is a method argument */ | 205 | #define ANOBJ_METHOD_ARG 0x04 /* Node is a method argument */ |
205 | #define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */ | 206 | #define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */ |
@@ -411,6 +412,7 @@ struct acpi_handler_info { | |||
411 | acpi_event_handler address; /* Address of handler, if any */ | 412 | acpi_event_handler address; /* Address of handler, if any */ |
412 | void *context; /* Context to be passed to handler */ | 413 | void *context; /* Context to be passed to handler */ |
413 | 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 */ | ||
414 | }; | 416 | }; |
415 | 417 | ||
416 | union acpi_gpe_dispatch_info { | 418 | union acpi_gpe_dispatch_info { |
@@ -428,7 +430,6 @@ struct acpi_gpe_event_info { | |||
428 | u8 flags; /* Misc info about this GPE */ | 430 | u8 flags; /* Misc info about this GPE */ |
429 | u8 gpe_number; /* This GPE */ | 431 | u8 gpe_number; /* This GPE */ |
430 | u8 runtime_count; /* References to a run GPE */ | 432 | u8 runtime_count; /* References to a run GPE */ |
431 | u8 wakeup_count; /* References to a wake GPE */ | ||
432 | }; | 433 | }; |
433 | 434 | ||
434 | /* Information about a GPE register pair, one per each status/enable pair in an array */ | 435 | /* Information about a GPE register pair, one per each status/enable pair in an array */ |
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 258159cfcdfa..9f60ff002203 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
@@ -369,11 +369,4 @@ struct acpi_namespace_node *acpi_ns_validate_handle(acpi_handle handle); | |||
369 | 369 | ||
370 | void acpi_ns_terminate(void); | 370 | void acpi_ns_terminate(void); |
371 | 371 | ||
372 | struct acpi_namespace_node *acpi_ns_get_parent_node(struct acpi_namespace_node | ||
373 | *node); | ||
374 | |||
375 | struct acpi_namespace_node *acpi_ns_get_next_valid_node(struct | ||
376 | acpi_namespace_node | ||
377 | *node); | ||
378 | |||
379 | #endif /* __ACNAMESP_H__ */ | 372 | #endif /* __ACNAMESP_H__ */ |
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index cde18ea82656..54857fa87aaf 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h | |||
@@ -91,14 +91,14 @@ | |||
91 | 91 | ||
92 | /* Values for Flag byte above */ | 92 | /* Values for Flag byte above */ |
93 | 93 | ||
94 | #define AOPOBJ_AML_CONSTANT 0x01 | 94 | #define AOPOBJ_AML_CONSTANT 0x01 /* Integer is an AML constant */ |
95 | #define AOPOBJ_STATIC_POINTER 0x02 | 95 | #define AOPOBJ_STATIC_POINTER 0x02 /* Data is part of an ACPI table, don't delete */ |
96 | #define AOPOBJ_DATA_VALID 0x04 | 96 | #define AOPOBJ_DATA_VALID 0x04 /* Object is intialized and data is valid */ |
97 | #define AOPOBJ_OBJECT_INITIALIZED 0x08 | 97 | #define AOPOBJ_OBJECT_INITIALIZED 0x08 /* Region is initialized, _REG was run */ |
98 | #define AOPOBJ_SETUP_COMPLETE 0x10 | 98 | #define AOPOBJ_SETUP_COMPLETE 0x10 /* Region setup is complete */ |
99 | #define AOPOBJ_SINGLE_DATUM 0x20 | 99 | #define AOPOBJ_INVALID 0x20 /* Host OS won't allow a Region address */ |
100 | #define AOPOBJ_INVALID 0x40 /* Used if host OS won't allow an op_region address */ | 100 | #define AOPOBJ_MODULE_LEVEL 0x40 /* Method is actually module-level code */ |
101 | #define AOPOBJ_MODULE_LEVEL 0x80 | 101 | #define AOPOBJ_MODIFIED_NAMESPACE 0x80 /* Method modified the namespace */ |
102 | 102 | ||
103 | /****************************************************************************** | 103 | /****************************************************************************** |
104 | * | 104 | * |
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index 97116082cb6c..10998d369ad0 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h | |||
@@ -503,15 +503,16 @@ static const union acpi_predefined_info predefined_names[] = | |||
503 | {{"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}}, | 503 | {{"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}}, |
504 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, /* Fixed-length (2 Int), but is optional */ | 504 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, /* Fixed-length (2 Int), but is optional */ |
505 | 505 | ||
506 | {{{0,0,0,0}, 0,0}} /* Table terminator */ | 506 | /* _WDG/_WED are MS extensions defined by "Windows Instrumentation" */ |
507 | }; | ||
508 | 507 | ||
509 | #if 0 | 508 | {{"_WDG", 0, ACPI_RTYPE_BUFFER}}, |
510 | /* Not implemented */ | 509 | {{"_WED", 1, |
510 | ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER}}, | ||
511 | 511 | ||
512 | {{"_WDG", 0, ACPI_RTYPE_BUFFER}}, /* MS Extension */ | 512 | {{{0, 0, 0, 0}, 0, 0}} /* Table terminator */ |
513 | {{"_WED", 1, ACPI_RTYPE_PACKAGE}}, /* MS Extension */ | 513 | }; |
514 | 514 | ||
515 | #if 0 | ||
515 | /* This is an internally implemented control method, no need to check */ | 516 | /* This is an internally implemented control method, no need to check */ |
516 | {{"_OSI", 1, ACPI_RTYPE_INTEGER}}, | 517 | {{"_OSI", 1, ACPI_RTYPE_INTEGER}}, |
517 | 518 | ||
diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h index 161bc0e3d70a..6e5dd97949fe 100644 --- a/drivers/acpi/acpica/acstruct.h +++ b/drivers/acpi/acpica/acstruct.h | |||
@@ -127,22 +127,22 @@ struct acpi_walk_state { | |||
127 | acpi_parse_upwards ascending_callback; | 127 | acpi_parse_upwards ascending_callback; |
128 | }; | 128 | }; |
129 | 129 | ||
130 | /* Info used by acpi_ps_init_objects */ | 130 | /* Info used by acpi_ns_initialize_objects and acpi_ds_initialize_objects */ |
131 | 131 | ||
132 | struct acpi_init_walk_info { | 132 | struct acpi_init_walk_info { |
133 | u16 method_count; | ||
134 | u16 device_count; | ||
135 | u16 op_region_count; | ||
136 | u16 field_count; | ||
137 | u16 buffer_count; | ||
138 | u16 package_count; | ||
139 | u16 op_region_init; | ||
140 | u16 field_init; | ||
141 | u16 buffer_init; | ||
142 | u16 package_init; | ||
143 | u16 object_count; | ||
144 | acpi_owner_id owner_id; | ||
145 | u32 table_index; | 133 | u32 table_index; |
134 | u32 object_count; | ||
135 | u32 method_count; | ||
136 | u32 device_count; | ||
137 | u32 op_region_count; | ||
138 | u32 field_count; | ||
139 | u32 buffer_count; | ||
140 | u32 package_count; | ||
141 | u32 op_region_init; | ||
142 | u32 field_init; | ||
143 | u32 buffer_init; | ||
144 | u32 package_init; | ||
145 | acpi_owner_id owner_id; | ||
146 | }; | 146 | }; |
147 | 147 | ||
148 | struct acpi_get_devices_info { | 148 | struct acpi_get_devices_info { |
@@ -201,11 +201,11 @@ struct acpi_evaluate_info { | |||
201 | /* Info used by acpi_ns_initialize_devices */ | 201 | /* Info used by acpi_ns_initialize_devices */ |
202 | 202 | ||
203 | struct acpi_device_walk_info { | 203 | struct acpi_device_walk_info { |
204 | u16 device_count; | ||
205 | u16 num_STA; | ||
206 | u16 num_INI; | ||
207 | struct acpi_table_desc *table_desc; | 204 | struct acpi_table_desc *table_desc; |
208 | struct acpi_evaluate_info *evaluate_info; | 205 | struct acpi_evaluate_info *evaluate_info; |
206 | u32 device_count; | ||
207 | u32 num_STA; | ||
208 | u32 num_INI; | ||
209 | }; | 209 | }; |
210 | 210 | ||
211 | /* TBD: [Restructure] Merge with struct above */ | 211 | /* TBD: [Restructure] Merge with struct above */ |
diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c index abe140318a74..cc4a38c57558 100644 --- a/drivers/acpi/acpica/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c | |||
@@ -171,12 +171,12 @@ acpi_ds_initialize_objects(u32 table_index, | |||
171 | "**** Starting initialization of namespace objects ****\n")); | 171 | "**** Starting initialization of namespace objects ****\n")); |
172 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:")); | 172 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:")); |
173 | 173 | ||
174 | info.method_count = 0; | 174 | /* Set all init info to zero */ |
175 | info.op_region_count = 0; | 175 | |
176 | info.object_count = 0; | 176 | ACPI_MEMSET(&info, 0, sizeof(struct acpi_init_walk_info)); |
177 | info.device_count = 0; | 177 | |
178 | info.table_index = table_index; | ||
179 | info.owner_id = owner_id; | 178 | info.owner_id = owner_id; |
179 | info.table_index = table_index; | ||
180 | 180 | ||
181 | /* Walk entire namespace from the supplied root */ | 181 | /* Walk entire namespace from the supplied root */ |
182 | 182 | ||
@@ -204,13 +204,13 @@ acpi_ds_initialize_objects(u32 table_index, | |||
204 | } | 204 | } |
205 | 205 | ||
206 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | 206 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
207 | "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n", | 207 | "\nTable [%4.4s](id %4.4X) - %u Objects with %u Devices %u Methods %u Regions\n", |
208 | table->signature, owner_id, info.object_count, | 208 | table->signature, owner_id, info.object_count, |
209 | info.device_count, info.method_count, | 209 | info.device_count, info.method_count, |
210 | info.op_region_count)); | 210 | info.op_region_count)); |
211 | 211 | ||
212 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 212 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
213 | "%hd Methods, %hd Regions\n", info.method_count, | 213 | "%u Methods, %u Regions\n", info.method_count, |
214 | info.op_region_count)); | 214 | info.op_region_count)); |
215 | 215 | ||
216 | return_ACPI_STATUS(AE_OK); | 216 | return_ACPI_STATUS(AE_OK); |
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 2a9a561c2f01..64750ee96e20 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c | |||
@@ -584,8 +584,22 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
584 | * want make the objects permanent. | 584 | * want make the objects permanent. |
585 | */ | 585 | */ |
586 | if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { | 586 | if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { |
587 | acpi_ns_delete_namespace_by_owner(method_desc->method. | 587 | |
588 | owner_id); | 588 | /* Delete any direct children of (created by) this method */ |
589 | |||
590 | acpi_ns_delete_namespace_subtree(walk_state-> | ||
591 | method_node); | ||
592 | |||
593 | /* | ||
594 | * Delete any objects that were created by this method | ||
595 | * elsewhere in the namespace (if any were created). | ||
596 | */ | ||
597 | if (method_desc->method. | ||
598 | flags & AOPOBJ_MODIFIED_NAMESPACE) { | ||
599 | acpi_ns_delete_namespace_by_owner(method_desc-> | ||
600 | method. | ||
601 | owner_id); | ||
602 | } | ||
589 | } | 603 | } |
590 | } | 604 | } |
591 | 605 | ||
@@ -605,7 +619,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
605 | * we immediately reuse it for the next thread executing this method | 619 | * we immediately reuse it for the next thread executing this method |
606 | */ | 620 | */ |
607 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 621 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
608 | "*** Completed execution of one thread, %d threads remaining\n", | 622 | "*** Completed execution of one thread, %u threads remaining\n", |
609 | method_desc->method.thread_count)); | 623 | method_desc->method.thread_count)); |
610 | } else { | 624 | } else { |
611 | /* This is the only executing thread for this method */ | 625 | /* This is the only executing thread for this method */ |
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index f3d52f59250b..8095306fcd8c 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c | |||
@@ -102,8 +102,7 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state) | |||
102 | walk_state->arguments[i].name.integer |= (i << 24); | 102 | walk_state->arguments[i].name.integer |= (i << 24); |
103 | walk_state->arguments[i].descriptor_type = ACPI_DESC_TYPE_NAMED; | 103 | walk_state->arguments[i].descriptor_type = ACPI_DESC_TYPE_NAMED; |
104 | walk_state->arguments[i].type = ACPI_TYPE_ANY; | 104 | walk_state->arguments[i].type = ACPI_TYPE_ANY; |
105 | walk_state->arguments[i].flags = | 105 | walk_state->arguments[i].flags = ANOBJ_METHOD_ARG; |
106 | ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG; | ||
107 | } | 106 | } |
108 | 107 | ||
109 | /* Init the method locals */ | 108 | /* Init the method locals */ |
@@ -116,8 +115,7 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state) | |||
116 | walk_state->local_variables[i].descriptor_type = | 115 | walk_state->local_variables[i].descriptor_type = |
117 | ACPI_DESC_TYPE_NAMED; | 116 | ACPI_DESC_TYPE_NAMED; |
118 | walk_state->local_variables[i].type = ACPI_TYPE_ANY; | 117 | walk_state->local_variables[i].type = ACPI_TYPE_ANY; |
119 | walk_state->local_variables[i].flags = | 118 | walk_state->local_variables[i].flags = ANOBJ_METHOD_LOCAL; |
120 | ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL; | ||
121 | } | 119 | } |
122 | 120 | ||
123 | return_VOID; | 121 | return_VOID; |
@@ -146,7 +144,7 @@ void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state) | |||
146 | 144 | ||
147 | for (index = 0; index < ACPI_METHOD_NUM_LOCALS; index++) { | 145 | for (index = 0; index < ACPI_METHOD_NUM_LOCALS; index++) { |
148 | if (walk_state->local_variables[index].object) { | 146 | if (walk_state->local_variables[index].object) { |
149 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Local%d=%p\n", | 147 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Local%u=%p\n", |
150 | index, | 148 | index, |
151 | walk_state->local_variables[index]. | 149 | walk_state->local_variables[index]. |
152 | object)); | 150 | object)); |
@@ -162,7 +160,7 @@ void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state) | |||
162 | 160 | ||
163 | for (index = 0; index < ACPI_METHOD_NUM_ARGS; index++) { | 161 | for (index = 0; index < ACPI_METHOD_NUM_ARGS; index++) { |
164 | if (walk_state->arguments[index].object) { | 162 | if (walk_state->arguments[index].object) { |
165 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Arg%d=%p\n", | 163 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Arg%u=%p\n", |
166 | index, | 164 | index, |
167 | walk_state->arguments[index].object)); | 165 | walk_state->arguments[index].object)); |
168 | 166 | ||
@@ -226,7 +224,7 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params, | |||
226 | index++; | 224 | index++; |
227 | } | 225 | } |
228 | 226 | ||
229 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%d args passed to method\n", index)); | 227 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%u args passed to method\n", index)); |
230 | return_ACPI_STATUS(AE_OK); | 228 | return_ACPI_STATUS(AE_OK); |
231 | } | 229 | } |
232 | 230 | ||
@@ -323,7 +321,7 @@ acpi_ds_method_data_set_value(u8 type, | |||
323 | ACPI_FUNCTION_TRACE(ds_method_data_set_value); | 321 | ACPI_FUNCTION_TRACE(ds_method_data_set_value); |
324 | 322 | ||
325 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 323 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
326 | "NewObj %p Type %2.2X, Refs=%d [%s]\n", object, | 324 | "NewObj %p Type %2.2X, Refs=%u [%s]\n", object, |
327 | type, object->common.reference_count, | 325 | type, object->common.reference_count, |
328 | acpi_ut_get_type_name(object->common.type))); | 326 | acpi_ut_get_type_name(object->common.type))); |
329 | 327 | ||
@@ -543,7 +541,7 @@ acpi_ds_store_object_to_local(u8 type, | |||
543 | union acpi_operand_object *new_obj_desc; | 541 | union acpi_operand_object *new_obj_desc; |
544 | 542 | ||
545 | ACPI_FUNCTION_TRACE(ds_store_object_to_local); | 543 | ACPI_FUNCTION_TRACE(ds_store_object_to_local); |
546 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Type=%2.2X Index=%d Obj=%p\n", | 544 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n", |
547 | type, index, obj_desc)); | 545 | type, index, obj_desc)); |
548 | 546 | ||
549 | /* Parameter validation */ | 547 | /* Parameter validation */ |
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index 3607adcaf085..8e85f54a8e0e 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c | |||
@@ -81,6 +81,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, | |||
81 | { | 81 | { |
82 | union acpi_operand_object *obj_desc; | 82 | union acpi_operand_object *obj_desc; |
83 | acpi_status status; | 83 | acpi_status status; |
84 | acpi_object_type type; | ||
84 | 85 | ||
85 | ACPI_FUNCTION_TRACE(ds_build_internal_object); | 86 | ACPI_FUNCTION_TRACE(ds_build_internal_object); |
86 | 87 | ||
@@ -172,7 +173,20 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, | |||
172 | return_ACPI_STATUS(status); | 173 | return_ACPI_STATUS(status); |
173 | } | 174 | } |
174 | 175 | ||
175 | switch (op->common.node->type) { | 176 | /* |
177 | * Special handling for Alias objects. We need to setup the type | ||
178 | * and the Op->Common.Node to point to the Alias target. Note, | ||
179 | * Alias has at most one level of indirection internally. | ||
180 | */ | ||
181 | type = op->common.node->type; | ||
182 | if (type == ACPI_TYPE_LOCAL_ALIAS) { | ||
183 | type = obj_desc->common.type; | ||
184 | op->common.node = | ||
185 | ACPI_CAST_PTR(struct acpi_namespace_node, | ||
186 | op->common.node->object); | ||
187 | } | ||
188 | |||
189 | switch (type) { | ||
176 | /* | 190 | /* |
177 | * For these types, we need the actual node, not the subobject. | 191 | * For these types, we need the actual node, not the subobject. |
178 | * However, the subobject did not get an extra reference count above. | 192 | * However, the subobject did not get an extra reference count above. |
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index 53a7e416f33e..7c0e74227171 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c | |||
@@ -213,7 +213,7 @@ acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc) | |||
213 | 213 | ||
214 | /* Execute the AML code for the term_arg arguments */ | 214 | /* Execute the AML code for the term_arg arguments */ |
215 | 215 | ||
216 | status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), | 216 | status = acpi_ds_execute_arguments(node, node->parent, |
217 | extra_desc->extra.aml_length, | 217 | extra_desc->extra.aml_length, |
218 | extra_desc->extra.aml_start); | 218 | extra_desc->extra.aml_start); |
219 | return_ACPI_STATUS(status); | 219 | return_ACPI_STATUS(status); |
@@ -257,7 +257,7 @@ acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc) | |||
257 | 257 | ||
258 | /* Execute the AML code for the term_arg arguments */ | 258 | /* Execute the AML code for the term_arg arguments */ |
259 | 259 | ||
260 | status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), | 260 | status = acpi_ds_execute_arguments(node, node->parent, |
261 | extra_desc->extra.aml_length, | 261 | extra_desc->extra.aml_length, |
262 | extra_desc->extra.aml_start); | 262 | extra_desc->extra.aml_start); |
263 | return_ACPI_STATUS(status); | 263 | return_ACPI_STATUS(status); |
@@ -394,7 +394,7 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc) | |||
394 | 394 | ||
395 | /* Execute the argument AML */ | 395 | /* Execute the argument AML */ |
396 | 396 | ||
397 | status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), | 397 | status = acpi_ds_execute_arguments(node, node->parent, |
398 | extra_desc->extra.aml_length, | 398 | extra_desc->extra.aml_length, |
399 | extra_desc->extra.aml_start); | 399 | extra_desc->extra.aml_start); |
400 | if (ACPI_FAILURE(status)) { | 400 | if (ACPI_FAILURE(status)) { |
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index 306c62ab2e88..15135c25aa9b 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c | |||
@@ -746,7 +746,7 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, | |||
746 | index--; | 746 | index--; |
747 | 747 | ||
748 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 748 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
749 | "Arg #%d (%p) done, Arg1=%p\n", index, arg, | 749 | "Arg #%u (%p) done, Arg1=%p\n", index, arg, |
750 | first_arg)); | 750 | first_arg)); |
751 | } | 751 | } |
752 | 752 | ||
@@ -760,7 +760,7 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, | |||
760 | */ | 760 | */ |
761 | acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); | 761 | acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); |
762 | 762 | ||
763 | ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index)); | 763 | ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %u", index)); |
764 | return_ACPI_STATUS(status); | 764 | return_ACPI_STATUS(status); |
765 | } | 765 | } |
766 | 766 | ||
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index f5795915a2e9..303618889da0 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c | |||
@@ -102,9 +102,8 @@ acpi_status acpi_ev_initialize_events(void) | |||
102 | * RETURN: Status | 102 | * RETURN: Status |
103 | * | 103 | * |
104 | * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks | 104 | * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks |
105 | * (0 and 1). This causes the _PRW methods to be run, so the HW | 105 | * (0 and 1). The HW must be fully initialized at this point, |
106 | * must be fully initialized at this point, including global lock | 106 | * including global lock support. |
107 | * support. | ||
108 | * | 107 | * |
109 | ******************************************************************************/ | 108 | ******************************************************************************/ |
110 | 109 | ||
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index a221ad404167..f226eac314db 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -54,47 +54,41 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context); | |||
54 | 54 | ||
55 | /******************************************************************************* | 55 | /******************************************************************************* |
56 | * | 56 | * |
57 | * FUNCTION: acpi_ev_update_gpe_enable_masks | 57 | * FUNCTION: acpi_ev_update_gpe_enable_mask |
58 | * | 58 | * |
59 | * PARAMETERS: gpe_event_info - GPE to update | 59 | * PARAMETERS: gpe_event_info - GPE to update |
60 | * | 60 | * |
61 | * RETURN: Status | 61 | * RETURN: Status |
62 | * | 62 | * |
63 | * DESCRIPTION: Updates GPE register enable masks based upon whether there are | 63 | * DESCRIPTION: Updates GPE register enable mask based upon whether there are |
64 | * references (either wake or run) to this GPE | 64 | * runtime references to this GPE |
65 | * | 65 | * |
66 | ******************************************************************************/ | 66 | ******************************************************************************/ |
67 | 67 | ||
68 | acpi_status | 68 | acpi_status |
69 | acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info) | 69 | acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info) |
70 | { | 70 | { |
71 | struct acpi_gpe_register_info *gpe_register_info; | 71 | struct acpi_gpe_register_info *gpe_register_info; |
72 | u8 register_bit; | 72 | u32 register_bit; |
73 | 73 | ||
74 | ACPI_FUNCTION_TRACE(ev_update_gpe_enable_masks); | 74 | ACPI_FUNCTION_TRACE(ev_update_gpe_enable_mask); |
75 | 75 | ||
76 | gpe_register_info = gpe_event_info->register_info; | 76 | gpe_register_info = gpe_event_info->register_info; |
77 | if (!gpe_register_info) { | 77 | if (!gpe_register_info) { |
78 | return_ACPI_STATUS(AE_NOT_EXIST); | 78 | return_ACPI_STATUS(AE_NOT_EXIST); |
79 | } | 79 | } |
80 | 80 | ||
81 | register_bit = (u8) | 81 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, |
82 | (1 << | 82 | gpe_register_info); |
83 | (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number)); | ||
84 | 83 | ||
85 | /* Clear the wake/run bits up front */ | 84 | /* Clear the run bit up front */ |
86 | 85 | ||
87 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, register_bit); | ||
88 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit); | 86 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_run, register_bit); |
89 | 87 | ||
90 | /* Set the mask bits only if there are references to this GPE */ | 88 | /* Set the mask bit only if there are references to this GPE */ |
91 | 89 | ||
92 | if (gpe_event_info->runtime_count) { | 90 | if (gpe_event_info->runtime_count) { |
93 | ACPI_SET_BIT(gpe_register_info->enable_for_run, register_bit); | 91 | ACPI_SET_BIT(gpe_register_info->enable_for_run, (u8)register_bit); |
94 | } | ||
95 | |||
96 | if (gpe_event_info->wakeup_count) { | ||
97 | ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit); | ||
98 | } | 92 | } |
99 | 93 | ||
100 | return_ACPI_STATUS(AE_OK); | 94 | return_ACPI_STATUS(AE_OK); |
@@ -104,25 +98,20 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info) | |||
104 | * | 98 | * |
105 | * FUNCTION: acpi_ev_enable_gpe | 99 | * FUNCTION: acpi_ev_enable_gpe |
106 | * | 100 | * |
107 | * PARAMETERS: gpe_event_info - GPE to enable | 101 | * PARAMETERS: gpe_event_info - GPE to enable |
108 | * | 102 | * |
109 | * RETURN: Status | 103 | * RETURN: Status |
110 | * | 104 | * |
111 | * DESCRIPTION: Hardware-enable a GPE. Always enables the GPE, regardless | 105 | * DESCRIPTION: Clear the given GPE from stale events and enable it. |
112 | * of type or number of references. | ||
113 | * | ||
114 | * Note: The GPE lock should be already acquired when this function is called. | ||
115 | * | 106 | * |
116 | ******************************************************************************/ | 107 | ******************************************************************************/ |
117 | 108 | acpi_status | |
118 | acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | 109 | acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) |
119 | { | 110 | { |
120 | acpi_status status; | 111 | acpi_status status; |
121 | 112 | ||
122 | |||
123 | ACPI_FUNCTION_TRACE(ev_enable_gpe); | 113 | ACPI_FUNCTION_TRACE(ev_enable_gpe); |
124 | 114 | ||
125 | |||
126 | /* | 115 | /* |
127 | * We will only allow a GPE to be enabled if it has either an | 116 | * We will only allow a GPE to be enabled if it has either an |
128 | * associated method (_Lxx/_Exx) or a handler. Otherwise, the | 117 | * associated method (_Lxx/_Exx) or a handler. Otherwise, the |
@@ -133,74 +122,92 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
133 | return_ACPI_STATUS(AE_NO_HANDLER); | 122 | return_ACPI_STATUS(AE_NO_HANDLER); |
134 | } | 123 | } |
135 | 124 | ||
136 | /* Ensure the HW enable masks are current */ | ||
137 | |||
138 | status = acpi_ev_update_gpe_enable_masks(gpe_event_info); | ||
139 | if (ACPI_FAILURE(status)) { | ||
140 | return_ACPI_STATUS(status); | ||
141 | } | ||
142 | |||
143 | /* Clear the GPE (of stale events) */ | 125 | /* Clear the GPE (of stale events) */ |
144 | |||
145 | status = acpi_hw_clear_gpe(gpe_event_info); | 126 | status = acpi_hw_clear_gpe(gpe_event_info); |
146 | if (ACPI_FAILURE(status)) { | 127 | if (ACPI_FAILURE(status)) { |
147 | return_ACPI_STATUS(status); | 128 | return_ACPI_STATUS(status); |
148 | } | 129 | } |
149 | 130 | ||
150 | /* Enable the requested GPE */ | 131 | /* Enable the requested GPE */ |
132 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); | ||
151 | 133 | ||
152 | status = acpi_hw_write_gpe_enable_reg(gpe_event_info); | ||
153 | return_ACPI_STATUS(status); | 134 | return_ACPI_STATUS(status); |
154 | } | 135 | } |
155 | 136 | ||
137 | |||
156 | /******************************************************************************* | 138 | /******************************************************************************* |
157 | * | 139 | * |
158 | * FUNCTION: acpi_ev_disable_gpe | 140 | * FUNCTION: acpi_raw_enable_gpe |
159 | * | 141 | * |
160 | * PARAMETERS: gpe_event_info - GPE to disable | 142 | * PARAMETERS: gpe_event_info - GPE to enable |
161 | * | 143 | * |
162 | * RETURN: Status | 144 | * RETURN: Status |
163 | * | 145 | * |
164 | * DESCRIPTION: Hardware-disable a GPE. Always disables the requested GPE, | 146 | * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is |
165 | * regardless of the type or number of references. | 147 | * hardware-enabled. |
166 | * | ||
167 | * Note: The GPE lock should be already acquired when this function is called. | ||
168 | * | 148 | * |
169 | ******************************************************************************/ | 149 | ******************************************************************************/ |
170 | 150 | ||
171 | acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | 151 | acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) |
172 | { | 152 | { |
173 | acpi_status status; | 153 | acpi_status status = AE_OK; |
174 | 154 | ||
175 | ACPI_FUNCTION_TRACE(ev_disable_gpe); | 155 | if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { |
156 | return_ACPI_STATUS(AE_LIMIT); | ||
157 | } | ||
176 | 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 | } | ||
177 | 165 | ||
178 | /* | 166 | if (ACPI_FAILURE(status)) { |
179 | * Note: Always disable the GPE, even if we think that that it is already | 167 | gpe_event_info->runtime_count--; |
180 | * disabled. It is possible that the AML or some other code has enabled | 168 | } |
181 | * the GPE behind our back. | 169 | } |
182 | */ | ||
183 | 170 | ||
184 | /* Ensure the HW enable masks are current */ | 171 | return_ACPI_STATUS(status); |
172 | } | ||
185 | 173 | ||
186 | status = acpi_ev_update_gpe_enable_masks(gpe_event_info); | 174 | /******************************************************************************* |
187 | if (ACPI_FAILURE(status)) { | 175 | * |
188 | return_ACPI_STATUS(status); | 176 | * FUNCTION: acpi_raw_disable_gpe |
177 | * | ||
178 | * PARAMETERS: gpe_event_info - GPE to disable | ||
179 | * | ||
180 | * RETURN: Status | ||
181 | * | ||
182 | * DESCRIPTION: Remove a reference to a GPE. When the last reference is | ||
183 | * removed, the GPE is hardware-disabled. | ||
184 | * | ||
185 | ******************************************************************************/ | ||
186 | |||
187 | acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | ||
188 | { | ||
189 | acpi_status status = AE_OK; | ||
190 | |||
191 | if (!gpe_event_info->runtime_count) { | ||
192 | return_ACPI_STATUS(AE_LIMIT); | ||
193 | } | ||
194 | |||
195 | gpe_event_info->runtime_count--; | ||
196 | if (!gpe_event_info->runtime_count) { | ||
197 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); | ||
198 | if (ACPI_SUCCESS(status)) { | ||
199 | status = acpi_hw_low_set_gpe(gpe_event_info, | ||
200 | ACPI_GPE_DISABLE); | ||
201 | } | ||
202 | |||
203 | if (ACPI_FAILURE(status)) { | ||
204 | gpe_event_info->runtime_count++; | ||
205 | } | ||
189 | } | 206 | } |
190 | 207 | ||
191 | /* | ||
192 | * Always H/W disable this GPE, even if we don't know the GPE type. | ||
193 | * Simply clear the enable bit for this particular GPE, but do not | ||
194 | * write out the current GPE enable mask since this may inadvertently | ||
195 | * enable GPEs too early. An example is a rogue GPE that has arrived | ||
196 | * during ACPICA initialization - possibly because AML or other code | ||
197 | * has enabled the GPE. | ||
198 | */ | ||
199 | status = acpi_hw_low_disable_gpe(gpe_event_info); | ||
200 | return_ACPI_STATUS(status); | 208 | return_ACPI_STATUS(status); |
201 | } | 209 | } |
202 | 210 | ||
203 | |||
204 | /******************************************************************************* | 211 | /******************************************************************************* |
205 | * | 212 | * |
206 | * FUNCTION: acpi_ev_low_get_gpe_info | 213 | * FUNCTION: acpi_ev_low_get_gpe_info |
@@ -451,10 +458,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
451 | return_VOID; | 458 | return_VOID; |
452 | } | 459 | } |
453 | 460 | ||
454 | /* Update the GPE register masks for return to enabled state */ | ||
455 | |||
456 | (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); | ||
457 | |||
458 | /* | 461 | /* |
459 | * Take a snapshot of the GPE info for this level - we copy the info to | 462 | * Take a snapshot of the GPE info for this level - we copy the info to |
460 | * prevent a race condition with remove_handler/remove_block. | 463 | * prevent a race condition with remove_handler/remove_block. |
@@ -522,8 +525,12 @@ static void acpi_ev_asynch_enable_gpe(void *context) | |||
522 | } | 525 | } |
523 | } | 526 | } |
524 | 527 | ||
525 | /* Enable this GPE */ | 528 | /* |
526 | (void)acpi_hw_write_gpe_enable_reg(gpe_event_info); | 529 | * Enable this GPE, conditionally. This means that the GPE will only be |
530 | * physically enabled if the enable_for_run bit is set in the event_info | ||
531 | */ | ||
532 | (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE); | ||
533 | |||
527 | return_VOID; | 534 | return_VOID; |
528 | } | 535 | } |
529 | 536 | ||
@@ -607,7 +614,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
607 | * Disable the GPE, so it doesn't keep firing before the method has a | 614 | * Disable the GPE, so it doesn't keep firing before the method has a |
608 | * chance to run (it runs asynchronously with interrupts enabled). | 615 | * chance to run (it runs asynchronously with interrupts enabled). |
609 | */ | 616 | */ |
610 | status = acpi_ev_disable_gpe(gpe_event_info); | 617 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); |
611 | if (ACPI_FAILURE(status)) { | 618 | if (ACPI_FAILURE(status)) { |
612 | ACPI_EXCEPTION((AE_INFO, status, | 619 | ACPI_EXCEPTION((AE_INFO, status, |
613 | "Unable to disable GPE[0x%2X]", | 620 | "Unable to disable GPE[0x%2X]", |
@@ -644,7 +651,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
644 | * Disable the GPE. The GPE will remain disabled a handler | 651 | * Disable the GPE. The GPE will remain disabled a handler |
645 | * is installed or ACPICA is restarted. | 652 | * is installed or ACPICA is restarted. |
646 | */ | 653 | */ |
647 | status = acpi_ev_disable_gpe(gpe_event_info); | 654 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); |
648 | if (ACPI_FAILURE(status)) { | 655 | if (ACPI_FAILURE(status)) { |
649 | ACPI_EXCEPTION((AE_INFO, status, | 656 | ACPI_EXCEPTION((AE_INFO, status, |
650 | "Unable to disable GPE[0x%2X]", | 657 | "Unable to disable GPE[0x%2X]", |
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 7c28f2d9fd35..85445fb5844e 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -439,8 +439,6 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
439 | { | 439 | { |
440 | acpi_status status; | 440 | acpi_status status; |
441 | struct acpi_gpe_event_info *gpe_event_info; | 441 | struct acpi_gpe_event_info *gpe_event_info; |
442 | struct acpi_gpe_walk_info walk_info; | ||
443 | u32 wake_gpe_count; | ||
444 | u32 gpe_enabled_count; | 442 | u32 gpe_enabled_count; |
445 | u32 gpe_index; | 443 | u32 gpe_index; |
446 | u32 gpe_number; | 444 | u32 gpe_number; |
@@ -456,37 +454,9 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
456 | } | 454 | } |
457 | 455 | ||
458 | /* | 456 | /* |
459 | * Runtime option: Should wake GPEs be enabled at runtime? The default | 457 | * Enable all GPEs that have a corresponding method. Any other GPEs |
460 | * is no, they should only be enabled just as the machine goes to sleep. | 458 | * within this block must be enabled via the acpi_enable_gpe interface. |
461 | */ | 459 | */ |
462 | if (acpi_gbl_leave_wake_gpes_disabled) { | ||
463 | /* | ||
464 | * Differentiate runtime vs wake GPEs, via the _PRW control methods. | ||
465 | * Each GPE that has one or more _PRWs that reference it is by | ||
466 | * definition a wake GPE and will not be enabled while the machine | ||
467 | * is running. | ||
468 | */ | ||
469 | walk_info.gpe_block = gpe_block; | ||
470 | walk_info.gpe_device = gpe_device; | ||
471 | walk_info.execute_by_owner_id = FALSE; | ||
472 | |||
473 | status = | ||
474 | acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
475 | ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, | ||
476 | acpi_ev_match_prw_and_gpe, NULL, | ||
477 | &walk_info, NULL); | ||
478 | if (ACPI_FAILURE(status)) { | ||
479 | ACPI_EXCEPTION((AE_INFO, status, | ||
480 | "While executing _PRW methods")); | ||
481 | } | ||
482 | } | ||
483 | |||
484 | /* | ||
485 | * Enable all GPEs that have a corresponding method and are not | ||
486 | * capable of generating wakeups. Any other GPEs within this block | ||
487 | * must be enabled via the acpi_enable_gpe interface. | ||
488 | */ | ||
489 | wake_gpe_count = 0; | ||
490 | gpe_enabled_count = 0; | 460 | gpe_enabled_count = 0; |
491 | 461 | ||
492 | if (gpe_device == acpi_gbl_fadt_gpe_device) { | 462 | if (gpe_device == acpi_gbl_fadt_gpe_device) { |
@@ -500,13 +470,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
500 | 470 | ||
501 | gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; | 471 | gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; |
502 | gpe_event_info = &gpe_block->event_info[gpe_index]; | 472 | gpe_event_info = &gpe_block->event_info[gpe_index]; |
503 | 473 | gpe_number = gpe_index + gpe_block->block_base_number; | |
504 | if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { | ||
505 | wake_gpe_count++; | ||
506 | if (acpi_gbl_leave_wake_gpes_disabled) { | ||
507 | continue; | ||
508 | } | ||
509 | } | ||
510 | 474 | ||
511 | /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ | 475 | /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ |
512 | 476 | ||
@@ -514,11 +478,15 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
514 | continue; | 478 | continue; |
515 | } | 479 | } |
516 | 480 | ||
517 | /* Enable this GPE */ | 481 | /* |
482 | * If the GPE has already been enabled for runtime | ||
483 | * signaling, make sure it remains enabled, but do not | ||
484 | * increment its reference counter. | ||
485 | */ | ||
486 | status = gpe_event_info->runtime_count ? | ||
487 | acpi_ev_enable_gpe(gpe_event_info) : | ||
488 | acpi_enable_gpe(gpe_device, gpe_number); | ||
518 | 489 | ||
519 | gpe_number = gpe_index + gpe_block->block_base_number; | ||
520 | status = acpi_enable_gpe(gpe_device, gpe_number, | ||
521 | ACPI_GPE_TYPE_RUNTIME); | ||
522 | if (ACPI_FAILURE(status)) { | 490 | if (ACPI_FAILURE(status)) { |
523 | ACPI_EXCEPTION((AE_INFO, status, | 491 | ACPI_EXCEPTION((AE_INFO, status, |
524 | "Could not enable GPE 0x%02X", | 492 | "Could not enable GPE 0x%02X", |
@@ -530,10 +498,10 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
530 | } | 498 | } |
531 | } | 499 | } |
532 | 500 | ||
533 | if (gpe_enabled_count || wake_gpe_count) { | 501 | if (gpe_enabled_count) { |
534 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, | 502 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, |
535 | "Enabled %u Runtime GPEs, added %u Wake GPEs in this block\n", | 503 | "Enabled %u GPEs in this block\n", |
536 | gpe_enabled_count, wake_gpe_count)); | 504 | gpe_enabled_count)); |
537 | } | 505 | } |
538 | 506 | ||
539 | return_ACPI_STATUS(AE_OK); | 507 | return_ACPI_STATUS(AE_OK); |
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 3f6c2d26410d..3084c5de1bba 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c | |||
@@ -211,9 +211,7 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
211 | * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a | 211 | * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a |
212 | * result of a Load() or load_table() operation. If new GPE | 212 | * result of a Load() or load_table() operation. If new GPE |
213 | * methods have been installed, register the new methods and | 213 | * methods have been installed, register the new methods and |
214 | * enable and runtime GPEs that are associated with them. Also, | 214 | * enable and runtime GPEs that are associated with them. |
215 | * run any newly loaded _PRW methods in order to discover any | ||
216 | * new CAN_WAKE GPEs. | ||
217 | * | 215 | * |
218 | ******************************************************************************/ | 216 | ******************************************************************************/ |
219 | 217 | ||
@@ -223,49 +221,12 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) | |||
223 | struct acpi_gpe_block_info *gpe_block; | 221 | struct acpi_gpe_block_info *gpe_block; |
224 | struct acpi_gpe_walk_info walk_info; | 222 | struct acpi_gpe_walk_info walk_info; |
225 | acpi_status status = AE_OK; | 223 | acpi_status status = AE_OK; |
226 | u32 new_wake_gpe_count = 0; | ||
227 | |||
228 | /* We will examine only _PRW/_Lxx/_Exx methods owned by this table */ | ||
229 | |||
230 | walk_info.owner_id = table_owner_id; | ||
231 | walk_info.execute_by_owner_id = TRUE; | ||
232 | walk_info.count = 0; | ||
233 | |||
234 | if (acpi_gbl_leave_wake_gpes_disabled) { | ||
235 | /* | ||
236 | * 1) Run any newly-loaded _PRW methods to find any GPEs that | ||
237 | * can now be marked as CAN_WAKE GPEs. Note: We must run the | ||
238 | * _PRW methods before we process the _Lxx/_Exx methods because | ||
239 | * we will enable all runtime GPEs associated with the new | ||
240 | * _Lxx/_Exx methods at the time we process those methods. | ||
241 | * | ||
242 | * Unlock interpreter so that we can run the _PRW methods. | ||
243 | */ | ||
244 | walk_info.gpe_block = NULL; | ||
245 | walk_info.gpe_device = NULL; | ||
246 | |||
247 | acpi_ex_exit_interpreter(); | ||
248 | |||
249 | status = | ||
250 | acpi_ns_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
251 | ACPI_UINT32_MAX, | ||
252 | ACPI_NS_WALK_NO_UNLOCK, | ||
253 | acpi_ev_match_prw_and_gpe, NULL, | ||
254 | &walk_info, NULL); | ||
255 | if (ACPI_FAILURE(status)) { | ||
256 | ACPI_EXCEPTION((AE_INFO, status, | ||
257 | "While executing _PRW methods")); | ||
258 | } | ||
259 | |||
260 | acpi_ex_enter_interpreter(); | ||
261 | new_wake_gpe_count = walk_info.count; | ||
262 | } | ||
263 | 224 | ||
264 | /* | 225 | /* |
265 | * 2) Find any _Lxx/_Exx GPE methods that have just been loaded. | 226 | * 2) Find any _Lxx/_Exx GPE methods that have just been loaded. |
266 | * | 227 | * |
267 | * Any GPEs that correspond to new _Lxx/_Exx methods and are not | 228 | * Any GPEs that correspond to new _Lxx/_Exx methods are immediately |
268 | * marked as CAN_WAKE are immediately enabled. | 229 | * enabled. |
269 | * | 230 | * |
270 | * Examine the namespace underneath each gpe_device within the | 231 | * Examine the namespace underneath each gpe_device within the |
271 | * gpe_block lists. | 232 | * gpe_block lists. |
@@ -275,6 +236,8 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) | |||
275 | return; | 236 | return; |
276 | } | 237 | } |
277 | 238 | ||
239 | walk_info.owner_id = table_owner_id; | ||
240 | walk_info.execute_by_owner_id = TRUE; | ||
278 | walk_info.count = 0; | 241 | walk_info.count = 0; |
279 | walk_info.enable_this_gpe = TRUE; | 242 | walk_info.enable_this_gpe = TRUE; |
280 | 243 | ||
@@ -307,10 +270,8 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) | |||
307 | gpe_xrupt_info = gpe_xrupt_info->next; | 270 | gpe_xrupt_info = gpe_xrupt_info->next; |
308 | } | 271 | } |
309 | 272 | ||
310 | if (walk_info.count || new_wake_gpe_count) { | 273 | if (walk_info.count) { |
311 | ACPI_INFO((AE_INFO, | 274 | ACPI_INFO((AE_INFO, "Enabled %u new GPEs", walk_info.count)); |
312 | "Enabled %u new runtime GPEs, added %u new wakeup GPEs", | ||
313 | walk_info.count, new_wake_gpe_count)); | ||
314 | } | 275 | } |
315 | 276 | ||
316 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 277 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
@@ -386,9 +347,6 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
386 | /* | 347 | /* |
387 | * 3) Edge/Level determination is based on the 2nd character | 348 | * 3) Edge/Level determination is based on the 2nd character |
388 | * of the method name | 349 | * of the method name |
389 | * | ||
390 | * NOTE: Default GPE type is RUNTIME only. Later, if a _PRW object is | ||
391 | * found that points to this GPE, the ACPI_GPE_CAN_WAKE flag is set. | ||
392 | */ | 350 | */ |
393 | switch (name[1]) { | 351 | switch (name[1]) { |
394 | case 'L': | 352 | case 'L': |
@@ -471,24 +429,18 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
471 | */ | 429 | */ |
472 | if (walk_info->enable_this_gpe) { | 430 | if (walk_info->enable_this_gpe) { |
473 | 431 | ||
474 | /* Ignore GPEs that can wake the system */ | 432 | walk_info->count++; |
433 | gpe_device = walk_info->gpe_device; | ||
475 | 434 | ||
476 | if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE) || | 435 | if (gpe_device == acpi_gbl_fadt_gpe_device) { |
477 | !acpi_gbl_leave_wake_gpes_disabled) { | 436 | gpe_device = NULL; |
478 | walk_info->count++; | 437 | } |
479 | gpe_device = walk_info->gpe_device; | ||
480 | |||
481 | if (gpe_device == acpi_gbl_fadt_gpe_device) { | ||
482 | gpe_device = NULL; | ||
483 | } | ||
484 | 438 | ||
485 | status = acpi_enable_gpe(gpe_device, gpe_number, | 439 | status = acpi_enable_gpe(gpe_device, gpe_number); |
486 | ACPI_GPE_TYPE_RUNTIME); | 440 | if (ACPI_FAILURE(status)) { |
487 | if (ACPI_FAILURE(status)) { | 441 | ACPI_EXCEPTION((AE_INFO, status, |
488 | ACPI_EXCEPTION((AE_INFO, status, | 442 | "Could not enable GPE 0x%02X", |
489 | "Could not enable GPE 0x%02X", | 443 | gpe_number)); |
490 | gpe_number)); | ||
491 | } | ||
492 | } | 444 | } |
493 | } | 445 | } |
494 | 446 | ||
@@ -497,157 +449,3 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
497 | name, gpe_number)); | 449 | name, gpe_number)); |
498 | return_ACPI_STATUS(AE_OK); | 450 | return_ACPI_STATUS(AE_OK); |
499 | } | 451 | } |
500 | |||
501 | /******************************************************************************* | ||
502 | * | ||
503 | * FUNCTION: acpi_ev_match_prw_and_gpe | ||
504 | * | ||
505 | * PARAMETERS: Callback from walk_namespace | ||
506 | * | ||
507 | * RETURN: Status. NOTE: We ignore errors so that the _PRW walk is | ||
508 | * not aborted on a single _PRW failure. | ||
509 | * | ||
510 | * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a | ||
511 | * Device. Run the _PRW method. If present, extract the GPE | ||
512 | * number and mark the GPE as a CAN_WAKE GPE. Allows a | ||
513 | * per-owner_id execution if execute_by_owner_id is TRUE in the | ||
514 | * walk_info parameter block. | ||
515 | * | ||
516 | * If walk_info->execute_by_owner_id is TRUE, we only execute _PRWs with that | ||
517 | * owner. | ||
518 | * If walk_info->gpe_device is NULL, we execute every _PRW found. Otherwise, | ||
519 | * we only execute _PRWs that refer to the input gpe_device. | ||
520 | * | ||
521 | ******************************************************************************/ | ||
522 | |||
523 | acpi_status | ||
524 | acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, | ||
525 | u32 level, void *context, void **return_value) | ||
526 | { | ||
527 | struct acpi_gpe_walk_info *walk_info = | ||
528 | ACPI_CAST_PTR(struct acpi_gpe_walk_info, context); | ||
529 | struct acpi_namespace_node *gpe_device; | ||
530 | struct acpi_gpe_block_info *gpe_block; | ||
531 | struct acpi_namespace_node *target_gpe_device; | ||
532 | struct acpi_namespace_node *prw_node; | ||
533 | struct acpi_gpe_event_info *gpe_event_info; | ||
534 | union acpi_operand_object *pkg_desc; | ||
535 | union acpi_operand_object *obj_desc; | ||
536 | u32 gpe_number; | ||
537 | acpi_status status; | ||
538 | |||
539 | ACPI_FUNCTION_TRACE(ev_match_prw_and_gpe); | ||
540 | |||
541 | /* Check for a _PRW method under this device */ | ||
542 | |||
543 | status = acpi_ns_get_node(obj_handle, METHOD_NAME__PRW, | ||
544 | ACPI_NS_NO_UPSEARCH, &prw_node); | ||
545 | if (ACPI_FAILURE(status)) { | ||
546 | return_ACPI_STATUS(AE_OK); | ||
547 | } | ||
548 | |||
549 | /* Check if requested owner_id matches this owner_id */ | ||
550 | |||
551 | if ((walk_info->execute_by_owner_id) && | ||
552 | (prw_node->owner_id != walk_info->owner_id)) { | ||
553 | return_ACPI_STATUS(AE_OK); | ||
554 | } | ||
555 | |||
556 | /* Execute the _PRW */ | ||
557 | |||
558 | status = acpi_ut_evaluate_object(prw_node, NULL, | ||
559 | ACPI_BTYPE_PACKAGE, &pkg_desc); | ||
560 | if (ACPI_FAILURE(status)) { | ||
561 | return_ACPI_STATUS(AE_OK); | ||
562 | } | ||
563 | |||
564 | /* The returned _PRW package must have at least two elements */ | ||
565 | |||
566 | if (pkg_desc->package.count < 2) { | ||
567 | goto cleanup; | ||
568 | } | ||
569 | |||
570 | /* Extract pointers from the input context */ | ||
571 | |||
572 | gpe_device = walk_info->gpe_device; | ||
573 | gpe_block = walk_info->gpe_block; | ||
574 | |||
575 | /* | ||
576 | * The _PRW object must return a package, we are only interested | ||
577 | * in the first element | ||
578 | */ | ||
579 | obj_desc = pkg_desc->package.elements[0]; | ||
580 | |||
581 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
582 | |||
583 | /* Use FADT-defined GPE device (from definition of _PRW) */ | ||
584 | |||
585 | target_gpe_device = NULL; | ||
586 | if (gpe_device) { | ||
587 | target_gpe_device = acpi_gbl_fadt_gpe_device; | ||
588 | } | ||
589 | |||
590 | /* Integer is the GPE number in the FADT described GPE blocks */ | ||
591 | |||
592 | gpe_number = (u32)obj_desc->integer.value; | ||
593 | } else if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { | ||
594 | |||
595 | /* Package contains a GPE reference and GPE number within a GPE block */ | ||
596 | |||
597 | if ((obj_desc->package.count < 2) || | ||
598 | ((obj_desc->package.elements[0])->common.type != | ||
599 | ACPI_TYPE_LOCAL_REFERENCE) || | ||
600 | ((obj_desc->package.elements[1])->common.type != | ||
601 | ACPI_TYPE_INTEGER)) { | ||
602 | goto cleanup; | ||
603 | } | ||
604 | |||
605 | /* Get GPE block reference and decode */ | ||
606 | |||
607 | target_gpe_device = | ||
608 | obj_desc->package.elements[0]->reference.node; | ||
609 | gpe_number = (u32)obj_desc->package.elements[1]->integer.value; | ||
610 | } else { | ||
611 | /* Unknown type, just ignore it */ | ||
612 | |||
613 | goto cleanup; | ||
614 | } | ||
615 | |||
616 | /* Get the gpe_event_info for this GPE */ | ||
617 | |||
618 | if (gpe_device) { | ||
619 | /* | ||
620 | * Is this GPE within this block? | ||
621 | * | ||
622 | * TRUE if and only if these conditions are true: | ||
623 | * 1) The GPE devices match. | ||
624 | * 2) The GPE index(number) is within the range of the Gpe Block | ||
625 | * associated with the GPE device. | ||
626 | */ | ||
627 | if (gpe_device != target_gpe_device) { | ||
628 | goto cleanup; | ||
629 | } | ||
630 | |||
631 | gpe_event_info = | ||
632 | acpi_ev_low_get_gpe_info(gpe_number, gpe_block); | ||
633 | } else { | ||
634 | /* gpe_device is NULL, just match the target_device and gpe_number */ | ||
635 | |||
636 | gpe_event_info = | ||
637 | acpi_ev_get_gpe_event_info(target_gpe_device, gpe_number); | ||
638 | } | ||
639 | |||
640 | if (gpe_event_info) { | ||
641 | if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { | ||
642 | |||
643 | /* This GPE can wake the system */ | ||
644 | |||
645 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | ||
646 | walk_info->count++; | ||
647 | } | ||
648 | } | ||
649 | |||
650 | cleanup: | ||
651 | acpi_ut_remove_reference(pkg_desc); | ||
652 | return_ACPI_STATUS(AE_OK); | ||
653 | } | ||
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 2e3b0334072f..f40d271bf568 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c | |||
@@ -199,7 +199,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
199 | return_ACPI_STATUS(status); | 199 | return_ACPI_STATUS(status); |
200 | } | 200 | } |
201 | 201 | ||
202 | parent_node = acpi_ns_get_parent_node(region_obj->region.node); | 202 | parent_node = region_obj->region.node->parent; |
203 | 203 | ||
204 | /* | 204 | /* |
205 | * Get the _SEG and _BBN values from the device upon which the handler | 205 | * Get the _SEG and _BBN values from the device upon which the handler |
@@ -248,7 +248,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
248 | break; | 248 | break; |
249 | } | 249 | } |
250 | 250 | ||
251 | pci_root_node = acpi_ns_get_parent_node(pci_root_node); | 251 | pci_root_node = pci_root_node->parent; |
252 | } | 252 | } |
253 | 253 | ||
254 | /* PCI root bridge not found, use namespace root node */ | 254 | /* PCI root bridge not found, use namespace root node */ |
@@ -280,7 +280,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
280 | */ | 280 | */ |
281 | pci_device_node = region_obj->region.node; | 281 | pci_device_node = region_obj->region.node; |
282 | while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) { | 282 | while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) { |
283 | pci_device_node = acpi_ns_get_parent_node(pci_device_node); | 283 | pci_device_node = pci_device_node->parent; |
284 | } | 284 | } |
285 | 285 | ||
286 | if (!pci_device_node) { | 286 | if (!pci_device_node) { |
@@ -521,7 +521,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, | |||
521 | return_ACPI_STATUS(AE_NOT_EXIST); | 521 | return_ACPI_STATUS(AE_NOT_EXIST); |
522 | } | 522 | } |
523 | 523 | ||
524 | node = acpi_ns_get_parent_node(region_obj->region.node); | 524 | node = region_obj->region.node->parent; |
525 | space_id = region_obj->region.space_id; | 525 | space_id = region_obj->region.space_id; |
526 | 526 | ||
527 | /* Setup defaults */ | 527 | /* Setup defaults */ |
@@ -654,7 +654,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, | |||
654 | 654 | ||
655 | /* This node does not have the handler we need; Pop up one level */ | 655 | /* This node does not have the handler we need; Pop up one level */ |
656 | 656 | ||
657 | node = acpi_ns_get_parent_node(node); | 657 | node = node->parent; |
658 | } | 658 | } |
659 | 659 | ||
660 | /* If we get here, there is no handler for this region */ | 660 | /* If we get here, there is no handler for this region */ |
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index cc825023012a..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,31 +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); | ||
721 | 727 | ||
722 | /* Disable the GPE before installing the handler */ | 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 | */ | ||
723 | 734 | ||
724 | status = acpi_ev_disable_gpe(gpe_event_info); | 735 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) |
725 | if (ACPI_FAILURE (status)) { | 736 | && !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) |
726 | goto unlock_and_exit; | 737 | (void)acpi_raw_disable_gpe(gpe_event_info); |
727 | } | ||
728 | 738 | ||
729 | /* Install the handler */ | 739 | /* Install the handler */ |
730 | 740 | ||
731 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
732 | gpe_event_info->dispatch.handler = handler; | 741 | gpe_event_info->dispatch.handler = handler; |
733 | 742 | ||
734 | /* Setup up dispatch flags to indicate handler (vs. method) */ | 743 | /* Setup up dispatch flags to indicate handler (vs. method) */ |
@@ -742,6 +751,11 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
742 | unlock_and_exit: | 751 | unlock_and_exit: |
743 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 752 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
744 | return_ACPI_STATUS(status); | 753 | return_ACPI_STATUS(status); |
754 | |||
755 | free_and_exit: | ||
756 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
757 | ACPI_FREE(handler); | ||
758 | goto unlock_and_exit; | ||
745 | } | 759 | } |
746 | 760 | ||
747 | ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler) | 761 | ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler) |
@@ -777,11 +791,17 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
777 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 791 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
778 | } | 792 | } |
779 | 793 | ||
794 | /* Make sure all deferred tasks are completed */ | ||
795 | |||
796 | acpi_os_wait_events_complete(NULL); | ||
797 | |||
780 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | 798 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); |
781 | if (ACPI_FAILURE(status)) { | 799 | if (ACPI_FAILURE(status)) { |
782 | return_ACPI_STATUS(status); | 800 | return_ACPI_STATUS(status); |
783 | } | 801 | } |
784 | 802 | ||
803 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
804 | |||
785 | /* Ensure that we have a valid GPE number */ | 805 | /* Ensure that we have a valid GPE number */ |
786 | 806 | ||
787 | 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); |
@@ -805,34 +825,34 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
805 | goto unlock_and_exit; | 825 | goto unlock_and_exit; |
806 | } | 826 | } |
807 | 827 | ||
808 | /* Make sure all deferred tasks are completed */ | ||
809 | |||
810 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
811 | acpi_os_wait_events_complete(NULL); | ||
812 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
813 | if (ACPI_FAILURE(status)) { | ||
814 | return_ACPI_STATUS(status); | ||
815 | } | ||
816 | |||
817 | /* Remove the handler */ | 828 | /* Remove the handler */ |
818 | 829 | ||
819 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
820 | handler = gpe_event_info->dispatch.handler; | 830 | handler = gpe_event_info->dispatch.handler; |
821 | 831 | ||
822 | /* Restore Method node (if any), set dispatch flags */ | 832 | /* Restore Method node (if any), set dispatch flags */ |
823 | 833 | ||
824 | gpe_event_info->dispatch.method_node = handler->method_node; | 834 | gpe_event_info->dispatch.method_node = handler->method_node; |
825 | gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */ | 835 | gpe_event_info->flags &= |
826 | if (handler->method_node) { | 836 | ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); |
827 | gpe_event_info->flags |= ACPI_GPE_DISPATCH_METHOD; | 837 | gpe_event_info->flags |= handler->orig_flags; |
828 | } | 838 | |
829 | 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); | ||
830 | 848 | ||
831 | /* Now we can free the handler object */ | 849 | /* Now we can free the handler object */ |
832 | 850 | ||
833 | ACPI_FREE(handler); | 851 | ACPI_FREE(handler); |
834 | 852 | ||
835 | unlock_and_exit: | 853 | unlock_and_exit: |
854 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
855 | |||
836 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 856 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
837 | return_ACPI_STATUS(status); | 857 | return_ACPI_STATUS(status); |
838 | } | 858 | } |
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index d5a5efc043bf..304825528d48 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
@@ -70,6 +70,7 @@ acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
70 | acpi_status acpi_enable(void) | 70 | acpi_status acpi_enable(void) |
71 | { | 71 | { |
72 | acpi_status status; | 72 | acpi_status status; |
73 | int retry; | ||
73 | 74 | ||
74 | ACPI_FUNCTION_TRACE(acpi_enable); | 75 | ACPI_FUNCTION_TRACE(acpi_enable); |
75 | 76 | ||
@@ -98,16 +99,18 @@ acpi_status acpi_enable(void) | |||
98 | 99 | ||
99 | /* Sanity check that transition succeeded */ | 100 | /* Sanity check that transition succeeded */ |
100 | 101 | ||
101 | if (acpi_hw_get_mode() != ACPI_SYS_MODE_ACPI) { | 102 | for (retry = 0; retry < 30000; ++retry) { |
102 | ACPI_ERROR((AE_INFO, | 103 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { |
103 | "Hardware did not enter ACPI mode")); | 104 | if (retry != 0) |
104 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); | 105 | ACPI_WARNING((AE_INFO, |
106 | "Platform took > %d00 usec to enter ACPI mode", retry)); | ||
107 | return_ACPI_STATUS(AE_OK); | ||
108 | } | ||
109 | acpi_os_stall(100); /* 100 usec */ | ||
105 | } | 110 | } |
106 | 111 | ||
107 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, | 112 | ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode")); |
108 | "Transition to ACPI mode successful\n")); | 113 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); |
109 | |||
110 | return_ACPI_STATUS(AE_OK); | ||
111 | } | 114 | } |
112 | 115 | ||
113 | ACPI_EXPORT_SYMBOL(acpi_enable) | 116 | ACPI_EXPORT_SYMBOL(acpi_enable) |
@@ -210,63 +213,71 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event) | |||
210 | 213 | ||
211 | /******************************************************************************* | 214 | /******************************************************************************* |
212 | * | 215 | * |
213 | * FUNCTION: acpi_set_gpe | 216 | * FUNCTION: acpi_gpe_wakeup |
214 | * | 217 | * |
215 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | 218 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 |
216 | * gpe_number - GPE level within the GPE block | 219 | * gpe_number - GPE level within the GPE block |
217 | * action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE | 220 | * Action - Enable or Disable |
218 | * | 221 | * |
219 | * RETURN: Status | 222 | * RETURN: Status |
220 | * | 223 | * |
221 | * DESCRIPTION: Enable or disable an individual GPE. This function bypasses | 224 | * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. |
222 | * the reference count mechanism used in the acpi_enable_gpe and | ||
223 | * acpi_disable_gpe interfaces -- and should be used with care. | ||
224 | * | ||
225 | * Note: Typically used to disable a runtime GPE for short period of time, | ||
226 | * then re-enable it, without disturbing the existing reference counts. This | ||
227 | * is useful, for example, in the Embedded Controller (EC) driver. | ||
228 | * | 225 | * |
229 | ******************************************************************************/ | 226 | ******************************************************************************/ |
230 | acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) | 227 | acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action) |
231 | { | 228 | { |
229 | acpi_status status = AE_OK; | ||
232 | struct acpi_gpe_event_info *gpe_event_info; | 230 | struct acpi_gpe_event_info *gpe_event_info; |
233 | acpi_status status; | 231 | struct acpi_gpe_register_info *gpe_register_info; |
234 | acpi_cpu_flags flags; | 232 | acpi_cpu_flags flags; |
233 | u32 register_bit; | ||
235 | 234 | ||
236 | ACPI_FUNCTION_TRACE(acpi_set_gpe); | 235 | ACPI_FUNCTION_TRACE(acpi_gpe_wakeup); |
237 | 236 | ||
238 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | 237 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
239 | 238 | ||
240 | /* Ensure that we have a valid GPE number */ | 239 | /* Ensure that we have a valid GPE number */ |
241 | 240 | ||
242 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | 241 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
243 | if (!gpe_event_info) { | 242 | if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { |
244 | status = AE_BAD_PARAMETER; | 243 | status = AE_BAD_PARAMETER; |
245 | goto unlock_and_exit; | 244 | goto unlock_and_exit; |
246 | } | 245 | } |
247 | 246 | ||
247 | gpe_register_info = gpe_event_info->register_info; | ||
248 | if (!gpe_register_info) { | ||
249 | status = AE_NOT_EXIST; | ||
250 | goto unlock_and_exit; | ||
251 | } | ||
252 | |||
253 | register_bit = | ||
254 | acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); | ||
255 | |||
248 | /* Perform the action */ | 256 | /* Perform the action */ |
249 | 257 | ||
250 | switch (action) { | 258 | switch (action) { |
251 | case ACPI_GPE_ENABLE: | 259 | case ACPI_GPE_ENABLE: |
252 | status = acpi_ev_enable_gpe(gpe_event_info); | 260 | ACPI_SET_BIT(gpe_register_info->enable_for_wake, |
261 | (u8)register_bit); | ||
253 | break; | 262 | break; |
254 | 263 | ||
255 | case ACPI_GPE_DISABLE: | 264 | case ACPI_GPE_DISABLE: |
256 | status = acpi_ev_disable_gpe(gpe_event_info); | 265 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, |
266 | (u8)register_bit); | ||
257 | break; | 267 | break; |
258 | 268 | ||
259 | default: | 269 | default: |
270 | ACPI_ERROR((AE_INFO, "%u, Invalid action", action)); | ||
260 | status = AE_BAD_PARAMETER; | 271 | status = AE_BAD_PARAMETER; |
261 | break; | 272 | break; |
262 | } | 273 | } |
263 | 274 | ||
264 | unlock_and_exit: | 275 | unlock_and_exit: |
265 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 276 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
266 | return_ACPI_STATUS(status); | 277 | return_ACPI_STATUS(status); |
267 | } | 278 | } |
268 | 279 | ||
269 | ACPI_EXPORT_SYMBOL(acpi_set_gpe) | 280 | ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup) |
270 | 281 | ||
271 | /******************************************************************************* | 282 | /******************************************************************************* |
272 | * | 283 | * |
@@ -274,80 +285,30 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe) | |||
274 | * | 285 | * |
275 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | 286 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 |
276 | * gpe_number - GPE level within the GPE block | 287 | * gpe_number - GPE level within the GPE block |
277 | * gpe_type - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE | ||
278 | * or both | ||
279 | * | 288 | * |
280 | * RETURN: Status | 289 | * RETURN: Status |
281 | * | 290 | * |
282 | * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is | 291 | * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is |
283 | * hardware-enabled (for runtime GPEs), or the GPE register mask | 292 | * hardware-enabled. |
284 | * is updated (for wake GPEs). | ||
285 | * | 293 | * |
286 | ******************************************************************************/ | 294 | ******************************************************************************/ |
287 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type) | 295 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) |
288 | { | 296 | { |
289 | acpi_status status = AE_OK; | 297 | acpi_status status = AE_BAD_PARAMETER; |
290 | struct acpi_gpe_event_info *gpe_event_info; | 298 | struct acpi_gpe_event_info *gpe_event_info; |
291 | acpi_cpu_flags flags; | 299 | acpi_cpu_flags flags; |
292 | 300 | ||
293 | ACPI_FUNCTION_TRACE(acpi_enable_gpe); | 301 | ACPI_FUNCTION_TRACE(acpi_enable_gpe); |
294 | 302 | ||
295 | /* Parameter validation */ | ||
296 | |||
297 | if (!gpe_type || (gpe_type & ~ACPI_GPE_TYPE_WAKE_RUN)) { | ||
298 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
299 | } | ||
300 | |||
301 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | 303 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
302 | 304 | ||
303 | /* Ensure that we have a valid GPE number */ | 305 | /* Ensure that we have a valid GPE number */ |
304 | 306 | ||
305 | 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); |
306 | if (!gpe_event_info) { | 308 | if (gpe_event_info) { |
307 | status = AE_BAD_PARAMETER; | 309 | status = acpi_raw_enable_gpe(gpe_event_info); |
308 | goto unlock_and_exit; | ||
309 | } | ||
310 | |||
311 | if (gpe_type & ACPI_GPE_TYPE_RUNTIME) { | ||
312 | if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { | ||
313 | status = AE_LIMIT; /* Too many references */ | ||
314 | goto unlock_and_exit; | ||
315 | } | ||
316 | |||
317 | gpe_event_info->runtime_count++; | ||
318 | if (gpe_event_info->runtime_count == 1) { | ||
319 | status = acpi_ev_enable_gpe(gpe_event_info); | ||
320 | if (ACPI_FAILURE(status)) { | ||
321 | gpe_event_info->runtime_count--; | ||
322 | goto unlock_and_exit; | ||
323 | } | ||
324 | } | ||
325 | } | ||
326 | |||
327 | if (gpe_type & ACPI_GPE_TYPE_WAKE) { | ||
328 | /* The GPE must have the ability to wake the system */ | ||
329 | |||
330 | if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { | ||
331 | status = AE_TYPE; | ||
332 | goto unlock_and_exit; | ||
333 | } | ||
334 | |||
335 | if (gpe_event_info->wakeup_count == ACPI_UINT8_MAX) { | ||
336 | status = AE_LIMIT; /* Too many references */ | ||
337 | goto unlock_and_exit; | ||
338 | } | ||
339 | |||
340 | /* | ||
341 | * Update the enable mask on the first wakeup reference. Wake GPEs | ||
342 | * are only hardware-enabled just before sleeping. | ||
343 | */ | ||
344 | gpe_event_info->wakeup_count++; | ||
345 | if (gpe_event_info->wakeup_count == 1) { | ||
346 | (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); | ||
347 | } | ||
348 | } | 310 | } |
349 | 311 | ||
350 | unlock_and_exit: | ||
351 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 312 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
352 | return_ACPI_STATUS(status); | 313 | return_ACPI_STATUS(status); |
353 | } | 314 | } |
@@ -359,8 +320,6 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe) | |||
359 | * | 320 | * |
360 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | 321 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 |
361 | * gpe_number - GPE level within the GPE block | 322 | * gpe_number - GPE level within the GPE block |
362 | * gpe_type - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE | ||
363 | * or both | ||
364 | * | 323 | * |
365 | * RETURN: Status | 324 | * RETURN: Status |
366 | * | 325 | * |
@@ -369,20 +328,52 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe) | |||
369 | * the GPE mask bit disabled (for wake GPEs) | 328 | * the GPE mask bit disabled (for wake GPEs) |
370 | * | 329 | * |
371 | ******************************************************************************/ | 330 | ******************************************************************************/ |
372 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type) | 331 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) |
373 | { | 332 | { |
374 | acpi_status status = AE_OK; | 333 | acpi_status status = AE_BAD_PARAMETER; |
375 | struct acpi_gpe_event_info *gpe_event_info; | 334 | struct acpi_gpe_event_info *gpe_event_info; |
376 | acpi_cpu_flags flags; | 335 | acpi_cpu_flags flags; |
377 | 336 | ||
378 | ACPI_FUNCTION_TRACE(acpi_disable_gpe); | 337 | ACPI_FUNCTION_TRACE(acpi_disable_gpe); |
379 | 338 | ||
380 | /* Parameter validation */ | 339 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
381 | 340 | ||
382 | if (!gpe_type || (gpe_type & ~ACPI_GPE_TYPE_WAKE_RUN)) { | 341 | /* Ensure that we have a valid GPE number */ |
383 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 342 | |
343 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
344 | if (gpe_event_info) { | ||
345 | status = acpi_raw_disable_gpe(gpe_event_info) ; | ||
384 | } | 346 | } |
385 | 347 | ||
348 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
349 | return_ACPI_STATUS(status); | ||
350 | } | ||
351 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) | ||
352 | |||
353 | /******************************************************************************* | ||
354 | * | ||
355 | * FUNCTION: acpi_gpe_can_wake | ||
356 | * | ||
357 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
358 | * gpe_number - GPE level within the GPE block | ||
359 | * | ||
360 | * RETURN: Status | ||
361 | * | ||
362 | * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE | ||
363 | * has a corresponding method and is currently enabled, disable it | ||
364 | * (GPEs with corresponding methods are enabled unconditionally | ||
365 | * during initialization, but GPEs that can wake up are expected | ||
366 | * to be initially disabled). | ||
367 | * | ||
368 | ******************************************************************************/ | ||
369 | acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number) | ||
370 | { | ||
371 | acpi_status status = AE_OK; | ||
372 | struct acpi_gpe_event_info *gpe_event_info; | ||
373 | acpi_cpu_flags flags; | ||
374 | |||
375 | ACPI_FUNCTION_TRACE(acpi_gpe_can_wake); | ||
376 | |||
386 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | 377 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
387 | 378 | ||
388 | /* Ensure that we have a valid GPE number */ | 379 | /* Ensure that we have a valid GPE number */ |
@@ -393,46 +384,20 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type | |||
393 | goto unlock_and_exit; | 384 | goto unlock_and_exit; |
394 | } | 385 | } |
395 | 386 | ||
396 | /* Hardware-disable a runtime GPE on removal of the last reference */ | 387 | if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { |
397 | 388 | goto unlock_and_exit; | |
398 | if (gpe_type & ACPI_GPE_TYPE_RUNTIME) { | ||
399 | if (!gpe_event_info->runtime_count) { | ||
400 | status = AE_LIMIT; /* There are no references to remove */ | ||
401 | goto unlock_and_exit; | ||
402 | } | ||
403 | |||
404 | gpe_event_info->runtime_count--; | ||
405 | if (!gpe_event_info->runtime_count) { | ||
406 | status = acpi_ev_disable_gpe(gpe_event_info); | ||
407 | if (ACPI_FAILURE(status)) { | ||
408 | gpe_event_info->runtime_count++; | ||
409 | goto unlock_and_exit; | ||
410 | } | ||
411 | } | ||
412 | } | 389 | } |
413 | 390 | ||
414 | /* | 391 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; |
415 | * Update masks for wake GPE on removal of the last reference. | 392 | if (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) { |
416 | * No need to hardware-disable wake GPEs here, they are not currently | 393 | (void)acpi_raw_disable_gpe(gpe_event_info); |
417 | * enabled. | ||
418 | */ | ||
419 | if (gpe_type & ACPI_GPE_TYPE_WAKE) { | ||
420 | if (!gpe_event_info->wakeup_count) { | ||
421 | status = AE_LIMIT; /* There are no references to remove */ | ||
422 | goto unlock_and_exit; | ||
423 | } | ||
424 | |||
425 | gpe_event_info->wakeup_count--; | ||
426 | if (!gpe_event_info->wakeup_count) { | ||
427 | (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); | ||
428 | } | ||
429 | } | 394 | } |
430 | 395 | ||
431 | unlock_and_exit: | 396 | unlock_and_exit: |
432 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 397 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
433 | return_ACPI_STATUS(status); | 398 | return_ACPI_STATUS(status); |
434 | } | 399 | } |
435 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) | 400 | ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake) |
436 | 401 | ||
437 | /******************************************************************************* | 402 | /******************************************************************************* |
438 | * | 403 | * |
@@ -750,7 +715,7 @@ acpi_install_gpe_block(acpi_handle gpe_device, | |||
750 | 715 | ||
751 | obj_desc->device.gpe_block = gpe_block; | 716 | obj_desc->device.gpe_block = gpe_block; |
752 | 717 | ||
753 | /* Run the _PRW methods and enable the runtime GPEs in the new block */ | 718 | /* Enable the runtime GPEs in the new block */ |
754 | 719 | ||
755 | status = acpi_ev_initialize_gpe_block(node, gpe_block); | 720 | status = acpi_ev_initialize_gpe_block(node, gpe_block); |
756 | 721 | ||
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 008621c5ad85..18832205b631 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
@@ -120,7 +120,7 @@ acpi_ex_add_table(u32 table_index, | |||
120 | acpi_ns_exec_module_code_list(); | 120 | acpi_ns_exec_module_code_list(); |
121 | acpi_ex_enter_interpreter(); | 121 | acpi_ex_enter_interpreter(); |
122 | 122 | ||
123 | /* Update GPEs for any new _PRW or _Lxx/_Exx methods. Ignore errors */ | 123 | /* Update GPEs for any new _Lxx/_Exx methods. Ignore errors */ |
124 | 124 | ||
125 | status = acpi_tb_get_owner_id(table_index, &owner_id); | 125 | status = acpi_tb_get_owner_id(table_index, &owner_id); |
126 | if (ACPI_SUCCESS(status)) { | 126 | if (ACPI_SUCCESS(status)) { |
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index d39d438ba1e3..f067bbb0d961 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c | |||
@@ -742,7 +742,7 @@ acpi_ex_dump_operands(union acpi_operand_object **operands, | |||
742 | } | 742 | } |
743 | 743 | ||
744 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 744 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
745 | "**** Start operand dump for opcode [%s], %d operands\n", | 745 | "**** Start operand dump for opcode [%s], %u operands\n", |
746 | opcode_name, num_operands)); | 746 | opcode_name, num_operands)); |
747 | 747 | ||
748 | if (num_operands == 0) { | 748 | if (num_operands == 0) { |
@@ -812,7 +812,7 @@ void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags) | |||
812 | acpi_ex_out_string("Type", acpi_ut_get_type_name(node->type)); | 812 | acpi_ex_out_string("Type", acpi_ut_get_type_name(node->type)); |
813 | acpi_ex_out_pointer("Attached Object", | 813 | acpi_ex_out_pointer("Attached Object", |
814 | acpi_ns_get_attached_object(node)); | 814 | acpi_ns_get_attached_object(node)); |
815 | acpi_ex_out_pointer("Parent", acpi_ns_get_parent_node(node)); | 815 | acpi_ex_out_pointer("Parent", node->parent); |
816 | 816 | ||
817 | acpi_ex_dump_object(ACPI_CAST_PTR(union acpi_operand_object, node), | 817 | acpi_ex_dump_object(ACPI_CAST_PTR(union acpi_operand_object, node), |
818 | acpi_ex_dump_node); | 818 | acpi_ex_dump_node); |
@@ -945,7 +945,7 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, | |||
945 | 945 | ||
946 | case ACPI_TYPE_PACKAGE: | 946 | case ACPI_TYPE_PACKAGE: |
947 | 947 | ||
948 | acpi_os_printf("[Package] Contains %d Elements:\n", | 948 | acpi_os_printf("[Package] Contains %u Elements:\n", |
949 | obj_desc->package.count); | 949 | obj_desc->package.count); |
950 | 950 | ||
951 | for (i = 0; i < obj_desc->package.count; i++) { | 951 | for (i = 0; i < obj_desc->package.count; i++) { |
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index a6dc26f0b3be..047217303a4b 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c | |||
@@ -534,13 +534,13 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, | |||
534 | if (ACPI_SUCCESS(status)) { | 534 | if (ACPI_SUCCESS(status)) { |
535 | if (read_write == ACPI_READ) { | 535 | if (read_write == ACPI_READ) { |
536 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 536 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
537 | "Value Read %8.8X%8.8X, Width %d\n", | 537 | "Value Read %8.8X%8.8X, Width %u\n", |
538 | ACPI_FORMAT_UINT64(*value), | 538 | ACPI_FORMAT_UINT64(*value), |
539 | obj_desc->common_field. | 539 | obj_desc->common_field. |
540 | access_byte_width)); | 540 | access_byte_width)); |
541 | } else { | 541 | } else { |
542 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 542 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
543 | "Value Written %8.8X%8.8X, Width %d\n", | 543 | "Value Written %8.8X%8.8X, Width %u\n", |
544 | ACPI_FORMAT_UINT64(*value), | 544 | ACPI_FORMAT_UINT64(*value), |
545 | obj_desc->common_field. | 545 | obj_desc->common_field. |
546 | access_byte_width)); | 546 | access_byte_width)); |
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 25059dace0ad..98a331d2249b 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c | |||
@@ -108,11 +108,11 @@ acpi_ex_generate_access(u32 field_bit_offset, | |||
108 | field_byte_length = field_byte_end_offset - field_byte_offset; | 108 | field_byte_length = field_byte_end_offset - field_byte_offset; |
109 | 109 | ||
110 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 110 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
111 | "Bit length %d, Bit offset %d\n", | 111 | "Bit length %u, Bit offset %u\n", |
112 | field_bit_length, field_bit_offset)); | 112 | field_bit_length, field_bit_offset)); |
113 | 113 | ||
114 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 114 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
115 | "Byte Length %d, Byte Offset %d, End Offset %d\n", | 115 | "Byte Length %u, Byte Offset %u, End Offset %u\n", |
116 | field_byte_length, field_byte_offset, | 116 | field_byte_length, field_byte_offset, |
117 | field_byte_end_offset)); | 117 | field_byte_end_offset)); |
118 | 118 | ||
@@ -147,11 +147,11 @@ acpi_ex_generate_access(u32 field_bit_offset, | |||
147 | accesses = field_end_offset - field_start_offset; | 147 | accesses = field_end_offset - field_start_offset; |
148 | 148 | ||
149 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 149 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
150 | "AccessWidth %d end is within region\n", | 150 | "AccessWidth %u end is within region\n", |
151 | access_byte_width)); | 151 | access_byte_width)); |
152 | 152 | ||
153 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 153 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
154 | "Field Start %d, Field End %d -- requires %d accesses\n", | 154 | "Field Start %u, Field End %u -- requires %u accesses\n", |
155 | field_start_offset, field_end_offset, | 155 | field_start_offset, field_end_offset, |
156 | accesses)); | 156 | accesses)); |
157 | 157 | ||
@@ -159,7 +159,7 @@ acpi_ex_generate_access(u32 field_bit_offset, | |||
159 | 159 | ||
160 | if (accesses <= 1) { | 160 | if (accesses <= 1) { |
161 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 161 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
162 | "Entire field can be accessed with one operation of size %d\n", | 162 | "Entire field can be accessed with one operation of size %u\n", |
163 | access_byte_width)); | 163 | access_byte_width)); |
164 | return_VALUE(access_byte_width); | 164 | return_VALUE(access_byte_width); |
165 | } | 165 | } |
@@ -174,7 +174,7 @@ acpi_ex_generate_access(u32 field_bit_offset, | |||
174 | } | 174 | } |
175 | } else { | 175 | } else { |
176 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 176 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
177 | "AccessWidth %d end is NOT within region\n", | 177 | "AccessWidth %u end is NOT within region\n", |
178 | access_byte_width)); | 178 | access_byte_width)); |
179 | if (access_byte_width == 1) { | 179 | if (access_byte_width == 1) { |
180 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 180 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
@@ -190,7 +190,7 @@ acpi_ex_generate_access(u32 field_bit_offset, | |||
190 | * previous access | 190 | * previous access |
191 | */ | 191 | */ |
192 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 192 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
193 | "Backing off to previous optimal access width of %d\n", | 193 | "Backing off to previous optimal access width of %u\n", |
194 | minimum_access_width)); | 194 | minimum_access_width)); |
195 | return_VALUE(minimum_access_width); | 195 | return_VALUE(minimum_access_width); |
196 | } | 196 | } |
@@ -385,15 +385,6 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc, | |||
385 | (field_bit_position - | 385 | (field_bit_position - |
386 | ACPI_MUL_8(obj_desc->common_field.base_byte_offset)); | 386 | ACPI_MUL_8(obj_desc->common_field.base_byte_offset)); |
387 | 387 | ||
388 | /* | ||
389 | * Does the entire field fit within a single field access element? (datum) | ||
390 | * (i.e., without crossing a datum boundary) | ||
391 | */ | ||
392 | if ((obj_desc->common_field.start_field_bit_offset + | ||
393 | field_bit_length) <= (u16) access_bit_width) { | ||
394 | obj_desc->common.flags |= AOPOBJ_SINGLE_DATUM; | ||
395 | } | ||
396 | |||
397 | return_ACPI_STATUS(AE_OK); | 388 | return_ACPI_STATUS(AE_OK); |
398 | } | 389 | } |
399 | 390 | ||
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 531000fc77d2..8819d2ac5aee 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c | |||
@@ -194,7 +194,7 @@ acpi_ex_system_memory_space_handler(u32 function, | |||
194 | ((u64) address - (u64) mem_info->mapped_physical_address); | 194 | ((u64) address - (u64) mem_info->mapped_physical_address); |
195 | 195 | ||
196 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 196 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
197 | "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n", | 197 | "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n", |
198 | bit_width, function, | 198 | bit_width, function, |
199 | ACPI_FORMAT_NATIVE_UINT(address))); | 199 | ACPI_FORMAT_NATIVE_UINT(address))); |
200 | 200 | ||
@@ -297,7 +297,7 @@ acpi_ex_system_io_space_handler(u32 function, | |||
297 | ACPI_FUNCTION_TRACE(ex_system_io_space_handler); | 297 | ACPI_FUNCTION_TRACE(ex_system_io_space_handler); |
298 | 298 | ||
299 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 299 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
300 | "System-IO (width %d) R/W %d Address=%8.8X%8.8X\n", | 300 | "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n", |
301 | bit_width, function, | 301 | bit_width, function, |
302 | ACPI_FORMAT_NATIVE_UINT(address))); | 302 | ACPI_FORMAT_NATIVE_UINT(address))); |
303 | 303 | ||
@@ -373,7 +373,7 @@ acpi_ex_pci_config_space_handler(u32 function, | |||
373 | pci_register = (u16) (u32) address; | 373 | pci_register = (u16) (u32) address; |
374 | 374 | ||
375 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 375 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
376 | "Pci-Config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n", | 376 | "Pci-Config %u (%u) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n", |
377 | function, bit_width, pci_id->segment, pci_id->bus, | 377 | function, bit_width, pci_id->segment, pci_id->bus, |
378 | pci_id->device, pci_id->function, pci_register)); | 378 | pci_id->device, pci_id->function, pci_register)); |
379 | 379 | ||
diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index 6d32e09327f1..675aaa91a770 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c | |||
@@ -201,6 +201,14 @@ acpi_status acpi_ex_system_do_sleep(u64 how_long) | |||
201 | 201 | ||
202 | acpi_ex_relinquish_interpreter(); | 202 | acpi_ex_relinquish_interpreter(); |
203 | 203 | ||
204 | /* | ||
205 | * For compatibility with other ACPI implementations and to prevent | ||
206 | * accidental deep sleeps, limit the sleep time to something reasonable. | ||
207 | */ | ||
208 | if (how_long > ACPI_MAX_SLEEP) { | ||
209 | how_long = ACPI_MAX_SLEEP; | ||
210 | } | ||
211 | |||
204 | acpi_os_sleep(how_long); | 212 | acpi_os_sleep(how_long); |
205 | 213 | ||
206 | /* And now we must get the interpreter again */ | 214 | /* And now we must get the interpreter again */ |
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index bd72319a38f0..14750db2a1b8 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c | |||
@@ -57,21 +57,47 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
57 | 57 | ||
58 | /****************************************************************************** | 58 | /****************************************************************************** |
59 | * | 59 | * |
60 | * FUNCTION: acpi_hw_low_disable_gpe | 60 | * FUNCTION: acpi_hw_get_gpe_register_bit |
61 | * | ||
62 | * PARAMETERS: gpe_event_info - Info block for the GPE | ||
63 | * gpe_register_info - Info block for the GPE register | ||
64 | * | ||
65 | * RETURN: Status | ||
66 | * | ||
67 | * DESCRIPTION: Compute GPE enable mask with one bit corresponding to the given | ||
68 | * GPE set. | ||
69 | * | ||
70 | ******************************************************************************/ | ||
71 | |||
72 | u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, | ||
73 | struct acpi_gpe_register_info *gpe_register_info) | ||
74 | { | ||
75 | return (u32)1 << (gpe_event_info->gpe_number - | ||
76 | gpe_register_info->base_gpe_number); | ||
77 | } | ||
78 | |||
79 | /****************************************************************************** | ||
80 | * | ||
81 | * FUNCTION: acpi_hw_low_set_gpe | ||
61 | * | 82 | * |
62 | * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled | 83 | * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled |
84 | * action - Enable or disable | ||
63 | * | 85 | * |
64 | * RETURN: Status | 86 | * RETURN: Status |
65 | * | 87 | * |
66 | * DESCRIPTION: Disable a single GPE in the enable register. | 88 | * DESCRIPTION: Enable or disable a single GPE in its enable register. |
67 | * | 89 | * |
68 | ******************************************************************************/ | 90 | ******************************************************************************/ |
69 | 91 | ||
70 | acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | 92 | acpi_status |
93 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action) | ||
71 | { | 94 | { |
72 | struct acpi_gpe_register_info *gpe_register_info; | 95 | struct acpi_gpe_register_info *gpe_register_info; |
73 | acpi_status status; | 96 | acpi_status status; |
74 | u32 enable_mask; | 97 | u32 enable_mask; |
98 | u32 register_bit; | ||
99 | |||
100 | ACPI_FUNCTION_ENTRY(); | ||
75 | 101 | ||
76 | /* Get the info block for the entire GPE register */ | 102 | /* Get the info block for the entire GPE register */ |
77 | 103 | ||
@@ -87,11 +113,27 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
87 | return (status); | 113 | return (status); |
88 | } | 114 | } |
89 | 115 | ||
90 | /* Clear just the bit that corresponds to this GPE */ | 116 | /* Set ot clear just the bit that corresponds to this GPE */ |
117 | |||
118 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, | ||
119 | gpe_register_info); | ||
120 | switch (action) { | ||
121 | case ACPI_GPE_COND_ENABLE: | ||
122 | if (!(register_bit & gpe_register_info->enable_for_run)) | ||
123 | return (AE_BAD_PARAMETER); | ||
124 | |||
125 | case ACPI_GPE_ENABLE: | ||
126 | ACPI_SET_BIT(enable_mask, register_bit); | ||
127 | break; | ||
128 | |||
129 | case ACPI_GPE_DISABLE: | ||
130 | ACPI_CLEAR_BIT(enable_mask, register_bit); | ||
131 | break; | ||
91 | 132 | ||
92 | ACPI_CLEAR_BIT(enable_mask, ((u32)1 << | 133 | default: |
93 | (gpe_event_info->gpe_number - | 134 | ACPI_ERROR((AE_INFO, "Invalid action\n")); |
94 | gpe_register_info->base_gpe_number))); | 135 | return (AE_BAD_PARAMETER); |
136 | } | ||
95 | 137 | ||
96 | /* Write the updated enable mask */ | 138 | /* Write the updated enable mask */ |
97 | 139 | ||
@@ -101,23 +143,21 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
101 | 143 | ||
102 | /****************************************************************************** | 144 | /****************************************************************************** |
103 | * | 145 | * |
104 | * FUNCTION: acpi_hw_write_gpe_enable_reg | 146 | * FUNCTION: acpi_hw_clear_gpe |
105 | * | 147 | * |
106 | * PARAMETERS: gpe_event_info - Info block for the GPE to be enabled | 148 | * PARAMETERS: gpe_event_info - Info block for the GPE to be cleared |
107 | * | 149 | * |
108 | * RETURN: Status | 150 | * RETURN: Status |
109 | * | 151 | * |
110 | * DESCRIPTION: Write a GPE enable register. Note: The bit for this GPE must | 152 | * DESCRIPTION: Clear the status bit for a single GPE. |
111 | * already be cleared or set in the parent register | ||
112 | * enable_for_run mask. | ||
113 | * | 153 | * |
114 | ******************************************************************************/ | 154 | ******************************************************************************/ |
115 | 155 | ||
116 | acpi_status | 156 | acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) |
117 | acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) | ||
118 | { | 157 | { |
119 | struct acpi_gpe_register_info *gpe_register_info; | 158 | struct acpi_gpe_register_info *gpe_register_info; |
120 | acpi_status status; | 159 | acpi_status status; |
160 | u32 register_bit; | ||
121 | 161 | ||
122 | ACPI_FUNCTION_ENTRY(); | 162 | ACPI_FUNCTION_ENTRY(); |
123 | 163 | ||
@@ -128,43 +168,15 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) | |||
128 | return (AE_NOT_EXIST); | 168 | return (AE_NOT_EXIST); |
129 | } | 169 | } |
130 | 170 | ||
131 | /* Write the entire GPE (runtime) enable register */ | 171 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, |
132 | 172 | gpe_register_info); | |
133 | status = acpi_hw_write(gpe_register_info->enable_for_run, | ||
134 | &gpe_register_info->enable_address); | ||
135 | |||
136 | return (status); | ||
137 | } | ||
138 | |||
139 | /****************************************************************************** | ||
140 | * | ||
141 | * FUNCTION: acpi_hw_clear_gpe | ||
142 | * | ||
143 | * PARAMETERS: gpe_event_info - Info block for the GPE to be cleared | ||
144 | * | ||
145 | * RETURN: Status | ||
146 | * | ||
147 | * DESCRIPTION: Clear the status bit for a single GPE. | ||
148 | * | ||
149 | ******************************************************************************/ | ||
150 | |||
151 | acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) | ||
152 | { | ||
153 | acpi_status status; | ||
154 | u8 register_bit; | ||
155 | |||
156 | ACPI_FUNCTION_ENTRY(); | ||
157 | |||
158 | register_bit = (u8)(1 << | ||
159 | (gpe_event_info->gpe_number - | ||
160 | gpe_event_info->register_info->base_gpe_number)); | ||
161 | 173 | ||
162 | /* | 174 | /* |
163 | * Write a one to the appropriate bit in the status register to | 175 | * Write a one to the appropriate bit in the status register to |
164 | * clear this GPE. | 176 | * clear this GPE. |
165 | */ | 177 | */ |
166 | status = acpi_hw_write(register_bit, | 178 | status = acpi_hw_write(register_bit, |
167 | &gpe_event_info->register_info->status_address); | 179 | &gpe_register_info->status_address); |
168 | 180 | ||
169 | return (status); | 181 | return (status); |
170 | } | 182 | } |
@@ -187,7 +199,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, | |||
187 | acpi_event_status * event_status) | 199 | acpi_event_status * event_status) |
188 | { | 200 | { |
189 | u32 in_byte; | 201 | u32 in_byte; |
190 | u8 register_bit; | 202 | u32 register_bit; |
191 | struct acpi_gpe_register_info *gpe_register_info; | 203 | struct acpi_gpe_register_info *gpe_register_info; |
192 | acpi_status status; | 204 | acpi_status status; |
193 | acpi_event_status local_event_status = 0; | 205 | acpi_event_status local_event_status = 0; |
@@ -204,9 +216,8 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, | |||
204 | 216 | ||
205 | /* Get the register bitmask for this GPE */ | 217 | /* Get the register bitmask for this GPE */ |
206 | 218 | ||
207 | register_bit = (u8)(1 << | 219 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, |
208 | (gpe_event_info->gpe_number - | 220 | gpe_register_info); |
209 | gpe_event_info->register_info->base_gpe_number)); | ||
210 | 221 | ||
211 | /* GPE currently enabled? (enabled for runtime?) */ | 222 | /* GPE currently enabled? (enabled for runtime?) */ |
212 | 223 | ||
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 36eb803dd9d0..3796811276ac 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c | |||
@@ -307,7 +307,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
307 | return_ACPI_STATUS(status); | 307 | return_ACPI_STATUS(status); |
308 | } | 308 | } |
309 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, | 309 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, |
310 | "Entering sleep state [S%d]\n", sleep_state)); | 310 | "Entering sleep state [S%u]\n", sleep_state)); |
311 | 311 | ||
312 | /* Clear the SLP_EN and SLP_TYP fields */ | 312 | /* Clear the SLP_EN and SLP_TYP fields */ |
313 | 313 | ||
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index c10d587c1641..e1d9c777b213 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c | |||
@@ -222,6 +222,12 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width) | |||
222 | u32 one_byte; | 222 | u32 one_byte; |
223 | u32 i; | 223 | u32 i; |
224 | 224 | ||
225 | /* Truncate address to 16 bits if requested */ | ||
226 | |||
227 | if (acpi_gbl_truncate_io_addresses) { | ||
228 | address &= ACPI_UINT16_MAX; | ||
229 | } | ||
230 | |||
225 | /* Validate the entire request and perform the I/O */ | 231 | /* Validate the entire request and perform the I/O */ |
226 | 232 | ||
227 | status = acpi_hw_validate_io_request(address, width); | 233 | status = acpi_hw_validate_io_request(address, width); |
@@ -279,6 +285,12 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width) | |||
279 | acpi_status status; | 285 | acpi_status status; |
280 | u32 i; | 286 | u32 i; |
281 | 287 | ||
288 | /* Truncate address to 16 bits if requested */ | ||
289 | |||
290 | if (acpi_gbl_truncate_io_addresses) { | ||
291 | address &= ACPI_UINT16_MAX; | ||
292 | } | ||
293 | |||
282 | /* Validate the entire request and perform the I/O */ | 294 | /* Validate the entire request and perform the I/O */ |
283 | 295 | ||
284 | status = acpi_hw_validate_io_request(address, width); | 296 | status = acpi_hw_validate_io_request(address, width); |
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index 3a2814676ac3..0cd925be5fc1 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c | |||
@@ -338,8 +338,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
338 | */ | 338 | */ |
339 | while (!acpi_ns_opens_scope(prefix_node->type) && | 339 | while (!acpi_ns_opens_scope(prefix_node->type) && |
340 | prefix_node->type != ACPI_TYPE_ANY) { | 340 | prefix_node->type != ACPI_TYPE_ANY) { |
341 | prefix_node = | 341 | prefix_node = prefix_node->parent; |
342 | acpi_ns_get_parent_node(prefix_node); | ||
343 | } | 342 | } |
344 | } | 343 | } |
345 | } | 344 | } |
@@ -419,7 +418,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
419 | /* Backup to the parent node */ | 418 | /* Backup to the parent node */ |
420 | 419 | ||
421 | num_carats++; | 420 | num_carats++; |
422 | this_node = acpi_ns_get_parent_node(this_node); | 421 | this_node = this_node->parent; |
423 | if (!this_node) { | 422 | if (!this_node) { |
424 | 423 | ||
425 | /* Current scope has no parent scope */ | 424 | /* Current scope has no parent scope */ |
@@ -433,7 +432,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
433 | 432 | ||
434 | if (search_parent_flag == ACPI_NS_NO_UPSEARCH) { | 433 | if (search_parent_flag == ACPI_NS_NO_UPSEARCH) { |
435 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | 434 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, |
436 | "Search scope is [%4.4s], path has %d carat(s)\n", | 435 | "Search scope is [%4.4s], path has %u carat(s)\n", |
437 | acpi_ut_get_node_name | 436 | acpi_ut_get_node_name |
438 | (this_node), num_carats)); | 437 | (this_node), num_carats)); |
439 | } | 438 | } |
@@ -495,7 +494,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
495 | path++; | 494 | path++; |
496 | 495 | ||
497 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | 496 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, |
498 | "Multi Pathname (%d Segments, Flags=%X)\n", | 497 | "Multi Pathname (%u Segments, Flags=%X)\n", |
499 | num_segments, flags)); | 498 | num_segments, flags)); |
500 | break; | 499 | break; |
501 | 500 | ||
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index 982269c1fa48..1e5ff803d9ad 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c | |||
@@ -159,7 +159,7 @@ void acpi_ns_remove_node(struct acpi_namespace_node *node) | |||
159 | 159 | ||
160 | ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node); | 160 | ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node); |
161 | 161 | ||
162 | parent_node = acpi_ns_get_parent_node(node); | 162 | parent_node = node->parent; |
163 | 163 | ||
164 | prev_node = NULL; | 164 | prev_node = NULL; |
165 | next_node = parent_node->child; | 165 | next_node = parent_node->child; |
@@ -168,29 +168,20 @@ void acpi_ns_remove_node(struct acpi_namespace_node *node) | |||
168 | 168 | ||
169 | while (next_node != node) { | 169 | while (next_node != node) { |
170 | prev_node = next_node; | 170 | prev_node = next_node; |
171 | next_node = prev_node->peer; | 171 | next_node = next_node->peer; |
172 | } | 172 | } |
173 | 173 | ||
174 | if (prev_node) { | 174 | if (prev_node) { |
175 | 175 | ||
176 | /* Node is not first child, unlink it */ | 176 | /* Node is not first child, unlink it */ |
177 | 177 | ||
178 | prev_node->peer = next_node->peer; | 178 | prev_node->peer = node->peer; |
179 | if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { | ||
180 | prev_node->flags |= ANOBJ_END_OF_PEER_LIST; | ||
181 | } | ||
182 | } else { | 179 | } else { |
183 | /* Node is first child (has no previous peer) */ | 180 | /* |
184 | 181 | * Node is first child (has no previous peer). | |
185 | if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { | 182 | * Link peer list to parent |
186 | 183 | */ | |
187 | /* No peers at all */ | 184 | parent_node->child = node->peer; |
188 | |||
189 | parent_node->child = NULL; | ||
190 | } else { /* Link peer list to parent */ | ||
191 | |||
192 | parent_node->child = next_node->peer; | ||
193 | } | ||
194 | } | 185 | } |
195 | 186 | ||
196 | /* Delete the node and any attached objects */ | 187 | /* Delete the node and any attached objects */ |
@@ -228,33 +219,42 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp | |||
228 | 219 | ||
229 | ACPI_FUNCTION_TRACE(ns_install_node); | 220 | ACPI_FUNCTION_TRACE(ns_install_node); |
230 | 221 | ||
231 | /* | ||
232 | * Get the owner ID from the Walk state. The owner ID is used to track | ||
233 | * table deletion and deletion of objects created by methods. | ||
234 | */ | ||
235 | if (walk_state) { | 222 | if (walk_state) { |
223 | /* | ||
224 | * Get the owner ID from the Walk state. The owner ID is used to | ||
225 | * track table deletion and deletion of objects created by methods. | ||
226 | */ | ||
236 | owner_id = walk_state->owner_id; | 227 | owner_id = walk_state->owner_id; |
228 | |||
229 | if ((walk_state->method_desc) && | ||
230 | (parent_node != walk_state->method_node)) { | ||
231 | /* | ||
232 | * A method is creating a new node that is not a child of the | ||
233 | * method (it is non-local). Mark the executing method as having | ||
234 | * modified the namespace. This is used for cleanup when the | ||
235 | * method exits. | ||
236 | */ | ||
237 | walk_state->method_desc->method.flags |= | ||
238 | AOPOBJ_MODIFIED_NAMESPACE; | ||
239 | } | ||
237 | } | 240 | } |
238 | 241 | ||
239 | /* Link the new entry into the parent and existing children */ | 242 | /* Link the new entry into the parent and existing children */ |
240 | 243 | ||
244 | node->peer = NULL; | ||
245 | node->parent = parent_node; | ||
241 | child_node = parent_node->child; | 246 | child_node = parent_node->child; |
247 | |||
242 | if (!child_node) { | 248 | if (!child_node) { |
243 | parent_node->child = node; | 249 | parent_node->child = node; |
244 | node->flags |= ANOBJ_END_OF_PEER_LIST; | ||
245 | node->peer = parent_node; | ||
246 | } else { | 250 | } else { |
247 | while (!(child_node->flags & ANOBJ_END_OF_PEER_LIST)) { | 251 | /* Add node to the end of the peer list */ |
252 | |||
253 | while (child_node->peer) { | ||
248 | child_node = child_node->peer; | 254 | child_node = child_node->peer; |
249 | } | 255 | } |
250 | 256 | ||
251 | child_node->peer = node; | 257 | child_node->peer = node; |
252 | |||
253 | /* Clear end-of-list flag */ | ||
254 | |||
255 | child_node->flags &= ~ANOBJ_END_OF_PEER_LIST; | ||
256 | node->flags |= ANOBJ_END_OF_PEER_LIST; | ||
257 | node->peer = parent_node; | ||
258 | } | 258 | } |
259 | 259 | ||
260 | /* Init the new entry */ | 260 | /* Init the new entry */ |
@@ -288,9 +288,8 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp | |||
288 | 288 | ||
289 | void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) | 289 | void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) |
290 | { | 290 | { |
291 | struct acpi_namespace_node *child_node; | ||
292 | struct acpi_namespace_node *next_node; | 291 | struct acpi_namespace_node *next_node; |
293 | u8 flags; | 292 | struct acpi_namespace_node *node_to_delete; |
294 | 293 | ||
295 | ACPI_FUNCTION_TRACE_PTR(ns_delete_children, parent_node); | 294 | ACPI_FUNCTION_TRACE_PTR(ns_delete_children, parent_node); |
296 | 295 | ||
@@ -298,37 +297,26 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) | |||
298 | return_VOID; | 297 | return_VOID; |
299 | } | 298 | } |
300 | 299 | ||
301 | /* If no children, all done! */ | ||
302 | |||
303 | child_node = parent_node->child; | ||
304 | if (!child_node) { | ||
305 | return_VOID; | ||
306 | } | ||
307 | |||
308 | /* Deallocate all children at this level */ | 300 | /* Deallocate all children at this level */ |
309 | 301 | ||
310 | do { | 302 | next_node = parent_node->child; |
311 | 303 | while (next_node) { | |
312 | /* Get the things we need */ | ||
313 | |||
314 | next_node = child_node->peer; | ||
315 | flags = child_node->flags; | ||
316 | 304 | ||
317 | /* Grandchildren should have all been deleted already */ | 305 | /* Grandchildren should have all been deleted already */ |
318 | 306 | ||
319 | if (child_node->child) { | 307 | if (next_node->child) { |
320 | ACPI_ERROR((AE_INFO, "Found a grandchild! P=%p C=%p", | 308 | ACPI_ERROR((AE_INFO, "Found a grandchild! P=%p C=%p", |
321 | parent_node, child_node)); | 309 | parent_node, next_node)); |
322 | } | 310 | } |
323 | 311 | ||
324 | /* | 312 | /* |
325 | * Delete this child node and move on to the next child in the list. | 313 | * Delete this child node and move on to the next child in the list. |
326 | * No need to unlink the node since we are deleting the entire branch. | 314 | * No need to unlink the node since we are deleting the entire branch. |
327 | */ | 315 | */ |
328 | acpi_ns_delete_node(child_node); | 316 | node_to_delete = next_node; |
329 | child_node = next_node; | 317 | next_node = next_node->peer; |
330 | 318 | acpi_ns_delete_node(node_to_delete); | |
331 | } while (!(flags & ANOBJ_END_OF_PEER_LIST)); | 319 | }; |
332 | 320 | ||
333 | /* Clear the parent's child pointer */ | 321 | /* Clear the parent's child pointer */ |
334 | 322 | ||
@@ -405,7 +393,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) | |||
405 | 393 | ||
406 | /* Move up the tree to the grandparent */ | 394 | /* Move up the tree to the grandparent */ |
407 | 395 | ||
408 | parent_node = acpi_ns_get_parent_node(parent_node); | 396 | parent_node = parent_node->parent; |
409 | } | 397 | } |
410 | } | 398 | } |
411 | 399 | ||
@@ -510,7 +498,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) | |||
510 | 498 | ||
511 | /* Move up the tree to the grandparent */ | 499 | /* Move up the tree to the grandparent */ |
512 | 500 | ||
513 | parent_node = acpi_ns_get_parent_node(parent_node); | 501 | parent_node = parent_node->parent; |
514 | } | 502 | } |
515 | } | 503 | } |
516 | 504 | ||
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index 2110cc2360f0..a54dc39e304b 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c | |||
@@ -441,7 +441,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
441 | return (AE_OK); | 441 | return (AE_OK); |
442 | } | 442 | } |
443 | 443 | ||
444 | acpi_os_printf("(R%d)", obj_desc->common.reference_count); | 444 | acpi_os_printf("(R%u)", obj_desc->common.reference_count); |
445 | 445 | ||
446 | switch (type) { | 446 | switch (type) { |
447 | case ACPI_TYPE_METHOD: | 447 | case ACPI_TYPE_METHOD: |
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 9bd6f050f299..660a2728908d 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c | |||
@@ -103,8 +103,8 @@ acpi_status acpi_ns_initialize_objects(void) | |||
103 | } | 103 | } |
104 | 104 | ||
105 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | 105 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
106 | "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd " | 106 | "\nInitialized %u/%u Regions %u/%u Fields %u/%u " |
107 | "Buffers %hd/%hd Packages (%hd nodes)\n", | 107 | "Buffers %u/%u Packages (%u nodes)\n", |
108 | info.op_region_init, info.op_region_count, | 108 | info.op_region_init, info.op_region_count, |
109 | info.field_init, info.field_count, | 109 | info.field_init, info.field_count, |
110 | info.buffer_init, info.buffer_count, | 110 | info.buffer_init, info.buffer_count, |
@@ -112,9 +112,9 @@ acpi_status acpi_ns_initialize_objects(void) | |||
112 | info.object_count)); | 112 | info.object_count)); |
113 | 113 | ||
114 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 114 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
115 | "%hd Control Methods found\n", info.method_count)); | 115 | "%u Control Methods found\n", info.method_count)); |
116 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 116 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
117 | "%hd Op Regions found\n", info.op_region_count)); | 117 | "%u Op Regions found\n", info.op_region_count)); |
118 | 118 | ||
119 | return_ACPI_STATUS(AE_OK); | 119 | return_ACPI_STATUS(AE_OK); |
120 | } | 120 | } |
@@ -193,14 +193,23 @@ acpi_status acpi_ns_initialize_devices(void) | |||
193 | acpi_ns_init_one_device, NULL, &info, | 193 | acpi_ns_init_one_device, NULL, &info, |
194 | NULL); | 194 | NULL); |
195 | 195 | ||
196 | /* | ||
197 | * Any _OSI requests should be completed by now. If the BIOS has | ||
198 | * requested any Windows OSI strings, we will always truncate | ||
199 | * I/O addresses to 16 bits -- for Windows compatibility. | ||
200 | */ | ||
201 | if (acpi_gbl_osi_data >= ACPI_OSI_WIN_2000) { | ||
202 | acpi_gbl_truncate_io_addresses = TRUE; | ||
203 | } | ||
204 | |||
196 | ACPI_FREE(info.evaluate_info); | 205 | ACPI_FREE(info.evaluate_info); |
197 | if (ACPI_FAILURE(status)) { | 206 | if (ACPI_FAILURE(status)) { |
198 | goto error_exit; | 207 | goto error_exit; |
199 | } | 208 | } |
200 | 209 | ||
201 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | 210 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
202 | "\nExecuted %hd _INI methods requiring %hd _STA executions " | 211 | "\nExecuted %u _INI methods requiring %u _STA executions " |
203 | "(examined %hd objects)\n", | 212 | "(examined %u objects)\n", |
204 | info.num_INI, info.num_STA, info.device_count)); | 213 | info.num_INI, info.num_STA, info.device_count)); |
205 | 214 | ||
206 | return_ACPI_STATUS(status); | 215 | return_ACPI_STATUS(status); |
@@ -401,7 +410,7 @@ acpi_ns_find_ini_methods(acpi_handle obj_handle, | |||
401 | * The only _INI methods that we care about are those that are | 410 | * The only _INI methods that we care about are those that are |
402 | * present under Device, Processor, and Thermal objects. | 411 | * present under Device, Processor, and Thermal objects. |
403 | */ | 412 | */ |
404 | parent_node = acpi_ns_get_parent_node(node); | 413 | parent_node = node->parent; |
405 | switch (parent_node->type) { | 414 | switch (parent_node->type) { |
406 | case ACPI_TYPE_DEVICE: | 415 | case ACPI_TYPE_DEVICE: |
407 | case ACPI_TYPE_PROCESSOR: | 416 | case ACPI_TYPE_PROCESSOR: |
@@ -411,7 +420,7 @@ acpi_ns_find_ini_methods(acpi_handle obj_handle, | |||
411 | 420 | ||
412 | while (parent_node) { | 421 | while (parent_node) { |
413 | parent_node->flags |= ANOBJ_SUBTREE_HAS_INI; | 422 | parent_node->flags |= ANOBJ_SUBTREE_HAS_INI; |
414 | parent_node = acpi_ns_get_parent_node(parent_node); | 423 | parent_node = parent_node->parent; |
415 | } | 424 | } |
416 | break; | 425 | break; |
417 | 426 | ||
diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index 7dea0031605c..d3104af57e13 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c | |||
@@ -93,7 +93,7 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node, | |||
93 | /* Put the name into the buffer */ | 93 | /* Put the name into the buffer */ |
94 | 94 | ||
95 | ACPI_MOVE_32_TO_32((name_buffer + index), &parent_node->name); | 95 | ACPI_MOVE_32_TO_32((name_buffer + index), &parent_node->name); |
96 | parent_node = acpi_ns_get_parent_node(parent_node); | 96 | parent_node = parent_node->parent; |
97 | 97 | ||
98 | /* Prefix name with the path separator */ | 98 | /* Prefix name with the path separator */ |
99 | 99 | ||
@@ -198,7 +198,7 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node) | |||
198 | return 0; | 198 | return 0; |
199 | } | 199 | } |
200 | size += ACPI_PATH_SEGMENT_LENGTH; | 200 | size += ACPI_PATH_SEGMENT_LENGTH; |
201 | next_node = acpi_ns_get_parent_node(next_node); | 201 | next_node = next_node->parent; |
202 | } | 202 | } |
203 | 203 | ||
204 | if (!size) { | 204 | if (!size) { |
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index 27cda52c76bc..5808c89e9fac 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c | |||
@@ -136,8 +136,8 @@ acpi_ns_one_complete_parse(u32 pass_number, | |||
136 | 136 | ||
137 | /* Parse the AML */ | 137 | /* Parse the AML */ |
138 | 138 | ||
139 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %d parse\n", | 139 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %u parse\n", |
140 | (unsigned)pass_number)); | 140 | pass_number)); |
141 | status = acpi_ps_parse_aml(walk_state); | 141 | status = acpi_ps_parse_aml(walk_state); |
142 | 142 | ||
143 | cleanup: | 143 | cleanup: |
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index d4be37751be4..d1c136692667 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c | |||
@@ -556,7 +556,7 @@ acpi_ns_repair_null_element(struct acpi_predefined_data *data, | |||
556 | 556 | ||
557 | /* Need an Integer - create a zero-value integer */ | 557 | /* Need an Integer - create a zero-value integer */ |
558 | 558 | ||
559 | new_object = acpi_ut_create_integer_object(0); | 559 | new_object = acpi_ut_create_integer_object((u64)0); |
560 | } else if (expected_btypes & ACPI_RTYPE_STRING) { | 560 | } else if (expected_btypes & ACPI_RTYPE_STRING) { |
561 | 561 | ||
562 | /* Need a String - create a NULL string */ | 562 | /* Need a String - create a NULL string */ |
diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 61bd0f6755d2..4009498fbabd 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c | |||
@@ -112,6 +112,13 @@ acpi_ns_sort_list(union acpi_operand_object **elements, | |||
112 | * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs | 112 | * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs |
113 | * _PSS: Sort the list descending by Power | 113 | * _PSS: Sort the list descending by Power |
114 | * _TSS: Sort the list descending by Power | 114 | * _TSS: Sort the list descending by Power |
115 | * | ||
116 | * Names that must be packages, but cannot be sorted: | ||
117 | * | ||
118 | * _BCL: Values are tied to the Package index where they appear, and cannot | ||
119 | * be moved or sorted. These index values are used for _BQC and _BCM. | ||
120 | * However, we can fix the case where a buffer is returned, by converting | ||
121 | * it to a Package of integers. | ||
115 | */ | 122 | */ |
116 | static const struct acpi_repair_info acpi_ns_repairable_names[] = { | 123 | static const struct acpi_repair_info acpi_ns_repairable_names[] = { |
117 | {"_ALR", acpi_ns_repair_ALR}, | 124 | {"_ALR", acpi_ns_repair_ALR}, |
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index a8e42b5e9463..41102a84272f 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c | |||
@@ -152,17 +152,6 @@ acpi_ns_search_one_scope(u32 target_name, | |||
152 | return_ACPI_STATUS(AE_OK); | 152 | return_ACPI_STATUS(AE_OK); |
153 | } | 153 | } |
154 | 154 | ||
155 | /* | ||
156 | * The last entry in the list points back to the parent, | ||
157 | * so a flag is used to indicate the end-of-list | ||
158 | */ | ||
159 | if (node->flags & ANOBJ_END_OF_PEER_LIST) { | ||
160 | |||
161 | /* Searched entire list, we are done */ | ||
162 | |||
163 | break; | ||
164 | } | ||
165 | |||
166 | /* Didn't match name, move on to the next peer object */ | 155 | /* Didn't match name, move on to the next peer object */ |
167 | 156 | ||
168 | node = node->peer; | 157 | node = node->peer; |
@@ -217,7 +206,7 @@ acpi_ns_search_parent_tree(u32 target_name, | |||
217 | 206 | ||
218 | ACPI_FUNCTION_TRACE(ns_search_parent_tree); | 207 | ACPI_FUNCTION_TRACE(ns_search_parent_tree); |
219 | 208 | ||
220 | parent_node = acpi_ns_get_parent_node(node); | 209 | parent_node = node->parent; |
221 | 210 | ||
222 | /* | 211 | /* |
223 | * If there is no parent (i.e., we are at the root) or type is "local", | 212 | * If there is no parent (i.e., we are at the root) or type is "local", |
@@ -261,7 +250,7 @@ acpi_ns_search_parent_tree(u32 target_name, | |||
261 | 250 | ||
262 | /* Not found here, go up another level (until we reach the root) */ | 251 | /* Not found here, go up another level (until we reach the root) */ |
263 | 252 | ||
264 | parent_node = acpi_ns_get_parent_node(parent_node); | 253 | parent_node = parent_node->parent; |
265 | } | 254 | } |
266 | 255 | ||
267 | /* Not found in parent tree */ | 256 | /* Not found in parent tree */ |
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index bab559712da1..e1add3491b04 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c | |||
@@ -847,116 +847,3 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node, | |||
847 | ACPI_FREE(internal_path); | 847 | ACPI_FREE(internal_path); |
848 | return_ACPI_STATUS(status); | 848 | return_ACPI_STATUS(status); |
849 | } | 849 | } |
850 | |||
851 | /******************************************************************************* | ||
852 | * | ||
853 | * FUNCTION: acpi_ns_get_parent_node | ||
854 | * | ||
855 | * PARAMETERS: Node - Current table entry | ||
856 | * | ||
857 | * RETURN: Parent entry of the given entry | ||
858 | * | ||
859 | * DESCRIPTION: Obtain the parent entry for a given entry in the namespace. | ||
860 | * | ||
861 | ******************************************************************************/ | ||
862 | |||
863 | struct acpi_namespace_node *acpi_ns_get_parent_node(struct acpi_namespace_node | ||
864 | *node) | ||
865 | { | ||
866 | ACPI_FUNCTION_ENTRY(); | ||
867 | |||
868 | if (!node) { | ||
869 | return (NULL); | ||
870 | } | ||
871 | |||
872 | /* | ||
873 | * Walk to the end of this peer list. The last entry is marked with a flag | ||
874 | * and the peer pointer is really a pointer back to the parent. This saves | ||
875 | * putting a parent back pointer in each and every named object! | ||
876 | */ | ||
877 | while (!(node->flags & ANOBJ_END_OF_PEER_LIST)) { | ||
878 | node = node->peer; | ||
879 | } | ||
880 | |||
881 | return (node->peer); | ||
882 | } | ||
883 | |||
884 | /******************************************************************************* | ||
885 | * | ||
886 | * FUNCTION: acpi_ns_get_next_valid_node | ||
887 | * | ||
888 | * PARAMETERS: Node - Current table entry | ||
889 | * | ||
890 | * RETURN: Next valid Node in the linked node list. NULL if no more valid | ||
891 | * nodes. | ||
892 | * | ||
893 | * DESCRIPTION: Find the next valid node within a name table. | ||
894 | * Useful for implementing NULL-end-of-list loops. | ||
895 | * | ||
896 | ******************************************************************************/ | ||
897 | |||
898 | struct acpi_namespace_node *acpi_ns_get_next_valid_node(struct | ||
899 | acpi_namespace_node | ||
900 | *node) | ||
901 | { | ||
902 | |||
903 | /* If we are at the end of this peer list, return NULL */ | ||
904 | |||
905 | if (node->flags & ANOBJ_END_OF_PEER_LIST) { | ||
906 | return NULL; | ||
907 | } | ||
908 | |||
909 | /* Otherwise just return the next peer */ | ||
910 | |||
911 | return (node->peer); | ||
912 | } | ||
913 | |||
914 | #ifdef ACPI_OBSOLETE_FUNCTIONS | ||
915 | /******************************************************************************* | ||
916 | * | ||
917 | * FUNCTION: acpi_ns_find_parent_name | ||
918 | * | ||
919 | * PARAMETERS: *child_node - Named Obj whose name is to be found | ||
920 | * | ||
921 | * RETURN: The ACPI name | ||
922 | * | ||
923 | * DESCRIPTION: Search for the given obj in its parent scope and return the | ||
924 | * name segment, or "????" if the parent name can't be found | ||
925 | * (which "should not happen"). | ||
926 | * | ||
927 | ******************************************************************************/ | ||
928 | |||
929 | acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node * child_node) | ||
930 | { | ||
931 | struct acpi_namespace_node *parent_node; | ||
932 | |||
933 | ACPI_FUNCTION_TRACE(ns_find_parent_name); | ||
934 | |||
935 | if (child_node) { | ||
936 | |||
937 | /* Valid entry. Get the parent Node */ | ||
938 | |||
939 | parent_node = acpi_ns_get_parent_node(child_node); | ||
940 | if (parent_node) { | ||
941 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
942 | "Parent of %p [%4.4s] is %p [%4.4s]\n", | ||
943 | child_node, | ||
944 | acpi_ut_get_node_name(child_node), | ||
945 | parent_node, | ||
946 | acpi_ut_get_node_name(parent_node))); | ||
947 | |||
948 | if (parent_node->name.integer) { | ||
949 | return_VALUE((acpi_name) parent_node->name. | ||
950 | integer); | ||
951 | } | ||
952 | } | ||
953 | |||
954 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
955 | "Unable to find parent of %p (%4.4s)\n", | ||
956 | child_node, | ||
957 | acpi_ut_get_node_name(child_node))); | ||
958 | } | ||
959 | |||
960 | return_VALUE(ACPI_UNKNOWN_NAME); | ||
961 | } | ||
962 | #endif | ||
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index 00e79fb26029..2cd5be8fe10f 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c | |||
@@ -79,15 +79,6 @@ struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node | |||
79 | return parent_node->child; | 79 | return parent_node->child; |
80 | } | 80 | } |
81 | 81 | ||
82 | /* | ||
83 | * Get the next node. | ||
84 | * | ||
85 | * If we are at the end of this peer list, return NULL | ||
86 | */ | ||
87 | if (child_node->flags & ANOBJ_END_OF_PEER_LIST) { | ||
88 | return NULL; | ||
89 | } | ||
90 | |||
91 | /* Otherwise just return the next peer */ | 82 | /* Otherwise just return the next peer */ |
92 | 83 | ||
93 | return child_node->peer; | 84 | return child_node->peer; |
@@ -146,9 +137,9 @@ struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type, | |||
146 | return (next_node); | 137 | return (next_node); |
147 | } | 138 | } |
148 | 139 | ||
149 | /* Otherwise, move on to the next node */ | 140 | /* Otherwise, move on to the next peer node */ |
150 | 141 | ||
151 | next_node = acpi_ns_get_next_valid_node(next_node); | 142 | next_node = next_node->peer; |
152 | } | 143 | } |
153 | 144 | ||
154 | /* Not found */ | 145 | /* Not found */ |
@@ -355,7 +346,7 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
355 | */ | 346 | */ |
356 | level--; | 347 | level--; |
357 | child_node = parent_node; | 348 | child_node = parent_node; |
358 | parent_node = acpi_ns_get_parent_node(parent_node); | 349 | parent_node = parent_node->parent; |
359 | 350 | ||
360 | node_previously_visited = TRUE; | 351 | node_previously_visited = TRUE; |
361 | } | 352 | } |
diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index eafef24ea448..a1f04e9b8030 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c | |||
@@ -190,7 +190,7 @@ acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) | |||
190 | 190 | ||
191 | /* Get the parent entry */ | 191 | /* Get the parent entry */ |
192 | 192 | ||
193 | parent_node = acpi_ns_get_parent_node(node); | 193 | parent_node = node->parent; |
194 | *ret_handle = ACPI_CAST_PTR(acpi_handle, parent_node); | 194 | *ret_handle = ACPI_CAST_PTR(acpi_handle, parent_node); |
195 | 195 | ||
196 | /* Return exception if parent is null */ | 196 | /* Return exception if parent is null */ |
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 66116750a0f9..0558747579ef 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -813,10 +813,10 @@ acpi_status acpi_ut_init_globals(void) | |||
813 | acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; | 813 | acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; |
814 | acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; | 814 | acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; |
815 | acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE; | 815 | acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE; |
816 | acpi_gbl_root_node_struct.parent = NULL; | ||
816 | acpi_gbl_root_node_struct.child = NULL; | 817 | acpi_gbl_root_node_struct.child = NULL; |
817 | acpi_gbl_root_node_struct.peer = NULL; | 818 | acpi_gbl_root_node_struct.peer = NULL; |
818 | acpi_gbl_root_node_struct.object = NULL; | 819 | acpi_gbl_root_node_struct.object = NULL; |
819 | acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST; | ||
820 | 820 | ||
821 | #ifdef ACPI_DEBUG_OUTPUT | 821 | #ifdef ACPI_DEBUG_OUTPUT |
822 | acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX); | 822 | acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX); |
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 058b3df48271..f5cca3a1300c 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c | |||
@@ -279,13 +279,10 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) | |||
279 | 279 | ||
280 | acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) | 280 | acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) |
281 | { | 281 | { |
282 | acpi_thread_id this_thread_id; | ||
283 | |||
284 | ACPI_FUNCTION_NAME(ut_release_mutex); | 282 | ACPI_FUNCTION_NAME(ut_release_mutex); |
285 | 283 | ||
286 | this_thread_id = acpi_os_get_thread_id(); | ||
287 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", | 284 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", |
288 | ACPI_CAST_PTR(void, this_thread_id), | 285 | ACPI_CAST_PTR(void, acpi_os_get_thread_id()), |
289 | acpi_ut_get_mutex_name(mutex_id))); | 286 | acpi_ut_get_mutex_name(mutex_id))); |
290 | 287 | ||
291 | if (mutex_id > ACPI_MAX_MUTEX) { | 288 | if (mutex_id > ACPI_MAX_MUTEX) { |
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index db9d8ca57987..7f8cefcb2b32 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -293,12 +293,8 @@ acpi_status acpi_initialize_objects(u32 flags) | |||
293 | * Complete the GPE initialization for the GPE blocks defined in the FADT | 293 | * Complete the GPE initialization for the GPE blocks defined in the FADT |
294 | * (GPE block 0 and 1). | 294 | * (GPE block 0 and 1). |
295 | * | 295 | * |
296 | * Note1: This is where the _PRW methods are executed for the GPEs. These | 296 | * NOTE: Currently, there seems to be no need to run the _REG methods |
297 | * methods can only be executed after the SCI and Global Lock handlers are | 297 | * before enabling the GPEs. |
298 | * installed and initialized. | ||
299 | * | ||
300 | * Note2: Currently, there seems to be no need to run the _REG methods | ||
301 | * before execution of the _PRW methods and enabling of the GPEs. | ||
302 | */ | 298 | */ |
303 | if (!(flags & ACPI_NO_EVENT_INIT)) { | 299 | if (!(flags & ACPI_NO_EVENT_INIT)) { |
304 | status = acpi_ev_install_fadt_gpes(); | 300 | status = acpi_ev_install_fadt_gpes(); |
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index f8c668f27b5a..907e350f1c7d 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig | |||
@@ -28,3 +28,12 @@ config ACPI_APEI_EINJ | |||
28 | EINJ provides a hardware error injection mechanism, it is | 28 | EINJ provides a hardware error injection mechanism, it is |
29 | mainly used for debugging and testing the other parts of | 29 | mainly used for debugging and testing the other parts of |
30 | APEI and some other RAS features. | 30 | APEI and some other RAS features. |
31 | |||
32 | config ACPI_APEI_ERST_DEBUG | ||
33 | tristate "APEI Error Record Serialization Table (ERST) Debug Support" | ||
34 | depends on ACPI_APEI | ||
35 | help | ||
36 | ERST is a way provided by APEI to save and retrieve hardware | ||
37 | error infomation to and from a persistent store. Enable this | ||
38 | if you want to debugging and testing the ERST kernel support | ||
39 | and firmware implementation. | ||
diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile index b13b03a17789..d1d1bc0a4ee1 100644 --- a/drivers/acpi/apei/Makefile +++ b/drivers/acpi/apei/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | obj-$(CONFIG_ACPI_APEI) += apei.o | 1 | obj-$(CONFIG_ACPI_APEI) += apei.o |
2 | obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o | 2 | obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o |
3 | obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o | 3 | obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o |
4 | obj-$(CONFIG_ACPI_APEI_ERST_DEBUG) += erst-dbg.o | ||
4 | 5 | ||
5 | apei-y := apei-base.o hest.o cper.o erst.o | 6 | apei-y := apei-base.o hest.o cper.o erst.o |
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index db3946e9c66b..73fd0c7487c1 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/acpi.h> | 36 | #include <linux/acpi.h> |
37 | #include <linux/slab.h> | ||
37 | #include <linux/io.h> | 38 | #include <linux/io.h> |
38 | #include <linux/kref.h> | 39 | #include <linux/kref.h> |
39 | #include <linux/rculist.h> | 40 | #include <linux/rculist.h> |
@@ -481,14 +482,14 @@ err_unmap_ioport: | |||
481 | list_for_each_entry(res, &resources->ioport, list) { | 482 | list_for_each_entry(res, &resources->ioport, list) { |
482 | if (res == res_bak) | 483 | if (res == res_bak) |
483 | break; | 484 | break; |
484 | release_mem_region(res->start, res->end - res->start); | 485 | release_region(res->start, res->end - res->start); |
485 | } | 486 | } |
486 | res_bak = NULL; | 487 | res_bak = NULL; |
487 | err_unmap_iomem: | 488 | err_unmap_iomem: |
488 | list_for_each_entry(res, &resources->iomem, list) { | 489 | list_for_each_entry(res, &resources->iomem, list) { |
489 | if (res == res_bak) | 490 | if (res == res_bak) |
490 | break; | 491 | break; |
491 | release_region(res->start, res->end - res->start); | 492 | release_mem_region(res->start, res->end - res->start); |
492 | } | 493 | } |
493 | return -EINVAL; | 494 | return -EINVAL; |
494 | } | 495 | } |
diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c new file mode 100644 index 000000000000..5281ddda2777 --- /dev/null +++ b/drivers/acpi/apei/erst-dbg.c | |||
@@ -0,0 +1,207 @@ | |||
1 | /* | ||
2 | * APEI Error Record Serialization Table debug support | ||
3 | * | ||
4 | * ERST is a way provided by APEI to save and retrieve hardware error | ||
5 | * infomation to and from a persistent store. This file provide the | ||
6 | * debugging/testing support for ERST kernel support and firmware | ||
7 | * implementation. | ||
8 | * | ||
9 | * Copyright 2010 Intel Corp. | ||
10 | * Author: Huang Ying <ying.huang@intel.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License version | ||
14 | * 2 as published by the Free Software Foundation. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/uaccess.h> | ||
29 | #include <acpi/apei.h> | ||
30 | #include <linux/miscdevice.h> | ||
31 | |||
32 | #include "apei-internal.h" | ||
33 | |||
34 | #define ERST_DBG_PFX "ERST DBG: " | ||
35 | |||
36 | #define ERST_DBG_RECORD_LEN_MAX 4096 | ||
37 | |||
38 | static void *erst_dbg_buf; | ||
39 | static unsigned int erst_dbg_buf_len; | ||
40 | |||
41 | /* Prevent erst_dbg_read/write from being invoked concurrently */ | ||
42 | static DEFINE_MUTEX(erst_dbg_mutex); | ||
43 | |||
44 | static int erst_dbg_open(struct inode *inode, struct file *file) | ||
45 | { | ||
46 | if (erst_disable) | ||
47 | return -ENODEV; | ||
48 | |||
49 | return nonseekable_open(inode, file); | ||
50 | } | ||
51 | |||
52 | static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | ||
53 | { | ||
54 | int rc; | ||
55 | u64 record_id; | ||
56 | u32 record_count; | ||
57 | |||
58 | switch (cmd) { | ||
59 | case APEI_ERST_CLEAR_RECORD: | ||
60 | rc = copy_from_user(&record_id, (void __user *)arg, | ||
61 | sizeof(record_id)); | ||
62 | if (rc) | ||
63 | return -EFAULT; | ||
64 | return erst_clear(record_id); | ||
65 | case APEI_ERST_GET_RECORD_COUNT: | ||
66 | rc = erst_get_record_count(); | ||
67 | if (rc < 0) | ||
68 | return rc; | ||
69 | record_count = rc; | ||
70 | rc = put_user(record_count, (u32 __user *)arg); | ||
71 | if (rc) | ||
72 | return rc; | ||
73 | return 0; | ||
74 | default: | ||
75 | return -ENOTTY; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf, | ||
80 | size_t usize, loff_t *off) | ||
81 | { | ||
82 | int rc; | ||
83 | ssize_t len = 0; | ||
84 | u64 id; | ||
85 | |||
86 | if (*off != 0) | ||
87 | return -EINVAL; | ||
88 | |||
89 | if (mutex_lock_interruptible(&erst_dbg_mutex) != 0) | ||
90 | return -EINTR; | ||
91 | |||
92 | retry_next: | ||
93 | rc = erst_get_next_record_id(&id); | ||
94 | if (rc) | ||
95 | goto out; | ||
96 | /* no more record */ | ||
97 | if (id == APEI_ERST_INVALID_RECORD_ID) | ||
98 | goto out; | ||
99 | retry: | ||
100 | rc = len = erst_read(id, erst_dbg_buf, erst_dbg_buf_len); | ||
101 | /* The record may be cleared by others, try read next record */ | ||
102 | if (rc == -ENOENT) | ||
103 | goto retry_next; | ||
104 | if (rc < 0) | ||
105 | goto out; | ||
106 | if (len > ERST_DBG_RECORD_LEN_MAX) { | ||
107 | pr_warning(ERST_DBG_PFX | ||
108 | "Record (ID: 0x%llx) length is too long: %zd\n", | ||
109 | id, len); | ||
110 | rc = -EIO; | ||
111 | goto out; | ||
112 | } | ||
113 | if (len > erst_dbg_buf_len) { | ||
114 | kfree(erst_dbg_buf); | ||
115 | rc = -ENOMEM; | ||
116 | erst_dbg_buf = kmalloc(len, GFP_KERNEL); | ||
117 | if (!erst_dbg_buf) | ||
118 | goto out; | ||
119 | erst_dbg_buf_len = len; | ||
120 | goto retry; | ||
121 | } | ||
122 | |||
123 | rc = -EINVAL; | ||
124 | if (len > usize) | ||
125 | goto out; | ||
126 | |||
127 | rc = -EFAULT; | ||
128 | if (copy_to_user(ubuf, erst_dbg_buf, len)) | ||
129 | goto out; | ||
130 | rc = 0; | ||
131 | out: | ||
132 | mutex_unlock(&erst_dbg_mutex); | ||
133 | return rc ? rc : len; | ||
134 | } | ||
135 | |||
136 | static ssize_t erst_dbg_write(struct file *filp, const char __user *ubuf, | ||
137 | size_t usize, loff_t *off) | ||
138 | { | ||
139 | int rc; | ||
140 | struct cper_record_header *rcd; | ||
141 | |||
142 | if (!capable(CAP_SYS_ADMIN)) | ||
143 | return -EPERM; | ||
144 | |||
145 | if (usize > ERST_DBG_RECORD_LEN_MAX) { | ||
146 | pr_err(ERST_DBG_PFX "Too long record to be written\n"); | ||
147 | return -EINVAL; | ||
148 | } | ||
149 | |||
150 | if (mutex_lock_interruptible(&erst_dbg_mutex)) | ||
151 | return -EINTR; | ||
152 | if (usize > erst_dbg_buf_len) { | ||
153 | kfree(erst_dbg_buf); | ||
154 | rc = -ENOMEM; | ||
155 | erst_dbg_buf = kmalloc(usize, GFP_KERNEL); | ||
156 | if (!erst_dbg_buf) | ||
157 | goto out; | ||
158 | erst_dbg_buf_len = usize; | ||
159 | } | ||
160 | rc = copy_from_user(erst_dbg_buf, ubuf, usize); | ||
161 | if (rc) { | ||
162 | rc = -EFAULT; | ||
163 | goto out; | ||
164 | } | ||
165 | rcd = erst_dbg_buf; | ||
166 | rc = -EINVAL; | ||
167 | if (rcd->record_length != usize) | ||
168 | goto out; | ||
169 | |||
170 | rc = erst_write(erst_dbg_buf); | ||
171 | |||
172 | out: | ||
173 | mutex_unlock(&erst_dbg_mutex); | ||
174 | return rc < 0 ? rc : usize; | ||
175 | } | ||
176 | |||
177 | static const struct file_operations erst_dbg_ops = { | ||
178 | .owner = THIS_MODULE, | ||
179 | .open = erst_dbg_open, | ||
180 | .read = erst_dbg_read, | ||
181 | .write = erst_dbg_write, | ||
182 | .unlocked_ioctl = erst_dbg_ioctl, | ||
183 | }; | ||
184 | |||
185 | static struct miscdevice erst_dbg_dev = { | ||
186 | .minor = MISC_DYNAMIC_MINOR, | ||
187 | .name = "erst_dbg", | ||
188 | .fops = &erst_dbg_ops, | ||
189 | }; | ||
190 | |||
191 | static __init int erst_dbg_init(void) | ||
192 | { | ||
193 | return misc_register(&erst_dbg_dev); | ||
194 | } | ||
195 | |||
196 | static __exit void erst_dbg_exit(void) | ||
197 | { | ||
198 | misc_deregister(&erst_dbg_dev); | ||
199 | kfree(erst_dbg_buf); | ||
200 | } | ||
201 | |||
202 | module_init(erst_dbg_init); | ||
203 | module_exit(erst_dbg_exit); | ||
204 | |||
205 | MODULE_AUTHOR("Huang Ying"); | ||
206 | MODULE_DESCRIPTION("APEI Error Record Serialization Table debug support"); | ||
207 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 2ebc39115507..18645f4e83cd 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/uaccess.h> | 33 | #include <linux/uaccess.h> |
34 | #include <linux/cper.h> | 34 | #include <linux/cper.h> |
35 | #include <linux/nmi.h> | 35 | #include <linux/nmi.h> |
36 | #include <linux/hardirq.h> | ||
36 | #include <acpi/apei.h> | 37 | #include <acpi/apei.h> |
37 | 38 | ||
38 | #include "apei-internal.h" | 39 | #include "apei-internal.h" |
@@ -781,7 +782,7 @@ static int __init erst_init(void) | |||
781 | status = acpi_get_table(ACPI_SIG_ERST, 0, | 782 | status = acpi_get_table(ACPI_SIG_ERST, 0, |
782 | (struct acpi_table_header **)&erst_tab); | 783 | (struct acpi_table_header **)&erst_tab); |
783 | if (status == AE_NOT_FOUND) { | 784 | if (status == AE_NOT_FOUND) { |
784 | pr_err(ERST_PFX "Table is not found!\n"); | 785 | pr_info(ERST_PFX "Table is not found!\n"); |
785 | goto err; | 786 | goto err; |
786 | } else if (ACPI_FAILURE(status)) { | 787 | } else if (ACPI_FAILURE(status)) { |
787 | const char *msg = acpi_format_exception(status); | 788 | const char *msg = acpi_format_exception(status); |
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index fd0cc016a099..385a6059714a 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -41,6 +41,8 @@ | |||
41 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
42 | #include <linux/cper.h> | 42 | #include <linux/cper.h> |
43 | #include <linux/kdebug.h> | 43 | #include <linux/kdebug.h> |
44 | #include <linux/platform_device.h> | ||
45 | #include <linux/mutex.h> | ||
44 | #include <acpi/apei.h> | 46 | #include <acpi/apei.h> |
45 | #include <acpi/atomicio.h> | 47 | #include <acpi/atomicio.h> |
46 | #include <acpi/hed.h> | 48 | #include <acpi/hed.h> |
@@ -87,6 +89,7 @@ struct ghes { | |||
87 | * used for that. | 89 | * used for that. |
88 | */ | 90 | */ |
89 | static LIST_HEAD(ghes_sci); | 91 | static LIST_HEAD(ghes_sci); |
92 | static DEFINE_MUTEX(ghes_list_mutex); | ||
90 | 93 | ||
91 | static struct ghes *ghes_new(struct acpi_hest_generic *generic) | 94 | static struct ghes *ghes_new(struct acpi_hest_generic *generic) |
92 | { | 95 | { |
@@ -132,26 +135,26 @@ static void ghes_fini(struct ghes *ghes) | |||
132 | } | 135 | } |
133 | 136 | ||
134 | enum { | 137 | enum { |
135 | GHES_SER_NO = 0x0, | 138 | GHES_SEV_NO = 0x0, |
136 | GHES_SER_CORRECTED = 0x1, | 139 | GHES_SEV_CORRECTED = 0x1, |
137 | GHES_SER_RECOVERABLE = 0x2, | 140 | GHES_SEV_RECOVERABLE = 0x2, |
138 | GHES_SER_PANIC = 0x3, | 141 | GHES_SEV_PANIC = 0x3, |
139 | }; | 142 | }; |
140 | 143 | ||
141 | static inline int ghes_severity(int severity) | 144 | static inline int ghes_severity(int severity) |
142 | { | 145 | { |
143 | switch (severity) { | 146 | switch (severity) { |
144 | case CPER_SER_INFORMATIONAL: | 147 | case CPER_SEV_INFORMATIONAL: |
145 | return GHES_SER_NO; | 148 | return GHES_SEV_NO; |
146 | case CPER_SER_CORRECTED: | 149 | case CPER_SEV_CORRECTED: |
147 | return GHES_SER_CORRECTED; | 150 | return GHES_SEV_CORRECTED; |
148 | case CPER_SER_RECOVERABLE: | 151 | case CPER_SEV_RECOVERABLE: |
149 | return GHES_SER_RECOVERABLE; | 152 | return GHES_SEV_RECOVERABLE; |
150 | case CPER_SER_FATAL: | 153 | case CPER_SEV_FATAL: |
151 | return GHES_SER_PANIC; | 154 | return GHES_SEV_PANIC; |
152 | default: | 155 | default: |
153 | /* Unkown, go panic */ | 156 | /* Unkown, go panic */ |
154 | return GHES_SER_PANIC; | 157 | return GHES_SEV_PANIC; |
155 | } | 158 | } |
156 | } | 159 | } |
157 | 160 | ||
@@ -237,16 +240,16 @@ static void ghes_clear_estatus(struct ghes *ghes) | |||
237 | 240 | ||
238 | static void ghes_do_proc(struct ghes *ghes) | 241 | static void ghes_do_proc(struct ghes *ghes) |
239 | { | 242 | { |
240 | int ser, processed = 0; | 243 | int sev, processed = 0; |
241 | struct acpi_hest_generic_data *gdata; | 244 | struct acpi_hest_generic_data *gdata; |
242 | 245 | ||
243 | ser = ghes_severity(ghes->estatus->error_severity); | 246 | sev = ghes_severity(ghes->estatus->error_severity); |
244 | apei_estatus_for_each_section(ghes->estatus, gdata) { | 247 | apei_estatus_for_each_section(ghes->estatus, gdata) { |
245 | #ifdef CONFIG_X86_MCE | 248 | #ifdef CONFIG_X86_MCE |
246 | if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, | 249 | if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, |
247 | CPER_SEC_PLATFORM_MEM)) { | 250 | CPER_SEC_PLATFORM_MEM)) { |
248 | apei_mce_report_mem_error( | 251 | apei_mce_report_mem_error( |
249 | ser == GHES_SER_CORRECTED, | 252 | sev == GHES_SEV_CORRECTED, |
250 | (struct cper_sec_mem_err *)(gdata+1)); | 253 | (struct cper_sec_mem_err *)(gdata+1)); |
251 | processed = 1; | 254 | processed = 1; |
252 | } | 255 | } |
@@ -293,18 +296,15 @@ static struct notifier_block ghes_notifier_sci = { | |||
293 | .notifier_call = ghes_notify_sci, | 296 | .notifier_call = ghes_notify_sci, |
294 | }; | 297 | }; |
295 | 298 | ||
296 | static int hest_ghes_parse(struct acpi_hest_header *hest_hdr, void *data) | 299 | static int __devinit ghes_probe(struct platform_device *ghes_dev) |
297 | { | 300 | { |
298 | struct acpi_hest_generic *generic; | 301 | struct acpi_hest_generic *generic; |
299 | struct ghes *ghes = NULL; | 302 | struct ghes *ghes = NULL; |
300 | int rc = 0; | 303 | int rc = -EINVAL; |
301 | 304 | ||
302 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) | 305 | generic = ghes_dev->dev.platform_data; |
303 | return 0; | ||
304 | |||
305 | generic = (struct acpi_hest_generic *)hest_hdr; | ||
306 | if (!generic->enabled) | 306 | if (!generic->enabled) |
307 | return 0; | 307 | return -ENODEV; |
308 | 308 | ||
309 | if (generic->error_block_length < | 309 | if (generic->error_block_length < |
310 | sizeof(struct acpi_hest_generic_status)) { | 310 | sizeof(struct acpi_hest_generic_status)) { |
@@ -327,62 +327,91 @@ static int hest_ghes_parse(struct acpi_hest_header *hest_hdr, void *data) | |||
327 | ghes = NULL; | 327 | ghes = NULL; |
328 | goto err; | 328 | goto err; |
329 | } | 329 | } |
330 | switch (generic->notify.type) { | 330 | if (generic->notify.type == ACPI_HEST_NOTIFY_SCI) { |
331 | case ACPI_HEST_NOTIFY_POLLED: | 331 | mutex_lock(&ghes_list_mutex); |
332 | pr_warning(GHES_PFX | ||
333 | "Generic hardware error source: %d notified via POLL is not supported!\n", | ||
334 | generic->header.source_id); | ||
335 | break; | ||
336 | case ACPI_HEST_NOTIFY_EXTERNAL: | ||
337 | case ACPI_HEST_NOTIFY_LOCAL: | ||
338 | pr_warning(GHES_PFX | ||
339 | "Generic hardware error source: %d notified via IRQ is not supported!\n", | ||
340 | generic->header.source_id); | ||
341 | break; | ||
342 | case ACPI_HEST_NOTIFY_SCI: | ||
343 | if (list_empty(&ghes_sci)) | 332 | if (list_empty(&ghes_sci)) |
344 | register_acpi_hed_notifier(&ghes_notifier_sci); | 333 | register_acpi_hed_notifier(&ghes_notifier_sci); |
345 | list_add_rcu(&ghes->list, &ghes_sci); | 334 | list_add_rcu(&ghes->list, &ghes_sci); |
346 | break; | 335 | mutex_unlock(&ghes_list_mutex); |
347 | case ACPI_HEST_NOTIFY_NMI: | 336 | } else { |
348 | pr_warning(GHES_PFX | 337 | unsigned char *notify = NULL; |
349 | "Generic hardware error source: %d notified via NMI is not supported!\n", | 338 | |
350 | generic->header.source_id); | 339 | switch (generic->notify.type) { |
351 | break; | 340 | case ACPI_HEST_NOTIFY_POLLED: |
352 | default: | 341 | notify = "POLL"; |
353 | pr_warning(FW_WARN GHES_PFX | 342 | break; |
354 | "Unknown notification type: %u for generic hardware error source: %d\n", | 343 | case ACPI_HEST_NOTIFY_EXTERNAL: |
355 | generic->notify.type, generic->header.source_id); | 344 | case ACPI_HEST_NOTIFY_LOCAL: |
356 | break; | 345 | notify = "IRQ"; |
346 | break; | ||
347 | case ACPI_HEST_NOTIFY_NMI: | ||
348 | notify = "NMI"; | ||
349 | break; | ||
350 | } | ||
351 | if (notify) { | ||
352 | pr_warning(GHES_PFX | ||
353 | "Generic hardware error source: %d notified via %s is not supported!\n", | ||
354 | generic->header.source_id, notify); | ||
355 | } else { | ||
356 | pr_warning(FW_WARN GHES_PFX | ||
357 | "Unknown notification type: %u for generic hardware error source: %d\n", | ||
358 | generic->notify.type, generic->header.source_id); | ||
359 | } | ||
360 | rc = -ENODEV; | ||
361 | goto err; | ||
357 | } | 362 | } |
363 | platform_set_drvdata(ghes_dev, ghes); | ||
358 | 364 | ||
359 | return 0; | 365 | return 0; |
360 | err: | 366 | err: |
361 | if (ghes) | 367 | if (ghes) { |
362 | ghes_fini(ghes); | 368 | ghes_fini(ghes); |
369 | kfree(ghes); | ||
370 | } | ||
363 | return rc; | 371 | return rc; |
364 | } | 372 | } |
365 | 373 | ||
366 | static void ghes_cleanup(void) | 374 | static int __devexit ghes_remove(struct platform_device *ghes_dev) |
367 | { | 375 | { |
368 | struct ghes *ghes, *nghes; | 376 | struct ghes *ghes; |
377 | struct acpi_hest_generic *generic; | ||
369 | 378 | ||
370 | if (!list_empty(&ghes_sci)) | 379 | ghes = platform_get_drvdata(ghes_dev); |
371 | unregister_acpi_hed_notifier(&ghes_notifier_sci); | 380 | generic = ghes->generic; |
381 | |||
382 | switch (generic->notify.type) { | ||
383 | case ACPI_HEST_NOTIFY_SCI: | ||
384 | mutex_lock(&ghes_list_mutex); | ||
385 | list_del_rcu(&ghes->list); | ||
386 | if (list_empty(&ghes_sci)) | ||
387 | unregister_acpi_hed_notifier(&ghes_notifier_sci); | ||
388 | mutex_unlock(&ghes_list_mutex); | ||
389 | break; | ||
390 | default: | ||
391 | BUG(); | ||
392 | break; | ||
393 | } | ||
372 | 394 | ||
373 | synchronize_rcu(); | 395 | synchronize_rcu(); |
396 | ghes_fini(ghes); | ||
397 | kfree(ghes); | ||
374 | 398 | ||
375 | list_for_each_entry_safe(ghes, nghes, &ghes_sci, list) { | 399 | platform_set_drvdata(ghes_dev, NULL); |
376 | list_del(&ghes->list); | 400 | |
377 | ghes_fini(ghes); | 401 | return 0; |
378 | kfree(ghes); | ||
379 | } | ||
380 | } | 402 | } |
381 | 403 | ||
404 | static struct platform_driver ghes_platform_driver = { | ||
405 | .driver = { | ||
406 | .name = "GHES", | ||
407 | .owner = THIS_MODULE, | ||
408 | }, | ||
409 | .probe = ghes_probe, | ||
410 | .remove = ghes_remove, | ||
411 | }; | ||
412 | |||
382 | static int __init ghes_init(void) | 413 | static int __init ghes_init(void) |
383 | { | 414 | { |
384 | int rc; | ||
385 | |||
386 | if (acpi_disabled) | 415 | if (acpi_disabled) |
387 | return -ENODEV; | 416 | return -ENODEV; |
388 | 417 | ||
@@ -391,32 +420,12 @@ static int __init ghes_init(void) | |||
391 | return -EINVAL; | 420 | return -EINVAL; |
392 | } | 421 | } |
393 | 422 | ||
394 | rc = apei_hest_parse(hest_ghes_parse, NULL); | 423 | return platform_driver_register(&ghes_platform_driver); |
395 | if (rc) { | ||
396 | pr_err(GHES_PFX | ||
397 | "Error during parsing HEST generic hardware error sources.\n"); | ||
398 | goto err_cleanup; | ||
399 | } | ||
400 | |||
401 | if (list_empty(&ghes_sci)) { | ||
402 | pr_info(GHES_PFX | ||
403 | "No functional generic hardware error sources.\n"); | ||
404 | rc = -ENODEV; | ||
405 | goto err_cleanup; | ||
406 | } | ||
407 | |||
408 | pr_info(GHES_PFX | ||
409 | "Generic Hardware Error Source support is initialized.\n"); | ||
410 | |||
411 | return 0; | ||
412 | err_cleanup: | ||
413 | ghes_cleanup(); | ||
414 | return rc; | ||
415 | } | 424 | } |
416 | 425 | ||
417 | static void __exit ghes_exit(void) | 426 | static void __exit ghes_exit(void) |
418 | { | 427 | { |
419 | ghes_cleanup(); | 428 | platform_driver_unregister(&ghes_platform_driver); |
420 | } | 429 | } |
421 | 430 | ||
422 | module_init(ghes_init); | 431 | module_init(ghes_init); |
@@ -425,3 +434,4 @@ module_exit(ghes_exit); | |||
425 | MODULE_AUTHOR("Huang Ying"); | 434 | MODULE_AUTHOR("Huang Ying"); |
426 | MODULE_DESCRIPTION("APEI Generic Hardware Error Source support"); | 435 | MODULE_DESCRIPTION("APEI Generic Hardware Error Source support"); |
427 | MODULE_LICENSE("GPL"); | 436 | MODULE_LICENSE("GPL"); |
437 | MODULE_ALIAS("platform:GHES"); | ||
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index e7f40d362cb3..343168d18266 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/kdebug.h> | 34 | #include <linux/kdebug.h> |
35 | #include <linux/highmem.h> | 35 | #include <linux/highmem.h> |
36 | #include <linux/io.h> | 36 | #include <linux/io.h> |
37 | #include <linux/platform_device.h> | ||
37 | #include <acpi/apei.h> | 38 | #include <acpi/apei.h> |
38 | 39 | ||
39 | #include "apei-internal.h" | 40 | #include "apei-internal.h" |
@@ -47,11 +48,6 @@ EXPORT_SYMBOL_GPL(hest_disable); | |||
47 | 48 | ||
48 | static struct acpi_table_hest *hest_tab; | 49 | static struct acpi_table_hest *hest_tab; |
49 | 50 | ||
50 | static int hest_void_parse(struct acpi_hest_header *hest_hdr, void *data) | ||
51 | { | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { | 51 | static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { |
56 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ | 52 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ |
57 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, | 53 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, |
@@ -125,6 +121,69 @@ int apei_hest_parse(apei_hest_func_t func, void *data) | |||
125 | } | 121 | } |
126 | EXPORT_SYMBOL_GPL(apei_hest_parse); | 122 | EXPORT_SYMBOL_GPL(apei_hest_parse); |
127 | 123 | ||
124 | struct ghes_arr { | ||
125 | struct platform_device **ghes_devs; | ||
126 | unsigned int count; | ||
127 | }; | ||
128 | |||
129 | static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | ||
130 | { | ||
131 | int *count = data; | ||
132 | |||
133 | if (hest_hdr->type == ACPI_HEST_TYPE_GENERIC_ERROR) | ||
134 | (*count)++; | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) | ||
139 | { | ||
140 | struct acpi_hest_generic *generic; | ||
141 | struct platform_device *ghes_dev; | ||
142 | struct ghes_arr *ghes_arr = data; | ||
143 | int rc; | ||
144 | |||
145 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) | ||
146 | return 0; | ||
147 | generic = (struct acpi_hest_generic *)hest_hdr; | ||
148 | if (!generic->enabled) | ||
149 | return 0; | ||
150 | ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); | ||
151 | if (!ghes_dev) | ||
152 | return -ENOMEM; | ||
153 | ghes_dev->dev.platform_data = generic; | ||
154 | rc = platform_device_add(ghes_dev); | ||
155 | if (rc) | ||
156 | goto err; | ||
157 | ghes_arr->ghes_devs[ghes_arr->count++] = ghes_dev; | ||
158 | |||
159 | return 0; | ||
160 | err: | ||
161 | platform_device_put(ghes_dev); | ||
162 | return rc; | ||
163 | } | ||
164 | |||
165 | static int hest_ghes_dev_register(unsigned int ghes_count) | ||
166 | { | ||
167 | int rc, i; | ||
168 | struct ghes_arr ghes_arr; | ||
169 | |||
170 | ghes_arr.count = 0; | ||
171 | ghes_arr.ghes_devs = kmalloc(sizeof(void *) * ghes_count, GFP_KERNEL); | ||
172 | if (!ghes_arr.ghes_devs) | ||
173 | return -ENOMEM; | ||
174 | |||
175 | rc = apei_hest_parse(hest_parse_ghes, &ghes_arr); | ||
176 | if (rc) | ||
177 | goto err; | ||
178 | out: | ||
179 | kfree(ghes_arr.ghes_devs); | ||
180 | return rc; | ||
181 | err: | ||
182 | for (i = 0; i < ghes_arr.count; i++) | ||
183 | platform_device_unregister(ghes_arr.ghes_devs[i]); | ||
184 | goto out; | ||
185 | } | ||
186 | |||
128 | static int __init setup_hest_disable(char *str) | 187 | static int __init setup_hest_disable(char *str) |
129 | { | 188 | { |
130 | hest_disable = 1; | 189 | hest_disable = 1; |
@@ -137,6 +196,7 @@ static int __init hest_init(void) | |||
137 | { | 196 | { |
138 | acpi_status status; | 197 | acpi_status status; |
139 | int rc = -ENODEV; | 198 | int rc = -ENODEV; |
199 | unsigned int ghes_count = 0; | ||
140 | 200 | ||
141 | if (acpi_disabled) | 201 | if (acpi_disabled) |
142 | goto err; | 202 | goto err; |
@@ -158,7 +218,11 @@ static int __init hest_init(void) | |||
158 | goto err; | 218 | goto err; |
159 | } | 219 | } |
160 | 220 | ||
161 | rc = apei_hest_parse(hest_void_parse, NULL); | 221 | rc = apei_hest_parse(hest_parse_ghes_count, &ghes_count); |
222 | if (rc) | ||
223 | goto err; | ||
224 | |||
225 | rc = hest_ghes_dev_register(ghes_count); | ||
162 | if (rc) | 226 | if (rc) |
163 | goto err; | 227 | goto err; |
164 | 228 | ||
diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c index 814b19249616..8f8bd736d4ff 100644 --- a/drivers/acpi/atomicio.c +++ b/drivers/acpi/atomicio.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/kref.h> | 31 | #include <linux/kref.h> |
32 | #include <linux/rculist.h> | 32 | #include <linux/rculist.h> |
33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
34 | #include <linux/slab.h> | ||
34 | #include <acpi/atomicio.h> | 35 | #include <acpi/atomicio.h> |
35 | 36 | ||
36 | #define ACPI_PFX "ACPI: " | 37 | #define ACPI_PFX "ACPI: " |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 3026e3fa83ef..dc58402b0a17 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -868,9 +868,15 @@ static void acpi_battery_remove_fs(struct acpi_device *device) | |||
868 | static void acpi_battery_notify(struct acpi_device *device, u32 event) | 868 | static void acpi_battery_notify(struct acpi_device *device, u32 event) |
869 | { | 869 | { |
870 | struct acpi_battery *battery = acpi_driver_data(device); | 870 | struct acpi_battery *battery = acpi_driver_data(device); |
871 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
872 | struct device *old; | ||
873 | #endif | ||
871 | 874 | ||
872 | if (!battery) | 875 | if (!battery) |
873 | return; | 876 | return; |
877 | #ifdef CONFIG_ACPI_SYSFS_POWER | ||
878 | old = battery->bat.dev; | ||
879 | #endif | ||
874 | acpi_battery_update(battery); | 880 | acpi_battery_update(battery); |
875 | acpi_bus_generate_proc_event(device, event, | 881 | acpi_bus_generate_proc_event(device, event, |
876 | acpi_battery_present(battery)); | 882 | acpi_battery_present(battery)); |
@@ -879,7 +885,7 @@ static void acpi_battery_notify(struct acpi_device *device, u32 event) | |||
879 | acpi_battery_present(battery)); | 885 | acpi_battery_present(battery)); |
880 | #ifdef CONFIG_ACPI_SYSFS_POWER | 886 | #ifdef CONFIG_ACPI_SYSFS_POWER |
881 | /* acpi_battery_update could remove power_supply object */ | 887 | /* acpi_battery_update could remove power_supply object */ |
882 | if (battery->bat.dev) | 888 | if (old && battery->bat.dev) |
883 | power_supply_changed(&battery->bat); | 889 | power_supply_changed(&battery->bat); |
884 | #endif | 890 | #endif |
885 | } | 891 | } |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 2815df66f6f7..2bb28b9d91c4 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -214,7 +214,15 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
214 | .ident = "Sony VGN-SR290J", | 214 | .ident = "Sony VGN-SR290J", |
215 | .matches = { | 215 | .matches = { |
216 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | 216 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), |
217 | DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"), | 217 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"), |
218 | }, | ||
219 | }, | ||
220 | { | ||
221 | .callback = dmi_disable_osi_vista, | ||
222 | .ident = "VGN-NS50B_L", | ||
223 | .matches = { | ||
224 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
225 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS50B_L"), | ||
218 | }, | 226 | }, |
219 | }, | 227 | }, |
220 | { | 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/button.c b/drivers/acpi/button.c index fd51c4ab4829..1575a9b51f1d 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -424,8 +424,7 @@ static int acpi_button_add(struct acpi_device *device) | |||
424 | if (device->wakeup.flags.valid) { | 424 | if (device->wakeup.flags.valid) { |
425 | /* Button's GPE is run-wake GPE */ | 425 | /* Button's GPE is run-wake GPE */ |
426 | acpi_enable_gpe(device->wakeup.gpe_device, | 426 | acpi_enable_gpe(device->wakeup.gpe_device, |
427 | device->wakeup.gpe_number, | 427 | device->wakeup.gpe_number); |
428 | ACPI_GPE_TYPE_WAKE_RUN); | ||
429 | device->wakeup.run_wake_count++; | 428 | device->wakeup.run_wake_count++; |
430 | device->wakeup.state.enabled = 1; | 429 | device->wakeup.state.enabled = 1; |
431 | } | 430 | } |
@@ -448,8 +447,7 @@ static int acpi_button_remove(struct acpi_device *device, int type) | |||
448 | 447 | ||
449 | if (device->wakeup.flags.valid) { | 448 | if (device->wakeup.flags.valid) { |
450 | acpi_disable_gpe(device->wakeup.gpe_device, | 449 | acpi_disable_gpe(device->wakeup.gpe_device, |
451 | device->wakeup.gpe_number, | 450 | device->wakeup.gpe_number); |
452 | ACPI_GPE_TYPE_WAKE_RUN); | ||
453 | device->wakeup.run_wake_count--; | 451 | device->wakeup.run_wake_count--; |
454 | device->wakeup.state.enabled = 0; | 452 | device->wakeup.state.enabled = 0; |
455 | } | 453 | } |
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c deleted file mode 100644 index 146135e7a6a1..000000000000 --- a/drivers/acpi/debug.c +++ /dev/null | |||
@@ -1,406 +0,0 @@ | |||
1 | /* | ||
2 | * debug.c - ACPI debug interface to userspace. | ||
3 | */ | ||
4 | |||
5 | #include <linux/proc_fs.h> | ||
6 | #include <linux/seq_file.h> | ||
7 | #include <linux/init.h> | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/moduleparam.h> | ||
11 | #include <linux/debugfs.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <asm/uaccess.h> | ||
14 | #include <acpi/acpi_drivers.h> | ||
15 | |||
16 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | ||
17 | ACPI_MODULE_NAME("debug"); | ||
18 | |||
19 | struct acpi_dlayer { | ||
20 | const char *name; | ||
21 | unsigned long value; | ||
22 | }; | ||
23 | struct acpi_dlevel { | ||
24 | const char *name; | ||
25 | unsigned long value; | ||
26 | }; | ||
27 | #define ACPI_DEBUG_INIT(v) { .name = #v, .value = v } | ||
28 | |||
29 | static const struct acpi_dlayer acpi_debug_layers[] = { | ||
30 | ACPI_DEBUG_INIT(ACPI_UTILITIES), | ||
31 | ACPI_DEBUG_INIT(ACPI_HARDWARE), | ||
32 | ACPI_DEBUG_INIT(ACPI_EVENTS), | ||
33 | ACPI_DEBUG_INIT(ACPI_TABLES), | ||
34 | ACPI_DEBUG_INIT(ACPI_NAMESPACE), | ||
35 | ACPI_DEBUG_INIT(ACPI_PARSER), | ||
36 | ACPI_DEBUG_INIT(ACPI_DISPATCHER), | ||
37 | ACPI_DEBUG_INIT(ACPI_EXECUTER), | ||
38 | ACPI_DEBUG_INIT(ACPI_RESOURCES), | ||
39 | ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER), | ||
40 | ACPI_DEBUG_INIT(ACPI_OS_SERVICES), | ||
41 | ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER), | ||
42 | ACPI_DEBUG_INIT(ACPI_COMPILER), | ||
43 | ACPI_DEBUG_INIT(ACPI_TOOLS), | ||
44 | |||
45 | ACPI_DEBUG_INIT(ACPI_BUS_COMPONENT), | ||
46 | ACPI_DEBUG_INIT(ACPI_AC_COMPONENT), | ||
47 | ACPI_DEBUG_INIT(ACPI_BATTERY_COMPONENT), | ||
48 | ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT), | ||
49 | ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT), | ||
50 | ACPI_DEBUG_INIT(ACPI_FAN_COMPONENT), | ||
51 | ACPI_DEBUG_INIT(ACPI_PCI_COMPONENT), | ||
52 | ACPI_DEBUG_INIT(ACPI_POWER_COMPONENT), | ||
53 | ACPI_DEBUG_INIT(ACPI_CONTAINER_COMPONENT), | ||
54 | ACPI_DEBUG_INIT(ACPI_SYSTEM_COMPONENT), | ||
55 | ACPI_DEBUG_INIT(ACPI_THERMAL_COMPONENT), | ||
56 | ACPI_DEBUG_INIT(ACPI_MEMORY_DEVICE_COMPONENT), | ||
57 | ACPI_DEBUG_INIT(ACPI_VIDEO_COMPONENT), | ||
58 | ACPI_DEBUG_INIT(ACPI_PROCESSOR_COMPONENT), | ||
59 | }; | ||
60 | |||
61 | static const struct acpi_dlevel acpi_debug_levels[] = { | ||
62 | ACPI_DEBUG_INIT(ACPI_LV_INIT), | ||
63 | ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT), | ||
64 | ACPI_DEBUG_INIT(ACPI_LV_INFO), | ||
65 | |||
66 | ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES), | ||
67 | ACPI_DEBUG_INIT(ACPI_LV_PARSE), | ||
68 | ACPI_DEBUG_INIT(ACPI_LV_LOAD), | ||
69 | ACPI_DEBUG_INIT(ACPI_LV_DISPATCH), | ||
70 | ACPI_DEBUG_INIT(ACPI_LV_EXEC), | ||
71 | ACPI_DEBUG_INIT(ACPI_LV_NAMES), | ||
72 | ACPI_DEBUG_INIT(ACPI_LV_OPREGION), | ||
73 | ACPI_DEBUG_INIT(ACPI_LV_BFIELD), | ||
74 | ACPI_DEBUG_INIT(ACPI_LV_TABLES), | ||
75 | ACPI_DEBUG_INIT(ACPI_LV_VALUES), | ||
76 | ACPI_DEBUG_INIT(ACPI_LV_OBJECTS), | ||
77 | ACPI_DEBUG_INIT(ACPI_LV_RESOURCES), | ||
78 | ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS), | ||
79 | ACPI_DEBUG_INIT(ACPI_LV_PACKAGE), | ||
80 | |||
81 | ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS), | ||
82 | ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS), | ||
83 | ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS), | ||
84 | |||
85 | ACPI_DEBUG_INIT(ACPI_LV_MUTEX), | ||
86 | ACPI_DEBUG_INIT(ACPI_LV_THREADS), | ||
87 | ACPI_DEBUG_INIT(ACPI_LV_IO), | ||
88 | ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS), | ||
89 | |||
90 | ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE), | ||
91 | ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO), | ||
92 | ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES), | ||
93 | ACPI_DEBUG_INIT(ACPI_LV_EVENTS), | ||
94 | }; | ||
95 | |||
96 | /* -------------------------------------------------------------------------- | ||
97 | FS Interface (/sys) | ||
98 | -------------------------------------------------------------------------- */ | ||
99 | static int param_get_debug_layer(char *buffer, struct kernel_param *kp) { | ||
100 | int result = 0; | ||
101 | int i; | ||
102 | |||
103 | result = sprintf(buffer, "%-25s\tHex SET\n", "Description"); | ||
104 | |||
105 | for(i = 0; i <ARRAY_SIZE(acpi_debug_layers); i++) { | ||
106 | result += sprintf(buffer+result, "%-25s\t0x%08lX [%c]\n", | ||
107 | acpi_debug_layers[i].name, | ||
108 | acpi_debug_layers[i].value, | ||
109 | (acpi_dbg_layer & acpi_debug_layers[i].value) ? '*' : ' '); | ||
110 | } | ||
111 | result += sprintf(buffer+result, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", | ||
112 | ACPI_ALL_DRIVERS, | ||
113 | (acpi_dbg_layer & ACPI_ALL_DRIVERS) == | ||
114 | ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & | ||
115 | ACPI_ALL_DRIVERS) == 0 ? ' ' : '-'); | ||
116 | result += sprintf(buffer+result, "--\ndebug_layer = 0x%08X ( * = enabled)\n", acpi_dbg_layer); | ||
117 | |||
118 | return result; | ||
119 | } | ||
120 | |||
121 | static int param_get_debug_level(char *buffer, struct kernel_param *kp) { | ||
122 | int result = 0; | ||
123 | int i; | ||
124 | |||
125 | result = sprintf(buffer, "%-25s\tHex SET\n", "Description"); | ||
126 | |||
127 | for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { | ||
128 | result += sprintf(buffer+result, "%-25s\t0x%08lX [%c]\n", | ||
129 | acpi_debug_levels[i].name, | ||
130 | acpi_debug_levels[i].value, | ||
131 | (acpi_dbg_level & acpi_debug_levels[i]. | ||
132 | value) ? '*' : ' '); | ||
133 | } | ||
134 | result += sprintf(buffer+result, "--\ndebug_level = 0x%08X (* = enabled)\n", | ||
135 | acpi_dbg_level); | ||
136 | |||
137 | return result; | ||
138 | } | ||
139 | |||
140 | module_param_call(debug_layer, param_set_uint, param_get_debug_layer, &acpi_dbg_layer, 0644); | ||
141 | module_param_call(debug_level, param_set_uint, param_get_debug_level, &acpi_dbg_level, 0644); | ||
142 | |||
143 | static char trace_method_name[6]; | ||
144 | module_param_string(trace_method_name, trace_method_name, 6, 0644); | ||
145 | static unsigned int trace_debug_layer; | ||
146 | module_param(trace_debug_layer, uint, 0644); | ||
147 | static unsigned int trace_debug_level; | ||
148 | module_param(trace_debug_level, uint, 0644); | ||
149 | |||
150 | static int param_set_trace_state(const char *val, struct kernel_param *kp) | ||
151 | { | ||
152 | int result = 0; | ||
153 | |||
154 | if (!strncmp(val, "enable", strlen("enable") - 1)) { | ||
155 | result = acpi_debug_trace(trace_method_name, trace_debug_level, | ||
156 | trace_debug_layer, 0); | ||
157 | if (result) | ||
158 | result = -EBUSY; | ||
159 | goto exit; | ||
160 | } | ||
161 | |||
162 | if (!strncmp(val, "disable", strlen("disable") - 1)) { | ||
163 | int name = 0; | ||
164 | result = acpi_debug_trace((char *)&name, trace_debug_level, | ||
165 | trace_debug_layer, 0); | ||
166 | if (result) | ||
167 | result = -EBUSY; | ||
168 | goto exit; | ||
169 | } | ||
170 | |||
171 | if (!strncmp(val, "1", 1)) { | ||
172 | result = acpi_debug_trace(trace_method_name, trace_debug_level, | ||
173 | trace_debug_layer, 1); | ||
174 | if (result) | ||
175 | result = -EBUSY; | ||
176 | goto exit; | ||
177 | } | ||
178 | |||
179 | result = -EINVAL; | ||
180 | exit: | ||
181 | return result; | ||
182 | } | ||
183 | |||
184 | static int param_get_trace_state(char *buffer, struct kernel_param *kp) | ||
185 | { | ||
186 | if (!acpi_gbl_trace_method_name) | ||
187 | return sprintf(buffer, "disable"); | ||
188 | else { | ||
189 | if (acpi_gbl_trace_flags & 1) | ||
190 | return sprintf(buffer, "1"); | ||
191 | else | ||
192 | return sprintf(buffer, "enable"); | ||
193 | } | ||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | module_param_call(trace_state, param_set_trace_state, param_get_trace_state, | ||
198 | NULL, 0644); | ||
199 | |||
200 | /* -------------------------------------------------------------------------- | ||
201 | DebugFS Interface | ||
202 | -------------------------------------------------------------------------- */ | ||
203 | |||
204 | static ssize_t cm_write(struct file *file, const char __user *user_buf, | ||
205 | size_t count, loff_t *ppos) | ||
206 | { | ||
207 | static char *buf; | ||
208 | static int uncopied_bytes; | ||
209 | struct acpi_table_header table; | ||
210 | acpi_status status; | ||
211 | |||
212 | if (!(*ppos)) { | ||
213 | /* parse the table header to get the table length */ | ||
214 | if (count <= sizeof(struct acpi_table_header)) | ||
215 | return -EINVAL; | ||
216 | if (copy_from_user(&table, user_buf, | ||
217 | sizeof(struct acpi_table_header))) | ||
218 | return -EFAULT; | ||
219 | uncopied_bytes = table.length; | ||
220 | buf = kzalloc(uncopied_bytes, GFP_KERNEL); | ||
221 | if (!buf) | ||
222 | return -ENOMEM; | ||
223 | } | ||
224 | |||
225 | if (uncopied_bytes < count) { | ||
226 | kfree(buf); | ||
227 | return -EINVAL; | ||
228 | } | ||
229 | |||
230 | if (copy_from_user(buf + (*ppos), user_buf, count)) { | ||
231 | kfree(buf); | ||
232 | return -EFAULT; | ||
233 | } | ||
234 | |||
235 | uncopied_bytes -= count; | ||
236 | *ppos += count; | ||
237 | |||
238 | if (!uncopied_bytes) { | ||
239 | status = acpi_install_method(buf); | ||
240 | kfree(buf); | ||
241 | if (ACPI_FAILURE(status)) | ||
242 | return -EINVAL; | ||
243 | add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); | ||
244 | } | ||
245 | |||
246 | return count; | ||
247 | } | ||
248 | |||
249 | static const struct file_operations cm_fops = { | ||
250 | .write = cm_write, | ||
251 | }; | ||
252 | |||
253 | static int acpi_debugfs_init(void) | ||
254 | { | ||
255 | struct dentry *acpi_dir, *cm_dentry; | ||
256 | |||
257 | acpi_dir = debugfs_create_dir("acpi", NULL); | ||
258 | if (!acpi_dir) | ||
259 | goto err; | ||
260 | |||
261 | cm_dentry = debugfs_create_file("custom_method", S_IWUGO, | ||
262 | acpi_dir, NULL, &cm_fops); | ||
263 | if (!cm_dentry) | ||
264 | goto err; | ||
265 | |||
266 | return 0; | ||
267 | |||
268 | err: | ||
269 | if (acpi_dir) | ||
270 | debugfs_remove(acpi_dir); | ||
271 | return -EINVAL; | ||
272 | } | ||
273 | |||
274 | /* -------------------------------------------------------------------------- | ||
275 | FS Interface (/proc) | ||
276 | -------------------------------------------------------------------------- */ | ||
277 | #ifdef CONFIG_ACPI_PROCFS | ||
278 | #define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer" | ||
279 | #define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level" | ||
280 | |||
281 | static int acpi_system_debug_proc_show(struct seq_file *m, void *v) | ||
282 | { | ||
283 | unsigned int i; | ||
284 | |||
285 | seq_printf(m, "%-25s\tHex SET\n", "Description"); | ||
286 | |||
287 | switch ((unsigned long)m->private) { | ||
288 | case 0: | ||
289 | for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) { | ||
290 | seq_printf(m, "%-25s\t0x%08lX [%c]\n", | ||
291 | acpi_debug_layers[i].name, | ||
292 | acpi_debug_layers[i].value, | ||
293 | (acpi_dbg_layer & acpi_debug_layers[i]. | ||
294 | value) ? '*' : ' '); | ||
295 | } | ||
296 | seq_printf(m, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", | ||
297 | ACPI_ALL_DRIVERS, | ||
298 | (acpi_dbg_layer & ACPI_ALL_DRIVERS) == | ||
299 | ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & | ||
300 | ACPI_ALL_DRIVERS) == | ||
301 | 0 ? ' ' : '-'); | ||
302 | seq_printf(m, | ||
303 | "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n", | ||
304 | acpi_dbg_layer); | ||
305 | break; | ||
306 | case 1: | ||
307 | for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { | ||
308 | seq_printf(m, "%-25s\t0x%08lX [%c]\n", | ||
309 | acpi_debug_levels[i].name, | ||
310 | acpi_debug_levels[i].value, | ||
311 | (acpi_dbg_level & acpi_debug_levels[i]. | ||
312 | value) ? '*' : ' '); | ||
313 | } | ||
314 | seq_printf(m, "--\ndebug_level = 0x%08X (* = enabled)\n", | ||
315 | acpi_dbg_level); | ||
316 | break; | ||
317 | } | ||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | static int acpi_system_debug_proc_open(struct inode *inode, struct file *file) | ||
322 | { | ||
323 | return single_open(file, acpi_system_debug_proc_show, PDE(inode)->data); | ||
324 | } | ||
325 | |||
326 | static ssize_t acpi_system_debug_proc_write(struct file *file, | ||
327 | const char __user * buffer, | ||
328 | size_t count, loff_t *pos) | ||
329 | { | ||
330 | char debug_string[12] = { '\0' }; | ||
331 | |||
332 | |||
333 | if (count > sizeof(debug_string) - 1) | ||
334 | return -EINVAL; | ||
335 | |||
336 | if (copy_from_user(debug_string, buffer, count)) | ||
337 | return -EFAULT; | ||
338 | |||
339 | debug_string[count] = '\0'; | ||
340 | |||
341 | switch ((unsigned long)PDE(file->f_path.dentry->d_inode)->data) { | ||
342 | case 0: | ||
343 | acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0); | ||
344 | break; | ||
345 | case 1: | ||
346 | acpi_dbg_level = simple_strtoul(debug_string, NULL, 0); | ||
347 | break; | ||
348 | default: | ||
349 | return -EINVAL; | ||
350 | } | ||
351 | |||
352 | return count; | ||
353 | } | ||
354 | |||
355 | static const struct file_operations acpi_system_debug_proc_fops = { | ||
356 | .owner = THIS_MODULE, | ||
357 | .open = acpi_system_debug_proc_open, | ||
358 | .read = seq_read, | ||
359 | .llseek = seq_lseek, | ||
360 | .release = single_release, | ||
361 | .write = acpi_system_debug_proc_write, | ||
362 | }; | ||
363 | #endif | ||
364 | |||
365 | int __init acpi_procfs_init(void) | ||
366 | { | ||
367 | #ifdef CONFIG_ACPI_PROCFS | ||
368 | struct proc_dir_entry *entry; | ||
369 | int error = 0; | ||
370 | char *name; | ||
371 | |||
372 | /* 'debug_layer' [R/W] */ | ||
373 | name = ACPI_SYSTEM_FILE_DEBUG_LAYER; | ||
374 | entry = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, | ||
375 | acpi_root_dir, &acpi_system_debug_proc_fops, | ||
376 | (void *)0); | ||
377 | if (!entry) | ||
378 | goto Error; | ||
379 | |||
380 | /* 'debug_level' [R/W] */ | ||
381 | name = ACPI_SYSTEM_FILE_DEBUG_LEVEL; | ||
382 | entry = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, | ||
383 | acpi_root_dir, &acpi_system_debug_proc_fops, | ||
384 | (void *)1); | ||
385 | if (!entry) | ||
386 | goto Error; | ||
387 | |||
388 | Done: | ||
389 | return error; | ||
390 | |||
391 | Error: | ||
392 | remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LEVEL, acpi_root_dir); | ||
393 | remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir); | ||
394 | error = -ENODEV; | ||
395 | goto Done; | ||
396 | #else | ||
397 | return 0; | ||
398 | #endif | ||
399 | } | ||
400 | |||
401 | int __init acpi_debug_init(void) | ||
402 | { | ||
403 | acpi_debugfs_init(); | ||
404 | acpi_procfs_init(); | ||
405 | return 0; | ||
406 | } | ||
diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c new file mode 100644 index 000000000000..7de27d49c4b9 --- /dev/null +++ b/drivers/acpi/debugfs.c | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * debugfs.c - ACPI debugfs interface to userspace. | ||
3 | */ | ||
4 | |||
5 | #include <linux/init.h> | ||
6 | #include <linux/module.h> | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/uaccess.h> | ||
9 | #include <linux/debugfs.h> | ||
10 | #include <acpi/acpi_drivers.h> | ||
11 | |||
12 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | ||
13 | ACPI_MODULE_NAME("debugfs"); | ||
14 | |||
15 | |||
16 | /* /sys/modules/acpi/parameters/aml_debug_output */ | ||
17 | |||
18 | module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object, | ||
19 | bool, 0644); | ||
20 | MODULE_PARM_DESC(aml_debug_output, | ||
21 | "To enable/disable the ACPI Debug Object output."); | ||
22 | |||
23 | /* /sys/kernel/debug/acpi/custom_method */ | ||
24 | |||
25 | static ssize_t cm_write(struct file *file, const char __user * user_buf, | ||
26 | size_t count, loff_t *ppos) | ||
27 | { | ||
28 | static char *buf; | ||
29 | static int uncopied_bytes; | ||
30 | struct acpi_table_header table; | ||
31 | acpi_status status; | ||
32 | |||
33 | if (!(*ppos)) { | ||
34 | /* parse the table header to get the table length */ | ||
35 | if (count <= sizeof(struct acpi_table_header)) | ||
36 | return -EINVAL; | ||
37 | if (copy_from_user(&table, user_buf, | ||
38 | sizeof(struct acpi_table_header))) | ||
39 | return -EFAULT; | ||
40 | uncopied_bytes = table.length; | ||
41 | buf = kzalloc(uncopied_bytes, GFP_KERNEL); | ||
42 | if (!buf) | ||
43 | return -ENOMEM; | ||
44 | } | ||
45 | |||
46 | if (uncopied_bytes < count) { | ||
47 | kfree(buf); | ||
48 | return -EINVAL; | ||
49 | } | ||
50 | |||
51 | if (copy_from_user(buf + (*ppos), user_buf, count)) { | ||
52 | kfree(buf); | ||
53 | return -EFAULT; | ||
54 | } | ||
55 | |||
56 | uncopied_bytes -= count; | ||
57 | *ppos += count; | ||
58 | |||
59 | if (!uncopied_bytes) { | ||
60 | status = acpi_install_method(buf); | ||
61 | kfree(buf); | ||
62 | if (ACPI_FAILURE(status)) | ||
63 | return -EINVAL; | ||
64 | add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); | ||
65 | } | ||
66 | |||
67 | return count; | ||
68 | } | ||
69 | |||
70 | static const struct file_operations cm_fops = { | ||
71 | .write = cm_write, | ||
72 | }; | ||
73 | |||
74 | int __init acpi_debugfs_init(void) | ||
75 | { | ||
76 | struct dentry *acpi_dir, *cm_dentry; | ||
77 | |||
78 | acpi_dir = debugfs_create_dir("acpi", NULL); | ||
79 | if (!acpi_dir) | ||
80 | goto err; | ||
81 | |||
82 | cm_dentry = debugfs_create_file("custom_method", S_IWUGO, | ||
83 | acpi_dir, NULL, &cm_fops); | ||
84 | if (!cm_dentry) | ||
85 | goto err; | ||
86 | |||
87 | return 0; | ||
88 | |||
89 | err: | ||
90 | if (acpi_dir) | ||
91 | debugfs_remove(acpi_dir); | ||
92 | return -EINVAL; | ||
93 | } | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e61d4f8e62a5..f31291ba94d0 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -34,8 +34,6 @@ | |||
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/types.h> | 35 | #include <linux/types.h> |
36 | #include <linux/delay.h> | 36 | #include <linux/delay.h> |
37 | #include <linux/proc_fs.h> | ||
38 | #include <linux/seq_file.h> | ||
39 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
40 | #include <linux/list.h> | 38 | #include <linux/list.h> |
41 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
@@ -45,10 +43,13 @@ | |||
45 | #include <acpi/acpi_drivers.h> | 43 | #include <acpi/acpi_drivers.h> |
46 | #include <linux/dmi.h> | 44 | #include <linux/dmi.h> |
47 | 45 | ||
46 | #include "internal.h" | ||
47 | |||
48 | #define ACPI_EC_CLASS "embedded_controller" | 48 | #define ACPI_EC_CLASS "embedded_controller" |
49 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" | 49 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" |
50 | #define ACPI_EC_FILE_INFO "info" | 50 | #define ACPI_EC_FILE_INFO "info" |
51 | 51 | ||
52 | #undef PREFIX | ||
52 | #define PREFIX "ACPI: EC: " | 53 | #define PREFIX "ACPI: EC: " |
53 | 54 | ||
54 | /* EC status register */ | 55 | /* EC status register */ |
@@ -79,7 +80,7 @@ enum { | |||
79 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ | 80 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ |
80 | EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and | 81 | EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and |
81 | * OpReg are installed */ | 82 | * OpReg are installed */ |
82 | EC_FLAGS_FROZEN, /* Transactions are suspended */ | 83 | EC_FLAGS_BLOCKED, /* Transactions are blocked */ |
83 | }; | 84 | }; |
84 | 85 | ||
85 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ | 86 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ |
@@ -106,19 +107,8 @@ struct transaction { | |||
106 | bool done; | 107 | bool done; |
107 | }; | 108 | }; |
108 | 109 | ||
109 | static struct acpi_ec { | 110 | struct acpi_ec *boot_ec, *first_ec; |
110 | acpi_handle handle; | 111 | EXPORT_SYMBOL(first_ec); |
111 | unsigned long gpe; | ||
112 | unsigned long command_addr; | ||
113 | unsigned long data_addr; | ||
114 | unsigned long global_lock; | ||
115 | unsigned long flags; | ||
116 | struct mutex lock; | ||
117 | wait_queue_head_t wait; | ||
118 | struct list_head list; | ||
119 | struct transaction *curr; | ||
120 | spinlock_t curr_lock; | ||
121 | } *boot_ec, *first_ec; | ||
122 | 112 | ||
123 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ | 113 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ |
124 | static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ | 114 | static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ |
@@ -293,7 +283,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
293 | if (t->rdata) | 283 | if (t->rdata) |
294 | memset(t->rdata, 0, t->rlen); | 284 | memset(t->rdata, 0, t->rlen); |
295 | mutex_lock(&ec->lock); | 285 | mutex_lock(&ec->lock); |
296 | if (test_bit(EC_FLAGS_FROZEN, &ec->flags)) { | 286 | if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) { |
297 | status = -EINVAL; | 287 | status = -EINVAL; |
298 | goto unlock; | 288 | goto unlock; |
299 | } | 289 | } |
@@ -313,11 +303,8 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
313 | pr_debug(PREFIX "transaction start\n"); | 303 | pr_debug(PREFIX "transaction start\n"); |
314 | /* disable GPE during transaction if storm is detected */ | 304 | /* disable GPE during transaction if storm is detected */ |
315 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 305 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
316 | /* | 306 | /* It has to be disabled, so that it doesn't trigger. */ |
317 | * It has to be disabled at the hardware level regardless of the | 307 | acpi_disable_gpe(NULL, ec->gpe); |
318 | * GPE reference counting, so that it doesn't trigger. | ||
319 | */ | ||
320 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); | ||
321 | } | 308 | } |
322 | 309 | ||
323 | status = acpi_ec_transaction_unlocked(ec, t); | 310 | status = acpi_ec_transaction_unlocked(ec, t); |
@@ -326,12 +313,8 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
326 | ec_check_sci_sync(ec, acpi_ec_read_status(ec)); | 313 | ec_check_sci_sync(ec, acpi_ec_read_status(ec)); |
327 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 314 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
328 | msleep(1); | 315 | msleep(1); |
329 | /* | 316 | /* It is safe to enable the GPE outside of the transaction. */ |
330 | * It is safe to enable the GPE outside of the transaction. Use | 317 | acpi_enable_gpe(NULL, ec->gpe); |
331 | * acpi_set_gpe() for that, since we used it to disable the GPE | ||
332 | * above. | ||
333 | */ | ||
334 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); | ||
335 | } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { | 318 | } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { |
336 | pr_info(PREFIX "GPE storm detected, " | 319 | pr_info(PREFIX "GPE storm detected, " |
337 | "transactions will use polling mode\n"); | 320 | "transactions will use polling mode\n"); |
@@ -459,7 +442,7 @@ int ec_transaction(u8 command, | |||
459 | 442 | ||
460 | EXPORT_SYMBOL(ec_transaction); | 443 | EXPORT_SYMBOL(ec_transaction); |
461 | 444 | ||
462 | void acpi_ec_suspend_transactions(void) | 445 | void acpi_ec_block_transactions(void) |
463 | { | 446 | { |
464 | struct acpi_ec *ec = first_ec; | 447 | struct acpi_ec *ec = first_ec; |
465 | 448 | ||
@@ -468,11 +451,11 @@ void acpi_ec_suspend_transactions(void) | |||
468 | 451 | ||
469 | mutex_lock(&ec->lock); | 452 | mutex_lock(&ec->lock); |
470 | /* Prevent transactions from being carried out */ | 453 | /* Prevent transactions from being carried out */ |
471 | set_bit(EC_FLAGS_FROZEN, &ec->flags); | 454 | set_bit(EC_FLAGS_BLOCKED, &ec->flags); |
472 | mutex_unlock(&ec->lock); | 455 | mutex_unlock(&ec->lock); |
473 | } | 456 | } |
474 | 457 | ||
475 | void acpi_ec_resume_transactions(void) | 458 | void acpi_ec_unblock_transactions(void) |
476 | { | 459 | { |
477 | struct acpi_ec *ec = first_ec; | 460 | struct acpi_ec *ec = first_ec; |
478 | 461 | ||
@@ -481,10 +464,20 @@ void acpi_ec_resume_transactions(void) | |||
481 | 464 | ||
482 | mutex_lock(&ec->lock); | 465 | mutex_lock(&ec->lock); |
483 | /* Allow transactions to be carried out again */ | 466 | /* Allow transactions to be carried out again */ |
484 | clear_bit(EC_FLAGS_FROZEN, &ec->flags); | 467 | clear_bit(EC_FLAGS_BLOCKED, &ec->flags); |
485 | mutex_unlock(&ec->lock); | 468 | mutex_unlock(&ec->lock); |
486 | } | 469 | } |
487 | 470 | ||
471 | void acpi_ec_unblock_transactions_early(void) | ||
472 | { | ||
473 | /* | ||
474 | * Allow transactions to happen again (this function is called from | ||
475 | * atomic context during wakeup, so we don't need to acquire the mutex). | ||
476 | */ | ||
477 | if (first_ec) | ||
478 | clear_bit(EC_FLAGS_BLOCKED, &first_ec->flags); | ||
479 | } | ||
480 | |||
488 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) | 481 | static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 * data) |
489 | { | 482 | { |
490 | int result; | 483 | int result; |
@@ -669,72 +662,6 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
669 | } | 662 | } |
670 | 663 | ||
671 | /* -------------------------------------------------------------------------- | 664 | /* -------------------------------------------------------------------------- |
672 | FS Interface (/proc) | ||
673 | -------------------------------------------------------------------------- */ | ||
674 | |||
675 | static struct proc_dir_entry *acpi_ec_dir; | ||
676 | |||
677 | static int acpi_ec_read_info(struct seq_file *seq, void *offset) | ||
678 | { | ||
679 | struct acpi_ec *ec = seq->private; | ||
680 | |||
681 | if (!ec) | ||
682 | goto end; | ||
683 | |||
684 | seq_printf(seq, "gpe:\t\t\t0x%02x\n", (u32) ec->gpe); | ||
685 | seq_printf(seq, "ports:\t\t\t0x%02x, 0x%02x\n", | ||
686 | (unsigned)ec->command_addr, (unsigned)ec->data_addr); | ||
687 | seq_printf(seq, "use global lock:\t%s\n", | ||
688 | ec->global_lock ? "yes" : "no"); | ||
689 | end: | ||
690 | return 0; | ||
691 | } | ||
692 | |||
693 | static int acpi_ec_info_open_fs(struct inode *inode, struct file *file) | ||
694 | { | ||
695 | return single_open(file, acpi_ec_read_info, PDE(inode)->data); | ||
696 | } | ||
697 | |||
698 | static const struct file_operations acpi_ec_info_ops = { | ||
699 | .open = acpi_ec_info_open_fs, | ||
700 | .read = seq_read, | ||
701 | .llseek = seq_lseek, | ||
702 | .release = single_release, | ||
703 | .owner = THIS_MODULE, | ||
704 | }; | ||
705 | |||
706 | static int acpi_ec_add_fs(struct acpi_device *device) | ||
707 | { | ||
708 | struct proc_dir_entry *entry = NULL; | ||
709 | |||
710 | if (!acpi_device_dir(device)) { | ||
711 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
712 | acpi_ec_dir); | ||
713 | if (!acpi_device_dir(device)) | ||
714 | return -ENODEV; | ||
715 | } | ||
716 | |||
717 | entry = proc_create_data(ACPI_EC_FILE_INFO, S_IRUGO, | ||
718 | acpi_device_dir(device), | ||
719 | &acpi_ec_info_ops, acpi_driver_data(device)); | ||
720 | if (!entry) | ||
721 | return -ENODEV; | ||
722 | return 0; | ||
723 | } | ||
724 | |||
725 | static int acpi_ec_remove_fs(struct acpi_device *device) | ||
726 | { | ||
727 | |||
728 | if (acpi_device_dir(device)) { | ||
729 | remove_proc_entry(ACPI_EC_FILE_INFO, acpi_device_dir(device)); | ||
730 | remove_proc_entry(acpi_device_bid(device), acpi_ec_dir); | ||
731 | acpi_device_dir(device) = NULL; | ||
732 | } | ||
733 | |||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | /* -------------------------------------------------------------------------- | ||
738 | Driver Interface | 665 | Driver Interface |
739 | -------------------------------------------------------------------------- */ | 666 | -------------------------------------------------------------------------- */ |
740 | static acpi_status | 667 | static acpi_status |
@@ -812,7 +739,7 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
812 | if (ACPI_FAILURE(status)) | 739 | if (ACPI_FAILURE(status)) |
813 | return -ENODEV; | 740 | return -ENODEV; |
814 | 741 | ||
815 | acpi_enable_gpe(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | 742 | acpi_enable_gpe(NULL, ec->gpe); |
816 | status = acpi_install_address_space_handler(ec->handle, | 743 | status = acpi_install_address_space_handler(ec->handle, |
817 | ACPI_ADR_SPACE_EC, | 744 | ACPI_ADR_SPACE_EC, |
818 | &acpi_ec_space_handler, | 745 | &acpi_ec_space_handler, |
@@ -829,7 +756,7 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
829 | } else { | 756 | } else { |
830 | acpi_remove_gpe_handler(NULL, ec->gpe, | 757 | acpi_remove_gpe_handler(NULL, ec->gpe, |
831 | &acpi_ec_gpe_handler); | 758 | &acpi_ec_gpe_handler); |
832 | acpi_disable_gpe(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | 759 | acpi_disable_gpe(NULL, ec->gpe); |
833 | return -ENODEV; | 760 | return -ENODEV; |
834 | } | 761 | } |
835 | } | 762 | } |
@@ -840,7 +767,7 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
840 | 767 | ||
841 | static void ec_remove_handlers(struct acpi_ec *ec) | 768 | static void ec_remove_handlers(struct acpi_ec *ec) |
842 | { | 769 | { |
843 | acpi_disable_gpe(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | 770 | acpi_disable_gpe(NULL, ec->gpe); |
844 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 771 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
845 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) | 772 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) |
846 | pr_err(PREFIX "failed to remove space handler\n"); | 773 | pr_err(PREFIX "failed to remove space handler\n"); |
@@ -884,7 +811,12 @@ static int acpi_ec_add(struct acpi_device *device) | |||
884 | if (!first_ec) | 811 | if (!first_ec) |
885 | first_ec = ec; | 812 | first_ec = ec; |
886 | device->driver_data = ec; | 813 | device->driver_data = ec; |
887 | acpi_ec_add_fs(device); | 814 | |
815 | WARN(!request_region(ec->data_addr, 1, "EC data"), | ||
816 | "Could not request EC data io port 0x%lx", ec->data_addr); | ||
817 | WARN(!request_region(ec->command_addr, 1, "EC cmd"), | ||
818 | "Could not request EC cmd io port 0x%lx", ec->command_addr); | ||
819 | |||
888 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | 820 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
889 | ec->gpe, ec->command_addr, ec->data_addr); | 821 | ec->gpe, ec->command_addr, ec->data_addr); |
890 | 822 | ||
@@ -911,7 +843,8 @@ static int acpi_ec_remove(struct acpi_device *device, int type) | |||
911 | kfree(handler); | 843 | kfree(handler); |
912 | } | 844 | } |
913 | mutex_unlock(&ec->lock); | 845 | mutex_unlock(&ec->lock); |
914 | acpi_ec_remove_fs(device); | 846 | release_region(ec->data_addr, 1); |
847 | release_region(ec->command_addr, 1); | ||
915 | device->driver_data = NULL; | 848 | device->driver_data = NULL; |
916 | if (ec == first_ec) | 849 | if (ec == first_ec) |
917 | first_ec = NULL; | 850 | first_ec = NULL; |
@@ -1078,22 +1011,6 @@ error: | |||
1078 | return -ENODEV; | 1011 | return -ENODEV; |
1079 | } | 1012 | } |
1080 | 1013 | ||
1081 | static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) | ||
1082 | { | ||
1083 | struct acpi_ec *ec = acpi_driver_data(device); | ||
1084 | /* Stop using the GPE, but keep it reference counted. */ | ||
1085 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); | ||
1086 | return 0; | ||
1087 | } | ||
1088 | |||
1089 | static int acpi_ec_resume(struct acpi_device *device) | ||
1090 | { | ||
1091 | struct acpi_ec *ec = acpi_driver_data(device); | ||
1092 | /* Enable the GPE again, but don't reference count it once more. */ | ||
1093 | acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); | ||
1094 | return 0; | ||
1095 | } | ||
1096 | |||
1097 | static struct acpi_driver acpi_ec_driver = { | 1014 | static struct acpi_driver acpi_ec_driver = { |
1098 | .name = "ec", | 1015 | .name = "ec", |
1099 | .class = ACPI_EC_CLASS, | 1016 | .class = ACPI_EC_CLASS, |
@@ -1101,8 +1018,6 @@ static struct acpi_driver acpi_ec_driver = { | |||
1101 | .ops = { | 1018 | .ops = { |
1102 | .add = acpi_ec_add, | 1019 | .add = acpi_ec_add, |
1103 | .remove = acpi_ec_remove, | 1020 | .remove = acpi_ec_remove, |
1104 | .suspend = acpi_ec_suspend, | ||
1105 | .resume = acpi_ec_resume, | ||
1106 | }, | 1021 | }, |
1107 | }; | 1022 | }; |
1108 | 1023 | ||
@@ -1110,16 +1025,10 @@ int __init acpi_ec_init(void) | |||
1110 | { | 1025 | { |
1111 | int result = 0; | 1026 | int result = 0; |
1112 | 1027 | ||
1113 | acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir); | ||
1114 | if (!acpi_ec_dir) | ||
1115 | return -ENODEV; | ||
1116 | |||
1117 | /* Now register the driver for the EC */ | 1028 | /* Now register the driver for the EC */ |
1118 | result = acpi_bus_register_driver(&acpi_ec_driver); | 1029 | result = acpi_bus_register_driver(&acpi_ec_driver); |
1119 | if (result < 0) { | 1030 | if (result < 0) |
1120 | remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir); | ||
1121 | return -ENODEV; | 1031 | return -ENODEV; |
1122 | } | ||
1123 | 1032 | ||
1124 | return result; | 1033 | return result; |
1125 | } | 1034 | } |
@@ -1130,9 +1039,6 @@ static void __exit acpi_ec_exit(void) | |||
1130 | { | 1039 | { |
1131 | 1040 | ||
1132 | acpi_bus_unregister_driver(&acpi_ec_driver); | 1041 | acpi_bus_unregister_driver(&acpi_ec_driver); |
1133 | |||
1134 | remove_proc_entry(ACPI_EC_CLASS, acpi_root_dir); | ||
1135 | |||
1136 | return; | 1042 | return; |
1137 | } | 1043 | } |
1138 | #endif /* 0 */ | 1044 | #endif /* 0 */ |
diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c new file mode 100644 index 000000000000..0e869b3f81ca --- /dev/null +++ b/drivers/acpi/ec_sys.c | |||
@@ -0,0 +1,160 @@ | |||
1 | /* | ||
2 | * ec_sys.c | ||
3 | * | ||
4 | * Copyright (C) 2010 SUSE Products GmbH/Novell | ||
5 | * Author: | ||
6 | * Thomas Renninger <trenn@suse.de> | ||
7 | * | ||
8 | * This work is licensed under the terms of the GNU GPL, version 2. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/acpi.h> | ||
13 | #include <linux/debugfs.h> | ||
14 | #include "internal.h" | ||
15 | |||
16 | MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>"); | ||
17 | MODULE_DESCRIPTION("ACPI EC sysfs access driver"); | ||
18 | MODULE_LICENSE("GPL"); | ||
19 | |||
20 | static bool write_support; | ||
21 | module_param(write_support, bool, 0644); | ||
22 | MODULE_PARM_DESC(write_support, "Dangerous, reboot and removal of battery may " | ||
23 | "be needed."); | ||
24 | |||
25 | #define EC_SPACE_SIZE 256 | ||
26 | |||
27 | struct sysdev_class acpi_ec_sysdev_class = { | ||
28 | .name = "ec", | ||
29 | }; | ||
30 | |||
31 | static struct dentry *acpi_ec_debugfs_dir; | ||
32 | |||
33 | static int acpi_ec_open_io(struct inode *i, struct file *f) | ||
34 | { | ||
35 | f->private_data = i->i_private; | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | static ssize_t acpi_ec_read_io(struct file *f, char __user *buf, | ||
40 | size_t count, loff_t *off) | ||
41 | { | ||
42 | /* Use this if support reading/writing multiple ECs exists in ec.c: | ||
43 | * struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private; | ||
44 | */ | ||
45 | unsigned int size = EC_SPACE_SIZE; | ||
46 | u8 *data = (u8 *) buf; | ||
47 | loff_t init_off = *off; | ||
48 | int err = 0; | ||
49 | |||
50 | if (*off >= size) | ||
51 | return 0; | ||
52 | if (*off + count >= size) { | ||
53 | size -= *off; | ||
54 | count = size; | ||
55 | } else | ||
56 | size = count; | ||
57 | |||
58 | while (size) { | ||
59 | err = ec_read(*off, &data[*off - init_off]); | ||
60 | if (err) | ||
61 | return err; | ||
62 | *off += 1; | ||
63 | size--; | ||
64 | } | ||
65 | return count; | ||
66 | } | ||
67 | |||
68 | static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf, | ||
69 | size_t count, loff_t *off) | ||
70 | { | ||
71 | /* Use this if support reading/writing multiple ECs exists in ec.c: | ||
72 | * struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private; | ||
73 | */ | ||
74 | |||
75 | unsigned int size = count; | ||
76 | loff_t init_off = *off; | ||
77 | u8 *data = (u8 *) buf; | ||
78 | int err = 0; | ||
79 | |||
80 | if (*off >= EC_SPACE_SIZE) | ||
81 | return 0; | ||
82 | if (*off + count >= EC_SPACE_SIZE) { | ||
83 | size = EC_SPACE_SIZE - *off; | ||
84 | count = size; | ||
85 | } | ||
86 | |||
87 | while (size) { | ||
88 | u8 byte_write = data[*off - init_off]; | ||
89 | err = ec_write(*off, byte_write); | ||
90 | if (err) | ||
91 | return err; | ||
92 | |||
93 | *off += 1; | ||
94 | size--; | ||
95 | } | ||
96 | return count; | ||
97 | } | ||
98 | |||
99 | static struct file_operations acpi_ec_io_ops = { | ||
100 | .owner = THIS_MODULE, | ||
101 | .open = acpi_ec_open_io, | ||
102 | .read = acpi_ec_read_io, | ||
103 | .write = acpi_ec_write_io, | ||
104 | }; | ||
105 | |||
106 | int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count) | ||
107 | { | ||
108 | struct dentry *dev_dir; | ||
109 | char name[64]; | ||
110 | mode_t mode = 0400; | ||
111 | |||
112 | if (ec_device_count == 0) { | ||
113 | acpi_ec_debugfs_dir = debugfs_create_dir("ec", NULL); | ||
114 | if (!acpi_ec_debugfs_dir) | ||
115 | return -ENOMEM; | ||
116 | } | ||
117 | |||
118 | sprintf(name, "ec%u", ec_device_count); | ||
119 | dev_dir = debugfs_create_dir(name, acpi_ec_debugfs_dir); | ||
120 | if (!dev_dir) { | ||
121 | if (ec_device_count != 0) | ||
122 | goto error; | ||
123 | return -ENOMEM; | ||
124 | } | ||
125 | |||
126 | if (!debugfs_create_x32("gpe", 0444, dev_dir, (u32 *)&first_ec->gpe)) | ||
127 | goto error; | ||
128 | if (!debugfs_create_bool("use_global_lock", 0444, dev_dir, | ||
129 | (u32 *)&first_ec->global_lock)) | ||
130 | goto error; | ||
131 | |||
132 | if (write_support) | ||
133 | mode = 0600; | ||
134 | if (!debugfs_create_file("io", mode, dev_dir, ec, &acpi_ec_io_ops)) | ||
135 | goto error; | ||
136 | |||
137 | return 0; | ||
138 | |||
139 | error: | ||
140 | debugfs_remove_recursive(acpi_ec_debugfs_dir); | ||
141 | return -ENOMEM; | ||
142 | } | ||
143 | |||
144 | static int __init acpi_ec_sys_init(void) | ||
145 | { | ||
146 | int err = 0; | ||
147 | if (first_ec) | ||
148 | err = acpi_ec_add_debugfs(first_ec, 0); | ||
149 | else | ||
150 | err = -ENODEV; | ||
151 | return err; | ||
152 | } | ||
153 | |||
154 | static void __exit acpi_ec_sys_exit(void) | ||
155 | { | ||
156 | debugfs_remove_recursive(acpi_ec_debugfs_dir); | ||
157 | } | ||
158 | |||
159 | module_init(acpi_ec_sys_init); | ||
160 | module_exit(acpi_ec_sys_exit); | ||
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index acf2ab249842..8a3b840c0bb2 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -347,7 +347,6 @@ static int __init acpi_fan_init(void) | |||
347 | { | 347 | { |
348 | int result = 0; | 348 | int result = 0; |
349 | 349 | ||
350 | |||
351 | #ifdef CONFIG_ACPI_PROCFS | 350 | #ifdef CONFIG_ACPI_PROCFS |
352 | acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir); | 351 | acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir); |
353 | if (!acpi_fan_dir) | 352 | if (!acpi_fan_dir) |
@@ -356,7 +355,9 @@ static int __init acpi_fan_init(void) | |||
356 | 355 | ||
357 | result = acpi_bus_register_driver(&acpi_fan_driver); | 356 | result = acpi_bus_register_driver(&acpi_fan_driver); |
358 | if (result < 0) { | 357 | if (result < 0) { |
358 | #ifdef CONFIG_ACPI_PROCFS | ||
359 | remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); | 359 | remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); |
360 | #endif | ||
360 | return -ENODEV; | 361 | return -ENODEV; |
361 | } | 362 | } |
362 | 363 | ||
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 e28411367239..a212bfeddf8c 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -18,16 +18,21 @@ | |||
18 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | 18 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #ifndef _ACPI_INTERNAL_H_ | ||
22 | #define _ACPI_INTERNAL_H_ | ||
23 | |||
24 | #include <linux/sysdev.h> | ||
25 | |||
21 | #define PREFIX "ACPI: " | 26 | #define PREFIX "ACPI: " |
22 | 27 | ||
23 | int init_acpi_device_notify(void); | 28 | int init_acpi_device_notify(void); |
24 | int acpi_scan_init(void); | 29 | int acpi_scan_init(void); |
25 | int acpi_system_init(void); | 30 | int acpi_sysfs_init(void); |
26 | 31 | ||
27 | #ifdef CONFIG_ACPI_DEBUG | 32 | #ifdef CONFIG_DEBUG_FS |
28 | int acpi_debug_init(void); | 33 | int acpi_debugfs_init(void); |
29 | #else | 34 | #else |
30 | static inline int acpi_debug_init(void) { return 0; } | 35 | static inline int acpi_debugfs_init(void) { return 0; } |
31 | #endif | 36 | #endif |
32 | 37 | ||
33 | /* -------------------------------------------------------------------------- | 38 | /* -------------------------------------------------------------------------- |
@@ -46,11 +51,29 @@ void acpi_early_processor_set_pdc(void); | |||
46 | /* -------------------------------------------------------------------------- | 51 | /* -------------------------------------------------------------------------- |
47 | Embedded Controller | 52 | Embedded Controller |
48 | -------------------------------------------------------------------------- */ | 53 | -------------------------------------------------------------------------- */ |
54 | struct acpi_ec { | ||
55 | acpi_handle handle; | ||
56 | unsigned long gpe; | ||
57 | unsigned long command_addr; | ||
58 | unsigned long data_addr; | ||
59 | unsigned long global_lock; | ||
60 | unsigned long flags; | ||
61 | struct mutex lock; | ||
62 | wait_queue_head_t wait; | ||
63 | struct list_head list; | ||
64 | struct transaction *curr; | ||
65 | spinlock_t curr_lock; | ||
66 | struct sys_device sysdev; | ||
67 | }; | ||
68 | |||
69 | extern struct acpi_ec *first_ec; | ||
70 | |||
49 | int acpi_ec_init(void); | 71 | int acpi_ec_init(void); |
50 | int acpi_ec_ecdt_probe(void); | 72 | int acpi_ec_ecdt_probe(void); |
51 | int acpi_boot_ec_enable(void); | 73 | int acpi_boot_ec_enable(void); |
52 | void acpi_ec_suspend_transactions(void); | 74 | void acpi_ec_block_transactions(void); |
53 | void acpi_ec_resume_transactions(void); | 75 | void acpi_ec_unblock_transactions(void); |
76 | void acpi_ec_unblock_transactions_early(void); | ||
54 | 77 | ||
55 | /*-------------------------------------------------------------------------- | 78 | /*-------------------------------------------------------------------------- |
56 | Suspend/Resume | 79 | Suspend/Resume |
@@ -62,3 +85,5 @@ int acpi_sleep_proc_init(void); | |||
62 | #else | 85 | #else |
63 | static inline int acpi_sleep_proc_init(void) { return 0; } | 86 | static inline int acpi_sleep_proc_init(void) { return 0; } |
64 | #endif | 87 | #endif |
88 | |||
89 | #endif /* _ACPI_INTERNAL_H_ */ | ||
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index b0337d314604..5718566e00f9 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -255,12 +255,10 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header, | |||
255 | 255 | ||
256 | static int __init acpi_parse_srat(struct acpi_table_header *table) | 256 | static int __init acpi_parse_srat(struct acpi_table_header *table) |
257 | { | 257 | { |
258 | struct acpi_table_srat *srat; | ||
259 | |||
260 | if (!table) | 258 | if (!table) |
261 | return -EINVAL; | 259 | return -EINVAL; |
262 | 260 | ||
263 | srat = (struct acpi_table_srat *)table; | 261 | /* Real work done in acpi_table_parse_srat below. */ |
264 | 262 | ||
265 | return 0; | 263 | return 0; |
266 | } | 264 | } |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 78418ce4fc78..65b25a303b86 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -141,15 +141,14 @@ static struct osi_linux { | |||
141 | static void __init acpi_request_region (struct acpi_generic_address *addr, | 141 | static void __init acpi_request_region (struct acpi_generic_address *addr, |
142 | unsigned int length, char *desc) | 142 | unsigned int length, char *desc) |
143 | { | 143 | { |
144 | struct resource *res; | ||
145 | |||
146 | if (!addr->address || !length) | 144 | if (!addr->address || !length) |
147 | return; | 145 | return; |
148 | 146 | ||
147 | /* Resources are never freed */ | ||
149 | if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO) | 148 | if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO) |
150 | res = request_region(addr->address, length, desc); | 149 | request_region(addr->address, length, desc); |
151 | else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) | 150 | else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) |
152 | res = request_mem_region(addr->address, length, desc); | 151 | request_mem_region(addr->address, length, desc); |
153 | } | 152 | } |
154 | 153 | ||
155 | static int __init acpi_reserve_resources(void) | 154 | static int __init acpi_reserve_resources(void) |
@@ -191,36 +190,11 @@ acpi_status __init acpi_os_initialize(void) | |||
191 | return AE_OK; | 190 | return AE_OK; |
192 | } | 191 | } |
193 | 192 | ||
194 | static void bind_to_cpu0(struct work_struct *work) | ||
195 | { | ||
196 | set_cpus_allowed_ptr(current, cpumask_of(0)); | ||
197 | kfree(work); | ||
198 | } | ||
199 | |||
200 | static void bind_workqueue(struct workqueue_struct *wq) | ||
201 | { | ||
202 | struct work_struct *work; | ||
203 | |||
204 | work = kzalloc(sizeof(struct work_struct), GFP_KERNEL); | ||
205 | INIT_WORK(work, bind_to_cpu0); | ||
206 | queue_work(wq, work); | ||
207 | } | ||
208 | |||
209 | acpi_status acpi_os_initialize1(void) | 193 | acpi_status acpi_os_initialize1(void) |
210 | { | 194 | { |
211 | /* | 195 | kacpid_wq = create_workqueue("kacpid"); |
212 | * On some machines, a software-initiated SMI causes corruption unless | 196 | kacpi_notify_wq = create_workqueue("kacpi_notify"); |
213 | * the SMI runs on CPU 0. An SMI can be initiated by any AML, but | 197 | kacpi_hotplug_wq = create_workqueue("kacpi_hotplug"); |
214 | * typically it's done in GPE-related methods that are run via | ||
215 | * workqueues, so we can avoid the known corruption cases by binding | ||
216 | * the workqueues to CPU 0. | ||
217 | */ | ||
218 | kacpid_wq = create_singlethread_workqueue("kacpid"); | ||
219 | bind_workqueue(kacpid_wq); | ||
220 | kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); | ||
221 | bind_workqueue(kacpi_notify_wq); | ||
222 | kacpi_hotplug_wq = create_singlethread_workqueue("kacpi_hotplug"); | ||
223 | bind_workqueue(kacpi_hotplug_wq); | ||
224 | BUG_ON(!kacpid_wq); | 198 | BUG_ON(!kacpid_wq); |
225 | BUG_ON(!kacpi_notify_wq); | 199 | BUG_ON(!kacpi_notify_wq); |
226 | BUG_ON(!kacpi_hotplug_wq); | 200 | BUG_ON(!kacpi_hotplug_wq); |
@@ -766,7 +740,14 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
766 | else | 740 | else |
767 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | 741 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
768 | 742 | ||
769 | ret = queue_work(queue, &dpc->work); | 743 | /* |
744 | * On some machines, a software-initiated SMI causes corruption unless | ||
745 | * the SMI runs on CPU 0. An SMI can be initiated by any AML, but | ||
746 | * typically it's done in GPE-related methods that are run via | ||
747 | * workqueues, so we can avoid the known corruption cases by always | ||
748 | * queueing on CPU 0. | ||
749 | */ | ||
750 | ret = queue_work_on(0, queue, &dpc->work); | ||
770 | 751 | ||
771 | if (!ret) { | 752 | if (!ret) { |
772 | printk(KERN_ERR PREFIX | 753 | printk(KERN_ERR PREFIX |
@@ -1064,26 +1045,6 @@ static int __init acpi_serialize_setup(char *str) | |||
1064 | 1045 | ||
1065 | __setup("acpi_serialize", acpi_serialize_setup); | 1046 | __setup("acpi_serialize", acpi_serialize_setup); |
1066 | 1047 | ||
1067 | /* | ||
1068 | * Wake and Run-Time GPES are expected to be separate. | ||
1069 | * We disable wake-GPEs at run-time to prevent spurious | ||
1070 | * interrupts. | ||
1071 | * | ||
1072 | * However, if a system exists that shares Wake and | ||
1073 | * Run-time events on the same GPE this flag is available | ||
1074 | * to tell Linux to keep the wake-time GPEs enabled at run-time. | ||
1075 | */ | ||
1076 | static int __init acpi_wake_gpes_always_on_setup(char *str) | ||
1077 | { | ||
1078 | printk(KERN_INFO PREFIX "wake GPEs not disabled\n"); | ||
1079 | |||
1080 | acpi_gbl_leave_wake_gpes_disabled = FALSE; | ||
1081 | |||
1082 | return 1; | ||
1083 | } | ||
1084 | |||
1085 | __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup); | ||
1086 | |||
1087 | /* Check of resource interference between native drivers and ACPI | 1048 | /* Check of resource interference between native drivers and ACPI |
1088 | * OperationRegions (SystemIO and System Memory only). | 1049 | * OperationRegions (SystemIO and System Memory only). |
1089 | * IO ports and memory declared in ACPI might be used by the ACPI subsystem | 1050 | * IO ports and memory declared in ACPI might be used by the ACPI subsystem |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 4eac59393edc..1f67057af2a5 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/pm_runtime.h> | 33 | #include <linux/pm_runtime.h> |
34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
35 | #include <linux/pci-acpi.h> | 35 | #include <linux/pci-acpi.h> |
36 | #include <linux/pci-aspm.h> | ||
36 | #include <linux/acpi.h> | 37 | #include <linux/acpi.h> |
37 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
38 | #include <acpi/acpi_bus.h> | 39 | #include <acpi/acpi_bus.h> |
@@ -543,6 +544,14 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
543 | if (flags != base_flags) | 544 | if (flags != base_flags) |
544 | acpi_pci_osc_support(root, flags); | 545 | acpi_pci_osc_support(root, flags); |
545 | 546 | ||
547 | status = acpi_pci_osc_control_set(root->device->handle, | ||
548 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
549 | |||
550 | if (ACPI_FAILURE(status)) { | ||
551 | printk(KERN_INFO "Unable to assume PCIe control: Disabling ASPM\n"); | ||
552 | pcie_no_aspm(); | ||
553 | } | ||
554 | |||
546 | pci_acpi_add_bus_pm_notifier(device, root->bus); | 555 | pci_acpi_add_bus_pm_notifier(device, root->bus); |
547 | if (device->wakeup.flags.run_wake) | 556 | if (device->wakeup.flags.run_wake) |
548 | device_set_run_wake(root->bus->bridge, true); | 557 | device_set_run_wake(root->bus->bridge, true); |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index f74d3b31e5c9..844c155aeb0f 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -40,8 +40,6 @@ | |||
40 | #include <linux/init.h> | 40 | #include <linux/init.h> |
41 | #include <linux/types.h> | 41 | #include <linux/types.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/proc_fs.h> | ||
44 | #include <linux/seq_file.h> | ||
45 | #include <acpi/acpi_bus.h> | 43 | #include <acpi/acpi_bus.h> |
46 | #include <acpi/acpi_drivers.h> | 44 | #include <acpi/acpi_drivers.h> |
47 | #include "sleep.h" | 45 | #include "sleep.h" |
@@ -64,7 +62,6 @@ module_param_named(power_nocheck, acpi_power_nocheck, bool, 000); | |||
64 | static int acpi_power_add(struct acpi_device *device); | 62 | static int acpi_power_add(struct acpi_device *device); |
65 | static int acpi_power_remove(struct acpi_device *device, int type); | 63 | static int acpi_power_remove(struct acpi_device *device, int type); |
66 | static int acpi_power_resume(struct acpi_device *device); | 64 | static int acpi_power_resume(struct acpi_device *device); |
67 | static int acpi_power_open_fs(struct inode *inode, struct file *file); | ||
68 | 65 | ||
69 | static const struct acpi_device_id power_device_ids[] = { | 66 | static const struct acpi_device_id power_device_ids[] = { |
70 | {ACPI_POWER_HID, 0}, | 67 | {ACPI_POWER_HID, 0}, |
@@ -99,14 +96,6 @@ struct acpi_power_resource { | |||
99 | 96 | ||
100 | static struct list_head acpi_power_resource_list; | 97 | static struct list_head acpi_power_resource_list; |
101 | 98 | ||
102 | static const struct file_operations acpi_power_fops = { | ||
103 | .owner = THIS_MODULE, | ||
104 | .open = acpi_power_open_fs, | ||
105 | .read = seq_read, | ||
106 | .llseek = seq_lseek, | ||
107 | .release = single_release, | ||
108 | }; | ||
109 | |||
110 | /* -------------------------------------------------------------------------- | 99 | /* -------------------------------------------------------------------------- |
111 | Power Resource Management | 100 | Power Resource Management |
112 | -------------------------------------------------------------------------- */ | 101 | -------------------------------------------------------------------------- */ |
@@ -255,7 +244,6 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) | |||
255 | struct list_head *node, *next; | 244 | struct list_head *node, *next; |
256 | struct acpi_power_reference *ref; | 245 | struct acpi_power_reference *ref; |
257 | 246 | ||
258 | |||
259 | result = acpi_power_get_context(handle, &resource); | 247 | result = acpi_power_get_context(handle, &resource); |
260 | if (result) | 248 | if (result) |
261 | return result; | 249 | return result; |
@@ -542,102 +530,6 @@ int acpi_power_transition(struct acpi_device *device, int state) | |||
542 | } | 530 | } |
543 | 531 | ||
544 | /* -------------------------------------------------------------------------- | 532 | /* -------------------------------------------------------------------------- |
545 | FS Interface (/proc) | ||
546 | -------------------------------------------------------------------------- */ | ||
547 | |||
548 | static struct proc_dir_entry *acpi_power_dir; | ||
549 | |||
550 | static int acpi_power_seq_show(struct seq_file *seq, void *offset) | ||
551 | { | ||
552 | int count = 0; | ||
553 | int result = 0, state; | ||
554 | struct acpi_power_resource *resource = NULL; | ||
555 | struct list_head *node, *next; | ||
556 | struct acpi_power_reference *ref; | ||
557 | |||
558 | |||
559 | resource = seq->private; | ||
560 | |||
561 | if (!resource) | ||
562 | goto end; | ||
563 | |||
564 | result = acpi_power_get_state(resource->device->handle, &state); | ||
565 | if (result) | ||
566 | goto end; | ||
567 | |||
568 | seq_puts(seq, "state: "); | ||
569 | switch (state) { | ||
570 | case ACPI_POWER_RESOURCE_STATE_ON: | ||
571 | seq_puts(seq, "on\n"); | ||
572 | break; | ||
573 | case ACPI_POWER_RESOURCE_STATE_OFF: | ||
574 | seq_puts(seq, "off\n"); | ||
575 | break; | ||
576 | default: | ||
577 | seq_puts(seq, "unknown\n"); | ||
578 | break; | ||
579 | } | ||
580 | |||
581 | mutex_lock(&resource->resource_lock); | ||
582 | list_for_each_safe(node, next, &resource->reference) { | ||
583 | ref = container_of(node, struct acpi_power_reference, node); | ||
584 | count++; | ||
585 | } | ||
586 | mutex_unlock(&resource->resource_lock); | ||
587 | |||
588 | seq_printf(seq, "system level: S%d\n" | ||
589 | "order: %d\n" | ||
590 | "reference count: %d\n", | ||
591 | resource->system_level, | ||
592 | resource->order, count); | ||
593 | |||
594 | end: | ||
595 | return 0; | ||
596 | } | ||
597 | |||
598 | static int acpi_power_open_fs(struct inode *inode, struct file *file) | ||
599 | { | ||
600 | return single_open(file, acpi_power_seq_show, PDE(inode)->data); | ||
601 | } | ||
602 | |||
603 | static int acpi_power_add_fs(struct acpi_device *device) | ||
604 | { | ||
605 | struct proc_dir_entry *entry = NULL; | ||
606 | |||
607 | |||
608 | if (!device) | ||
609 | return -EINVAL; | ||
610 | |||
611 | if (!acpi_device_dir(device)) { | ||
612 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
613 | acpi_power_dir); | ||
614 | if (!acpi_device_dir(device)) | ||
615 | return -ENODEV; | ||
616 | } | ||
617 | |||
618 | /* 'status' [R] */ | ||
619 | entry = proc_create_data(ACPI_POWER_FILE_STATUS, | ||
620 | S_IRUGO, acpi_device_dir(device), | ||
621 | &acpi_power_fops, acpi_driver_data(device)); | ||
622 | if (!entry) | ||
623 | return -EIO; | ||
624 | return 0; | ||
625 | } | ||
626 | |||
627 | static int acpi_power_remove_fs(struct acpi_device *device) | ||
628 | { | ||
629 | |||
630 | if (acpi_device_dir(device)) { | ||
631 | remove_proc_entry(ACPI_POWER_FILE_STATUS, | ||
632 | acpi_device_dir(device)); | ||
633 | remove_proc_entry(acpi_device_bid(device), acpi_power_dir); | ||
634 | acpi_device_dir(device) = NULL; | ||
635 | } | ||
636 | |||
637 | return 0; | ||
638 | } | ||
639 | |||
640 | /* -------------------------------------------------------------------------- | ||
641 | Driver Interface | 533 | Driver Interface |
642 | -------------------------------------------------------------------------- */ | 534 | -------------------------------------------------------------------------- */ |
643 | 535 | ||
@@ -690,10 +582,6 @@ static int acpi_power_add(struct acpi_device *device) | |||
690 | break; | 582 | break; |
691 | } | 583 | } |
692 | 584 | ||
693 | result = acpi_power_add_fs(device); | ||
694 | if (result) | ||
695 | goto end; | ||
696 | |||
697 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), | 585 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), |
698 | acpi_device_bid(device), state ? "on" : "off"); | 586 | acpi_device_bid(device), state ? "on" : "off"); |
699 | 587 | ||
@@ -715,8 +603,6 @@ static int acpi_power_remove(struct acpi_device *device, int type) | |||
715 | 603 | ||
716 | resource = acpi_driver_data(device); | 604 | resource = acpi_driver_data(device); |
717 | 605 | ||
718 | acpi_power_remove_fs(device); | ||
719 | |||
720 | mutex_lock(&resource->resource_lock); | 606 | mutex_lock(&resource->resource_lock); |
721 | list_for_each_safe(node, next, &resource->reference) { | 607 | list_for_each_safe(node, next, &resource->reference) { |
722 | struct acpi_power_reference *ref = container_of(node, struct acpi_power_reference, node); | 608 | struct acpi_power_reference *ref = container_of(node, struct acpi_power_reference, node); |
@@ -760,19 +646,6 @@ static int acpi_power_resume(struct acpi_device *device) | |||
760 | 646 | ||
761 | int __init acpi_power_init(void) | 647 | int __init acpi_power_init(void) |
762 | { | 648 | { |
763 | int result = 0; | ||
764 | |||
765 | INIT_LIST_HEAD(&acpi_power_resource_list); | 649 | INIT_LIST_HEAD(&acpi_power_resource_list); |
766 | 650 | return acpi_bus_register_driver(&acpi_power_driver); | |
767 | acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir); | ||
768 | if (!acpi_power_dir) | ||
769 | return -ENODEV; | ||
770 | |||
771 | result = acpi_bus_register_driver(&acpi_power_driver); | ||
772 | if (result < 0) { | ||
773 | remove_proc_entry(ACPI_POWER_CLASS, acpi_root_dir); | ||
774 | return -ENODEV; | ||
775 | } | ||
776 | |||
777 | return 0; | ||
778 | } | 651 | } |
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 1ac678d2c51c..afad67769db6 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
@@ -17,64 +17,11 @@ | |||
17 | 17 | ||
18 | /* | 18 | /* |
19 | * this file provides support for: | 19 | * this file provides support for: |
20 | * /proc/acpi/sleep | ||
21 | * /proc/acpi/alarm | 20 | * /proc/acpi/alarm |
22 | * /proc/acpi/wakeup | 21 | * /proc/acpi/wakeup |
23 | */ | 22 | */ |
24 | 23 | ||
25 | ACPI_MODULE_NAME("sleep") | 24 | ACPI_MODULE_NAME("sleep") |
26 | #ifdef CONFIG_ACPI_PROCFS | ||
27 | static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset) | ||
28 | { | ||
29 | int i; | ||
30 | |||
31 | for (i = 0; i <= ACPI_STATE_S5; i++) { | ||
32 | if (sleep_states[i]) { | ||
33 | seq_printf(seq, "S%d ", i); | ||
34 | } | ||
35 | } | ||
36 | |||
37 | seq_puts(seq, "\n"); | ||
38 | |||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static int acpi_system_sleep_open_fs(struct inode *inode, struct file *file) | ||
43 | { | ||
44 | return single_open(file, acpi_system_sleep_seq_show, PDE(inode)->data); | ||
45 | } | ||
46 | |||
47 | static ssize_t | ||
48 | acpi_system_write_sleep(struct file *file, | ||
49 | const char __user * buffer, size_t count, loff_t * ppos) | ||
50 | { | ||
51 | char str[12]; | ||
52 | u32 state = 0; | ||
53 | int error = 0; | ||
54 | |||
55 | if (count > sizeof(str) - 1) | ||
56 | goto Done; | ||
57 | memset(str, 0, sizeof(str)); | ||
58 | if (copy_from_user(str, buffer, count)) | ||
59 | return -EFAULT; | ||
60 | |||
61 | /* Check for S4 bios request */ | ||
62 | if (!strcmp(str, "4b")) { | ||
63 | error = acpi_suspend(4); | ||
64 | goto Done; | ||
65 | } | ||
66 | state = simple_strtoul(str, NULL, 0); | ||
67 | #ifdef CONFIG_HIBERNATION | ||
68 | if (state == 4) { | ||
69 | error = hibernate(); | ||
70 | goto Done; | ||
71 | } | ||
72 | #endif | ||
73 | error = acpi_suspend(state); | ||
74 | Done: | ||
75 | return error ? error : count; | ||
76 | } | ||
77 | #endif /* CONFIG_ACPI_PROCFS */ | ||
78 | 25 | ||
79 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86) | 26 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86) |
80 | /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ | 27 | /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ |
@@ -463,17 +410,6 @@ static const struct file_operations acpi_system_wakeup_device_fops = { | |||
463 | .release = single_release, | 410 | .release = single_release, |
464 | }; | 411 | }; |
465 | 412 | ||
466 | #ifdef CONFIG_ACPI_PROCFS | ||
467 | static const struct file_operations acpi_system_sleep_fops = { | ||
468 | .owner = THIS_MODULE, | ||
469 | .open = acpi_system_sleep_open_fs, | ||
470 | .read = seq_read, | ||
471 | .write = acpi_system_write_sleep, | ||
472 | .llseek = seq_lseek, | ||
473 | .release = single_release, | ||
474 | }; | ||
475 | #endif /* CONFIG_ACPI_PROCFS */ | ||
476 | |||
477 | #ifdef HAVE_ACPI_LEGACY_ALARM | 413 | #ifdef HAVE_ACPI_LEGACY_ALARM |
478 | static const struct file_operations acpi_system_alarm_fops = { | 414 | static const struct file_operations acpi_system_alarm_fops = { |
479 | .owner = THIS_MODULE, | 415 | .owner = THIS_MODULE, |
@@ -495,12 +431,6 @@ static u32 rtc_handler(void *context) | |||
495 | 431 | ||
496 | int __init acpi_sleep_proc_init(void) | 432 | int __init acpi_sleep_proc_init(void) |
497 | { | 433 | { |
498 | #ifdef CONFIG_ACPI_PROCFS | ||
499 | /* 'sleep' [R/W] */ | ||
500 | proc_create("sleep", S_IFREG | S_IRUGO | S_IWUSR, | ||
501 | acpi_root_dir, &acpi_system_sleep_fops); | ||
502 | #endif /* CONFIG_ACPI_PROCFS */ | ||
503 | |||
504 | #ifdef HAVE_ACPI_LEGACY_ALARM | 434 | #ifdef HAVE_ACPI_LEGACY_ALARM |
505 | /* 'alarm' [R/W] */ | 435 | /* 'alarm' [R/W] */ |
506 | proc_create("alarm", S_IFREG | S_IRUGO | S_IWUSR, | 436 | proc_create("alarm", S_IFREG | S_IRUGO | S_IWUSR, |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 51284351418f..e9699aaed109 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -223,7 +223,7 @@ static bool processor_physically_present(acpi_handle handle) | |||
223 | type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; | 223 | type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; |
224 | cpuid = acpi_get_cpuid(handle, type, acpi_id); | 224 | cpuid = acpi_get_cpuid(handle, type, acpi_id); |
225 | 225 | ||
226 | if (cpuid == -1) | 226 | if ((cpuid == -1) && (num_possible_cpus() > 1)) |
227 | return false; | 227 | return false; |
228 | 228 | ||
229 | return true; | 229 | return true; |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index b1034a9ada4e..156021892389 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -83,9 +83,6 @@ MODULE_LICENSE("GPL"); | |||
83 | 83 | ||
84 | static int acpi_processor_add(struct acpi_device *device); | 84 | static int acpi_processor_add(struct acpi_device *device); |
85 | static int acpi_processor_remove(struct acpi_device *device, int type); | 85 | static int acpi_processor_remove(struct acpi_device *device, int type); |
86 | #ifdef CONFIG_ACPI_PROCFS | ||
87 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); | ||
88 | #endif | ||
89 | static void acpi_processor_notify(struct acpi_device *device, u32 event); | 86 | static void acpi_processor_notify(struct acpi_device *device, u32 event); |
90 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); | 87 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); |
91 | static int acpi_processor_handle_eject(struct acpi_processor *pr); | 88 | static int acpi_processor_handle_eject(struct acpi_processor *pr); |
@@ -113,15 +110,6 @@ static struct acpi_driver acpi_processor_driver = { | |||
113 | 110 | ||
114 | #define INSTALL_NOTIFY_HANDLER 1 | 111 | #define INSTALL_NOTIFY_HANDLER 1 |
115 | #define UNINSTALL_NOTIFY_HANDLER 2 | 112 | #define UNINSTALL_NOTIFY_HANDLER 2 |
116 | #ifdef CONFIG_ACPI_PROCFS | ||
117 | static const struct file_operations acpi_processor_info_fops = { | ||
118 | .owner = THIS_MODULE, | ||
119 | .open = acpi_processor_info_open_fs, | ||
120 | .read = seq_read, | ||
121 | .llseek = seq_lseek, | ||
122 | .release = single_release, | ||
123 | }; | ||
124 | #endif | ||
125 | 113 | ||
126 | DEFINE_PER_CPU(struct acpi_processor *, processors); | 114 | DEFINE_PER_CPU(struct acpi_processor *, processors); |
127 | EXPORT_PER_CPU_SYMBOL(processors); | 115 | EXPORT_PER_CPU_SYMBOL(processors); |
@@ -256,44 +244,8 @@ static int acpi_processor_errata(struct acpi_processor *pr) | |||
256 | return result; | 244 | return result; |
257 | } | 245 | } |
258 | 246 | ||
259 | /* -------------------------------------------------------------------------- | ||
260 | FS Interface (/proc) | ||
261 | -------------------------------------------------------------------------- */ | ||
262 | |||
263 | #ifdef CONFIG_ACPI_PROCFS | ||
264 | static struct proc_dir_entry *acpi_processor_dir = NULL; | 247 | static struct proc_dir_entry *acpi_processor_dir = NULL; |
265 | 248 | ||
266 | static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) | ||
267 | { | ||
268 | struct acpi_processor *pr = seq->private; | ||
269 | |||
270 | |||
271 | if (!pr) | ||
272 | goto end; | ||
273 | |||
274 | seq_printf(seq, "processor id: %d\n" | ||
275 | "acpi id: %d\n" | ||
276 | "bus mastering control: %s\n" | ||
277 | "power management: %s\n" | ||
278 | "throttling control: %s\n" | ||
279 | "limit interface: %s\n", | ||
280 | pr->id, | ||
281 | pr->acpi_id, | ||
282 | pr->flags.bm_control ? "yes" : "no", | ||
283 | pr->flags.power ? "yes" : "no", | ||
284 | pr->flags.throttling ? "yes" : "no", | ||
285 | pr->flags.limit ? "yes" : "no"); | ||
286 | |||
287 | end: | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file) | ||
292 | { | ||
293 | return single_open(file, acpi_processor_info_seq_show, | ||
294 | PDE(inode)->data); | ||
295 | } | ||
296 | |||
297 | static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) | 249 | static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) |
298 | { | 250 | { |
299 | struct proc_dir_entry *entry = NULL; | 251 | struct proc_dir_entry *entry = NULL; |
@@ -306,14 +258,6 @@ static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) | |||
306 | return -ENODEV; | 258 | return -ENODEV; |
307 | } | 259 | } |
308 | 260 | ||
309 | /* 'info' [R] */ | ||
310 | entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO, | ||
311 | S_IRUGO, acpi_device_dir(device), | ||
312 | &acpi_processor_info_fops, | ||
313 | acpi_driver_data(device)); | ||
314 | if (!entry) | ||
315 | return -EIO; | ||
316 | |||
317 | /* 'throttling' [R/W] */ | 261 | /* 'throttling' [R/W] */ |
318 | entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING, | 262 | entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING, |
319 | S_IFREG | S_IRUGO | S_IWUSR, | 263 | S_IFREG | S_IRUGO | S_IWUSR, |
@@ -322,43 +266,20 @@ static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) | |||
322 | acpi_driver_data(device)); | 266 | acpi_driver_data(device)); |
323 | if (!entry) | 267 | if (!entry) |
324 | return -EIO; | 268 | return -EIO; |
325 | |||
326 | /* 'limit' [R/W] */ | ||
327 | entry = proc_create_data(ACPI_PROCESSOR_FILE_LIMIT, | ||
328 | S_IFREG | S_IRUGO | S_IWUSR, | ||
329 | acpi_device_dir(device), | ||
330 | &acpi_processor_limit_fops, | ||
331 | acpi_driver_data(device)); | ||
332 | if (!entry) | ||
333 | return -EIO; | ||
334 | return 0; | 269 | return 0; |
335 | } | 270 | } |
336 | static int acpi_processor_remove_fs(struct acpi_device *device) | 271 | static int acpi_processor_remove_fs(struct acpi_device *device) |
337 | { | 272 | { |
338 | 273 | ||
339 | if (acpi_device_dir(device)) { | 274 | if (acpi_device_dir(device)) { |
340 | remove_proc_entry(ACPI_PROCESSOR_FILE_INFO, | ||
341 | acpi_device_dir(device)); | ||
342 | remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, | 275 | remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, |
343 | acpi_device_dir(device)); | 276 | acpi_device_dir(device)); |
344 | remove_proc_entry(ACPI_PROCESSOR_FILE_LIMIT, | ||
345 | acpi_device_dir(device)); | ||
346 | remove_proc_entry(acpi_device_bid(device), acpi_processor_dir); | 277 | remove_proc_entry(acpi_device_bid(device), acpi_processor_dir); |
347 | acpi_device_dir(device) = NULL; | 278 | acpi_device_dir(device) = NULL; |
348 | } | 279 | } |
349 | 280 | ||
350 | return 0; | 281 | return 0; |
351 | } | 282 | } |
352 | #else | ||
353 | static inline int acpi_processor_add_fs(struct acpi_device *device) | ||
354 | { | ||
355 | return 0; | ||
356 | } | ||
357 | static inline int acpi_processor_remove_fs(struct acpi_device *device) | ||
358 | { | ||
359 | return 0; | ||
360 | } | ||
361 | #endif | ||
362 | 283 | ||
363 | /* -------------------------------------------------------------------------- | 284 | /* -------------------------------------------------------------------------- |
364 | Driver Interface | 285 | Driver Interface |
@@ -581,6 +502,11 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) | |||
581 | return 0; | 502 | return 0; |
582 | } | 503 | } |
583 | 504 | ||
505 | #ifdef CONFIG_SMP | ||
506 | if (pr->id >= setup_max_cpus && pr->id != 0) | ||
507 | return 0; | ||
508 | #endif | ||
509 | |||
584 | BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); | 510 | BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); |
585 | 511 | ||
586 | /* | 512 | /* |
@@ -916,11 +842,9 @@ static int __init acpi_processor_init(void) | |||
916 | 842 | ||
917 | memset(&errata, 0, sizeof(errata)); | 843 | memset(&errata, 0, sizeof(errata)); |
918 | 844 | ||
919 | #ifdef CONFIG_ACPI_PROCFS | ||
920 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 845 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
921 | if (!acpi_processor_dir) | 846 | if (!acpi_processor_dir) |
922 | return -ENOMEM; | 847 | return -ENOMEM; |
923 | #endif | ||
924 | 848 | ||
925 | if (!cpuidle_register_driver(&acpi_idle_driver)) { | 849 | if (!cpuidle_register_driver(&acpi_idle_driver)) { |
926 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", | 850 | printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", |
@@ -947,9 +871,7 @@ static int __init acpi_processor_init(void) | |||
947 | out_cpuidle: | 871 | out_cpuidle: |
948 | cpuidle_unregister_driver(&acpi_idle_driver); | 872 | cpuidle_unregister_driver(&acpi_idle_driver); |
949 | 873 | ||
950 | #ifdef CONFIG_ACPI_PROCFS | ||
951 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 874 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
952 | #endif | ||
953 | 875 | ||
954 | return result; | 876 | return result; |
955 | } | 877 | } |
@@ -969,9 +891,7 @@ static void __exit acpi_processor_exit(void) | |||
969 | 891 | ||
970 | cpuidle_unregister_driver(&acpi_idle_driver); | 892 | cpuidle_unregister_driver(&acpi_idle_driver); |
971 | 893 | ||
972 | #ifdef CONFIG_ACPI_PROCFS | ||
973 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 894 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
974 | #endif | ||
975 | 895 | ||
976 | return; | 896 | return; |
977 | } | 897 | } |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 2e8c27d48f2b..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> |
@@ -76,14 +74,12 @@ static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER; | |||
76 | module_param(max_cstate, uint, 0000); | 74 | module_param(max_cstate, uint, 0000); |
77 | static unsigned int nocst __read_mostly; | 75 | static unsigned int nocst __read_mostly; |
78 | module_param(nocst, uint, 0000); | 76 | module_param(nocst, uint, 0000); |
77 | static int bm_check_disable __read_mostly; | ||
78 | module_param(bm_check_disable, uint, 0000); | ||
79 | 79 | ||
80 | static unsigned int latency_factor __read_mostly = 2; | 80 | static unsigned int latency_factor __read_mostly = 2; |
81 | module_param(latency_factor, uint, 0644); | 81 | module_param(latency_factor, uint, 0644); |
82 | 82 | ||
83 | static s64 us_to_pm_timer_ticks(s64 t) | ||
84 | { | ||
85 | return div64_u64(t * PM_TIMER_FREQUENCY, 1000000); | ||
86 | } | ||
87 | /* | 83 | /* |
88 | * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. | 84 | * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. |
89 | * For now disable this. Probably a bug somewhere else. | 85 | * For now disable this. Probably a bug somewhere else. |
@@ -159,7 +155,7 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr, | |||
159 | if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT)) | 155 | if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT)) |
160 | return; | 156 | return; |
161 | 157 | ||
162 | if (boot_cpu_has(X86_FEATURE_AMDC1E)) | 158 | if (c1e_detected) |
163 | type = ACPI_STATE_C1; | 159 | type = ACPI_STATE_C1; |
164 | 160 | ||
165 | /* | 161 | /* |
@@ -259,7 +255,7 @@ int acpi_processor_resume(struct acpi_device * device) | |||
259 | return 0; | 255 | return 0; |
260 | } | 256 | } |
261 | 257 | ||
262 | #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) | 258 | #if defined(CONFIG_X86) |
263 | static void tsc_check_state(int state) | 259 | static void tsc_check_state(int state) |
264 | { | 260 | { |
265 | switch (boot_cpu_data.x86_vendor) { | 261 | switch (boot_cpu_data.x86_vendor) { |
@@ -684,78 +680,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) | |||
684 | return 0; | 680 | return 0; |
685 | } | 681 | } |
686 | 682 | ||
687 | #ifdef CONFIG_ACPI_PROCFS | ||
688 | static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) | ||
689 | { | ||
690 | struct acpi_processor *pr = seq->private; | ||
691 | unsigned int i; | ||
692 | |||
693 | |||
694 | if (!pr) | ||
695 | goto end; | ||
696 | |||
697 | seq_printf(seq, "active state: C%zd\n" | ||
698 | "max_cstate: C%d\n" | ||
699 | "maximum allowed latency: %d usec\n", | ||
700 | pr->power.state ? pr->power.state - pr->power.states : 0, | ||
701 | max_cstate, pm_qos_request(PM_QOS_CPU_DMA_LATENCY)); | ||
702 | |||
703 | seq_puts(seq, "states:\n"); | ||
704 | |||
705 | for (i = 1; i <= pr->power.count; i++) { | ||
706 | seq_printf(seq, " %cC%d: ", | ||
707 | (&pr->power.states[i] == | ||
708 | pr->power.state ? '*' : ' '), i); | ||
709 | |||
710 | if (!pr->power.states[i].valid) { | ||
711 | seq_puts(seq, "<not supported>\n"); | ||
712 | continue; | ||
713 | } | ||
714 | |||
715 | switch (pr->power.states[i].type) { | ||
716 | case ACPI_STATE_C1: | ||
717 | seq_printf(seq, "type[C1] "); | ||
718 | break; | ||
719 | case ACPI_STATE_C2: | ||
720 | seq_printf(seq, "type[C2] "); | ||
721 | break; | ||
722 | case ACPI_STATE_C3: | ||
723 | seq_printf(seq, "type[C3] "); | ||
724 | break; | ||
725 | default: | ||
726 | seq_printf(seq, "type[--] "); | ||
727 | break; | ||
728 | } | ||
729 | |||
730 | seq_puts(seq, "promotion[--] "); | ||
731 | |||
732 | seq_puts(seq, "demotion[--] "); | ||
733 | |||
734 | seq_printf(seq, "latency[%03d] usage[%08d] duration[%020llu]\n", | ||
735 | pr->power.states[i].latency, | ||
736 | pr->power.states[i].usage, | ||
737 | (unsigned long long)pr->power.states[i].time); | ||
738 | } | ||
739 | |||
740 | end: | ||
741 | return 0; | ||
742 | } | ||
743 | |||
744 | static int acpi_processor_power_open_fs(struct inode *inode, struct file *file) | ||
745 | { | ||
746 | return single_open(file, acpi_processor_power_seq_show, | ||
747 | PDE(inode)->data); | ||
748 | } | ||
749 | |||
750 | static const struct file_operations acpi_processor_power_fops = { | ||
751 | .owner = THIS_MODULE, | ||
752 | .open = acpi_processor_power_open_fs, | ||
753 | .read = seq_read, | ||
754 | .llseek = seq_lseek, | ||
755 | .release = single_release, | ||
756 | }; | ||
757 | #endif | ||
758 | |||
759 | /** | 683 | /** |
760 | * acpi_idle_bm_check - checks if bus master activity was detected | 684 | * acpi_idle_bm_check - checks if bus master activity was detected |
761 | */ | 685 | */ |
@@ -763,6 +687,9 @@ static int acpi_idle_bm_check(void) | |||
763 | { | 687 | { |
764 | u32 bm_status = 0; | 688 | u32 bm_status = 0; |
765 | 689 | ||
690 | if (bm_check_disable) | ||
691 | return 0; | ||
692 | |||
766 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); | 693 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); |
767 | if (bm_status) | 694 | if (bm_status) |
768 | acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); | 695 | acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); |
@@ -795,13 +722,12 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) | |||
795 | } else if (cx->entry_method == ACPI_CSTATE_HALT) { | 722 | } else if (cx->entry_method == ACPI_CSTATE_HALT) { |
796 | acpi_safe_halt(); | 723 | acpi_safe_halt(); |
797 | } else { | 724 | } else { |
798 | int unused; | ||
799 | /* IO port based C-state */ | 725 | /* IO port based C-state */ |
800 | inb(cx->address); | 726 | inb(cx->address); |
801 | /* Dummy wait op - must do something useless after P_LVL2 read | 727 | /* Dummy wait op - must do something useless after P_LVL2 read |
802 | because chipsets cannot guarantee that STPCLK# signal | 728 | because chipsets cannot guarantee that STPCLK# signal |
803 | gets asserted in time to freeze execution properly. */ | 729 | gets asserted in time to freeze execution properly. */ |
804 | unused = inl(acpi_gbl_FADT.xpm_timer_block.address); | 730 | inl(acpi_gbl_FADT.xpm_timer_block.address); |
805 | } | 731 | } |
806 | start_critical_timings(); | 732 | start_critical_timings(); |
807 | } | 733 | } |
@@ -861,7 +787,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
861 | ktime_t kt1, kt2; | 787 | ktime_t kt1, kt2; |
862 | s64 idle_time_ns; | 788 | s64 idle_time_ns; |
863 | s64 idle_time; | 789 | s64 idle_time; |
864 | s64 sleep_ticks = 0; | ||
865 | 790 | ||
866 | pr = __get_cpu_var(processors); | 791 | pr = __get_cpu_var(processors); |
867 | 792 | ||
@@ -906,8 +831,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
906 | idle_time = idle_time_ns; | 831 | idle_time = idle_time_ns; |
907 | do_div(idle_time, NSEC_PER_USEC); | 832 | do_div(idle_time, NSEC_PER_USEC); |
908 | 833 | ||
909 | sleep_ticks = us_to_pm_timer_ticks(idle_time); | ||
910 | |||
911 | /* Tell the scheduler how much we idled: */ | 834 | /* Tell the scheduler how much we idled: */ |
912 | sched_clock_idle_wakeup_event(idle_time_ns); | 835 | sched_clock_idle_wakeup_event(idle_time_ns); |
913 | 836 | ||
@@ -918,7 +841,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
918 | cx->usage++; | 841 | cx->usage++; |
919 | 842 | ||
920 | lapic_timer_state_broadcast(pr, cx, 0); | 843 | lapic_timer_state_broadcast(pr, cx, 0); |
921 | cx->time += sleep_ticks; | 844 | cx->time += idle_time; |
922 | return idle_time; | 845 | return idle_time; |
923 | } | 846 | } |
924 | 847 | ||
@@ -940,7 +863,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
940 | ktime_t kt1, kt2; | 863 | ktime_t kt1, kt2; |
941 | s64 idle_time_ns; | 864 | s64 idle_time_ns; |
942 | s64 idle_time; | 865 | s64 idle_time; |
943 | s64 sleep_ticks = 0; | ||
944 | 866 | ||
945 | 867 | ||
946 | pr = __get_cpu_var(processors); | 868 | pr = __get_cpu_var(processors); |
@@ -951,7 +873,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
951 | if (acpi_idle_suspend) | 873 | if (acpi_idle_suspend) |
952 | return(acpi_idle_enter_c1(dev, state)); | 874 | return(acpi_idle_enter_c1(dev, state)); |
953 | 875 | ||
954 | if (acpi_idle_bm_check()) { | 876 | if (!cx->bm_sts_skip && acpi_idle_bm_check()) { |
955 | if (dev->safe_state) { | 877 | if (dev->safe_state) { |
956 | dev->last_state = dev->safe_state; | 878 | dev->last_state = dev->safe_state; |
957 | return dev->safe_state->enter(dev, dev->safe_state); | 879 | return dev->safe_state->enter(dev, dev->safe_state); |
@@ -1022,11 +944,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1022 | spin_unlock(&c3_lock); | 944 | spin_unlock(&c3_lock); |
1023 | } | 945 | } |
1024 | kt2 = ktime_get_real(); | 946 | kt2 = ktime_get_real(); |
1025 | idle_time_ns = ktime_to_us(ktime_sub(kt2, kt1)); | 947 | idle_time_ns = ktime_to_ns(ktime_sub(kt2, kt1)); |
1026 | idle_time = idle_time_ns; | 948 | idle_time = idle_time_ns; |
1027 | do_div(idle_time, NSEC_PER_USEC); | 949 | do_div(idle_time, NSEC_PER_USEC); |
1028 | 950 | ||
1029 | sleep_ticks = us_to_pm_timer_ticks(idle_time); | ||
1030 | /* Tell the scheduler how much we idled: */ | 951 | /* Tell the scheduler how much we idled: */ |
1031 | sched_clock_idle_wakeup_event(idle_time_ns); | 952 | sched_clock_idle_wakeup_event(idle_time_ns); |
1032 | 953 | ||
@@ -1037,7 +958,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1037 | cx->usage++; | 958 | cx->usage++; |
1038 | 959 | ||
1039 | lapic_timer_state_broadcast(pr, cx, 0); | 960 | lapic_timer_state_broadcast(pr, cx, 0); |
1040 | cx->time += sleep_ticks; | 961 | cx->time += idle_time; |
1041 | return idle_time; | 962 | return idle_time; |
1042 | } | 963 | } |
1043 | 964 | ||
@@ -1169,9 +1090,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1169 | { | 1090 | { |
1170 | acpi_status status = 0; | 1091 | acpi_status status = 0; |
1171 | static int first_run; | 1092 | static int first_run; |
1172 | #ifdef CONFIG_ACPI_PROCFS | ||
1173 | struct proc_dir_entry *entry = NULL; | ||
1174 | #endif | ||
1175 | 1093 | ||
1176 | if (boot_option_idle_override) | 1094 | if (boot_option_idle_override) |
1177 | return 0; | 1095 | return 0; |
@@ -1220,15 +1138,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1220 | if (cpuidle_register_device(&pr->power.dev)) | 1138 | if (cpuidle_register_device(&pr->power.dev)) |
1221 | return -EIO; | 1139 | return -EIO; |
1222 | } | 1140 | } |
1223 | #ifdef CONFIG_ACPI_PROCFS | ||
1224 | /* 'power' [R] */ | ||
1225 | entry = proc_create_data(ACPI_PROCESSOR_FILE_POWER, | ||
1226 | S_IRUGO, acpi_device_dir(device), | ||
1227 | &acpi_processor_power_fops, | ||
1228 | acpi_driver_data(device)); | ||
1229 | if (!entry) | ||
1230 | return -EIO; | ||
1231 | #endif | ||
1232 | return 0; | 1141 | return 0; |
1233 | } | 1142 | } |
1234 | 1143 | ||
@@ -1241,11 +1150,5 @@ int acpi_processor_power_exit(struct acpi_processor *pr, | |||
1241 | cpuidle_unregister_device(&pr->power.dev); | 1150 | cpuidle_unregister_device(&pr->power.dev); |
1242 | pr->flags.power_setup_done = 0; | 1151 | pr->flags.power_setup_done = 0; |
1243 | 1152 | ||
1244 | #ifdef CONFIG_ACPI_PROCFS | ||
1245 | if (acpi_device_dir(device)) | ||
1246 | remove_proc_entry(ACPI_PROCESSOR_FILE_POWER, | ||
1247 | acpi_device_dir(device)); | ||
1248 | #endif | ||
1249 | |||
1250 | return 0; | 1153 | return 0; |
1251 | } | 1154 | } |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 6deafb4aa0da..953b25fb9869 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
@@ -30,8 +30,6 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/cpufreq.h> | 32 | #include <linux/cpufreq.h> |
33 | #include <linux/proc_fs.h> | ||
34 | #include <linux/seq_file.h> | ||
35 | #include <linux/sysdev.h> | 33 | #include <linux/sysdev.h> |
36 | 34 | ||
37 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
@@ -438,84 +436,3 @@ struct thermal_cooling_device_ops processor_cooling_ops = { | |||
438 | .get_cur_state = processor_get_cur_state, | 436 | .get_cur_state = processor_get_cur_state, |
439 | .set_cur_state = processor_set_cur_state, | 437 | .set_cur_state = processor_set_cur_state, |
440 | }; | 438 | }; |
441 | |||
442 | /* /proc interface */ | ||
443 | #ifdef CONFIG_ACPI_PROCFS | ||
444 | static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset) | ||
445 | { | ||
446 | struct acpi_processor *pr = seq->private; | ||
447 | |||
448 | if (!pr) | ||
449 | goto end; | ||
450 | |||
451 | if (!pr->flags.limit) { | ||
452 | seq_puts(seq, "<not supported>\n"); | ||
453 | goto end; | ||
454 | } | ||
455 | |||
456 | seq_printf(seq, "active limit: P%d:T%d\n" | ||
457 | "user limit: P%d:T%d\n" | ||
458 | "thermal limit: P%d:T%d\n", | ||
459 | pr->limit.state.px, pr->limit.state.tx, | ||
460 | pr->limit.user.px, pr->limit.user.tx, | ||
461 | pr->limit.thermal.px, pr->limit.thermal.tx); | ||
462 | |||
463 | end: | ||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | static int acpi_processor_limit_open_fs(struct inode *inode, struct file *file) | ||
468 | { | ||
469 | return single_open(file, acpi_processor_limit_seq_show, | ||
470 | PDE(inode)->data); | ||
471 | } | ||
472 | |||
473 | static ssize_t acpi_processor_write_limit(struct file * file, | ||
474 | const char __user * buffer, | ||
475 | size_t count, loff_t * data) | ||
476 | { | ||
477 | int result = 0; | ||
478 | struct seq_file *m = file->private_data; | ||
479 | struct acpi_processor *pr = m->private; | ||
480 | char limit_string[25] = { '\0' }; | ||
481 | int px = 0; | ||
482 | int tx = 0; | ||
483 | |||
484 | |||
485 | if (!pr || (count > sizeof(limit_string) - 1)) { | ||
486 | return -EINVAL; | ||
487 | } | ||
488 | |||
489 | if (copy_from_user(limit_string, buffer, count)) { | ||
490 | return -EFAULT; | ||
491 | } | ||
492 | |||
493 | limit_string[count] = '\0'; | ||
494 | |||
495 | if (sscanf(limit_string, "%d:%d", &px, &tx) != 2) { | ||
496 | printk(KERN_ERR PREFIX "Invalid data format\n"); | ||
497 | return -EINVAL; | ||
498 | } | ||
499 | |||
500 | if (pr->flags.throttling) { | ||
501 | if ((tx < 0) || (tx > (pr->throttling.state_count - 1))) { | ||
502 | printk(KERN_ERR PREFIX "Invalid tx\n"); | ||
503 | return -EINVAL; | ||
504 | } | ||
505 | pr->limit.user.tx = tx; | ||
506 | } | ||
507 | |||
508 | result = acpi_processor_apply_limit(pr); | ||
509 | |||
510 | return count; | ||
511 | } | ||
512 | |||
513 | const struct file_operations acpi_processor_limit_fops = { | ||
514 | .owner = THIS_MODULE, | ||
515 | .open = acpi_processor_limit_open_fs, | ||
516 | .read = seq_read, | ||
517 | .write = acpi_processor_write_limit, | ||
518 | .llseek = seq_lseek, | ||
519 | .release = single_release, | ||
520 | }; | ||
521 | #endif | ||
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 9ade1a5b32ed..730863855ed5 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -1215,7 +1215,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) | |||
1215 | } | 1215 | } |
1216 | 1216 | ||
1217 | /* proc interface */ | 1217 | /* proc interface */ |
1218 | #ifdef CONFIG_ACPI_PROCFS | ||
1219 | static int acpi_processor_throttling_seq_show(struct seq_file *seq, | 1218 | static int acpi_processor_throttling_seq_show(struct seq_file *seq, |
1220 | void *offset) | 1219 | void *offset) |
1221 | { | 1220 | { |
@@ -1323,4 +1322,3 @@ const struct file_operations acpi_processor_throttling_fops = { | |||
1323 | .llseek = seq_lseek, | 1322 | .llseek = seq_lseek, |
1324 | .release = single_release, | 1323 | .release = single_release, |
1325 | }; | 1324 | }; |
1326 | #endif | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7f2e051ed4f1..b23825ecfa37 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -740,6 +740,8 @@ acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, | |||
740 | device->wakeup.resources.handles[i] = element->reference.handle; | 740 | device->wakeup.resources.handles[i] = element->reference.handle; |
741 | } | 741 | } |
742 | 742 | ||
743 | acpi_gpe_can_wake(device->wakeup.gpe_device, device->wakeup.gpe_number); | ||
744 | |||
743 | return AE_OK; | 745 | return AE_OK; |
744 | } | 746 | } |
745 | 747 | ||
@@ -764,8 +766,9 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) | |||
764 | return; | 766 | return; |
765 | } | 767 | } |
766 | 768 | ||
767 | status = acpi_get_gpe_status(NULL, device->wakeup.gpe_number, | 769 | status = acpi_get_gpe_status(device->wakeup.gpe_device, |
768 | &event_status); | 770 | device->wakeup.gpe_number, |
771 | &event_status); | ||
769 | if (status == AE_OK) | 772 | if (status == AE_OK) |
770 | device->wakeup.flags.run_wake = | 773 | device->wakeup.flags.run_wake = |
771 | !!(event_status & ACPI_EVENT_FLAG_HANDLE); | 774 | !!(event_status & ACPI_EVENT_FLAG_HANDLE); |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 4ab2275b4461..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 | } |
@@ -82,6 +82,20 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
82 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | 82 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
83 | 83 | ||
84 | /* | 84 | /* |
85 | * The ACPI specification wants us to save NVS memory regions during hibernation | ||
86 | * and to restore them during the subsequent resume. Windows does that also for | ||
87 | * suspend to RAM. However, it is known that this mechanism does not work on | ||
88 | * all machines, so we allow the user to disable it with the help of the | ||
89 | * 'acpi_sleep=nonvs' kernel command line option. | ||
90 | */ | ||
91 | static bool nvs_nosave; | ||
92 | |||
93 | void __init acpi_nvs_nosave(void) | ||
94 | { | ||
95 | nvs_nosave = true; | ||
96 | } | ||
97 | |||
98 | /* | ||
85 | * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the | 99 | * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the |
86 | * user to request that behavior by using the 'acpi_old_suspend_ordering' | 100 | * user to request that behavior by using the 'acpi_old_suspend_ordering' |
87 | * kernel command line option that causes the following variable to be set. | 101 | * kernel command line option that causes the following variable to be set. |
@@ -94,11 +108,23 @@ void __init acpi_old_suspend_ordering(void) | |||
94 | } | 108 | } |
95 | 109 | ||
96 | /** | 110 | /** |
97 | * acpi_pm_disable_gpes - Disable the GPEs. | 111 | * acpi_pm_freeze - Disable the GPEs and suspend EC transactions. |
98 | */ | 112 | */ |
99 | static int acpi_pm_disable_gpes(void) | 113 | static int acpi_pm_freeze(void) |
100 | { | 114 | { |
101 | acpi_disable_all_gpes(); | 115 | acpi_disable_all_gpes(); |
116 | acpi_os_wait_events_complete(NULL); | ||
117 | acpi_ec_block_transactions(); | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | /** | ||
122 | * acpi_pre_suspend - Enable wakeup devices, "freeze" EC and save NVS. | ||
123 | */ | ||
124 | static int acpi_pm_pre_suspend(void) | ||
125 | { | ||
126 | acpi_pm_freeze(); | ||
127 | suspend_nvs_save(); | ||
102 | return 0; | 128 | return 0; |
103 | } | 129 | } |
104 | 130 | ||
@@ -111,9 +137,9 @@ static int acpi_pm_disable_gpes(void) | |||
111 | static int __acpi_pm_prepare(void) | 137 | static int __acpi_pm_prepare(void) |
112 | { | 138 | { |
113 | int error = acpi_sleep_prepare(acpi_target_sleep_state); | 139 | int error = acpi_sleep_prepare(acpi_target_sleep_state); |
114 | |||
115 | if (error) | 140 | if (error) |
116 | acpi_target_sleep_state = ACPI_STATE_S0; | 141 | acpi_target_sleep_state = ACPI_STATE_S0; |
142 | |||
117 | return error; | 143 | return error; |
118 | } | 144 | } |
119 | 145 | ||
@@ -124,9 +150,9 @@ static int __acpi_pm_prepare(void) | |||
124 | static int acpi_pm_prepare(void) | 150 | static int acpi_pm_prepare(void) |
125 | { | 151 | { |
126 | int error = __acpi_pm_prepare(); | 152 | int error = __acpi_pm_prepare(); |
127 | |||
128 | if (!error) | 153 | if (!error) |
129 | acpi_disable_all_gpes(); | 154 | acpi_pm_pre_suspend(); |
155 | |||
130 | return error; | 156 | return error; |
131 | } | 157 | } |
132 | 158 | ||
@@ -140,12 +166,14 @@ static void acpi_pm_finish(void) | |||
140 | { | 166 | { |
141 | u32 acpi_state = acpi_target_sleep_state; | 167 | u32 acpi_state = acpi_target_sleep_state; |
142 | 168 | ||
169 | acpi_ec_unblock_transactions(); | ||
170 | |||
143 | if (acpi_state == ACPI_STATE_S0) | 171 | if (acpi_state == ACPI_STATE_S0) |
144 | return; | 172 | return; |
145 | 173 | ||
146 | 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", |
147 | acpi_state); | 175 | acpi_state); |
148 | acpi_disable_wakeup_device(acpi_state); | 176 | acpi_disable_wakeup_devices(acpi_state); |
149 | acpi_leave_sleep_state(acpi_state); | 177 | acpi_leave_sleep_state(acpi_state); |
150 | 178 | ||
151 | /* reset firmware waking vector */ | 179 | /* reset firmware waking vector */ |
@@ -159,6 +187,7 @@ static void acpi_pm_finish(void) | |||
159 | */ | 187 | */ |
160 | static void acpi_pm_end(void) | 188 | static void acpi_pm_end(void) |
161 | { | 189 | { |
190 | suspend_nvs_free(); | ||
162 | /* | 191 | /* |
163 | * 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 |
164 | * failing transition to a sleep state. | 193 | * failing transition to a sleep state. |
@@ -189,6 +218,10 @@ static int acpi_suspend_begin(suspend_state_t pm_state) | |||
189 | u32 acpi_state = acpi_suspend_states[pm_state]; | 218 | u32 acpi_state = acpi_suspend_states[pm_state]; |
190 | int error = 0; | 219 | int error = 0; |
191 | 220 | ||
221 | error = nvs_nosave ? 0 : suspend_nvs_alloc(); | ||
222 | if (error) | ||
223 | return error; | ||
224 | |||
192 | if (sleep_states[acpi_state]) { | 225 | if (sleep_states[acpi_state]) { |
193 | acpi_target_sleep_state = acpi_state; | 226 | acpi_target_sleep_state = acpi_state; |
194 | acpi_sleep_tts_switch(acpi_target_sleep_state); | 227 | acpi_sleep_tts_switch(acpi_target_sleep_state); |
@@ -225,7 +258,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
225 | } | 258 | } |
226 | 259 | ||
227 | local_irq_save(flags); | 260 | local_irq_save(flags); |
228 | acpi_enable_wakeup_device(acpi_state); | ||
229 | switch (acpi_state) { | 261 | switch (acpi_state) { |
230 | case ACPI_STATE_S1: | 262 | case ACPI_STATE_S1: |
231 | barrier(); | 263 | barrier(); |
@@ -256,6 +288,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
256 | * acpi_leave_sleep_state will reenable specific GPEs later | 288 | * acpi_leave_sleep_state will reenable specific GPEs later |
257 | */ | 289 | */ |
258 | acpi_disable_all_gpes(); | 290 | acpi_disable_all_gpes(); |
291 | /* Allow EC transactions to happen. */ | ||
292 | acpi_ec_unblock_transactions_early(); | ||
259 | 293 | ||
260 | local_irq_restore(flags); | 294 | local_irq_restore(flags); |
261 | printk(KERN_DEBUG "Back to C!\n"); | 295 | printk(KERN_DEBUG "Back to C!\n"); |
@@ -264,6 +298,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
264 | if (acpi_state == ACPI_STATE_S3) | 298 | if (acpi_state == ACPI_STATE_S3) |
265 | acpi_restore_state_mem(); | 299 | acpi_restore_state_mem(); |
266 | 300 | ||
301 | suspend_nvs_restore(); | ||
302 | |||
267 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 303 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
268 | } | 304 | } |
269 | 305 | ||
@@ -301,9 +337,9 @@ static struct platform_suspend_ops acpi_suspend_ops = { | |||
301 | static int acpi_suspend_begin_old(suspend_state_t pm_state) | 337 | static int acpi_suspend_begin_old(suspend_state_t pm_state) |
302 | { | 338 | { |
303 | int error = acpi_suspend_begin(pm_state); | 339 | int error = acpi_suspend_begin(pm_state); |
304 | |||
305 | if (!error) | 340 | if (!error) |
306 | error = __acpi_pm_prepare(); | 341 | error = __acpi_pm_prepare(); |
342 | |||
307 | return error; | 343 | return error; |
308 | } | 344 | } |
309 | 345 | ||
@@ -314,7 +350,7 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state) | |||
314 | static struct platform_suspend_ops acpi_suspend_ops_old = { | 350 | static struct platform_suspend_ops acpi_suspend_ops_old = { |
315 | .valid = acpi_suspend_state_valid, | 351 | .valid = acpi_suspend_state_valid, |
316 | .begin = acpi_suspend_begin_old, | 352 | .begin = acpi_suspend_begin_old, |
317 | .prepare_late = acpi_pm_disable_gpes, | 353 | .prepare_late = acpi_pm_pre_suspend, |
318 | .enter = acpi_suspend_enter, | 354 | .enter = acpi_suspend_enter, |
319 | .wake = acpi_pm_finish, | 355 | .wake = acpi_pm_finish, |
320 | .end = acpi_pm_end, | 356 | .end = acpi_pm_end, |
@@ -366,20 +402,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
366 | #endif /* CONFIG_SUSPEND */ | 402 | #endif /* CONFIG_SUSPEND */ |
367 | 403 | ||
368 | #ifdef CONFIG_HIBERNATION | 404 | #ifdef CONFIG_HIBERNATION |
369 | /* | ||
370 | * The ACPI specification wants us to save NVS memory regions during hibernation | ||
371 | * and to restore them during the subsequent resume. However, it is not certain | ||
372 | * if this mechanism is going to work on all machines, so we allow the user to | ||
373 | * disable this mechanism using the 'acpi_sleep=s4_nonvs' kernel command line | ||
374 | * option. | ||
375 | */ | ||
376 | static bool s4_no_nvs; | ||
377 | |||
378 | void __init acpi_s4_no_nvs(void) | ||
379 | { | ||
380 | s4_no_nvs = true; | ||
381 | } | ||
382 | |||
383 | static unsigned long s4_hardware_signature; | 405 | static unsigned long s4_hardware_signature; |
384 | static struct acpi_table_facs *facs; | 406 | static struct acpi_table_facs *facs; |
385 | static bool nosigcheck; | 407 | static bool nosigcheck; |
@@ -393,7 +415,7 @@ static int acpi_hibernation_begin(void) | |||
393 | { | 415 | { |
394 | int error; | 416 | int error; |
395 | 417 | ||
396 | error = s4_no_nvs ? 0 : hibernate_nvs_alloc(); | 418 | error = nvs_nosave ? 0 : suspend_nvs_alloc(); |
397 | if (!error) { | 419 | if (!error) { |
398 | acpi_target_sleep_state = ACPI_STATE_S4; | 420 | acpi_target_sleep_state = ACPI_STATE_S4; |
399 | acpi_sleep_tts_switch(acpi_target_sleep_state); | 421 | acpi_sleep_tts_switch(acpi_target_sleep_state); |
@@ -402,16 +424,6 @@ static int acpi_hibernation_begin(void) | |||
402 | return error; | 424 | return error; |
403 | } | 425 | } |
404 | 426 | ||
405 | static int acpi_hibernation_pre_snapshot(void) | ||
406 | { | ||
407 | int error = acpi_pm_prepare(); | ||
408 | |||
409 | if (!error) | ||
410 | hibernate_nvs_save(); | ||
411 | |||
412 | return error; | ||
413 | } | ||
414 | |||
415 | static int acpi_hibernation_enter(void) | 427 | static int acpi_hibernation_enter(void) |
416 | { | 428 | { |
417 | acpi_status status = AE_OK; | 429 | acpi_status status = AE_OK; |
@@ -420,7 +432,6 @@ static int acpi_hibernation_enter(void) | |||
420 | ACPI_FLUSH_CPU_CACHE(); | 432 | ACPI_FLUSH_CPU_CACHE(); |
421 | 433 | ||
422 | local_irq_save(flags); | 434 | local_irq_save(flags); |
423 | acpi_enable_wakeup_device(ACPI_STATE_S4); | ||
424 | /* This shouldn't return. If it returns, we have a problem */ | 435 | /* This shouldn't return. If it returns, we have a problem */ |
425 | status = acpi_enter_sleep_state(ACPI_STATE_S4); | 436 | status = acpi_enter_sleep_state(ACPI_STATE_S4); |
426 | /* Reprogram control registers and execute _BFS */ | 437 | /* Reprogram control registers and execute _BFS */ |
@@ -430,12 +441,6 @@ static int acpi_hibernation_enter(void) | |||
430 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 441 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
431 | } | 442 | } |
432 | 443 | ||
433 | static void acpi_hibernation_finish(void) | ||
434 | { | ||
435 | hibernate_nvs_free(); | ||
436 | acpi_pm_finish(); | ||
437 | } | ||
438 | |||
439 | static void acpi_hibernation_leave(void) | 444 | static void acpi_hibernation_leave(void) |
440 | { | 445 | { |
441 | /* | 446 | /* |
@@ -452,33 +457,27 @@ static void acpi_hibernation_leave(void) | |||
452 | panic("ACPI S4 hardware signature mismatch"); | 457 | panic("ACPI S4 hardware signature mismatch"); |
453 | } | 458 | } |
454 | /* Restore the NVS memory area */ | 459 | /* Restore the NVS memory area */ |
455 | hibernate_nvs_restore(); | 460 | suspend_nvs_restore(); |
456 | } | 461 | /* Allow EC transactions to happen. */ |
457 | 462 | acpi_ec_unblock_transactions_early(); | |
458 | static int acpi_pm_pre_restore(void) | ||
459 | { | ||
460 | acpi_disable_all_gpes(); | ||
461 | acpi_os_wait_events_complete(NULL); | ||
462 | acpi_ec_suspend_transactions(); | ||
463 | return 0; | ||
464 | } | 463 | } |
465 | 464 | ||
466 | static void acpi_pm_restore_cleanup(void) | 465 | static void acpi_pm_thaw(void) |
467 | { | 466 | { |
468 | acpi_ec_resume_transactions(); | 467 | acpi_ec_unblock_transactions(); |
469 | acpi_enable_all_runtime_gpes(); | 468 | acpi_enable_all_runtime_gpes(); |
470 | } | 469 | } |
471 | 470 | ||
472 | static struct platform_hibernation_ops acpi_hibernation_ops = { | 471 | static struct platform_hibernation_ops acpi_hibernation_ops = { |
473 | .begin = acpi_hibernation_begin, | 472 | .begin = acpi_hibernation_begin, |
474 | .end = acpi_pm_end, | 473 | .end = acpi_pm_end, |
475 | .pre_snapshot = acpi_hibernation_pre_snapshot, | 474 | .pre_snapshot = acpi_pm_prepare, |
476 | .finish = acpi_hibernation_finish, | 475 | .finish = acpi_pm_finish, |
477 | .prepare = acpi_pm_prepare, | 476 | .prepare = acpi_pm_prepare, |
478 | .enter = acpi_hibernation_enter, | 477 | .enter = acpi_hibernation_enter, |
479 | .leave = acpi_hibernation_leave, | 478 | .leave = acpi_hibernation_leave, |
480 | .pre_restore = acpi_pm_pre_restore, | 479 | .pre_restore = acpi_pm_freeze, |
481 | .restore_cleanup = acpi_pm_restore_cleanup, | 480 | .restore_cleanup = acpi_pm_thaw, |
482 | }; | 481 | }; |
483 | 482 | ||
484 | /** | 483 | /** |
@@ -500,24 +499,14 @@ static int acpi_hibernation_begin_old(void) | |||
500 | error = acpi_sleep_prepare(ACPI_STATE_S4); | 499 | error = acpi_sleep_prepare(ACPI_STATE_S4); |
501 | 500 | ||
502 | if (!error) { | 501 | if (!error) { |
503 | if (!s4_no_nvs) | 502 | if (!nvs_nosave) |
504 | error = hibernate_nvs_alloc(); | 503 | error = suspend_nvs_alloc(); |
505 | if (!error) | 504 | if (!error) |
506 | acpi_target_sleep_state = ACPI_STATE_S4; | 505 | acpi_target_sleep_state = ACPI_STATE_S4; |
507 | } | 506 | } |
508 | return error; | 507 | return error; |
509 | } | 508 | } |
510 | 509 | ||
511 | static int acpi_hibernation_pre_snapshot_old(void) | ||
512 | { | ||
513 | int error = acpi_pm_disable_gpes(); | ||
514 | |||
515 | if (!error) | ||
516 | hibernate_nvs_save(); | ||
517 | |||
518 | return error; | ||
519 | } | ||
520 | |||
521 | /* | 510 | /* |
522 | * 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 |
523 | * been requested. | 512 | * been requested. |
@@ -525,13 +514,13 @@ static int acpi_hibernation_pre_snapshot_old(void) | |||
525 | static struct platform_hibernation_ops acpi_hibernation_ops_old = { | 514 | static struct platform_hibernation_ops acpi_hibernation_ops_old = { |
526 | .begin = acpi_hibernation_begin_old, | 515 | .begin = acpi_hibernation_begin_old, |
527 | .end = acpi_pm_end, | 516 | .end = acpi_pm_end, |
528 | .pre_snapshot = acpi_hibernation_pre_snapshot_old, | 517 | .pre_snapshot = acpi_pm_pre_suspend, |
529 | .finish = acpi_hibernation_finish, | 518 | .prepare = acpi_pm_freeze, |
530 | .prepare = acpi_pm_disable_gpes, | 519 | .finish = acpi_pm_finish, |
531 | .enter = acpi_hibernation_enter, | 520 | .enter = acpi_hibernation_enter, |
532 | .leave = acpi_hibernation_leave, | 521 | .leave = acpi_hibernation_leave, |
533 | .pre_restore = acpi_pm_pre_restore, | 522 | .pre_restore = acpi_pm_freeze, |
534 | .restore_cleanup = acpi_pm_restore_cleanup, | 523 | .restore_cleanup = acpi_pm_thaw, |
535 | .recover = acpi_pm_finish, | 524 | .recover = acpi_pm_finish, |
536 | }; | 525 | }; |
537 | #endif /* CONFIG_HIBERNATION */ | 526 | #endif /* CONFIG_HIBERNATION */ |
@@ -657,18 +646,9 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | |||
657 | return -ENODEV; | 646 | return -ENODEV; |
658 | } | 647 | } |
659 | 648 | ||
660 | if (enable) { | 649 | error = enable ? |
661 | error = acpi_enable_wakeup_device_power(adev, | 650 | acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : |
662 | acpi_target_sleep_state); | 651 | acpi_disable_wakeup_device_power(adev); |
663 | if (!error) | ||
664 | acpi_enable_gpe(adev->wakeup.gpe_device, | ||
665 | adev->wakeup.gpe_number, | ||
666 | ACPI_GPE_TYPE_WAKE); | ||
667 | } else { | ||
668 | acpi_disable_gpe(adev->wakeup.gpe_device, adev->wakeup.gpe_number, | ||
669 | ACPI_GPE_TYPE_WAKE); | ||
670 | error = acpi_disable_wakeup_device_power(adev); | ||
671 | } | ||
672 | if (!error) | 652 | if (!error) |
673 | dev_info(dev, "wake-up capability %s by ACPI\n", | 653 | dev_info(dev, "wake-up capability %s by ACPI\n", |
674 | enable ? "enabled" : "disabled"); | 654 | enable ? "enabled" : "disabled"); |
@@ -689,7 +669,6 @@ static void acpi_power_off(void) | |||
689 | /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ | 669 | /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ |
690 | printk(KERN_DEBUG "%s called\n", __func__); | 670 | printk(KERN_DEBUG "%s called\n", __func__); |
691 | local_irq_disable(); | 671 | local_irq_disable(); |
692 | acpi_enable_wakeup_device(ACPI_STATE_S5); | ||
693 | acpi_enter_sleep_state(ACPI_STATE_S5); | 672 | acpi_enter_sleep_state(ACPI_STATE_S5); |
694 | } | 673 | } |
695 | 674 | ||
diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h index 25b8bd149284..d8821805c3bc 100644 --- a/drivers/acpi/sleep.h +++ b/drivers/acpi/sleep.h | |||
@@ -2,9 +2,8 @@ | |||
2 | extern u8 sleep_states[]; | 2 | extern u8 sleep_states[]; |
3 | extern int acpi_suspend(u32 state); | 3 | extern int acpi_suspend(u32 state); |
4 | 4 | ||
5 | extern void acpi_enable_wakeup_device_prep(u8 sleep_state); | 5 | extern void acpi_enable_wakeup_devices(u8 sleep_state); |
6 | extern void acpi_enable_wakeup_device(u8 sleep_state); | 6 | extern void acpi_disable_wakeup_devices(u8 sleep_state); |
7 | extern void acpi_disable_wakeup_device(u8 sleep_state); | ||
8 | 7 | ||
9 | extern struct list_head acpi_wakeup_device_list; | 8 | extern struct list_head acpi_wakeup_device_list; |
10 | extern struct mutex acpi_device_lock; | 9 | extern struct mutex acpi_device_lock; |
diff --git a/drivers/acpi/system.c b/drivers/acpi/sysfs.c index c79e789ed03a..68e2e4582fa2 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/sysfs.c | |||
@@ -1,51 +1,218 @@ | |||
1 | /* | 1 | /* |
2 | * acpi_system.c - ACPI System Driver ($Revision: 63 $) | 2 | * sysfs.c - ACPI sysfs interface to userspace. |
3 | * | ||
4 | * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> | ||
5 | * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> | ||
6 | * | ||
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or (at | ||
12 | * your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
22 | * | ||
23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
24 | */ | 3 | */ |
25 | 4 | ||
26 | #include <linux/proc_fs.h> | ||
27 | #include <linux/seq_file.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/init.h> | 5 | #include <linux/init.h> |
30 | #include <linux/string.h> | 6 | #include <linux/kernel.h> |
31 | #include <asm/uaccess.h> | 7 | #include <linux/moduleparam.h> |
32 | |||
33 | #include <acpi/acpi_drivers.h> | 8 | #include <acpi/acpi_drivers.h> |
34 | 9 | ||
35 | #define PREFIX "ACPI: " | ||
36 | |||
37 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 10 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
38 | ACPI_MODULE_NAME("system"); | 11 | ACPI_MODULE_NAME("sysfs"); |
39 | |||
40 | #define ACPI_SYSTEM_CLASS "system" | ||
41 | #define ACPI_SYSTEM_DEVICE_NAME "System" | ||
42 | 12 | ||
43 | u32 acpi_irq_handled; | 13 | #define PREFIX "ACPI: " |
44 | u32 acpi_irq_not_handled; | ||
45 | 14 | ||
15 | #ifdef CONFIG_ACPI_DEBUG | ||
46 | /* | 16 | /* |
47 | * Make ACPICA version work as module param | 17 | * ACPI debug sysfs I/F, including: |
18 | * /sys/modules/acpi/parameters/debug_layer | ||
19 | * /sys/modules/acpi/parameters/debug_level | ||
20 | * /sys/modules/acpi/parameters/trace_method_name | ||
21 | * /sys/modules/acpi/parameters/trace_state | ||
22 | * /sys/modules/acpi/parameters/trace_debug_layer | ||
23 | * /sys/modules/acpi/parameters/trace_debug_level | ||
48 | */ | 24 | */ |
25 | |||
26 | struct acpi_dlayer { | ||
27 | const char *name; | ||
28 | unsigned long value; | ||
29 | }; | ||
30 | struct acpi_dlevel { | ||
31 | const char *name; | ||
32 | unsigned long value; | ||
33 | }; | ||
34 | #define ACPI_DEBUG_INIT(v) { .name = #v, .value = v } | ||
35 | |||
36 | static const struct acpi_dlayer acpi_debug_layers[] = { | ||
37 | ACPI_DEBUG_INIT(ACPI_UTILITIES), | ||
38 | ACPI_DEBUG_INIT(ACPI_HARDWARE), | ||
39 | ACPI_DEBUG_INIT(ACPI_EVENTS), | ||
40 | ACPI_DEBUG_INIT(ACPI_TABLES), | ||
41 | ACPI_DEBUG_INIT(ACPI_NAMESPACE), | ||
42 | ACPI_DEBUG_INIT(ACPI_PARSER), | ||
43 | ACPI_DEBUG_INIT(ACPI_DISPATCHER), | ||
44 | ACPI_DEBUG_INIT(ACPI_EXECUTER), | ||
45 | ACPI_DEBUG_INIT(ACPI_RESOURCES), | ||
46 | ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER), | ||
47 | ACPI_DEBUG_INIT(ACPI_OS_SERVICES), | ||
48 | ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER), | ||
49 | ACPI_DEBUG_INIT(ACPI_COMPILER), | ||
50 | ACPI_DEBUG_INIT(ACPI_TOOLS), | ||
51 | |||
52 | ACPI_DEBUG_INIT(ACPI_BUS_COMPONENT), | ||
53 | ACPI_DEBUG_INIT(ACPI_AC_COMPONENT), | ||
54 | ACPI_DEBUG_INIT(ACPI_BATTERY_COMPONENT), | ||
55 | ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT), | ||
56 | ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT), | ||
57 | ACPI_DEBUG_INIT(ACPI_FAN_COMPONENT), | ||
58 | ACPI_DEBUG_INIT(ACPI_PCI_COMPONENT), | ||
59 | ACPI_DEBUG_INIT(ACPI_POWER_COMPONENT), | ||
60 | ACPI_DEBUG_INIT(ACPI_CONTAINER_COMPONENT), | ||
61 | ACPI_DEBUG_INIT(ACPI_SYSTEM_COMPONENT), | ||
62 | ACPI_DEBUG_INIT(ACPI_THERMAL_COMPONENT), | ||
63 | ACPI_DEBUG_INIT(ACPI_MEMORY_DEVICE_COMPONENT), | ||
64 | ACPI_DEBUG_INIT(ACPI_VIDEO_COMPONENT), | ||
65 | ACPI_DEBUG_INIT(ACPI_PROCESSOR_COMPONENT), | ||
66 | }; | ||
67 | |||
68 | static const struct acpi_dlevel acpi_debug_levels[] = { | ||
69 | ACPI_DEBUG_INIT(ACPI_LV_INIT), | ||
70 | ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT), | ||
71 | ACPI_DEBUG_INIT(ACPI_LV_INFO), | ||
72 | |||
73 | ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES), | ||
74 | ACPI_DEBUG_INIT(ACPI_LV_PARSE), | ||
75 | ACPI_DEBUG_INIT(ACPI_LV_LOAD), | ||
76 | ACPI_DEBUG_INIT(ACPI_LV_DISPATCH), | ||
77 | ACPI_DEBUG_INIT(ACPI_LV_EXEC), | ||
78 | ACPI_DEBUG_INIT(ACPI_LV_NAMES), | ||
79 | ACPI_DEBUG_INIT(ACPI_LV_OPREGION), | ||
80 | ACPI_DEBUG_INIT(ACPI_LV_BFIELD), | ||
81 | ACPI_DEBUG_INIT(ACPI_LV_TABLES), | ||
82 | ACPI_DEBUG_INIT(ACPI_LV_VALUES), | ||
83 | ACPI_DEBUG_INIT(ACPI_LV_OBJECTS), | ||
84 | ACPI_DEBUG_INIT(ACPI_LV_RESOURCES), | ||
85 | ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS), | ||
86 | ACPI_DEBUG_INIT(ACPI_LV_PACKAGE), | ||
87 | |||
88 | ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS), | ||
89 | ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS), | ||
90 | ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS), | ||
91 | |||
92 | ACPI_DEBUG_INIT(ACPI_LV_MUTEX), | ||
93 | ACPI_DEBUG_INIT(ACPI_LV_THREADS), | ||
94 | ACPI_DEBUG_INIT(ACPI_LV_IO), | ||
95 | ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS), | ||
96 | |||
97 | ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE), | ||
98 | ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO), | ||
99 | ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES), | ||
100 | ACPI_DEBUG_INIT(ACPI_LV_EVENTS), | ||
101 | }; | ||
102 | |||
103 | static int param_get_debug_layer(char *buffer, struct kernel_param *kp) | ||
104 | { | ||
105 | int result = 0; | ||
106 | int i; | ||
107 | |||
108 | result = sprintf(buffer, "%-25s\tHex SET\n", "Description"); | ||
109 | |||
110 | for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) { | ||
111 | result += sprintf(buffer + result, "%-25s\t0x%08lX [%c]\n", | ||
112 | acpi_debug_layers[i].name, | ||
113 | acpi_debug_layers[i].value, | ||
114 | (acpi_dbg_layer & acpi_debug_layers[i].value) | ||
115 | ? '*' : ' '); | ||
116 | } | ||
117 | result += | ||
118 | sprintf(buffer + result, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", | ||
119 | ACPI_ALL_DRIVERS, | ||
120 | (acpi_dbg_layer & ACPI_ALL_DRIVERS) == | ||
121 | ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & ACPI_ALL_DRIVERS) | ||
122 | == 0 ? ' ' : '-'); | ||
123 | result += | ||
124 | sprintf(buffer + result, | ||
125 | "--\ndebug_layer = 0x%08X ( * = enabled)\n", | ||
126 | acpi_dbg_layer); | ||
127 | |||
128 | return result; | ||
129 | } | ||
130 | |||
131 | static int param_get_debug_level(char *buffer, struct kernel_param *kp) | ||
132 | { | ||
133 | int result = 0; | ||
134 | int i; | ||
135 | |||
136 | result = sprintf(buffer, "%-25s\tHex SET\n", "Description"); | ||
137 | |||
138 | for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { | ||
139 | result += sprintf(buffer + result, "%-25s\t0x%08lX [%c]\n", | ||
140 | acpi_debug_levels[i].name, | ||
141 | acpi_debug_levels[i].value, | ||
142 | (acpi_dbg_level & acpi_debug_levels[i].value) | ||
143 | ? '*' : ' '); | ||
144 | } | ||
145 | result += | ||
146 | sprintf(buffer + result, "--\ndebug_level = 0x%08X (* = enabled)\n", | ||
147 | acpi_dbg_level); | ||
148 | |||
149 | return result; | ||
150 | } | ||
151 | |||
152 | module_param_call(debug_layer, param_set_uint, param_get_debug_layer, | ||
153 | &acpi_dbg_layer, 0644); | ||
154 | module_param_call(debug_level, param_set_uint, param_get_debug_level, | ||
155 | &acpi_dbg_level, 0644); | ||
156 | |||
157 | static char trace_method_name[6]; | ||
158 | module_param_string(trace_method_name, trace_method_name, 6, 0644); | ||
159 | static unsigned int trace_debug_layer; | ||
160 | module_param(trace_debug_layer, uint, 0644); | ||
161 | static unsigned int trace_debug_level; | ||
162 | module_param(trace_debug_level, uint, 0644); | ||
163 | |||
164 | static int param_set_trace_state(const char *val, struct kernel_param *kp) | ||
165 | { | ||
166 | int result = 0; | ||
167 | |||
168 | if (!strncmp(val, "enable", strlen("enable") - 1)) { | ||
169 | result = acpi_debug_trace(trace_method_name, trace_debug_level, | ||
170 | trace_debug_layer, 0); | ||
171 | if (result) | ||
172 | result = -EBUSY; | ||
173 | goto exit; | ||
174 | } | ||
175 | |||
176 | if (!strncmp(val, "disable", strlen("disable") - 1)) { | ||
177 | int name = 0; | ||
178 | result = acpi_debug_trace((char *)&name, trace_debug_level, | ||
179 | trace_debug_layer, 0); | ||
180 | if (result) | ||
181 | result = -EBUSY; | ||
182 | goto exit; | ||
183 | } | ||
184 | |||
185 | if (!strncmp(val, "1", 1)) { | ||
186 | result = acpi_debug_trace(trace_method_name, trace_debug_level, | ||
187 | trace_debug_layer, 1); | ||
188 | if (result) | ||
189 | result = -EBUSY; | ||
190 | goto exit; | ||
191 | } | ||
192 | |||
193 | result = -EINVAL; | ||
194 | exit: | ||
195 | return result; | ||
196 | } | ||
197 | |||
198 | static int param_get_trace_state(char *buffer, struct kernel_param *kp) | ||
199 | { | ||
200 | if (!acpi_gbl_trace_method_name) | ||
201 | return sprintf(buffer, "disable"); | ||
202 | else { | ||
203 | if (acpi_gbl_trace_flags & 1) | ||
204 | return sprintf(buffer, "1"); | ||
205 | else | ||
206 | return sprintf(buffer, "enable"); | ||
207 | } | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | module_param_call(trace_state, param_set_trace_state, param_get_trace_state, | ||
212 | NULL, 0644); | ||
213 | #endif /* CONFIG_ACPI_DEBUG */ | ||
214 | |||
215 | /* /sys/module/acpi/parameters/acpica_version */ | ||
49 | static int param_get_acpica_version(char *buffer, struct kernel_param *kp) | 216 | static int param_get_acpica_version(char *buffer, struct kernel_param *kp) |
50 | { | 217 | { |
51 | int result; | 218 | int result; |
@@ -57,9 +224,12 @@ static int param_get_acpica_version(char *buffer, struct kernel_param *kp) | |||
57 | 224 | ||
58 | module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); | 225 | module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); |
59 | 226 | ||
60 | /* -------------------------------------------------------------------------- | 227 | /* |
61 | FS Interface (/sys) | 228 | * ACPI table sysfs I/F: |
62 | -------------------------------------------------------------------------- */ | 229 | * /sys/firmware/acpi/tables/ |
230 | * /sys/firmware/acpi/tables/dynamic/ | ||
231 | */ | ||
232 | |||
63 | static LIST_HEAD(acpi_table_attr_list); | 233 | static LIST_HEAD(acpi_table_attr_list); |
64 | static struct kobject *tables_kobj; | 234 | static struct kobject *tables_kobj; |
65 | static struct kobject *dynamic_tables_kobj; | 235 | static struct kobject *dynamic_tables_kobj; |
@@ -86,14 +256,12 @@ static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj, | |||
86 | else | 256 | else |
87 | memcpy(name, "\0\0\0\0", 4); | 257 | memcpy(name, "\0\0\0\0", 4); |
88 | 258 | ||
89 | status = | 259 | status = acpi_get_table(name, table_attr->instance, &table_header); |
90 | acpi_get_table(name, table_attr->instance, | ||
91 | &table_header); | ||
92 | if (ACPI_FAILURE(status)) | 260 | if (ACPI_FAILURE(status)) |
93 | return -ENODEV; | 261 | return -ENODEV; |
94 | 262 | ||
95 | return memory_read_from_buffer(buf, count, &offset, | 263 | return memory_read_from_buffer(buf, count, &offset, |
96 | table_header, table_header->length); | 264 | table_header, table_header->length); |
97 | } | 265 | } |
98 | 266 | ||
99 | static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | 267 | static void acpi_table_attr_init(struct acpi_table_attr *table_attr, |
@@ -105,7 +273,7 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | |||
105 | sysfs_attr_init(&table_attr->attr.attr); | 273 | sysfs_attr_init(&table_attr->attr.attr); |
106 | if (table_header->signature[0] != '\0') | 274 | if (table_header->signature[0] != '\0') |
107 | memcpy(table_attr->name, table_header->signature, | 275 | memcpy(table_attr->name, table_header->signature, |
108 | ACPI_NAME_SIZE); | 276 | ACPI_NAME_SIZE); |
109 | else | 277 | else |
110 | memcpy(table_attr->name, "NULL", 4); | 278 | memcpy(table_attr->name, "NULL", 4); |
111 | 279 | ||
@@ -117,8 +285,8 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | |||
117 | table_attr->instance++; | 285 | table_attr->instance++; |
118 | 286 | ||
119 | if (table_attr->instance > 1 || (table_attr->instance == 1 && | 287 | if (table_attr->instance > 1 || (table_attr->instance == 1 && |
120 | !acpi_get_table | 288 | !acpi_get_table |
121 | (table_header->signature, 2, &header))) | 289 | (table_header->signature, 2, &header))) |
122 | sprintf(table_attr->name + ACPI_NAME_SIZE, "%d", | 290 | sprintf(table_attr->name + ACPI_NAME_SIZE, "%d", |
123 | table_attr->instance); | 291 | table_attr->instance); |
124 | 292 | ||
@@ -138,18 +306,17 @@ acpi_sysfs_table_handler(u32 event, void *table, void *context) | |||
138 | switch (event) { | 306 | switch (event) { |
139 | case ACPI_TABLE_EVENT_LOAD: | 307 | case ACPI_TABLE_EVENT_LOAD: |
140 | table_attr = | 308 | table_attr = |
141 | kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); | 309 | kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); |
142 | if (!table_attr) | 310 | if (!table_attr) |
143 | return AE_NO_MEMORY; | 311 | return AE_NO_MEMORY; |
144 | 312 | ||
145 | acpi_table_attr_init(table_attr, table); | 313 | acpi_table_attr_init(table_attr, table); |
146 | if (sysfs_create_bin_file(dynamic_tables_kobj, | 314 | if (sysfs_create_bin_file(dynamic_tables_kobj, |
147 | &table_attr->attr)) { | 315 | &table_attr->attr)) { |
148 | kfree(table_attr); | 316 | kfree(table_attr); |
149 | return AE_ERROR; | 317 | return AE_ERROR; |
150 | } else | 318 | } else |
151 | list_add_tail(&table_attr->node, | 319 | list_add_tail(&table_attr->node, &acpi_table_attr_list); |
152 | &acpi_table_attr_list); | ||
153 | break; | 320 | break; |
154 | case ACPI_TABLE_EVENT_UNLOAD: | 321 | case ACPI_TABLE_EVENT_UNLOAD: |
155 | /* | 322 | /* |
@@ -164,7 +331,7 @@ acpi_sysfs_table_handler(u32 event, void *table, void *context) | |||
164 | return AE_OK; | 331 | return AE_OK; |
165 | } | 332 | } |
166 | 333 | ||
167 | static int acpi_system_sysfs_init(void) | 334 | static int acpi_tables_sysfs_init(void) |
168 | { | 335 | { |
169 | struct acpi_table_attr *table_attr; | 336 | struct acpi_table_attr *table_attr; |
170 | struct acpi_table_header *table_header = NULL; | 337 | struct acpi_table_header *table_header = NULL; |
@@ -213,14 +380,17 @@ err: | |||
213 | } | 380 | } |
214 | 381 | ||
215 | /* | 382 | /* |
216 | * Detailed ACPI IRQ counters in /sys/firmware/acpi/interrupts/ | 383 | * Detailed ACPI IRQ counters: |
217 | * See Documentation/ABI/testing/sysfs-firmware-acpi | 384 | * /sys/firmware/acpi/interrupts/ |
218 | */ | 385 | */ |
219 | 386 | ||
387 | u32 acpi_irq_handled; | ||
388 | u32 acpi_irq_not_handled; | ||
389 | |||
220 | #define COUNT_GPE 0 | 390 | #define COUNT_GPE 0 |
221 | #define COUNT_SCI 1 /* acpi_irq_handled */ | 391 | #define COUNT_SCI 1 /* acpi_irq_handled */ |
222 | #define COUNT_SCI_NOT 2 /* acpi_irq_not_handled */ | 392 | #define COUNT_SCI_NOT 2 /* acpi_irq_not_handled */ |
223 | #define COUNT_ERROR 3 /* other */ | 393 | #define COUNT_ERROR 3 /* other */ |
224 | #define NUM_COUNTERS_EXTRA 4 | 394 | #define NUM_COUNTERS_EXTRA 4 |
225 | 395 | ||
226 | struct event_counter { | 396 | struct event_counter { |
@@ -237,6 +407,7 @@ static u32 acpi_gpe_count; | |||
237 | static struct attribute_group interrupt_stats_attr_group = { | 407 | static struct attribute_group interrupt_stats_attr_group = { |
238 | .name = "interrupts", | 408 | .name = "interrupts", |
239 | }; | 409 | }; |
410 | |||
240 | static struct kobj_attribute *counter_attrs; | 411 | static struct kobj_attribute *counter_attrs; |
241 | 412 | ||
242 | static void delete_gpe_attr_array(void) | 413 | static void delete_gpe_attr_array(void) |
@@ -269,8 +440,8 @@ void acpi_os_gpe_count(u32 gpe_number) | |||
269 | if (gpe_number < num_gpes) | 440 | if (gpe_number < num_gpes) |
270 | all_counters[gpe_number].count++; | 441 | all_counters[gpe_number].count++; |
271 | else | 442 | else |
272 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]. | 443 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + |
273 | count++; | 444 | COUNT_ERROR].count++; |
274 | 445 | ||
275 | return; | 446 | return; |
276 | } | 447 | } |
@@ -283,13 +454,14 @@ void acpi_os_fixed_event_count(u32 event_number) | |||
283 | if (event_number < ACPI_NUM_FIXED_EVENTS) | 454 | if (event_number < ACPI_NUM_FIXED_EVENTS) |
284 | all_counters[num_gpes + event_number].count++; | 455 | all_counters[num_gpes + event_number].count++; |
285 | else | 456 | else |
286 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]. | 457 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + |
287 | count++; | 458 | COUNT_ERROR].count++; |
288 | 459 | ||
289 | return; | 460 | return; |
290 | } | 461 | } |
291 | 462 | ||
292 | static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) | 463 | static int get_status(u32 index, acpi_event_status *status, |
464 | acpi_handle *handle) | ||
293 | { | 465 | { |
294 | int result = 0; | 466 | int result = 0; |
295 | 467 | ||
@@ -300,7 +472,7 @@ static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) | |||
300 | result = acpi_get_gpe_device(index, handle); | 472 | result = acpi_get_gpe_device(index, handle); |
301 | if (result) { | 473 | if (result) { |
302 | ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND, | 474 | ACPI_EXCEPTION((AE_INFO, AE_NOT_FOUND, |
303 | "Invalid GPE 0x%x\n", index)); | 475 | "Invalid GPE 0x%x\n", index)); |
304 | goto end; | 476 | goto end; |
305 | } | 477 | } |
306 | result = acpi_get_gpe_status(*handle, index, status); | 478 | result = acpi_get_gpe_status(*handle, index, status); |
@@ -312,7 +484,7 @@ end: | |||
312 | } | 484 | } |
313 | 485 | ||
314 | static ssize_t counter_show(struct kobject *kobj, | 486 | static ssize_t counter_show(struct kobject *kobj, |
315 | struct kobj_attribute *attr, char *buf) | 487 | struct kobj_attribute *attr, char *buf) |
316 | { | 488 | { |
317 | int index = attr - counter_attrs; | 489 | int index = attr - counter_attrs; |
318 | int size; | 490 | int size; |
@@ -321,12 +493,11 @@ static ssize_t counter_show(struct kobject *kobj, | |||
321 | int result = 0; | 493 | int result = 0; |
322 | 494 | ||
323 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count = | 495 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count = |
324 | acpi_irq_handled; | 496 | acpi_irq_handled; |
325 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count = | 497 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count = |
326 | acpi_irq_not_handled; | 498 | acpi_irq_not_handled; |
327 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count = | 499 | all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count = |
328 | acpi_gpe_count; | 500 | acpi_gpe_count; |
329 | |||
330 | size = sprintf(buf, "%8d", all_counters[index].count); | 501 | size = sprintf(buf, "%8d", all_counters[index].count); |
331 | 502 | ||
332 | /* "gpe_all" or "sci" */ | 503 | /* "gpe_all" or "sci" */ |
@@ -338,13 +509,13 @@ static ssize_t counter_show(struct kobject *kobj, | |||
338 | goto end; | 509 | goto end; |
339 | 510 | ||
340 | if (!(status & ACPI_EVENT_FLAG_HANDLE)) | 511 | if (!(status & ACPI_EVENT_FLAG_HANDLE)) |
341 | size += sprintf(buf + size, " invalid"); | 512 | size += sprintf(buf + size, " invalid"); |
342 | else if (status & ACPI_EVENT_FLAG_ENABLED) | 513 | else if (status & ACPI_EVENT_FLAG_ENABLED) |
343 | size += sprintf(buf + size, " enabled"); | 514 | size += sprintf(buf + size, " enabled"); |
344 | else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED) | 515 | else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED) |
345 | size += sprintf(buf + size, " wake_enabled"); | 516 | size += sprintf(buf + size, " wake_enabled"); |
346 | else | 517 | else |
347 | size += sprintf(buf + size, " disabled"); | 518 | size += sprintf(buf + size, " disabled"); |
348 | 519 | ||
349 | end: | 520 | end: |
350 | size += sprintf(buf + size, "\n"); | 521 | size += sprintf(buf + size, "\n"); |
@@ -357,7 +528,8 @@ end: | |||
357 | * enable/disable/clear a gpe/fixed event in user space. | 528 | * enable/disable/clear a gpe/fixed event in user space. |
358 | */ | 529 | */ |
359 | static ssize_t counter_set(struct kobject *kobj, | 530 | static ssize_t counter_set(struct kobject *kobj, |
360 | struct kobj_attribute *attr, const char *buf, size_t size) | 531 | struct kobj_attribute *attr, const char *buf, |
532 | size_t size) | ||
361 | { | 533 | { |
362 | int index = attr - counter_attrs; | 534 | int index = attr - counter_attrs; |
363 | acpi_event_status status; | 535 | acpi_event_status status; |
@@ -381,32 +553,32 @@ static ssize_t counter_set(struct kobject *kobj, | |||
381 | 553 | ||
382 | if (!(status & ACPI_EVENT_FLAG_HANDLE)) { | 554 | if (!(status & ACPI_EVENT_FLAG_HANDLE)) { |
383 | printk(KERN_WARNING PREFIX | 555 | printk(KERN_WARNING PREFIX |
384 | "Can not change Invalid GPE/Fixed Event status\n"); | 556 | "Can not change Invalid GPE/Fixed Event status\n"); |
385 | return -EINVAL; | 557 | return -EINVAL; |
386 | } | 558 | } |
387 | 559 | ||
388 | if (index < num_gpes) { | 560 | if (index < num_gpes) { |
389 | if (!strcmp(buf, "disable\n") && | 561 | if (!strcmp(buf, "disable\n") && |
390 | (status & ACPI_EVENT_FLAG_ENABLED)) | 562 | (status & ACPI_EVENT_FLAG_ENABLED)) |
391 | result = acpi_set_gpe(handle, index, ACPI_GPE_DISABLE); | 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_set_gpe(handle, index, ACPI_GPE_ENABLE); | 566 | result = acpi_enable_gpe(handle, index); |
395 | else if (!strcmp(buf, "clear\n") && | 567 | else if (!strcmp(buf, "clear\n") && |
396 | (status & ACPI_EVENT_FLAG_SET)) | 568 | (status & ACPI_EVENT_FLAG_SET)) |
397 | result = acpi_clear_gpe(handle, index); | 569 | result = acpi_clear_gpe(handle, index); |
398 | else | 570 | else |
399 | all_counters[index].count = strtoul(buf, NULL, 0); | 571 | all_counters[index].count = strtoul(buf, NULL, 0); |
400 | } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { | 572 | } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { |
401 | int event = index - num_gpes; | 573 | int event = index - num_gpes; |
402 | if (!strcmp(buf, "disable\n") && | 574 | if (!strcmp(buf, "disable\n") && |
403 | (status & ACPI_EVENT_FLAG_ENABLED)) | 575 | (status & ACPI_EVENT_FLAG_ENABLED)) |
404 | result = acpi_disable_event(event, ACPI_NOT_ISR); | 576 | result = acpi_disable_event(event, ACPI_NOT_ISR); |
405 | else if (!strcmp(buf, "enable\n") && | 577 | else if (!strcmp(buf, "enable\n") && |
406 | !(status & ACPI_EVENT_FLAG_ENABLED)) | 578 | !(status & ACPI_EVENT_FLAG_ENABLED)) |
407 | result = acpi_enable_event(event, ACPI_NOT_ISR); | 579 | result = acpi_enable_event(event, ACPI_NOT_ISR); |
408 | else if (!strcmp(buf, "clear\n") && | 580 | else if (!strcmp(buf, "clear\n") && |
409 | (status & ACPI_EVENT_FLAG_SET)) | 581 | (status & ACPI_EVENT_FLAG_SET)) |
410 | result = acpi_clear_event(event); | 582 | result = acpi_clear_event(event); |
411 | else | 583 | else |
412 | all_counters[index].count = strtoul(buf, NULL, 0); | 584 | all_counters[index].count = strtoul(buf, NULL, 0); |
@@ -430,17 +602,17 @@ void acpi_irq_stats_init(void) | |||
430 | num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA; | 602 | num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA; |
431 | 603 | ||
432 | all_attrs = kzalloc(sizeof(struct attribute *) * (num_counters + 1), | 604 | all_attrs = kzalloc(sizeof(struct attribute *) * (num_counters + 1), |
433 | GFP_KERNEL); | 605 | GFP_KERNEL); |
434 | if (all_attrs == NULL) | 606 | if (all_attrs == NULL) |
435 | return; | 607 | return; |
436 | 608 | ||
437 | all_counters = kzalloc(sizeof(struct event_counter) * (num_counters), | 609 | all_counters = kzalloc(sizeof(struct event_counter) * (num_counters), |
438 | GFP_KERNEL); | 610 | GFP_KERNEL); |
439 | if (all_counters == NULL) | 611 | if (all_counters == NULL) |
440 | goto fail; | 612 | goto fail; |
441 | 613 | ||
442 | counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), | 614 | counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), |
443 | GFP_KERNEL); | 615 | GFP_KERNEL); |
444 | if (counter_attrs == NULL) | 616 | if (counter_attrs == NULL) |
445 | goto fail; | 617 | goto fail; |
446 | 618 | ||
@@ -503,135 +675,11 @@ static void __exit interrupt_stats_exit(void) | |||
503 | return; | 675 | return; |
504 | } | 676 | } |
505 | 677 | ||
506 | /* -------------------------------------------------------------------------- | 678 | int __init acpi_sysfs_init(void) |
507 | FS Interface (/proc) | ||
508 | -------------------------------------------------------------------------- */ | ||
509 | #ifdef CONFIG_ACPI_PROCFS | ||
510 | #define ACPI_SYSTEM_FILE_INFO "info" | ||
511 | #define ACPI_SYSTEM_FILE_EVENT "event" | ||
512 | #define ACPI_SYSTEM_FILE_DSDT "dsdt" | ||
513 | #define ACPI_SYSTEM_FILE_FADT "fadt" | ||
514 | |||
515 | static int acpi_system_read_info(struct seq_file *seq, void *offset) | ||
516 | { | ||
517 | |||
518 | seq_printf(seq, "version: %x\n", ACPI_CA_VERSION); | ||
519 | return 0; | ||
520 | } | ||
521 | |||
522 | static int acpi_system_info_open_fs(struct inode *inode, struct file *file) | ||
523 | { | ||
524 | return single_open(file, acpi_system_read_info, PDE(inode)->data); | ||
525 | } | ||
526 | |||
527 | static const struct file_operations acpi_system_info_ops = { | ||
528 | .owner = THIS_MODULE, | ||
529 | .open = acpi_system_info_open_fs, | ||
530 | .read = seq_read, | ||
531 | .llseek = seq_lseek, | ||
532 | .release = single_release, | ||
533 | }; | ||
534 | |||
535 | static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t, | ||
536 | loff_t *); | ||
537 | |||
538 | static const struct file_operations acpi_system_dsdt_ops = { | ||
539 | .owner = THIS_MODULE, | ||
540 | .read = acpi_system_read_dsdt, | ||
541 | }; | ||
542 | |||
543 | static ssize_t | ||
544 | acpi_system_read_dsdt(struct file *file, | ||
545 | char __user * buffer, size_t count, loff_t * ppos) | ||
546 | { | ||
547 | acpi_status status = AE_OK; | ||
548 | struct acpi_table_header *dsdt = NULL; | ||
549 | ssize_t res; | ||
550 | |||
551 | status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt); | ||
552 | if (ACPI_FAILURE(status)) | ||
553 | return -ENODEV; | ||
554 | |||
555 | res = simple_read_from_buffer(buffer, count, ppos, dsdt, dsdt->length); | ||
556 | |||
557 | return res; | ||
558 | } | ||
559 | |||
560 | static ssize_t acpi_system_read_fadt(struct file *, char __user *, size_t, | ||
561 | loff_t *); | ||
562 | |||
563 | static const struct file_operations acpi_system_fadt_ops = { | ||
564 | .owner = THIS_MODULE, | ||
565 | .read = acpi_system_read_fadt, | ||
566 | }; | ||
567 | |||
568 | static ssize_t | ||
569 | acpi_system_read_fadt(struct file *file, | ||
570 | char __user * buffer, size_t count, loff_t * ppos) | ||
571 | { | ||
572 | acpi_status status = AE_OK; | ||
573 | struct acpi_table_header *fadt = NULL; | ||
574 | ssize_t res; | ||
575 | |||
576 | status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt); | ||
577 | if (ACPI_FAILURE(status)) | ||
578 | return -ENODEV; | ||
579 | |||
580 | res = simple_read_from_buffer(buffer, count, ppos, fadt, fadt->length); | ||
581 | |||
582 | return res; | ||
583 | } | ||
584 | |||
585 | static int acpi_system_procfs_init(void) | ||
586 | { | ||
587 | struct proc_dir_entry *entry; | ||
588 | int error = 0; | ||
589 | |||
590 | /* 'info' [R] */ | ||
591 | entry = proc_create(ACPI_SYSTEM_FILE_INFO, S_IRUGO, acpi_root_dir, | ||
592 | &acpi_system_info_ops); | ||
593 | if (!entry) | ||
594 | goto Error; | ||
595 | |||
596 | /* 'dsdt' [R] */ | ||
597 | entry = proc_create(ACPI_SYSTEM_FILE_DSDT, S_IRUSR, acpi_root_dir, | ||
598 | &acpi_system_dsdt_ops); | ||
599 | if (!entry) | ||
600 | goto Error; | ||
601 | |||
602 | /* 'fadt' [R] */ | ||
603 | entry = proc_create(ACPI_SYSTEM_FILE_FADT, S_IRUSR, acpi_root_dir, | ||
604 | &acpi_system_fadt_ops); | ||
605 | if (!entry) | ||
606 | goto Error; | ||
607 | |||
608 | Done: | ||
609 | return error; | ||
610 | |||
611 | Error: | ||
612 | remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir); | ||
613 | remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir); | ||
614 | remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir); | ||
615 | |||
616 | error = -EFAULT; | ||
617 | goto Done; | ||
618 | } | ||
619 | #else | ||
620 | static int acpi_system_procfs_init(void) | ||
621 | { | ||
622 | return 0; | ||
623 | } | ||
624 | #endif | ||
625 | |||
626 | int __init acpi_system_init(void) | ||
627 | { | 679 | { |
628 | int result; | 680 | int result; |
629 | 681 | ||
630 | result = acpi_system_procfs_init(); | 682 | result = acpi_tables_sysfs_init(); |
631 | if (result) | ||
632 | return result; | ||
633 | |||
634 | result = acpi_system_sysfs_init(); | ||
635 | 683 | ||
636 | return result; | 684 | return result; |
637 | } | 685 | } |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index efad1f33aeb5..2f8f17131d9f 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -37,10 +37,14 @@ | |||
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/types.h> | 39 | #include <linux/types.h> |
40 | |||
41 | #ifdef CONFIG_ACPI_PROCFS | ||
40 | #include <linux/proc_fs.h> | 42 | #include <linux/proc_fs.h> |
43 | #include <linux/seq_file.h> | ||
44 | #endif | ||
45 | |||
41 | #include <linux/jiffies.h> | 46 | #include <linux/jiffies.h> |
42 | #include <linux/kmod.h> | 47 | #include <linux/kmod.h> |
43 | #include <linux/seq_file.h> | ||
44 | #include <linux/reboot.h> | 48 | #include <linux/reboot.h> |
45 | #include <linux/device.h> | 49 | #include <linux/device.h> |
46 | #include <asm/uaccess.h> | 50 | #include <asm/uaccess.h> |
@@ -102,16 +106,6 @@ static int acpi_thermal_add(struct acpi_device *device); | |||
102 | static int acpi_thermal_remove(struct acpi_device *device, int type); | 106 | static int acpi_thermal_remove(struct acpi_device *device, int type); |
103 | static int acpi_thermal_resume(struct acpi_device *device); | 107 | static int acpi_thermal_resume(struct acpi_device *device); |
104 | static void acpi_thermal_notify(struct acpi_device *device, u32 event); | 108 | static void acpi_thermal_notify(struct acpi_device *device, u32 event); |
105 | static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); | ||
106 | static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); | ||
107 | static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); | ||
108 | static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); | ||
109 | static ssize_t acpi_thermal_write_cooling_mode(struct file *, | ||
110 | const char __user *, size_t, | ||
111 | loff_t *); | ||
112 | static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); | ||
113 | static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, | ||
114 | size_t, loff_t *); | ||
115 | 109 | ||
116 | static const struct acpi_device_id thermal_device_ids[] = { | 110 | static const struct acpi_device_id thermal_device_ids[] = { |
117 | {ACPI_THERMAL_HID, 0}, | 111 | {ACPI_THERMAL_HID, 0}, |
@@ -201,6 +195,18 @@ struct acpi_thermal { | |||
201 | struct mutex lock; | 195 | struct mutex lock; |
202 | }; | 196 | }; |
203 | 197 | ||
198 | #ifdef CONFIG_ACPI_PROCFS | ||
199 | static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); | ||
200 | static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); | ||
201 | static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); | ||
202 | static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); | ||
203 | static ssize_t acpi_thermal_write_cooling_mode(struct file *, | ||
204 | const char __user *, size_t, | ||
205 | loff_t *); | ||
206 | static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); | ||
207 | static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, | ||
208 | size_t, loff_t *); | ||
209 | |||
204 | static const struct file_operations acpi_thermal_state_fops = { | 210 | static const struct file_operations acpi_thermal_state_fops = { |
205 | .owner = THIS_MODULE, | 211 | .owner = THIS_MODULE, |
206 | .open = acpi_thermal_state_open_fs, | 212 | .open = acpi_thermal_state_open_fs, |
@@ -242,6 +248,7 @@ static const struct file_operations acpi_thermal_polling_fops = { | |||
242 | .llseek = seq_lseek, | 248 | .llseek = seq_lseek, |
243 | .release = single_release, | 249 | .release = single_release, |
244 | }; | 250 | }; |
251 | #endif /* CONFIG_ACPI_PROCFS*/ | ||
245 | 252 | ||
246 | /* -------------------------------------------------------------------------- | 253 | /* -------------------------------------------------------------------------- |
247 | Thermal Zone Management | 254 | Thermal Zone Management |
@@ -287,26 +294,6 @@ static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) | |||
287 | return 0; | 294 | return 0; |
288 | } | 295 | } |
289 | 296 | ||
290 | static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) | ||
291 | { | ||
292 | |||
293 | if (!tz) | ||
294 | return -EINVAL; | ||
295 | |||
296 | tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */ | ||
297 | |||
298 | tz->thermal_zone->polling_delay = seconds * 1000; | ||
299 | |||
300 | if (tz->tz_enabled) | ||
301 | thermal_zone_device_update(tz->thermal_zone); | ||
302 | |||
303 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
304 | "Polling frequency set to %lu seconds\n", | ||
305 | tz->polling_frequency/10)); | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) | 297 | static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) |
311 | { | 298 | { |
312 | acpi_status status = AE_OK; | 299 | acpi_status status = AE_OK; |
@@ -973,7 +960,7 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) | |||
973 | /* -------------------------------------------------------------------------- | 960 | /* -------------------------------------------------------------------------- |
974 | FS Interface (/proc) | 961 | FS Interface (/proc) |
975 | -------------------------------------------------------------------------- */ | 962 | -------------------------------------------------------------------------- */ |
976 | 963 | #ifdef CONFIG_ACPI_PROCFS | |
977 | static struct proc_dir_entry *acpi_thermal_dir; | 964 | static struct proc_dir_entry *acpi_thermal_dir; |
978 | 965 | ||
979 | static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) | 966 | static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) |
@@ -1187,6 +1174,26 @@ static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file) | |||
1187 | PDE(inode)->data); | 1174 | PDE(inode)->data); |
1188 | } | 1175 | } |
1189 | 1176 | ||
1177 | static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) | ||
1178 | { | ||
1179 | if (!tz) | ||
1180 | return -EINVAL; | ||
1181 | |||
1182 | /* Convert value to deci-seconds */ | ||
1183 | tz->polling_frequency = seconds * 10; | ||
1184 | |||
1185 | tz->thermal_zone->polling_delay = seconds * 1000; | ||
1186 | |||
1187 | if (tz->tz_enabled) | ||
1188 | thermal_zone_device_update(tz->thermal_zone); | ||
1189 | |||
1190 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
1191 | "Polling frequency set to %lu seconds\n", | ||
1192 | tz->polling_frequency/10)); | ||
1193 | |||
1194 | return 0; | ||
1195 | } | ||
1196 | |||
1190 | static ssize_t | 1197 | static ssize_t |
1191 | acpi_thermal_write_polling(struct file *file, | 1198 | acpi_thermal_write_polling(struct file *file, |
1192 | const char __user * buffer, | 1199 | const char __user * buffer, |
@@ -1295,7 +1302,13 @@ static int acpi_thermal_remove_fs(struct acpi_device *device) | |||
1295 | 1302 | ||
1296 | return 0; | 1303 | return 0; |
1297 | } | 1304 | } |
1298 | 1305 | #else | |
1306 | static inline int acpi_thermal_add_fs(struct acpi_device *device) { return 0; } | ||
1307 | static inline int acpi_thermal_remove_fs(struct acpi_device *device) | ||
1308 | { | ||
1309 | return 0; | ||
1310 | } | ||
1311 | #endif /* CONFIG_ACPI_PROCFS */ | ||
1299 | /* -------------------------------------------------------------------------- | 1312 | /* -------------------------------------------------------------------------- |
1300 | Driver Interface | 1313 | Driver Interface |
1301 | -------------------------------------------------------------------------- */ | 1314 | -------------------------------------------------------------------------- */ |
@@ -1566,13 +1579,18 @@ static int __init acpi_thermal_init(void) | |||
1566 | printk(KERN_NOTICE "ACPI: thermal control disabled\n"); | 1579 | printk(KERN_NOTICE "ACPI: thermal control disabled\n"); |
1567 | return -ENODEV; | 1580 | return -ENODEV; |
1568 | } | 1581 | } |
1582 | |||
1583 | #ifdef CONFIG_ACPI_PROCFS | ||
1569 | acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); | 1584 | acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); |
1570 | if (!acpi_thermal_dir) | 1585 | if (!acpi_thermal_dir) |
1571 | return -ENODEV; | 1586 | return -ENODEV; |
1587 | #endif | ||
1572 | 1588 | ||
1573 | result = acpi_bus_register_driver(&acpi_thermal_driver); | 1589 | result = acpi_bus_register_driver(&acpi_thermal_driver); |
1574 | if (result < 0) { | 1590 | if (result < 0) { |
1591 | #ifdef CONFIG_ACPI_PROCFS | ||
1575 | remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); | 1592 | remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); |
1593 | #endif | ||
1576 | return -ENODEV; | 1594 | return -ENODEV; |
1577 | } | 1595 | } |
1578 | 1596 | ||
@@ -1584,7 +1602,9 @@ static void __exit acpi_thermal_exit(void) | |||
1584 | 1602 | ||
1585 | acpi_bus_unregister_driver(&acpi_thermal_driver); | 1603 | acpi_bus_unregister_driver(&acpi_thermal_driver); |
1586 | 1604 | ||
1605 | #ifdef CONFIG_ACPI_PROCFS | ||
1587 | remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); | 1606 | remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); |
1607 | #endif | ||
1588 | 1608 | ||
1589 | return; | 1609 | return; |
1590 | } | 1610 | } |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 9865d46f49a8..67dec0c675aa 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -152,7 +152,9 @@ struct acpi_video_bus { | |||
152 | struct acpi_video_bus_flags flags; | 152 | struct acpi_video_bus_flags flags; |
153 | struct list_head video_device_list; | 153 | struct list_head video_device_list; |
154 | struct mutex device_list_lock; /* protects video_device_list */ | 154 | struct mutex device_list_lock; /* protects video_device_list */ |
155 | #ifdef CONFIG_ACPI_PROCFS | ||
155 | struct proc_dir_entry *dir; | 156 | struct proc_dir_entry *dir; |
157 | #endif | ||
156 | struct input_dev *input; | 158 | struct input_dev *input; |
157 | char phys[32]; /* for input device */ | 159 | char phys[32]; /* for input device */ |
158 | struct notifier_block pm_nb; | 160 | struct notifier_block pm_nb; |
@@ -208,6 +210,7 @@ struct acpi_video_device { | |||
208 | struct output_device *output_dev; | 210 | struct output_device *output_dev; |
209 | }; | 211 | }; |
210 | 212 | ||
213 | #ifdef CONFIG_ACPI_PROCFS | ||
211 | /* bus */ | 214 | /* bus */ |
212 | static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file); | 215 | static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file); |
213 | static const struct file_operations acpi_video_bus_info_fops = { | 216 | static const struct file_operations acpi_video_bus_info_fops = { |
@@ -307,6 +310,7 @@ static const struct file_operations acpi_video_device_EDID_fops = { | |||
307 | .llseek = seq_lseek, | 310 | .llseek = seq_lseek, |
308 | .release = single_release, | 311 | .release = single_release, |
309 | }; | 312 | }; |
313 | #endif /* CONFIG_ACPI_PROCFS */ | ||
310 | 314 | ||
311 | static const char device_decode[][30] = { | 315 | static const char device_decode[][30] = { |
312 | "motherboard VGA device", | 316 | "motherboard VGA device", |
@@ -450,16 +454,6 @@ static struct thermal_cooling_device_ops video_cooling_ops = { | |||
450 | /* device */ | 454 | /* device */ |
451 | 455 | ||
452 | static int | 456 | static int |
453 | acpi_video_device_query(struct acpi_video_device *device, unsigned long long *state) | ||
454 | { | ||
455 | int status; | ||
456 | |||
457 | status = acpi_evaluate_integer(device->dev->handle, "_DGS", NULL, state); | ||
458 | |||
459 | return status; | ||
460 | } | ||
461 | |||
462 | static int | ||
463 | acpi_video_device_get_state(struct acpi_video_device *device, | 457 | acpi_video_device_get_state(struct acpi_video_device *device, |
464 | unsigned long long *state) | 458 | unsigned long long *state) |
465 | { | 459 | { |
@@ -698,46 +692,6 @@ acpi_video_device_EDID(struct acpi_video_device *device, | |||
698 | 692 | ||
699 | /* bus */ | 693 | /* bus */ |
700 | 694 | ||
701 | static int | ||
702 | acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option) | ||
703 | { | ||
704 | int status; | ||
705 | unsigned long long tmp; | ||
706 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
707 | struct acpi_object_list args = { 1, &arg0 }; | ||
708 | |||
709 | |||
710 | arg0.integer.value = option; | ||
711 | |||
712 | status = acpi_evaluate_integer(video->device->handle, "_SPD", &args, &tmp); | ||
713 | if (ACPI_SUCCESS(status)) | ||
714 | status = tmp ? (-EINVAL) : (AE_OK); | ||
715 | |||
716 | return status; | ||
717 | } | ||
718 | |||
719 | static int | ||
720 | acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id) | ||
721 | { | ||
722 | int status; | ||
723 | |||
724 | status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id); | ||
725 | |||
726 | return status; | ||
727 | } | ||
728 | |||
729 | static int | ||
730 | acpi_video_bus_POST_options(struct acpi_video_bus *video, | ||
731 | unsigned long long *options) | ||
732 | { | ||
733 | int status; | ||
734 | |||
735 | status = acpi_evaluate_integer(video->device->handle, "_VPO", NULL, options); | ||
736 | *options &= 3; | ||
737 | |||
738 | return status; | ||
739 | } | ||
740 | |||
741 | /* | 695 | /* |
742 | * Arg: | 696 | * Arg: |
743 | * video : video bus device pointer | 697 | * video : video bus device pointer |
@@ -1159,6 +1113,7 @@ static int acpi_video_bus_check(struct acpi_video_bus *video) | |||
1159 | /* -------------------------------------------------------------------------- | 1113 | /* -------------------------------------------------------------------------- |
1160 | FS Interface (/proc) | 1114 | FS Interface (/proc) |
1161 | -------------------------------------------------------------------------- */ | 1115 | -------------------------------------------------------------------------- */ |
1116 | #ifdef CONFIG_ACPI_PROCFS | ||
1162 | 1117 | ||
1163 | static struct proc_dir_entry *acpi_video_dir; | 1118 | static struct proc_dir_entry *acpi_video_dir; |
1164 | 1119 | ||
@@ -1198,6 +1153,18 @@ acpi_video_device_info_open_fs(struct inode *inode, struct file *file) | |||
1198 | PDE(inode)->data); | 1153 | PDE(inode)->data); |
1199 | } | 1154 | } |
1200 | 1155 | ||
1156 | static int | ||
1157 | acpi_video_device_query(struct acpi_video_device *device, | ||
1158 | unsigned long long *state) | ||
1159 | { | ||
1160 | int status; | ||
1161 | |||
1162 | status = acpi_evaluate_integer(device->dev->handle, "_DGS", | ||
1163 | NULL, state); | ||
1164 | |||
1165 | return status; | ||
1166 | } | ||
1167 | |||
1201 | static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) | 1168 | static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) |
1202 | { | 1169 | { |
1203 | int status; | 1170 | int status; |
@@ -1492,6 +1459,19 @@ static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file) | |||
1492 | return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data); | 1459 | return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data); |
1493 | } | 1460 | } |
1494 | 1461 | ||
1462 | static int | ||
1463 | acpi_video_bus_POST_options(struct acpi_video_bus *video, | ||
1464 | unsigned long long *options) | ||
1465 | { | ||
1466 | int status; | ||
1467 | |||
1468 | status = acpi_evaluate_integer(video->device->handle, "_VPO", | ||
1469 | NULL, options); | ||
1470 | *options &= 3; | ||
1471 | |||
1472 | return status; | ||
1473 | } | ||
1474 | |||
1495 | static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) | 1475 | static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) |
1496 | { | 1476 | { |
1497 | struct acpi_video_bus *video = seq->private; | 1477 | struct acpi_video_bus *video = seq->private; |
@@ -1530,6 +1510,16 @@ acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file) | |||
1530 | PDE(inode)->data); | 1510 | PDE(inode)->data); |
1531 | } | 1511 | } |
1532 | 1512 | ||
1513 | static int | ||
1514 | acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id) | ||
1515 | { | ||
1516 | int status; | ||
1517 | |||
1518 | status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id); | ||
1519 | |||
1520 | return status; | ||
1521 | } | ||
1522 | |||
1533 | static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) | 1523 | static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) |
1534 | { | 1524 | { |
1535 | struct acpi_video_bus *video = seq->private; | 1525 | struct acpi_video_bus *video = seq->private; |
@@ -1572,6 +1562,25 @@ static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file) | |||
1572 | return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data); | 1562 | return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data); |
1573 | } | 1563 | } |
1574 | 1564 | ||
1565 | static int | ||
1566 | acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option) | ||
1567 | { | ||
1568 | int status; | ||
1569 | unsigned long long tmp; | ||
1570 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
1571 | struct acpi_object_list args = { 1, &arg0 }; | ||
1572 | |||
1573 | |||
1574 | arg0.integer.value = option; | ||
1575 | |||
1576 | status = acpi_evaluate_integer(video->device->handle, "_SPD", | ||
1577 | &args, &tmp); | ||
1578 | if (ACPI_SUCCESS(status)) | ||
1579 | status = tmp ? (-EINVAL) : (AE_OK); | ||
1580 | |||
1581 | return status; | ||
1582 | } | ||
1583 | |||
1575 | static ssize_t | 1584 | static ssize_t |
1576 | acpi_video_bus_write_POST(struct file *file, | 1585 | acpi_video_bus_write_POST(struct file *file, |
1577 | const char __user * buffer, | 1586 | const char __user * buffer, |
@@ -1722,6 +1731,24 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device) | |||
1722 | 1731 | ||
1723 | return 0; | 1732 | return 0; |
1724 | } | 1733 | } |
1734 | #else | ||
1735 | static inline int acpi_video_device_add_fs(struct acpi_device *device) | ||
1736 | { | ||
1737 | return 0; | ||
1738 | } | ||
1739 | static inline int acpi_video_device_remove_fs(struct acpi_device *device) | ||
1740 | { | ||
1741 | return 0; | ||
1742 | } | ||
1743 | static inline int acpi_video_bus_add_fs(struct acpi_device *device) | ||
1744 | { | ||
1745 | return 0; | ||
1746 | } | ||
1747 | static inline int acpi_video_bus_remove_fs(struct acpi_device *device) | ||
1748 | { | ||
1749 | return 0; | ||
1750 | } | ||
1751 | #endif /* CONFIG_ACPI_PROCFS */ | ||
1725 | 1752 | ||
1726 | /* -------------------------------------------------------------------------- | 1753 | /* -------------------------------------------------------------------------- |
1727 | Driver Interface | 1754 | Driver Interface |
@@ -2140,7 +2167,7 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, | |||
2140 | status = acpi_video_bus_get_one_device(dev, video); | 2167 | status = acpi_video_bus_get_one_device(dev, video); |
2141 | if (ACPI_FAILURE(status)) { | 2168 | if (ACPI_FAILURE(status)) { |
2142 | printk(KERN_WARNING PREFIX | 2169 | printk(KERN_WARNING PREFIX |
2143 | "Cant attach device"); | 2170 | "Cant attach device\n"); |
2144 | continue; | 2171 | continue; |
2145 | } | 2172 | } |
2146 | } | 2173 | } |
@@ -2150,19 +2177,19 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, | |||
2150 | static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | 2177 | static int acpi_video_bus_put_one_device(struct acpi_video_device *device) |
2151 | { | 2178 | { |
2152 | acpi_status status; | 2179 | acpi_status status; |
2153 | struct acpi_video_bus *video; | ||
2154 | |||
2155 | 2180 | ||
2156 | if (!device || !device->video) | 2181 | if (!device || !device->video) |
2157 | return -ENOENT; | 2182 | return -ENOENT; |
2158 | 2183 | ||
2159 | video = device->video; | ||
2160 | |||
2161 | acpi_video_device_remove_fs(device->dev); | 2184 | acpi_video_device_remove_fs(device->dev); |
2162 | 2185 | ||
2163 | status = acpi_remove_notify_handler(device->dev->handle, | 2186 | status = acpi_remove_notify_handler(device->dev->handle, |
2164 | ACPI_DEVICE_NOTIFY, | 2187 | ACPI_DEVICE_NOTIFY, |
2165 | acpi_video_device_notify); | 2188 | acpi_video_device_notify); |
2189 | if (ACPI_FAILURE(status)) { | ||
2190 | printk(KERN_WARNING PREFIX | ||
2191 | "Cant remove video notify handler\n"); | ||
2192 | } | ||
2166 | if (device->backlight) { | 2193 | if (device->backlight) { |
2167 | sysfs_remove_link(&device->backlight->dev.kobj, "device"); | 2194 | sysfs_remove_link(&device->backlight->dev.kobj, "device"); |
2168 | backlight_device_unregister(device->backlight); | 2195 | backlight_device_unregister(device->backlight); |
@@ -2557,9 +2584,11 @@ int acpi_video_register(void) | |||
2557 | return 0; | 2584 | return 0; |
2558 | } | 2585 | } |
2559 | 2586 | ||
2587 | #ifdef CONFIG_ACPI_PROCFS | ||
2560 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); | 2588 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); |
2561 | if (!acpi_video_dir) | 2589 | if (!acpi_video_dir) |
2562 | return -ENODEV; | 2590 | return -ENODEV; |
2591 | #endif | ||
2563 | 2592 | ||
2564 | result = acpi_bus_register_driver(&acpi_video_bus); | 2593 | result = acpi_bus_register_driver(&acpi_video_bus); |
2565 | if (result < 0) { | 2594 | if (result < 0) { |
@@ -2588,7 +2617,9 @@ void acpi_video_unregister(void) | |||
2588 | } | 2617 | } |
2589 | acpi_bus_unregister_driver(&acpi_video_bus); | 2618 | acpi_bus_unregister_driver(&acpi_video_bus); |
2590 | 2619 | ||
2620 | #ifdef CONFIG_ACPI_PROCFS | ||
2591 | remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); | 2621 | remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); |
2622 | #endif | ||
2592 | 2623 | ||
2593 | register_count = 0; | 2624 | register_count = 0; |
2594 | 2625 | ||
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index 4b9d339a6e28..f62a50c3ed34 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c | |||
@@ -21,70 +21,40 @@ | |||
21 | ACPI_MODULE_NAME("wakeup_devices") | 21 | ACPI_MODULE_NAME("wakeup_devices") |
22 | 22 | ||
23 | /** | 23 | /** |
24 | * acpi_enable_wakeup_device_prep - Prepare wake-up devices. | 24 | * acpi_enable_wakeup_devices - Enable wake-up device GPEs. |
25 | * @sleep_state: ACPI system sleep state. | 25 | * @sleep_state: ACPI system sleep state. |
26 | * | 26 | * |
27 | * Enable all wake-up devices' power, unless the requested system sleep state is | 27 | * Enable wakeup device power of devices with the state.enable flag set and set |
28 | * too deep. | 28 | * the wakeup enable mask bits in the GPE registers that correspond to wakeup |
29 | * devices. | ||
29 | */ | 30 | */ |
30 | void acpi_enable_wakeup_device_prep(u8 sleep_state) | 31 | void acpi_enable_wakeup_devices(u8 sleep_state) |
31 | { | 32 | { |
32 | struct list_head *node, *next; | 33 | struct list_head *node, *next; |
33 | 34 | ||
34 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { | 35 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { |
35 | struct acpi_device *dev = container_of(node, | ||
36 | struct acpi_device, | ||
37 | wakeup_list); | ||
38 | |||
39 | if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled | ||
40 | || (sleep_state > (u32) dev->wakeup.sleep_state)) | ||
41 | continue; | ||
42 | |||
43 | acpi_enable_wakeup_device_power(dev, sleep_state); | ||
44 | } | ||
45 | } | ||
46 | |||
47 | /** | ||
48 | * acpi_enable_wakeup_device - Enable wake-up device GPEs. | ||
49 | * @sleep_state: ACPI system sleep state. | ||
50 | * | ||
51 | * Enable all wake-up devices' GPEs, with the assumption that | ||
52 | * acpi_disable_all_gpes() was executed before, so we don't need to disable any | ||
53 | * GPEs here. | ||
54 | */ | ||
55 | void acpi_enable_wakeup_device(u8 sleep_state) | ||
56 | { | ||
57 | struct list_head *node, *next; | ||
58 | |||
59 | /* | ||
60 | * Caution: this routine must be invoked when interrupt is disabled | ||
61 | * Refer ACPI2.0: P212 | ||
62 | */ | ||
63 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { | ||
64 | struct acpi_device *dev = | 36 | struct acpi_device *dev = |
65 | container_of(node, struct acpi_device, wakeup_list); | 37 | container_of(node, struct acpi_device, wakeup_list); |
66 | 38 | ||
67 | if (!dev->wakeup.flags.valid) | 39 | if (!dev->wakeup.flags.valid |
68 | continue; | 40 | || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) |
69 | |||
70 | if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count) | ||
71 | || sleep_state > (u32) dev->wakeup.sleep_state) | 41 | || sleep_state > (u32) dev->wakeup.sleep_state) |
72 | continue; | 42 | continue; |
73 | 43 | ||
44 | if (dev->wakeup.state.enabled) | ||
45 | acpi_enable_wakeup_device_power(dev, sleep_state); | ||
46 | |||
74 | /* The wake-up power should have been enabled already. */ | 47 | /* The wake-up power should have been enabled already. */ |
75 | acpi_set_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, | 48 | acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, |
76 | ACPI_GPE_ENABLE); | 49 | ACPI_GPE_ENABLE); |
77 | } | 50 | } |
78 | } | 51 | } |
79 | 52 | ||
80 | /** | 53 | /** |
81 | * acpi_disable_wakeup_device - Disable devices' wakeup capability. | 54 | * acpi_disable_wakeup_devices - Disable devices' wakeup capability. |
82 | * @sleep_state: ACPI system sleep state. | 55 | * @sleep_state: ACPI system sleep state. |
83 | * | ||
84 | * This function only affects devices with wakeup.state.enabled set, which means | ||
85 | * that it reverses the changes made by acpi_enable_wakeup_device_prep(). | ||
86 | */ | 56 | */ |
87 | void acpi_disable_wakeup_device(u8 sleep_state) | 57 | void acpi_disable_wakeup_devices(u8 sleep_state) |
88 | { | 58 | { |
89 | struct list_head *node, *next; | 59 | struct list_head *node, *next; |
90 | 60 | ||
@@ -92,11 +62,16 @@ void acpi_disable_wakeup_device(u8 sleep_state) | |||
92 | struct acpi_device *dev = | 62 | struct acpi_device *dev = |
93 | container_of(node, struct acpi_device, wakeup_list); | 63 | container_of(node, struct acpi_device, wakeup_list); |
94 | 64 | ||
95 | if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled | 65 | if (!dev->wakeup.flags.valid |
66 | || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) | ||
96 | || (sleep_state > (u32) dev->wakeup.sleep_state)) | 67 | || (sleep_state > (u32) dev->wakeup.sleep_state)) |
97 | continue; | 68 | continue; |
98 | 69 | ||
99 | acpi_disable_wakeup_device_power(dev); | 70 | acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, |
71 | ACPI_GPE_DISABLE); | ||
72 | |||
73 | if (dev->wakeup.state.enabled) | ||
74 | acpi_disable_wakeup_device_power(dev); | ||
100 | } | 75 | } |
101 | } | 76 | } |
102 | 77 | ||
@@ -109,13 +84,8 @@ int __init acpi_wakeup_device_init(void) | |||
109 | struct acpi_device *dev = container_of(node, | 84 | struct acpi_device *dev = container_of(node, |
110 | struct acpi_device, | 85 | struct acpi_device, |
111 | wakeup_list); | 86 | wakeup_list); |
112 | /* In case user doesn't load button driver */ | 87 | if (dev->wakeup.flags.always_enabled) |
113 | if (!dev->wakeup.flags.always_enabled || | 88 | dev->wakeup.state.enabled = 1; |
114 | dev->wakeup.state.enabled) | ||
115 | continue; | ||
116 | acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, | ||
117 | ACPI_GPE_TYPE_WAKE); | ||
118 | dev->wakeup.state.enabled = 1; | ||
119 | } | 89 | } |
120 | mutex_unlock(&acpi_device_lock); | 90 | mutex_unlock(&acpi_device_lock); |
121 | return 0; | 91 | return 0; |