aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/asus_acpi.c55
-rw-r--r--drivers/acpi/battery.c5
-rw-r--r--drivers/acpi/bay.c6
-rw-r--r--drivers/acpi/blacklist.c58
-rw-r--r--drivers/acpi/debug.c57
-rw-r--r--drivers/acpi/dock.c6
-rw-r--r--drivers/acpi/ec.c19
-rw-r--r--drivers/acpi/events/evevent.c2
-rw-r--r--drivers/acpi/events/evgpe.c27
-rw-r--r--drivers/acpi/hardware/hwsleep.c81
-rw-r--r--drivers/acpi/namespace/nsxfeval.c10
-rw-r--r--drivers/acpi/osl.c81
-rw-r--r--drivers/acpi/pci_irq.c5
-rw-r--r--drivers/acpi/power.c6
-rw-r--r--drivers/acpi/processor_core.c17
-rw-r--r--drivers/acpi/processor_idle.c65
-rw-r--r--drivers/acpi/processor_perflib.c16
-rw-r--r--drivers/acpi/scan.c102
-rw-r--r--drivers/acpi/sleep/main.c146
-rw-r--r--drivers/acpi/sleep/proc.c46
-rw-r--r--drivers/acpi/sleep/sleep.h2
-rw-r--r--drivers/acpi/system.c208
-rw-r--r--drivers/acpi/tables/Makefile2
-rw-r--r--drivers/acpi/tables/tbxfroot.c4
-rw-r--r--drivers/acpi/thermal.c17
-rw-r--r--drivers/acpi/utilities/utglobal.c2
-rw-r--r--drivers/acpi/utilities/utresrc.c2
-rw-r--r--drivers/acpi/video.c49
28 files changed, 851 insertions, 245 deletions
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index d915fec9bf63..d25ef961415c 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -142,6 +142,7 @@ struct asus_hotk {
142 xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N 142 xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N
143 A4S, //Z81sp 143 A4S, //Z81sp
144 //(Centrino) 144 //(Centrino)
145 F3Sa,
145 END_MODEL 146 END_MODEL
146 } model; //Models currently supported 147 } model; //Models currently supported
147 u16 event_count[128]; //count for each event TODO make this better 148 u16 event_count[128]; //count for each event TODO make this better
@@ -405,7 +406,20 @@ static struct model_data model_conf[END_MODEL] = {
405 .brightness_get = "GPLV", 406 .brightness_get = "GPLV",
406 .mt_bt_switch = "BLED", 407 .mt_bt_switch = "BLED",
407 .mt_wled = "WLED" 408 .mt_wled = "WLED"
408 } 409 },
410
411 {
412 .name = "F3Sa",
413 .mt_bt_switch = "BLED",
414 .mt_wled = "WLED",
415 .mt_mled = "MLED",
416 .brightness_get = "GPLV",
417 .brightness_set = "SPLV",
418 .mt_lcd_switch = "\\_SB.PCI0.SBRG.EC0._Q10",
419 .lcd_status = "\\_SB.PCI0.SBRG.EC0.RPIN",
420 .display_get = "\\ADVG",
421 .display_set = "SDSP",
422 },
409 423
410}; 424};
411 425
@@ -710,15 +724,8 @@ static int get_lcd_state(void)
710{ 724{
711 int lcd = 0; 725 int lcd = 0;
712 726
713 if (hotk->model != L3H) { 727 if (hotk->model == L3H) {
714 /* We don't have to check anything if we are here */ 728 /* L3H and the like have to be handled differently */
715 if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd))
716 printk(KERN_WARNING
717 "Asus ACPI: Error reading LCD status\n");
718
719 if (hotk->model == L2D)
720 lcd = ~lcd;
721 } else { /* L3H and the like have to be handled differently */
722 acpi_status status = 0; 729 acpi_status status = 0;
723 struct acpi_object_list input; 730 struct acpi_object_list input;
724 union acpi_object mt_params[2]; 731 union acpi_object mt_params[2];
@@ -745,6 +752,32 @@ static int get_lcd_state(void)
745 if (out_obj.type == ACPI_TYPE_INTEGER) 752 if (out_obj.type == ACPI_TYPE_INTEGER)
746 /* That's what the AML code does */ 753 /* That's what the AML code does */
747 lcd = out_obj.integer.value >> 8; 754 lcd = out_obj.integer.value >> 8;
755 } else if (hotk->model == F3Sa) {
756 unsigned long tmp;
757 union acpi_object param;
758 struct acpi_object_list input;
759 acpi_status status;
760
761 /* Read pin 11 */
762 param.type = ACPI_TYPE_INTEGER;
763 param.integer.value = 0x11;
764 input.count = 1;
765 input.pointer = &param;
766
767 status = acpi_evaluate_integer(NULL, hotk->methods->lcd_status,
768 &input, &tmp);
769 if (status != AE_OK)
770 return -1;
771
772 lcd = tmp;
773 } else {
774 /* We don't have to check anything if we are here */
775 if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd))
776 printk(KERN_WARNING
777 "Asus ACPI: Error reading LCD status\n");
778
779 if (hotk->model == L2D)
780 lcd = ~lcd;
748 } 781 }
749 782
750 return (lcd & 1); 783 return (lcd & 1);
@@ -1134,6 +1167,8 @@ static int asus_model_match(char *model)
1134 return W5A; 1167 return W5A;
1135 else if (strncmp(model, "A4S", 3) == 0) 1168 else if (strncmp(model, "A4S", 3) == 0)
1136 return A4S; 1169 return A4S;
1170 else if (strncmp(model, "F3Sa", 4) == 0)
1171 return F3Sa;
1137 else 1172 else
1138 return END_MODEL; 1173 return END_MODEL;
1139} 1174}
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index c4a769d1ba85..f6215e809808 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -194,6 +194,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
194 case POWER_SUPPLY_PROP_MANUFACTURER: 194 case POWER_SUPPLY_PROP_MANUFACTURER:
195 val->strval = battery->oem_info; 195 val->strval = battery->oem_info;
196 break; 196 break;
197 case POWER_SUPPLY_PROP_SERIAL_NUMBER:
198 val->strval = battery->serial_number;
199 break;
197 default: 200 default:
198 return -EINVAL; 201 return -EINVAL;
199 } 202 }
@@ -212,6 +215,7 @@ static enum power_supply_property charge_battery_props[] = {
212 POWER_SUPPLY_PROP_CHARGE_NOW, 215 POWER_SUPPLY_PROP_CHARGE_NOW,
213 POWER_SUPPLY_PROP_MODEL_NAME, 216 POWER_SUPPLY_PROP_MODEL_NAME,
214 POWER_SUPPLY_PROP_MANUFACTURER, 217 POWER_SUPPLY_PROP_MANUFACTURER,
218 POWER_SUPPLY_PROP_SERIAL_NUMBER,
215}; 219};
216 220
217static enum power_supply_property energy_battery_props[] = { 221static enum power_supply_property energy_battery_props[] = {
@@ -226,6 +230,7 @@ static enum power_supply_property energy_battery_props[] = {
226 POWER_SUPPLY_PROP_ENERGY_NOW, 230 POWER_SUPPLY_PROP_ENERGY_NOW,
227 POWER_SUPPLY_PROP_MODEL_NAME, 231 POWER_SUPPLY_PROP_MODEL_NAME,
228 POWER_SUPPLY_PROP_MANUFACTURER, 232 POWER_SUPPLY_PROP_MANUFACTURER,
233 POWER_SUPPLY_PROP_SERIAL_NUMBER,
229}; 234};
230#endif 235#endif
231 236
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
index 6daf6088ac88..477711435b24 100644
--- a/drivers/acpi/bay.c
+++ b/drivers/acpi/bay.c
@@ -46,6 +46,12 @@ MODULE_LICENSE("GPL");
46 printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); } 46 printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); }
47static void bay_notify(acpi_handle handle, u32 event, void *data); 47static void bay_notify(acpi_handle handle, u32 event, void *data);
48 48
49static const struct acpi_device_id bay_device_ids[] = {
50 {"LNXIOBAY", 0},
51 {"", 0},
52};
53MODULE_DEVICE_TABLE(acpi, bay_device_ids);
54
49struct bay { 55struct bay {
50 acpi_handle handle; 56 acpi_handle handle;
51 char *name; 57 char *name;
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index 8809654d6cc9..6dbaa2d15fe0 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -70,8 +70,6 @@ static struct acpi_blacklist_item acpi_blacklist[] __initdata = {
70 /* IBM 600E - _ADR should return 7, but it returns 1 */ 70 /* IBM 600E - _ADR should return 7, but it returns 1 */
71 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal, 71 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
72 "Incorrect _ADR", 1}, 72 "Incorrect _ADR", 1},
73 {"ASUS\0\0", "P2B-S ", 0, ACPI_SIG_DSDT, all_versions,
74 "Bogus PCI routing", 1},
75 73
76 {""} 74 {""}
77}; 75};
@@ -208,33 +206,35 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
208 * Disable OSI(Linux) warnings on all "Acer, inc." 206 * Disable OSI(Linux) warnings on all "Acer, inc."
209 * 207 *
210 * _OSI(Linux) disables the latest Windows BIOS code: 208 * _OSI(Linux) disables the latest Windows BIOS code:
209 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"),
211 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5050"), 210 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5050"),
211 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
212 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5580"), 212 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5580"),
213 * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 3010"), 213 * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 3010"),
214 * _OSI(Linux) effect unknown: 214 * _OSI(Linux) effect unknown:
215 * DMI_MATCH(DMI_PRODUCT_NAME, "Ferrari 5000"), 215 * DMI_MATCH(DMI_PRODUCT_NAME, "Ferrari 5000"),
216 */ 216 */
217 { 217 /*
218 .callback = dmi_disable_osi_linux, 218 * note that dmi_check_system() uses strstr()
219 .ident = "Acer, inc.", 219 * to match sub-strings rather than !strcmp(),
220 .matches = { 220 * so "Acer" below matches "Acer, inc." above.
221 DMI_MATCH(DMI_SYS_VENDOR, "Acer, inc."), 221 */
222 },
223 },
224 /* 222 /*
225 * Disable OSI(Linux) warnings on all "Acer" 223 * Disable OSI(Linux) warnings on all "Acer"
226 * 224 *
227 * _OSI(Linux) effect unknown: 225 * _OSI(Linux) effect unknown:
228 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
229 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), 226 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
230 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720Z"), 227 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720Z"),
231 * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5520"), 228 * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5520"),
232 * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 6460"), 229 * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 6460"),
233 * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 7510"), 230 * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 7510"),
234 * DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5220"), 231 * DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5220"),
232 *
233 * _OSI(Linux) is a NOP:
234 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"),
235 */ 235 */
236 { 236 {
237 .callback = dmi_unknown_osi_linux, 237 .callback = dmi_disable_osi_linux,
238 .ident = "Acer", 238 .ident = "Acer",
239 .matches = { 239 .matches = {
240 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 240 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -242,21 +242,22 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
242 }, 242 },
243 /* 243 /*
244 * Disable OSI(Linux) warnings on all "Apple Computer, Inc." 244 * Disable OSI(Linux) warnings on all "Apple Computer, Inc."
245 * Disable OSI(Linux) warnings on all "Apple Inc."
245 * 246 *
246 * _OSI(Linux) confirmed to be a NOP: 247 * _OSI(Linux) confirmed to be a NOP:
247 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), 248 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"),
248 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"), 249 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"),
249 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2"), 250 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2"),
251 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"),
250 * _OSI(Linux) effect unknown: 252 * _OSI(Linux) effect unknown:
251 * DMI_MATCH(DMI_PRODUCT_NAME, "MacPro2,1"), 253 * DMI_MATCH(DMI_PRODUCT_NAME, "MacPro2,1"),
252 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,1"), 254 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,1"),
253 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"),
254 */ 255 */
255 { 256 {
256 .callback = dmi_disable_osi_linux, 257 .callback = dmi_disable_osi_linux,
257 .ident = "Apple", 258 .ident = "Apple",
258 .matches = { 259 .matches = {
259 DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), 260 DMI_MATCH(DMI_SYS_VENDOR, "Apple"),
260 }, 261 },
261 }, 262 },
262 /* 263 /*
@@ -294,13 +295,13 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
294 * DMI_MATCH(DMI_BOARD_NAME, "IFL91"), 295 * DMI_MATCH(DMI_BOARD_NAME, "IFL91"),
295 */ 296 */
296 { 297 {
297 .callback = dmi_unknown_osi_linux, 298 .callback = dmi_disable_osi_linux,
298 .ident = "Compal", 299 .ident = "Compal",
299 .matches = { 300 .matches = {
300 DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), 301 DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
301 }, 302 },
302 }, 303 },
303 { /* OSI(Linux) touches USB, breaks suspend to disk */ 304 { /* OSI(Linux) touches USB, unknown side-effect */
304 .callback = dmi_disable_osi_linux, 305 .callback = dmi_disable_osi_linux,
305 .ident = "Dell Dimension 5150", 306 .ident = "Dell Dimension 5150",
306 .matches = { 307 .matches = {
@@ -310,7 +311,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
310 }, 311 },
311 { /* OSI(Linux) is a NOP */ 312 { /* OSI(Linux) is a NOP */
312 .callback = dmi_disable_osi_linux, 313 .callback = dmi_disable_osi_linux,
313 .ident = "Dell", 314 .ident = "Dell i1501",
314 .matches = { 315 .matches = {
315 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 316 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
316 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1501"), 317 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1501"),
@@ -318,7 +319,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
318 }, 319 },
319 { /* OSI(Linux) effect unknown */ 320 { /* OSI(Linux) effect unknown */
320 .callback = dmi_unknown_osi_linux, 321 .callback = dmi_unknown_osi_linux,
321 .ident = "Dell", 322 .ident = "Dell Latitude D830",
322 .matches = { 323 .matches = {
323 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 324 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
324 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D830"), 325 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D830"),
@@ -326,7 +327,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
326 }, 327 },
327 { /* OSI(Linux) effect unknown */ 328 { /* OSI(Linux) effect unknown */
328 .callback = dmi_unknown_osi_linux, 329 .callback = dmi_unknown_osi_linux,
329 .ident = "Dell", 330 .ident = "Dell OP GX620",
330 .matches = { 331 .matches = {
331 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 332 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
332 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX620"), 333 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX620"),
@@ -334,15 +335,23 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
334 }, 335 },
335 { /* OSI(Linux) effect unknown */ 336 { /* OSI(Linux) effect unknown */
336 .callback = dmi_unknown_osi_linux, 337 .callback = dmi_unknown_osi_linux,
337 .ident = "Dell", 338 .ident = "Dell PE 1900",
338 .matches = { 339 .matches = {
339 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 340 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
340 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1900"), 341 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1900"),
341 }, 342 },
342 }, 343 },
344 { /* OSI(Linux) is a NOP */
345 .callback = dmi_disable_osi_linux,
346 .ident = "Dell PE R200",
347 .matches = {
348 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
349 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R200"),
350 },
351 },
343 { /* OSI(Linux) touches USB */ 352 { /* OSI(Linux) touches USB */
344 .callback = dmi_disable_osi_linux, 353 .callback = dmi_disable_osi_linux,
345 .ident = "Dell", 354 .ident = "Dell PR 390",
346 .matches = { 355 .matches = {
347 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 356 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
348 DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 390"), 357 DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 390"),
@@ -358,7 +367,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
358 }, 367 },
359 { /* OSI(Linux) effect unknown */ 368 { /* OSI(Linux) effect unknown */
360 .callback = dmi_unknown_osi_linux, 369 .callback = dmi_unknown_osi_linux,
361 .ident = "Dell", 370 .ident = "Dell PE SC440",
362 .matches = { 371 .matches = {
363 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 372 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
364 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge SC440"), 373 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge SC440"),
@@ -474,6 +483,11 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
474 * 483 *
475 * _OSI(Linux) confirmed to be a NOP: 484 * _OSI(Linux) confirmed to be a NOP:
476 * DMI_MATCH(DMI_PRODUCT_NAME, "P1-J150B"), 485 * DMI_MATCH(DMI_PRODUCT_NAME, "P1-J150B"),
486 * with DMI_MATCH(DMI_BOARD_NAME, "ROCKY"),
487 *
488 * unknown:
489 * DMI_MATCH(DMI_PRODUCT_NAME, "S1-MDGDG"),
490 * with DMI_MATCH(DMI_BOARD_NAME, "ROCKY"),
477 */ 491 */
478 { 492 {
479 .callback = dmi_disable_osi_linux, 493 .callback = dmi_disable_osi_linux,
@@ -516,7 +530,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
516 * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ11M"), 530 * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ11M"),
517 */ 531 */
518 { 532 {
519 .callback = dmi_unknown_osi_linux, 533 .callback = dmi_disable_osi_linux,
520 .ident = "Sony", 534 .ident = "Sony",
521 .matches = { 535 .matches = {
522 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 536 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index bf513e07b773..6df564f4ca6e 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -130,6 +130,63 @@ static int param_get_debug_level(char *buffer, struct kernel_param *kp) {
130module_param_call(debug_layer, param_set_uint, param_get_debug_layer, &acpi_dbg_layer, 0644); 130module_param_call(debug_layer, param_set_uint, param_get_debug_layer, &acpi_dbg_layer, 0644);
131module_param_call(debug_level, param_set_uint, param_get_debug_level, &acpi_dbg_level, 0644); 131module_param_call(debug_level, param_set_uint, param_get_debug_level, &acpi_dbg_level, 0644);
132 132
133static char trace_method_name[6];
134module_param_string(trace_method_name, trace_method_name, 6, 0644);
135static unsigned int trace_debug_layer;
136module_param(trace_debug_layer, uint, 0644);
137static unsigned int trace_debug_level;
138module_param(trace_debug_level, uint, 0644);
139
140static int param_set_trace_state(const char *val, struct kernel_param *kp)
141{
142 int result = 0;
143
144 if (!strncmp(val, "enable", strlen("enable") - 1)) {
145 result = acpi_debug_trace(trace_method_name, trace_debug_level,
146 trace_debug_layer, 0);
147 if (result)
148 result = -EBUSY;
149 goto exit;
150 }
151
152 if (!strncmp(val, "disable", strlen("disable") - 1)) {
153 int name = 0;
154 result = acpi_debug_trace((char *)&name, trace_debug_level,
155 trace_debug_layer, 0);
156 if (result)
157 result = -EBUSY;
158 goto exit;
159 }
160
161 if (!strncmp(val, "1", 1)) {
162 result = acpi_debug_trace(trace_method_name, trace_debug_level,
163 trace_debug_layer, 1);
164 if (result)
165 result = -EBUSY;
166 goto exit;
167 }
168
169 result = -EINVAL;
170exit:
171 return result;
172}
173
174static int param_get_trace_state(char *buffer, struct kernel_param *kp)
175{
176 if (!acpi_gbl_trace_method_name)
177 return sprintf(buffer, "disable");
178 else {
179 if (acpi_gbl_trace_flags & 1)
180 return sprintf(buffer, "1");
181 else
182 return sprintf(buffer, "enable");
183 }
184 return 0;
185}
186
187module_param_call(trace_state, param_set_trace_state, param_get_trace_state,
188 NULL, 0644);
189
133/* -------------------------------------------------------------------------- 190/* --------------------------------------------------------------------------
134 FS Interface (/proc) 191 FS Interface (/proc)
135 -------------------------------------------------------------------------- */ 192 -------------------------------------------------------------------------- */
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 1dabdf4c07b3..b3dec2101e2e 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -51,6 +51,12 @@ static struct atomic_notifier_head dock_notifier_list;
51static struct platform_device *dock_device; 51static struct platform_device *dock_device;
52static char dock_device_name[] = "dock"; 52static char dock_device_name[] = "dock";
53 53
54static const struct acpi_device_id dock_device_ids[] = {
55 {"LNXDOCK", 0},
56 {"", 0},
57};
58MODULE_DEVICE_TABLE(acpi, dock_device_ids);
59
54struct dock_station { 60struct dock_station {
55 acpi_handle handle; 61 acpi_handle handle;
56 unsigned long last_dock_time; 62 unsigned long last_dock_time;
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 987b967c7467..7222a18a0319 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -573,7 +573,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
573 void *handler_context, void *region_context) 573 void *handler_context, void *region_context)
574{ 574{
575 struct acpi_ec *ec = handler_context; 575 struct acpi_ec *ec = handler_context;
576 int result = 0, i = 0; 576 int result = 0, i;
577 u8 temp = 0; 577 u8 temp = 0;
578 578
579 if ((address > 0xFF) || !value || !handler_context) 579 if ((address > 0xFF) || !value || !handler_context)
@@ -585,7 +585,18 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
585 if (bits != 8 && acpi_strict) 585 if (bits != 8 && acpi_strict)
586 return AE_BAD_PARAMETER; 586 return AE_BAD_PARAMETER;
587 587
588 while (bits - i > 0) { 588 acpi_ec_burst_enable(ec);
589
590 if (function == ACPI_READ) {
591 result = acpi_ec_read(ec, address, &temp);
592 *value = temp;
593 } else {
594 temp = 0xff & (*value);
595 result = acpi_ec_write(ec, address, temp);
596 }
597
598 for (i = 8; unlikely(bits - i > 0); i += 8) {
599 ++address;
589 if (function == ACPI_READ) { 600 if (function == ACPI_READ) {
590 result = acpi_ec_read(ec, address, &temp); 601 result = acpi_ec_read(ec, address, &temp);
591 (*value) |= ((acpi_integer)temp) << i; 602 (*value) |= ((acpi_integer)temp) << i;
@@ -593,10 +604,10 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
593 temp = 0xff & ((*value) >> i); 604 temp = 0xff & ((*value) >> i);
594 result = acpi_ec_write(ec, address, temp); 605 result = acpi_ec_write(ec, address, temp);
595 } 606 }
596 i += 8;
597 ++address;
598 } 607 }
599 608
609 acpi_ec_burst_disable(ec);
610
600 switch (result) { 611 switch (result) {
601 case -EINVAL: 612 case -EINVAL:
602 return AE_BAD_PARAMETER; 613 return AE_BAD_PARAMETER;
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
index e41287815ea1..3048801a37b5 100644
--- a/drivers/acpi/events/evevent.c
+++ b/drivers/acpi/events/evevent.c
@@ -259,7 +259,7 @@ u32 acpi_ev_fixed_event_detect(void)
259 enable_bit_mask)) { 259 enable_bit_mask)) {
260 260
261 /* Found an active (signalled) event */ 261 /* Found an active (signalled) event */
262 262 acpi_os_fixed_event_count(i);
263 int_status |= acpi_ev_fixed_event_dispatch((u32) i); 263 int_status |= acpi_ev_fixed_event_dispatch((u32) i);
264 } 264 }
265 } 265 }
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index e22f4a973c0f..0dadd2adc800 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -270,18 +270,18 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
270 case ACPI_GPE_TYPE_WAKE_RUN: 270 case ACPI_GPE_TYPE_WAKE_RUN:
271 ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED); 271 ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
272 272
273 /*lint -fallthrough */ 273 /* fallthrough */
274 274
275 case ACPI_GPE_TYPE_RUNTIME: 275 case ACPI_GPE_TYPE_RUNTIME:
276 276
277 /* Disable the requested runtime GPE */ 277 /* Disable the requested runtime GPE */
278 278
279 ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED); 279 ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
280 status = acpi_hw_write_gpe_enable_reg(gpe_event_info); 280
281 break; 281 /* fallthrough */
282 282
283 default: 283 default:
284 return_ACPI_STATUS(AE_BAD_PARAMETER); 284 acpi_hw_write_gpe_enable_reg(gpe_event_info);
285 } 285 }
286 286
287 return_ACPI_STATUS(AE_OK); 287 return_ACPI_STATUS(AE_OK);
@@ -501,6 +501,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
501 * an interrupt handler. 501 * an interrupt handler.
502 * 502 *
503 ******************************************************************************/ 503 ******************************************************************************/
504static void acpi_ev_asynch_enable_gpe(void *context);
504 505
505static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) 506static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
506{ 507{
@@ -576,22 +577,30 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
576 method_node))); 577 method_node)));
577 } 578 }
578 } 579 }
580 /* Defer enabling of GPE until all notify handlers are done */
581 acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe,
582 gpe_event_info);
583 return_VOID;
584}
579 585
580 if ((local_gpe_event_info.flags & ACPI_GPE_XRUPT_TYPE_MASK) == 586static void acpi_ev_asynch_enable_gpe(void *context)
587{
588 struct acpi_gpe_event_info *gpe_event_info = context;
589 acpi_status status;
590 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
581 ACPI_GPE_LEVEL_TRIGGERED) { 591 ACPI_GPE_LEVEL_TRIGGERED) {
582 /* 592 /*
583 * GPE is level-triggered, we clear the GPE status bit after 593 * GPE is level-triggered, we clear the GPE status bit after
584 * handling the event. 594 * handling the event.
585 */ 595 */
586 status = acpi_hw_clear_gpe(&local_gpe_event_info); 596 status = acpi_hw_clear_gpe(gpe_event_info);
587 if (ACPI_FAILURE(status)) { 597 if (ACPI_FAILURE(status)) {
588 return_VOID; 598 return_VOID;
589 } 599 }
590 } 600 }
591 601
592 /* Enable this GPE */ 602 /* Enable this GPE */
593 603 (void)acpi_hw_write_gpe_enable_reg(gpe_event_info);
594 (void)acpi_hw_write_gpe_enable_reg(&local_gpe_event_info);
595 return_VOID; 604 return_VOID;
596} 605}
597 606
@@ -618,7 +627,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
618 627
619 ACPI_FUNCTION_TRACE(ev_gpe_dispatch); 628 ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
620 629
621 acpi_gpe_count++; 630 acpi_os_gpe_count(gpe_number);
622 631
623 /* 632 /*
624 * If edge-triggered, clear the GPE status bit now. Note that 633 * If edge-triggered, clear the GPE status bit now. Note that
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 81b248429703..058d0be5cbe2 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -192,18 +192,13 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
192 arg.type = ACPI_TYPE_INTEGER; 192 arg.type = ACPI_TYPE_INTEGER;
193 arg.integer.value = sleep_state; 193 arg.integer.value = sleep_state;
194 194
195 /* Run the _PTS and _GTS methods */ 195 /* Run the _PTS method */
196 196
197 status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL); 197 status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL);
198 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { 198 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
199 return_ACPI_STATUS(status); 199 return_ACPI_STATUS(status);
200 } 200 }
201 201
202 status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
203 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
204 return_ACPI_STATUS(status);
205 }
206
207 /* Setup the argument to _SST */ 202 /* Setup the argument to _SST */
208 203
209 switch (sleep_state) { 204 switch (sleep_state) {
@@ -234,10 +229,6 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
234 "While executing method _SST")); 229 "While executing method _SST"));
235 } 230 }
236 231
237 /* Disable/Clear all GPEs */
238
239 status = acpi_hw_disable_all_gpes();
240
241 return_ACPI_STATUS(status); 232 return_ACPI_STATUS(status);
242} 233}
243 234
@@ -262,6 +253,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
262 struct acpi_bit_register_info *sleep_type_reg_info; 253 struct acpi_bit_register_info *sleep_type_reg_info;
263 struct acpi_bit_register_info *sleep_enable_reg_info; 254 struct acpi_bit_register_info *sleep_enable_reg_info;
264 u32 in_value; 255 u32 in_value;
256 struct acpi_object_list arg_list;
257 union acpi_object arg;
265 acpi_status status; 258 acpi_status status;
266 259
267 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state); 260 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state);
@@ -293,13 +286,13 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
293 } 286 }
294 287
295 /* 288 /*
289 * 1) Disable/Clear all GPEs
296 * 2) Enable all wakeup GPEs 290 * 2) Enable all wakeup GPEs
297 */ 291 */
298 status = acpi_hw_disable_all_gpes(); 292 status = acpi_hw_disable_all_gpes();
299 if (ACPI_FAILURE(status)) { 293 if (ACPI_FAILURE(status)) {
300 return_ACPI_STATUS(status); 294 return_ACPI_STATUS(status);
301 } 295 }
302
303 acpi_gbl_system_awake_and_running = FALSE; 296 acpi_gbl_system_awake_and_running = FALSE;
304 297
305 status = acpi_hw_enable_all_wakeup_gpes(); 298 status = acpi_hw_enable_all_wakeup_gpes();
@@ -307,6 +300,18 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
307 return_ACPI_STATUS(status); 300 return_ACPI_STATUS(status);
308 } 301 }
309 302
303 /* Execute the _GTS method */
304
305 arg_list.count = 1;
306 arg_list.pointer = &arg;
307 arg.type = ACPI_TYPE_INTEGER;
308 arg.integer.value = sleep_state;
309
310 status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
311 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
312 return_ACPI_STATUS(status);
313 }
314
310 /* Get current value of PM1A control */ 315 /* Get current value of PM1A control */
311 316
312 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); 317 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
@@ -473,17 +478,18 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios)
473 478
474/******************************************************************************* 479/*******************************************************************************
475 * 480 *
476 * FUNCTION: acpi_leave_sleep_state 481 * FUNCTION: acpi_leave_sleep_state_prep
477 * 482 *
478 * PARAMETERS: sleep_state - Which sleep state we just exited 483 * PARAMETERS: sleep_state - Which sleep state we are exiting
479 * 484 *
480 * RETURN: Status 485 * RETURN: Status
481 * 486 *
482 * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep 487 * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a
483 * Called with interrupts ENABLED. 488 * sleep.
489 * Called with interrupts DISABLED.
484 * 490 *
485 ******************************************************************************/ 491 ******************************************************************************/
486acpi_status acpi_leave_sleep_state(u8 sleep_state) 492acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
487{ 493{
488 struct acpi_object_list arg_list; 494 struct acpi_object_list arg_list;
489 union acpi_object arg; 495 union acpi_object arg;
@@ -493,7 +499,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
493 u32 PM1Acontrol; 499 u32 PM1Acontrol;
494 u32 PM1Bcontrol; 500 u32 PM1Bcontrol;
495 501
496 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); 502 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
497 503
498 /* 504 /*
499 * Set SLP_TYPE and SLP_EN to state S0. 505 * Set SLP_TYPE and SLP_EN to state S0.
@@ -540,6 +546,41 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
540 } 546 }
541 } 547 }
542 548
549 /* Execute the _BFS method */
550
551 arg_list.count = 1;
552 arg_list.pointer = &arg;
553 arg.type = ACPI_TYPE_INTEGER;
554 arg.integer.value = sleep_state;
555
556 status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
557 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
558 ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
559 }
560
561 return_ACPI_STATUS(status);
562}
563
564/*******************************************************************************
565 *
566 * FUNCTION: acpi_leave_sleep_state
567 *
568 * PARAMETERS: sleep_state - Which sleep state we just exited
569 *
570 * RETURN: Status
571 *
572 * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
573 * Called with interrupts ENABLED.
574 *
575 ******************************************************************************/
576acpi_status acpi_leave_sleep_state(u8 sleep_state)
577{
578 struct acpi_object_list arg_list;
579 union acpi_object arg;
580 acpi_status status;
581
582 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state);
583
543 /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ 584 /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */
544 585
545 acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; 586 acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID;
@@ -558,12 +599,6 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
558 ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); 599 ACPI_EXCEPTION((AE_INFO, status, "During Method _SST"));
559 } 600 }
560 601
561 arg.integer.value = sleep_state;
562 status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
563 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
564 ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
565 }
566
567 /* 602 /*
568 * GPEs must be enabled before _WAK is called as GPEs 603 * GPEs must be enabled before _WAK is called as GPEs
569 * might get fired there 604 * might get fired there
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index f39fbc6b9237..b92133faf5b7 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -443,6 +443,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
443 struct acpica_device_id hid; 443 struct acpica_device_id hid;
444 struct acpi_compatible_id_list *cid; 444 struct acpi_compatible_id_list *cid;
445 acpi_native_uint i; 445 acpi_native_uint i;
446 int found;
446 447
447 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 448 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
448 if (ACPI_FAILURE(status)) { 449 if (ACPI_FAILURE(status)) {
@@ -496,16 +497,19 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
496 497
497 /* Walk the CID list */ 498 /* Walk the CID list */
498 499
500 found = 0;
499 for (i = 0; i < cid->count; i++) { 501 for (i = 0; i < cid->count; i++) {
500 if (ACPI_STRNCMP(cid->id[i].value, info->hid, 502 if (ACPI_STRNCMP(cid->id[i].value, info->hid,
501 sizeof(struct 503 sizeof(struct
502 acpi_compatible_id)) != 504 acpi_compatible_id)) ==
503 0) { 505 0) {
504 ACPI_FREE(cid); 506 found = 1;
505 return (AE_OK); 507 break;
506 } 508 }
507 } 509 }
508 ACPI_FREE(cid); 510 ACPI_FREE(cid);
511 if (!found)
512 return (AE_OK);
509 } 513 }
510 } 514 }
511 515
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index e53fb516f9d4..3b8aef3aefe5 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -120,7 +120,7 @@ static char osi_additional_string[OSI_STRING_LENGTH_MAX];
120 */ 120 */
121#define OSI_LINUX_ENABLE 0 121#define OSI_LINUX_ENABLE 0
122 122
123struct osi_linux { 123static struct osi_linux {
124 unsigned int enable:1; 124 unsigned int enable:1;
125 unsigned int dmi:1; 125 unsigned int dmi:1;
126 unsigned int cmdline:1; 126 unsigned int cmdline:1;
@@ -250,11 +250,16 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
250 "System description tables not found\n"); 250 "System description tables not found\n");
251 return 0; 251 return 0;
252 } 252 }
253 } else 253 } else {
254 return acpi_find_rsdp(); 254 acpi_physical_address pa = 0;
255
256 acpi_find_root_pointer(&pa);
257 return pa;
258 }
255} 259}
256 260
257void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size) 261void __iomem *__init_refok
262acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
258{ 263{
259 if (phys > ULONG_MAX) { 264 if (phys > ULONG_MAX) {
260 printk(KERN_ERR PREFIX "Cannot map memory that high\n"); 265 printk(KERN_ERR PREFIX "Cannot map memory that high\n");
@@ -332,7 +337,15 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
332 337
333static irqreturn_t acpi_irq(int irq, void *dev_id) 338static irqreturn_t acpi_irq(int irq, void *dev_id)
334{ 339{
335 return (*acpi_irq_handler) (acpi_irq_context) ? IRQ_HANDLED : IRQ_NONE; 340 u32 handled;
341
342 handled = (*acpi_irq_handler) (acpi_irq_context);
343
344 if (handled) {
345 acpi_irq_handled++;
346 return IRQ_HANDLED;
347 } else
348 return IRQ_NONE;
336} 349}
337 350
338acpi_status 351acpi_status
@@ -341,6 +354,8 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
341{ 354{
342 unsigned int irq; 355 unsigned int irq;
343 356
357 acpi_irq_stats_init();
358
344 /* 359 /*
345 * Ignore the GSI from the core, and use the value in our copy of the 360 * Ignore the GSI from the core, and use the value in our copy of the
346 * FADT. It may not be the same if an interrupt source override exists 361 * FADT. It may not be the same if an interrupt source override exists
@@ -661,25 +676,6 @@ static void acpi_os_execute_deferred(struct work_struct *work)
661 dpc->function(dpc->context); 676 dpc->function(dpc->context);
662 kfree(dpc); 677 kfree(dpc);
663 678
664 /* Yield cpu to notify thread */
665 cond_resched();
666
667 return;
668}
669
670static void acpi_os_execute_notify(struct work_struct *work)
671{
672 struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
673
674 if (!dpc) {
675 printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
676 return;
677 }
678
679 dpc->function(dpc->context);
680
681 kfree(dpc);
682
683 return; 679 return;
684} 680}
685 681
@@ -703,7 +699,7 @@ acpi_status acpi_os_execute(acpi_execute_type type,
703{ 699{
704 acpi_status status = AE_OK; 700 acpi_status status = AE_OK;
705 struct acpi_os_dpc *dpc; 701 struct acpi_os_dpc *dpc;
706 702 struct workqueue_struct *queue;
707 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 703 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
708 "Scheduling function [%p(%p)] for deferred execution.\n", 704 "Scheduling function [%p(%p)] for deferred execution.\n",
709 function, context)); 705 function, context));
@@ -727,20 +723,13 @@ acpi_status acpi_os_execute(acpi_execute_type type,
727 dpc->function = function; 723 dpc->function = function;
728 dpc->context = context; 724 dpc->context = context;
729 725
730 if (type == OSL_NOTIFY_HANDLER) { 726 INIT_WORK(&dpc->work, acpi_os_execute_deferred);
731 INIT_WORK(&dpc->work, acpi_os_execute_notify); 727 queue = (type == OSL_NOTIFY_HANDLER) ? kacpi_notify_wq : kacpid_wq;
732 if (!queue_work(kacpi_notify_wq, &dpc->work)) { 728 if (!queue_work(queue, &dpc->work)) {
733 status = AE_ERROR; 729 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
734 kfree(dpc); 730 "Call to queue_work() failed.\n"));
735 } 731 status = AE_ERROR;
736 } else { 732 kfree(dpc);
737 INIT_WORK(&dpc->work, acpi_os_execute_deferred);
738 if (!queue_work(kacpid_wq, &dpc->work)) {
739 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
740 "Call to queue_work() failed.\n"));
741 status = AE_ERROR;
742 kfree(dpc);
743 }
744 } 733 }
745 return_ACPI_STATUS(status); 734 return_ACPI_STATUS(status);
746} 735}
@@ -1213,24 +1202,24 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
1213 * 1202 *
1214 * Returns 0 on success 1203 * Returns 0 on success
1215 */ 1204 */
1216int acpi_dmi_dump(void) 1205static int acpi_dmi_dump(void)
1217{ 1206{
1218 1207
1219 if (!dmi_available) 1208 if (!dmi_available)
1220 return -1; 1209 return -1;
1221 1210
1222 printk(KERN_NOTICE PREFIX "DMI System Vendor: %s\n", 1211 printk(KERN_NOTICE PREFIX "DMI System Vendor: %s\n",
1223 dmi_get_slot(DMI_SYS_VENDOR)); 1212 dmi_get_system_info(DMI_SYS_VENDOR));
1224 printk(KERN_NOTICE PREFIX "DMI Product Name: %s\n", 1213 printk(KERN_NOTICE PREFIX "DMI Product Name: %s\n",
1225 dmi_get_slot(DMI_PRODUCT_NAME)); 1214 dmi_get_system_info(DMI_PRODUCT_NAME));
1226 printk(KERN_NOTICE PREFIX "DMI Product Version: %s\n", 1215 printk(KERN_NOTICE PREFIX "DMI Product Version: %s\n",
1227 dmi_get_slot(DMI_PRODUCT_VERSION)); 1216 dmi_get_system_info(DMI_PRODUCT_VERSION));
1228 printk(KERN_NOTICE PREFIX "DMI Board Name: %s\n", 1217 printk(KERN_NOTICE PREFIX "DMI Board Name: %s\n",
1229 dmi_get_slot(DMI_BOARD_NAME)); 1218 dmi_get_system_info(DMI_BOARD_NAME));
1230 printk(KERN_NOTICE PREFIX "DMI BIOS Vendor: %s\n", 1219 printk(KERN_NOTICE PREFIX "DMI BIOS Vendor: %s\n",
1231 dmi_get_slot(DMI_BIOS_VENDOR)); 1220 dmi_get_system_info(DMI_BIOS_VENDOR));
1232 printk(KERN_NOTICE PREFIX "DMI BIOS Date: %s\n", 1221 printk(KERN_NOTICE PREFIX "DMI BIOS Date: %s\n",
1233 dmi_get_slot(DMI_BIOS_DATE)); 1222 dmi_get_system_info(DMI_BIOS_DATE));
1234 1223
1235 return 0; 1224 return 0;
1236} 1225}
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 62010c2481b3..76d9c669d2d8 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -51,10 +51,8 @@ static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(int segment,
51 int bus, 51 int bus,
52 int device, int pin) 52 int device, int pin)
53{ 53{
54 struct list_head *node = NULL;
55 struct acpi_prt_entry *entry = NULL; 54 struct acpi_prt_entry *entry = NULL;
56 55
57
58 if (!acpi_prt.count) 56 if (!acpi_prt.count)
59 return NULL; 57 return NULL;
60 58
@@ -64,8 +62,7 @@ static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(int segment,
64 * 62 *
65 */ 63 */
66 spin_lock(&acpi_prt_lock); 64 spin_lock(&acpi_prt_lock);
67 list_for_each(node, &acpi_prt.entries) { 65 list_for_each_entry(entry, &acpi_prt.entries, node) {
68 entry = list_entry(node, struct acpi_prt_entry, node);
69 if ((segment == entry->id.segment) 66 if ((segment == entry->id.segment)
70 && (bus == entry->id.bus) 67 && (bus == entry->id.bus)
71 && (device == entry->id.device) 68 && (device == entry->id.device)
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index af1769a20c7a..76bf6d90c700 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -458,11 +458,9 @@ int acpi_power_transition(struct acpi_device *device, int state)
458 } 458 }
459 459
460 end: 460 end:
461 if (result) { 461 if (result)
462 device->power.state = ACPI_STATE_UNKNOWN; 462 device->power.state = ACPI_STATE_UNKNOWN;
463 printk(KERN_WARNING PREFIX "Transitioning device [%s] to D%d\n", 463 else {
464 device->pnp.bus_id, state);
465 } else {
466 /* We shouldn't change the state till all above operations succeed */ 464 /* We shouldn't change the state till all above operations succeed */
467 device->power.state = state; 465 device->power.state = state;
468 } 466 }
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 5668c5e8ae19..315fd8f7e8a1 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -835,11 +835,18 @@ static int is_processor_present(acpi_handle handle)
835 835
836 836
837 status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); 837 status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
838 if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT)) { 838 /*
839 ACPI_EXCEPTION((AE_INFO, status, "Processor Device is not present")); 839 * if a processor object does not have an _STA object,
840 return 0; 840 * OSPM assumes that the processor is present.
841 } 841 */
842 return 1; 842 if (status == AE_NOT_FOUND)
843 return 1;
844
845 if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
846 return 1;
847
848 ACPI_EXCEPTION((AE_INFO, status, "Processor Device is not present"));
849 return 0;
843} 850}
844 851
845static 852static
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index eb1f82f79153..32003fdc91e8 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -38,7 +38,7 @@
38#include <linux/dmi.h> 38#include <linux/dmi.h>
39#include <linux/moduleparam.h> 39#include <linux/moduleparam.h>
40#include <linux/sched.h> /* need_resched() */ 40#include <linux/sched.h> /* need_resched() */
41#include <linux/latency.h> 41#include <linux/pm_qos_params.h>
42#include <linux/clockchips.h> 42#include <linux/clockchips.h>
43#include <linux/cpuidle.h> 43#include <linux/cpuidle.h>
44 44
@@ -98,6 +98,9 @@ module_param(bm_history, uint, 0644);
98 98
99static int acpi_processor_set_power_policy(struct acpi_processor *pr); 99static int acpi_processor_set_power_policy(struct acpi_processor *pr);
100 100
101#else /* CONFIG_CPU_IDLE */
102static unsigned int latency_factor __read_mostly = 2;
103module_param(latency_factor, uint, 0644);
101#endif 104#endif
102 105
103/* 106/*
@@ -201,6 +204,10 @@ static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
201 return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2); 204 return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
202} 205}
203 206
207/*
208 * Callers should disable interrupts before the call and enable
209 * interrupts after return.
210 */
204static void acpi_safe_halt(void) 211static void acpi_safe_halt(void)
205{ 212{
206 current_thread_info()->status &= ~TS_POLLING; 213 current_thread_info()->status &= ~TS_POLLING;
@@ -261,7 +268,7 @@ static atomic_t c3_cpu_count;
261/* Common C-state entry for C2, C3, .. */ 268/* Common C-state entry for C2, C3, .. */
262static void acpi_cstate_enter(struct acpi_processor_cx *cstate) 269static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
263{ 270{
264 if (cstate->space_id == ACPI_CSTATE_FFH) { 271 if (cstate->entry_method == ACPI_CSTATE_FFH) {
265 /* Call into architectural FFH based C-state */ 272 /* Call into architectural FFH based C-state */
266 acpi_processor_ffh_cstate_enter(cstate); 273 acpi_processor_ffh_cstate_enter(cstate);
267 } else { 274 } else {
@@ -413,6 +420,8 @@ static void acpi_processor_idle(void)
413 pm_idle_save(); 420 pm_idle_save();
414 else 421 else
415 acpi_safe_halt(); 422 acpi_safe_halt();
423
424 local_irq_enable();
416 return; 425 return;
417 } 426 }
418 427
@@ -521,6 +530,7 @@ static void acpi_processor_idle(void)
521 * skew otherwise. 530 * skew otherwise.
522 */ 531 */
523 sleep_ticks = 0xFFFFFFFF; 532 sleep_ticks = 0xFFFFFFFF;
533 local_irq_enable();
524 break; 534 break;
525 535
526 case ACPI_STATE_C2: 536 case ACPI_STATE_C2:
@@ -648,7 +658,8 @@ static void acpi_processor_idle(void)
648 if (cx->promotion.state && 658 if (cx->promotion.state &&
649 ((cx->promotion.state - pr->power.states) <= max_cstate)) { 659 ((cx->promotion.state - pr->power.states) <= max_cstate)) {
650 if (sleep_ticks > cx->promotion.threshold.ticks && 660 if (sleep_ticks > cx->promotion.threshold.ticks &&
651 cx->promotion.state->latency <= system_latency_constraint()) { 661 cx->promotion.state->latency <=
662 pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) {
652 cx->promotion.count++; 663 cx->promotion.count++;
653 cx->demotion.count = 0; 664 cx->demotion.count = 0;
654 if (cx->promotion.count >= 665 if (cx->promotion.count >=
@@ -692,7 +703,8 @@ static void acpi_processor_idle(void)
692 * or if the latency of the current state is unacceptable 703 * or if the latency of the current state is unacceptable
693 */ 704 */
694 if ((pr->power.state - pr->power.states) > max_cstate || 705 if ((pr->power.state - pr->power.states) > max_cstate ||
695 pr->power.state->latency > system_latency_constraint()) { 706 pr->power.state->latency >
707 pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) {
696 if (cx->demotion.state) 708 if (cx->demotion.state)
697 next_state = cx->demotion.state; 709 next_state = cx->demotion.state;
698 } 710 }
@@ -920,20 +932,20 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
920 cx.address = reg->address; 932 cx.address = reg->address;
921 cx.index = current_count + 1; 933 cx.index = current_count + 1;
922 934
923 cx.space_id = ACPI_CSTATE_SYSTEMIO; 935 cx.entry_method = ACPI_CSTATE_SYSTEMIO;
924 if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { 936 if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) {
925 if (acpi_processor_ffh_cstate_probe 937 if (acpi_processor_ffh_cstate_probe
926 (pr->id, &cx, reg) == 0) { 938 (pr->id, &cx, reg) == 0) {
927 cx.space_id = ACPI_CSTATE_FFH; 939 cx.entry_method = ACPI_CSTATE_FFH;
928 } else if (cx.type != ACPI_STATE_C1) { 940 } else if (cx.type == ACPI_STATE_C1) {
929 /* 941 /*
930 * C1 is a special case where FIXED_HARDWARE 942 * C1 is a special case where FIXED_HARDWARE
931 * can be handled in non-MWAIT way as well. 943 * can be handled in non-MWAIT way as well.
932 * In that case, save this _CST entry info. 944 * In that case, save this _CST entry info.
933 * That is, we retain space_id of SYSTEM_IO for
934 * halt based C1.
935 * Otherwise, ignore this info and continue. 945 * Otherwise, ignore this info and continue.
936 */ 946 */
947 cx.entry_method = ACPI_CSTATE_HALT;
948 } else {
937 continue; 949 continue;
938 } 950 }
939 } 951 }
@@ -1200,7 +1212,7 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
1200 "maximum allowed latency: %d usec\n", 1212 "maximum allowed latency: %d usec\n",
1201 pr->power.state ? pr->power.state - pr->power.states : 0, 1213 pr->power.state ? pr->power.state - pr->power.states : 0,
1202 max_cstate, (unsigned)pr->power.bm_activity, 1214 max_cstate, (unsigned)pr->power.bm_activity,
1203 system_latency_constraint()); 1215 pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
1204 1216
1205 seq_puts(seq, "states:\n"); 1217 seq_puts(seq, "states:\n");
1206 1218
@@ -1367,12 +1379,16 @@ static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr,
1367/** 1379/**
1368 * acpi_idle_do_entry - a helper function that does C2 and C3 type entry 1380 * acpi_idle_do_entry - a helper function that does C2 and C3 type entry
1369 * @cx: cstate data 1381 * @cx: cstate data
1382 *
1383 * Caller disables interrupt before call and enables interrupt after return.
1370 */ 1384 */
1371static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) 1385static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
1372{ 1386{
1373 if (cx->space_id == ACPI_CSTATE_FFH) { 1387 if (cx->entry_method == ACPI_CSTATE_FFH) {
1374 /* Call into architectural FFH based C-state */ 1388 /* Call into architectural FFH based C-state */
1375 acpi_processor_ffh_cstate_enter(cx); 1389 acpi_processor_ffh_cstate_enter(cx);
1390 } else if (cx->entry_method == ACPI_CSTATE_HALT) {
1391 acpi_safe_halt();
1376 } else { 1392 } else {
1377 int unused; 1393 int unused;
1378 /* IO port based C-state */ 1394 /* IO port based C-state */
@@ -1394,21 +1410,27 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
1394static int acpi_idle_enter_c1(struct cpuidle_device *dev, 1410static int acpi_idle_enter_c1(struct cpuidle_device *dev,
1395 struct cpuidle_state *state) 1411 struct cpuidle_state *state)
1396{ 1412{
1413 u32 t1, t2;
1397 struct acpi_processor *pr; 1414 struct acpi_processor *pr;
1398 struct acpi_processor_cx *cx = cpuidle_get_statedata(state); 1415 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
1416
1399 pr = processors[smp_processor_id()]; 1417 pr = processors[smp_processor_id()];
1400 1418
1401 if (unlikely(!pr)) 1419 if (unlikely(!pr))
1402 return 0; 1420 return 0;
1403 1421
1422 local_irq_disable();
1404 if (pr->flags.bm_check) 1423 if (pr->flags.bm_check)
1405 acpi_idle_update_bm_rld(pr, cx); 1424 acpi_idle_update_bm_rld(pr, cx);
1406 1425
1407 acpi_safe_halt(); 1426 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
1427 acpi_idle_do_entry(cx);
1428 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
1408 1429
1430 local_irq_enable();
1409 cx->usage++; 1431 cx->usage++;
1410 1432
1411 return 0; 1433 return ticks_elapsed_in_us(t1, t2);
1412} 1434}
1413 1435
1414/** 1436/**
@@ -1515,7 +1537,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1515 if (dev->safe_state) { 1537 if (dev->safe_state) {
1516 return dev->safe_state->enter(dev, dev->safe_state); 1538 return dev->safe_state->enter(dev, dev->safe_state);
1517 } else { 1539 } else {
1540 local_irq_disable();
1518 acpi_safe_halt(); 1541 acpi_safe_halt();
1542 local_irq_enable();
1519 return 0; 1543 return 0;
1520 } 1544 }
1521 } 1545 }
@@ -1607,7 +1631,7 @@ struct cpuidle_driver acpi_idle_driver = {
1607 */ 1631 */
1608static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) 1632static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1609{ 1633{
1610 int i, count = 0; 1634 int i, count = CPUIDLE_DRIVER_STATE_START;
1611 struct acpi_processor_cx *cx; 1635 struct acpi_processor_cx *cx;
1612 struct cpuidle_state *state; 1636 struct cpuidle_state *state;
1613 struct cpuidle_device *dev = &pr->power.dev; 1637 struct cpuidle_device *dev = &pr->power.dev;
@@ -1636,13 +1660,14 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1636 1660
1637 snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i); 1661 snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i);
1638 state->exit_latency = cx->latency; 1662 state->exit_latency = cx->latency;
1639 state->target_residency = cx->latency * 6; 1663 state->target_residency = cx->latency * latency_factor;
1640 state->power_usage = cx->power; 1664 state->power_usage = cx->power;
1641 1665
1642 state->flags = 0; 1666 state->flags = 0;
1643 switch (cx->type) { 1667 switch (cx->type) {
1644 case ACPI_STATE_C1: 1668 case ACPI_STATE_C1:
1645 state->flags |= CPUIDLE_FLAG_SHALLOW; 1669 state->flags |= CPUIDLE_FLAG_SHALLOW;
1670 state->flags |= CPUIDLE_FLAG_TIME_VALID;
1646 state->enter = acpi_idle_enter_c1; 1671 state->enter = acpi_idle_enter_c1;
1647 dev->safe_state = state; 1672 dev->safe_state = state;
1648 break; 1673 break;
@@ -1665,6 +1690,8 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1665 } 1690 }
1666 1691
1667 count++; 1692 count++;
1693 if (count == CPUIDLE_STATE_MAX)
1694 break;
1668 } 1695 }
1669 1696
1670 dev->state_count = count; 1697 dev->state_count = count;
@@ -1718,8 +1745,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1718 "ACPI: processor limited to max C-state %d\n", 1745 "ACPI: processor limited to max C-state %d\n",
1719 max_cstate); 1746 max_cstate);
1720 first_run++; 1747 first_run++;
1721#if !defined (CONFIG_CPU_IDLE) && defined (CONFIG_SMP) 1748#if !defined(CONFIG_CPU_IDLE) && defined(CONFIG_SMP)
1722 register_latency_notifier(&acpi_processor_latency_notifier); 1749 pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY,
1750 &acpi_processor_latency_notifier);
1723#endif 1751#endif
1724 } 1752 }
1725 1753
@@ -1806,7 +1834,8 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
1806 */ 1834 */
1807 cpu_idle_wait(); 1835 cpu_idle_wait();
1808#ifdef CONFIG_SMP 1836#ifdef CONFIG_SMP
1809 unregister_latency_notifier(&acpi_processor_latency_notifier); 1837 pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY,
1838 &acpi_processor_latency_notifier);
1810#endif 1839#endif
1811 } 1840 }
1812#endif 1841#endif
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 463b0247cbc5..f32010bee4d5 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -60,6 +60,11 @@ static DEFINE_MUTEX(performance_mutex);
60 * policy is adjusted accordingly. 60 * policy is adjusted accordingly.
61 */ 61 */
62 62
63static unsigned int ignore_ppc = 0;
64module_param(ignore_ppc, uint, 0644);
65MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \
66 "limited by BIOS, this should help");
67
63#define PPC_REGISTERED 1 68#define PPC_REGISTERED 1
64#define PPC_IN_USE 2 69#define PPC_IN_USE 2
65 70
@@ -72,6 +77,9 @@ static int acpi_processor_ppc_notifier(struct notifier_block *nb,
72 struct acpi_processor *pr; 77 struct acpi_processor *pr;
73 unsigned int ppc = 0; 78 unsigned int ppc = 0;
74 79
80 if (ignore_ppc)
81 return 0;
82
75 mutex_lock(&performance_mutex); 83 mutex_lock(&performance_mutex);
76 84
77 if (event != CPUFREQ_INCOMPATIBLE) 85 if (event != CPUFREQ_INCOMPATIBLE)
@@ -130,7 +138,13 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
130 138
131int acpi_processor_ppc_has_changed(struct acpi_processor *pr) 139int acpi_processor_ppc_has_changed(struct acpi_processor *pr)
132{ 140{
133 int ret = acpi_processor_get_platform_limit(pr); 141 int ret;
142
143 if (ignore_ppc)
144 return 0;
145
146 ret = acpi_processor_get_platform_limit(pr);
147
134 if (ret < 0) 148 if (ret < 0)
135 return (ret); 149 return (ret);
136 else 150 else
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index cbfe9ae7a9e5..c7b0aa52dd23 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -830,7 +830,7 @@ static int acpi_bus_get_flags(struct acpi_device *device)
830 if (ACPI_SUCCESS(status)) 830 if (ACPI_SUCCESS(status))
831 device->flags.wake_capable = 1; 831 device->flags.wake_capable = 1;
832 832
833 /* TBD: Peformance management */ 833 /* TBD: Performance management */
834 834
835 return 0; 835 return 0;
836} 836}
@@ -941,6 +941,15 @@ static int acpi_bay_match(struct acpi_device *device){
941 return -ENODEV; 941 return -ENODEV;
942} 942}
943 943
944/*
945 * acpi_dock_match - see if a device has a _DCK method
946 */
947static int acpi_dock_match(struct acpi_device *device)
948{
949 acpi_handle tmp;
950 return acpi_get_handle(device->handle, "_DCK", &tmp);
951}
952
944static void acpi_device_set_id(struct acpi_device *device, 953static void acpi_device_set_id(struct acpi_device *device,
945 struct acpi_device *parent, acpi_handle handle, 954 struct acpi_device *parent, acpi_handle handle,
946 int type) 955 int type)
@@ -950,6 +959,7 @@ static void acpi_device_set_id(struct acpi_device *device,
950 char *hid = NULL; 959 char *hid = NULL;
951 char *uid = NULL; 960 char *uid = NULL;
952 struct acpi_compatible_id_list *cid_list = NULL; 961 struct acpi_compatible_id_list *cid_list = NULL;
962 const char *cid_add = NULL;
953 acpi_status status; 963 acpi_status status;
954 964
955 switch (type) { 965 switch (type) {
@@ -972,15 +982,18 @@ static void acpi_device_set_id(struct acpi_device *device,
972 device->flags.bus_address = 1; 982 device->flags.bus_address = 1;
973 } 983 }
974 984
975 if(!(info->valid & (ACPI_VALID_HID | ACPI_VALID_CID))){ 985 /* If we have a video/bay/dock device, add our selfdefined
976 status = acpi_video_bus_match(device); 986 HID to the CID list. Like that the video/bay/dock drivers
977 if(ACPI_SUCCESS(status)) 987 will get autoloaded and the device might still match
978 hid = ACPI_VIDEO_HID; 988 against another driver.
989 */
990 if (ACPI_SUCCESS(acpi_video_bus_match(device)))
991 cid_add = ACPI_VIDEO_HID;
992 else if (ACPI_SUCCESS(acpi_bay_match(device)))
993 cid_add = ACPI_BAY_HID;
994 else if (ACPI_SUCCESS(acpi_dock_match(device)))
995 cid_add = ACPI_DOCK_HID;
979 996
980 status = acpi_bay_match(device);
981 if (ACPI_SUCCESS(status))
982 hid = ACPI_BAY_HID;
983 }
984 break; 997 break;
985 case ACPI_BUS_TYPE_POWER: 998 case ACPI_BUS_TYPE_POWER:
986 hid = ACPI_POWER_HID; 999 hid = ACPI_POWER_HID;
@@ -1021,11 +1034,44 @@ static void acpi_device_set_id(struct acpi_device *device,
1021 strcpy(device->pnp.unique_id, uid); 1034 strcpy(device->pnp.unique_id, uid);
1022 device->flags.unique_id = 1; 1035 device->flags.unique_id = 1;
1023 } 1036 }
1024 if (cid_list) { 1037 if (cid_list || cid_add) {
1025 device->pnp.cid_list = kmalloc(cid_list->size, GFP_KERNEL); 1038 struct acpi_compatible_id_list *list;
1026 if (device->pnp.cid_list) 1039 int size = 0;
1027 memcpy(device->pnp.cid_list, cid_list, cid_list->size); 1040 int count = 0;
1028 else 1041
1042 if (cid_list) {
1043 size = cid_list->size;
1044 } else if (cid_add) {
1045 size = sizeof(struct acpi_compatible_id_list);
1046 cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
1047 if (!cid_list) {
1048 printk(KERN_ERR "Memory allocation error\n");
1049 kfree(buffer.pointer);
1050 return;
1051 } else {
1052 cid_list->count = 0;
1053 cid_list->size = size;
1054 }
1055 }
1056 if (cid_add)
1057 size += sizeof(struct acpi_compatible_id);
1058 list = kmalloc(size, GFP_KERNEL);
1059
1060 if (list) {
1061 if (cid_list) {
1062 memcpy(list, cid_list, cid_list->size);
1063 count = cid_list->count;
1064 }
1065 if (cid_add) {
1066 strncpy(list->id[count].value, cid_add,
1067 ACPI_MAX_CID_LENGTH);
1068 count++;
1069 device->flags.compatible_ids = 1;
1070 }
1071 list->size = size;
1072 list->count = count;
1073 device->pnp.cid_list = list;
1074 } else
1029 printk(KERN_ERR "Memory allocation error\n"); 1075 printk(KERN_ERR "Memory allocation error\n");
1030 } 1076 }
1031 1077
@@ -1081,6 +1127,20 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
1081} 1127}
1082 1128
1083static int 1129static int
1130acpi_is_child_device(struct acpi_device *device,
1131 int (*matcher)(struct acpi_device *))
1132{
1133 int result = -ENODEV;
1134
1135 do {
1136 if (ACPI_SUCCESS(matcher(device)))
1137 return AE_OK;
1138 } while ((device = device->parent));
1139
1140 return result;
1141}
1142
1143static int
1084acpi_add_single_object(struct acpi_device **child, 1144acpi_add_single_object(struct acpi_device **child,
1085 struct acpi_device *parent, acpi_handle handle, int type, 1145 struct acpi_device *parent, acpi_handle handle, int type,
1086 struct acpi_bus_ops *ops) 1146 struct acpi_bus_ops *ops)
@@ -1131,10 +1191,20 @@ acpi_add_single_object(struct acpi_device **child,
1131 case ACPI_BUS_TYPE_PROCESSOR: 1191 case ACPI_BUS_TYPE_PROCESSOR:
1132 case ACPI_BUS_TYPE_DEVICE: 1192 case ACPI_BUS_TYPE_DEVICE:
1133 result = acpi_bus_get_status(device); 1193 result = acpi_bus_get_status(device);
1134 if (ACPI_FAILURE(result) || !device->status.present) { 1194 if (ACPI_FAILURE(result)) {
1135 result = -ENOENT; 1195 result = -ENODEV;
1136 goto end; 1196 goto end;
1137 } 1197 }
1198 if (!device->status.present) {
1199 /* Bay and dock should be handled even if absent */
1200 if (!ACPI_SUCCESS(
1201 acpi_is_child_device(device, acpi_bay_match)) &&
1202 !ACPI_SUCCESS(
1203 acpi_is_child_device(device, acpi_dock_match))) {
1204 result = -ENODEV;
1205 goto end;
1206 }
1207 }
1138 break; 1208 break;
1139 default: 1209 default:
1140 STRUCT_TO_INT(device->status) = 1210 STRUCT_TO_INT(device->status) =
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 2c0b6630f8ba..293a1cbb47c0 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -26,9 +26,24 @@ u8 sleep_states[ACPI_S_STATE_COUNT];
26 26
27#ifdef CONFIG_PM_SLEEP 27#ifdef CONFIG_PM_SLEEP
28static u32 acpi_target_sleep_state = ACPI_STATE_S0; 28static u32 acpi_target_sleep_state = ACPI_STATE_S0;
29static bool acpi_sleep_finish_wake_up;
30
31/*
32 * ACPI 2.0 and later want us to execute _PTS after suspending devices, so we
33 * allow the user to request that behavior by using the 'acpi_new_pts_ordering'
34 * kernel command line option that causes the following variable to be set.
35 */
36static bool new_pts_ordering;
37
38static int __init acpi_new_pts_ordering(char *str)
39{
40 new_pts_ordering = true;
41 return 1;
42}
43__setup("acpi_new_pts_ordering", acpi_new_pts_ordering);
29#endif 44#endif
30 45
31int acpi_sleep_prepare(u32 acpi_state) 46static int acpi_sleep_prepare(u32 acpi_state)
32{ 47{
33#ifdef CONFIG_ACPI_SLEEP 48#ifdef CONFIG_ACPI_SLEEP
34 /* do we have a wakeup address for S2 and S3? */ 49 /* do we have a wakeup address for S2 and S3? */
@@ -44,6 +59,8 @@ int acpi_sleep_prepare(u32 acpi_state)
44 ACPI_FLUSH_CPU_CACHE(); 59 ACPI_FLUSH_CPU_CACHE();
45 acpi_enable_wakeup_device_prep(acpi_state); 60 acpi_enable_wakeup_device_prep(acpi_state);
46#endif 61#endif
62 printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n",
63 acpi_state);
47 acpi_enter_sleep_state_prep(acpi_state); 64 acpi_enter_sleep_state_prep(acpi_state);
48 return 0; 65 return 0;
49} 66}
@@ -63,17 +80,25 @@ static u32 acpi_suspend_states[] = {
63static int init_8259A_after_S1; 80static int init_8259A_after_S1;
64 81
65/** 82/**
66 * acpi_pm_set_target - Set the target system sleep state to the state 83 * acpi_pm_begin - Set the target system sleep state to the state
67 * associated with given @pm_state, if supported. 84 * associated with given @pm_state, if supported.
68 */ 85 */
69 86
70static int acpi_pm_set_target(suspend_state_t pm_state) 87static int acpi_pm_begin(suspend_state_t pm_state)
71{ 88{
72 u32 acpi_state = acpi_suspend_states[pm_state]; 89 u32 acpi_state = acpi_suspend_states[pm_state];
73 int error = 0; 90 int error = 0;
74 91
75 if (sleep_states[acpi_state]) { 92 if (sleep_states[acpi_state]) {
76 acpi_target_sleep_state = acpi_state; 93 acpi_target_sleep_state = acpi_state;
94 if (new_pts_ordering)
95 return 0;
96
97 error = acpi_sleep_prepare(acpi_state);
98 if (error)
99 acpi_target_sleep_state = ACPI_STATE_S0;
100 else
101 acpi_sleep_finish_wake_up = true;
77 } else { 102 } else {
78 printk(KERN_ERR "ACPI does not support this state: %d\n", 103 printk(KERN_ERR "ACPI does not support this state: %d\n",
79 pm_state); 104 pm_state);
@@ -91,12 +116,17 @@ static int acpi_pm_set_target(suspend_state_t pm_state)
91 116
92static int acpi_pm_prepare(void) 117static int acpi_pm_prepare(void)
93{ 118{
94 int error = acpi_sleep_prepare(acpi_target_sleep_state); 119 if (new_pts_ordering) {
120 int error = acpi_sleep_prepare(acpi_target_sleep_state);
95 121
96 if (error) 122 if (error) {
97 acpi_target_sleep_state = ACPI_STATE_S0; 123 acpi_target_sleep_state = ACPI_STATE_S0;
124 return error;
125 }
126 acpi_sleep_finish_wake_up = true;
127 }
98 128
99 return error; 129 return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT;
100} 130}
101 131
102/** 132/**
@@ -120,10 +150,8 @@ static int acpi_pm_enter(suspend_state_t pm_state)
120 if (acpi_state == ACPI_STATE_S3) { 150 if (acpi_state == ACPI_STATE_S3) {
121 int error = acpi_save_state_mem(); 151 int error = acpi_save_state_mem();
122 152
123 if (error) { 153 if (error)
124 acpi_target_sleep_state = ACPI_STATE_S0;
125 return error; 154 return error;
126 }
127 } 155 }
128 156
129 local_irq_save(flags); 157 local_irq_save(flags);
@@ -139,13 +167,23 @@ static int acpi_pm_enter(suspend_state_t pm_state)
139 break; 167 break;
140 } 168 }
141 169
142 /* ACPI 3.0 specs (P62) says that it's the responsabilty 170 /* Reprogram control registers and execute _BFS */
171 acpi_leave_sleep_state_prep(acpi_state);
172
173 /* ACPI 3.0 specs (P62) says that it's the responsibility
143 * of the OSPM to clear the status bit [ implying that the 174 * of the OSPM to clear the status bit [ implying that the
144 * POWER_BUTTON event should not reach userspace ] 175 * POWER_BUTTON event should not reach userspace ]
145 */ 176 */
146 if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) 177 if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3))
147 acpi_clear_event(ACPI_EVENT_POWER_BUTTON); 178 acpi_clear_event(ACPI_EVENT_POWER_BUTTON);
148 179
180 /*
181 * Disable and clear GPE status before interrupt is enabled. Some GPEs
182 * (like wakeup GPE) haven't handler, this can avoid such GPE misfire.
183 * acpi_leave_sleep_state will reenable specific GPEs later
184 */
185 acpi_hw_disable_all_gpes();
186
149 local_irq_restore(flags); 187 local_irq_restore(flags);
150 printk(KERN_DEBUG "Back to C!\n"); 188 printk(KERN_DEBUG "Back to C!\n");
151 189
@@ -157,7 +195,7 @@ static int acpi_pm_enter(suspend_state_t pm_state)
157} 195}
158 196
159/** 197/**
160 * acpi_pm_finish - Finish up suspend sequence. 198 * acpi_pm_finish - Instruct the platform to leave a sleep state.
161 * 199 *
162 * This is called after we wake back up (or if entering the sleep state 200 * This is called after we wake back up (or if entering the sleep state
163 * failed). 201 * failed).
@@ -174,6 +212,7 @@ static void acpi_pm_finish(void)
174 acpi_set_firmware_waking_vector((acpi_physical_address) 0); 212 acpi_set_firmware_waking_vector((acpi_physical_address) 0);
175 213
176 acpi_target_sleep_state = ACPI_STATE_S0; 214 acpi_target_sleep_state = ACPI_STATE_S0;
215 acpi_sleep_finish_wake_up = false;
177 216
178#ifdef CONFIG_X86 217#ifdef CONFIG_X86
179 if (init_8259A_after_S1) { 218 if (init_8259A_after_S1) {
@@ -183,6 +222,20 @@ static void acpi_pm_finish(void)
183#endif 222#endif
184} 223}
185 224
225/**
226 * acpi_pm_end - Finish up suspend sequence.
227 */
228
229static void acpi_pm_end(void)
230{
231 /*
232 * This is necessary in case acpi_pm_finish() is not called directly
233 * during a failing transition to a sleep state.
234 */
235 if (acpi_sleep_finish_wake_up)
236 acpi_pm_finish();
237}
238
186static int acpi_pm_state_valid(suspend_state_t pm_state) 239static int acpi_pm_state_valid(suspend_state_t pm_state)
187{ 240{
188 u32 acpi_state; 241 u32 acpi_state;
@@ -201,10 +254,11 @@ static int acpi_pm_state_valid(suspend_state_t pm_state)
201 254
202static struct platform_suspend_ops acpi_pm_ops = { 255static struct platform_suspend_ops acpi_pm_ops = {
203 .valid = acpi_pm_state_valid, 256 .valid = acpi_pm_state_valid,
204 .set_target = acpi_pm_set_target, 257 .begin = acpi_pm_begin,
205 .prepare = acpi_pm_prepare, 258 .prepare = acpi_pm_prepare,
206 .enter = acpi_pm_enter, 259 .enter = acpi_pm_enter,
207 .finish = acpi_pm_finish, 260 .finish = acpi_pm_finish,
261 .end = acpi_pm_end,
208}; 262};
209 263
210/* 264/*
@@ -229,15 +283,36 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
229#endif /* CONFIG_SUSPEND */ 283#endif /* CONFIG_SUSPEND */
230 284
231#ifdef CONFIG_HIBERNATION 285#ifdef CONFIG_HIBERNATION
232static int acpi_hibernation_start(void) 286static int acpi_hibernation_begin(void)
233{ 287{
288 int error;
289
234 acpi_target_sleep_state = ACPI_STATE_S4; 290 acpi_target_sleep_state = ACPI_STATE_S4;
235 return 0; 291 if (new_pts_ordering)
292 return 0;
293
294 error = acpi_sleep_prepare(ACPI_STATE_S4);
295 if (error)
296 acpi_target_sleep_state = ACPI_STATE_S0;
297 else
298 acpi_sleep_finish_wake_up = true;
299
300 return error;
236} 301}
237 302
238static int acpi_hibernation_prepare(void) 303static int acpi_hibernation_prepare(void)
239{ 304{
240 return acpi_sleep_prepare(ACPI_STATE_S4); 305 if (new_pts_ordering) {
306 int error = acpi_sleep_prepare(ACPI_STATE_S4);
307
308 if (error) {
309 acpi_target_sleep_state = ACPI_STATE_S0;
310 return error;
311 }
312 acpi_sleep_finish_wake_up = true;
313 }
314
315 return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT;
241} 316}
242 317
243static int acpi_hibernation_enter(void) 318static int acpi_hibernation_enter(void)
@@ -251,6 +326,8 @@ static int acpi_hibernation_enter(void)
251 acpi_enable_wakeup_device(ACPI_STATE_S4); 326 acpi_enable_wakeup_device(ACPI_STATE_S4);
252 /* This shouldn't return. If it returns, we have a problem */ 327 /* This shouldn't return. If it returns, we have a problem */
253 status = acpi_enter_sleep_state(ACPI_STATE_S4); 328 status = acpi_enter_sleep_state(ACPI_STATE_S4);
329 /* Reprogram control registers and execute _BFS */
330 acpi_leave_sleep_state_prep(ACPI_STATE_S4);
254 local_irq_restore(flags); 331 local_irq_restore(flags);
255 332
256 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 333 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
@@ -263,15 +340,12 @@ static void acpi_hibernation_leave(void)
263 * enable it here. 340 * enable it here.
264 */ 341 */
265 acpi_enable(); 342 acpi_enable();
343 /* Reprogram control registers and execute _BFS */
344 acpi_leave_sleep_state_prep(ACPI_STATE_S4);
266} 345}
267 346
268static void acpi_hibernation_finish(void) 347static void acpi_hibernation_finish(void)
269{ 348{
270 /*
271 * If ACPI is not enabled by the BIOS and the boot kernel, we need to
272 * enable it here.
273 */
274 acpi_enable();
275 acpi_disable_wakeup_device(ACPI_STATE_S4); 349 acpi_disable_wakeup_device(ACPI_STATE_S4);
276 acpi_leave_sleep_state(ACPI_STATE_S4); 350 acpi_leave_sleep_state(ACPI_STATE_S4);
277 351
@@ -279,6 +353,17 @@ static void acpi_hibernation_finish(void)
279 acpi_set_firmware_waking_vector((acpi_physical_address) 0); 353 acpi_set_firmware_waking_vector((acpi_physical_address) 0);
280 354
281 acpi_target_sleep_state = ACPI_STATE_S0; 355 acpi_target_sleep_state = ACPI_STATE_S0;
356 acpi_sleep_finish_wake_up = false;
357}
358
359static void acpi_hibernation_end(void)
360{
361 /*
362 * This is necessary in case acpi_hibernation_finish() is not called
363 * directly during a failing transition to the sleep state.
364 */
365 if (acpi_sleep_finish_wake_up)
366 acpi_hibernation_finish();
282} 367}
283 368
284static int acpi_hibernation_pre_restore(void) 369static int acpi_hibernation_pre_restore(void)
@@ -296,7 +381,8 @@ static void acpi_hibernation_restore_cleanup(void)
296} 381}
297 382
298static struct platform_hibernation_ops acpi_hibernation_ops = { 383static struct platform_hibernation_ops acpi_hibernation_ops = {
299 .start = acpi_hibernation_start, 384 .begin = acpi_hibernation_begin,
385 .end = acpi_hibernation_end,
300 .pre_snapshot = acpi_hibernation_prepare, 386 .pre_snapshot = acpi_hibernation_prepare,
301 .finish = acpi_hibernation_finish, 387 .finish = acpi_hibernation_finish,
302 .prepare = acpi_hibernation_prepare, 388 .prepare = acpi_hibernation_prepare,
@@ -386,11 +472,20 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p)
386 if (acpi_target_sleep_state == ACPI_STATE_S0 || 472 if (acpi_target_sleep_state == ACPI_STATE_S0 ||
387 (wake && adev->wakeup.state.enabled && 473 (wake && adev->wakeup.state.enabled &&
388 adev->wakeup.sleep_state <= acpi_target_sleep_state)) { 474 adev->wakeup.sleep_state <= acpi_target_sleep_state)) {
475 acpi_status status;
476
389 acpi_method[3] = 'W'; 477 acpi_method[3] = 'W';
390 acpi_evaluate_integer(handle, acpi_method, NULL, &d_max); 478 status = acpi_evaluate_integer(handle, acpi_method, NULL,
391 /* Sanity check */ 479 &d_max);
392 if (d_max < d_min) 480 if (ACPI_FAILURE(status)) {
481 d_max = d_min;
482 } else if (d_max < d_min) {
483 /* Warn the user of the broken DSDT */
484 printk(KERN_WARNING "ACPI: Wrong value from %s\n",
485 acpi_method);
486 /* Sanitize it */
393 d_min = d_max; 487 d_min = d_max;
488 }
394 } 489 }
395 490
396 if (d_min_p) 491 if (d_min_p)
@@ -403,6 +498,7 @@ static void acpi_power_off_prepare(void)
403{ 498{
404 /* Prepare to power off the system */ 499 /* Prepare to power off the system */
405 acpi_sleep_prepare(ACPI_STATE_S5); 500 acpi_sleep_prepare(ACPI_STATE_S5);
501 acpi_hw_disable_all_gpes();
406} 502}
407 503
408static void acpi_power_off(void) 504static void acpi_power_off(void)
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index 1538355c266b..f8df5217d477 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -178,6 +178,9 @@ static int get_date_field(char **p, u32 * value)
178 * Try to find delimeter, only to insert null. The end of the 178 * Try to find delimeter, only to insert null. The end of the
179 * string won't have one, but is still valid. 179 * string won't have one, but is still valid.
180 */ 180 */
181 if (*p == NULL)
182 return result;
183
181 next = strpbrk(*p, "- :"); 184 next = strpbrk(*p, "- :");
182 if (next) 185 if (next)
183 *next++ = '\0'; 186 *next++ = '\0';
@@ -190,6 +193,8 @@ static int get_date_field(char **p, u32 * value)
190 193
191 if (next) 194 if (next)
192 *p = next; 195 *p = next;
196 else
197 *p = NULL;
193 198
194 return result; 199 return result;
195} 200}
@@ -251,27 +256,6 @@ acpi_system_write_alarm(struct file *file,
251 if ((result = get_date_field(&p, &sec))) 256 if ((result = get_date_field(&p, &sec)))
252 goto end; 257 goto end;
253 258
254 if (sec > 59) {
255 min += 1;
256 sec -= 60;
257 }
258 if (min > 59) {
259 hr += 1;
260 min -= 60;
261 }
262 if (hr > 23) {
263 day += 1;
264 hr -= 24;
265 }
266 if (day > 31) {
267 mo += 1;
268 day -= 31;
269 }
270 if (mo > 12) {
271 yr += 1;
272 mo -= 12;
273 }
274
275 spin_lock_irq(&rtc_lock); 259 spin_lock_irq(&rtc_lock);
276 260
277 rtc_control = CMOS_READ(RTC_CONTROL); 261 rtc_control = CMOS_READ(RTC_CONTROL);
@@ -288,24 +272,24 @@ acpi_system_write_alarm(struct file *file,
288 spin_unlock_irq(&rtc_lock); 272 spin_unlock_irq(&rtc_lock);
289 273
290 if (sec > 59) { 274 if (sec > 59) {
291 min++; 275 min += sec/60;
292 sec -= 60; 276 sec = sec%60;
293 } 277 }
294 if (min > 59) { 278 if (min > 59) {
295 hr++; 279 hr += min/60;
296 min -= 60; 280 min = min%60;
297 } 281 }
298 if (hr > 23) { 282 if (hr > 23) {
299 day++; 283 day += hr/24;
300 hr -= 24; 284 hr = hr%24;
301 } 285 }
302 if (day > 31) { 286 if (day > 31) {
303 mo++; 287 mo += day/32;
304 day -= 31; 288 day = day%32;
305 } 289 }
306 if (mo > 12) { 290 if (mo > 12) {
307 yr++; 291 yr += mo/13;
308 mo -= 12; 292 mo = mo%13;
309 } 293 }
310 294
311 spin_lock_irq(&rtc_lock); 295 spin_lock_irq(&rtc_lock);
diff --git a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h
index a2ea125ae2d0..cfaf8f5b0a14 100644
--- a/drivers/acpi/sleep/sleep.h
+++ b/drivers/acpi/sleep/sleep.h
@@ -5,5 +5,3 @@ extern int acpi_suspend (u32 state);
5extern void acpi_enable_wakeup_device_prep(u8 sleep_state); 5extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
6extern void acpi_enable_wakeup_device(u8 sleep_state); 6extern void acpi_enable_wakeup_device(u8 sleep_state);
7extern void acpi_disable_wakeup_device(u8 sleep_state); 7extern void acpi_disable_wakeup_device(u8 sleep_state);
8
9extern int acpi_sleep_prepare(u32 acpi_state);
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 5ffe0ea18967..ce881713f7a6 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -40,6 +40,8 @@ ACPI_MODULE_NAME("system");
40#define ACPI_SYSTEM_CLASS "system" 40#define ACPI_SYSTEM_CLASS "system"
41#define ACPI_SYSTEM_DEVICE_NAME "System" 41#define ACPI_SYSTEM_DEVICE_NAME "System"
42 42
43u32 acpi_irq_handled;
44
43/* 45/*
44 * Make ACPICA version work as module param 46 * Make ACPICA version work as module param
45 */ 47 */
@@ -166,6 +168,212 @@ static int acpi_system_sysfs_init(void)
166 return 0; 168 return 0;
167} 169}
168 170
171/*
172 * Detailed ACPI IRQ counters in /sys/firmware/acpi/interrupts/
173 * See Documentation/ABI/testing/sysfs-firmware-acpi
174 */
175
176#define COUNT_GPE 0
177#define COUNT_SCI 1 /* acpi_irq_handled */
178#define COUNT_ERROR 2 /* other */
179#define NUM_COUNTERS_EXTRA 3
180
181static u32 *all_counters;
182static u32 num_gpes;
183static u32 num_counters;
184static struct attribute **all_attrs;
185static u32 acpi_gpe_count;
186
187static struct attribute_group interrupt_stats_attr_group = {
188 .name = "interrupts",
189};
190static struct kobj_attribute *counter_attrs;
191
192static int count_num_gpes(void)
193{
194 int count = 0;
195 struct acpi_gpe_xrupt_info *gpe_xrupt_info;
196 struct acpi_gpe_block_info *gpe_block;
197 acpi_cpu_flags flags;
198
199 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
200
201 gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head;
202 while (gpe_xrupt_info) {
203 gpe_block = gpe_xrupt_info->gpe_block_list_head;
204 while (gpe_block) {
205 count += gpe_block->register_count *
206 ACPI_GPE_REGISTER_WIDTH;
207 gpe_block = gpe_block->next;
208 }
209 gpe_xrupt_info = gpe_xrupt_info->next;
210 }
211 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
212
213 return count;
214}
215
216static void delete_gpe_attr_array(void)
217{
218 u32 *tmp = all_counters;
219
220 all_counters = NULL;
221 kfree(tmp);
222
223 if (counter_attrs) {
224 int i;
225
226 for (i = 0; i < num_gpes; i++)
227 kfree(counter_attrs[i].attr.name);
228
229 kfree(counter_attrs);
230 }
231 kfree(all_attrs);
232
233 return;
234}
235
236void acpi_os_gpe_count(u32 gpe_number)
237{
238 acpi_gpe_count++;
239
240 if (!all_counters)
241 return;
242
243 if (gpe_number < num_gpes)
244 all_counters[gpe_number]++;
245 else
246 all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]++;
247
248 return;
249}
250
251void acpi_os_fixed_event_count(u32 event_number)
252{
253 if (!all_counters)
254 return;
255
256 if (event_number < ACPI_NUM_FIXED_EVENTS)
257 all_counters[num_gpes + event_number]++;
258 else
259 all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR]++;
260
261 return;
262}
263
264static ssize_t counter_show(struct kobject *kobj,
265 struct kobj_attribute *attr, char *buf)
266{
267 all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI] =
268 acpi_irq_handled;
269 all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE] =
270 acpi_gpe_count;
271
272 return sprintf(buf, "%d\n", all_counters[attr - counter_attrs]);
273}
274
275/*
276 * counter_set() sets the specified counter.
277 * setting the total "sci" file to any value clears all counters.
278 */
279static ssize_t counter_set(struct kobject *kobj,
280 struct kobj_attribute *attr, const char *buf, size_t size)
281{
282 int index = attr - counter_attrs;
283
284 if (index == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) {
285 int i;
286 for (i = 0; i < num_counters; ++i)
287 all_counters[i] = 0;
288 acpi_gpe_count = 0;
289 acpi_irq_handled = 0;
290
291 } else
292 all_counters[index] = strtoul(buf, NULL, 0);
293
294 return size;
295}
296
297void acpi_irq_stats_init(void)
298{
299 int i;
300
301 if (all_counters)
302 return;
303
304 num_gpes = count_num_gpes();
305 num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA;
306
307 all_attrs = kzalloc(sizeof(struct attribute *) * (num_counters + 1),
308 GFP_KERNEL);
309 if (all_attrs == NULL)
310 return;
311
312 all_counters = kzalloc(sizeof(u32) * (num_counters), GFP_KERNEL);
313 if (all_counters == NULL)
314 goto fail;
315
316 counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters),
317 GFP_KERNEL);
318 if (counter_attrs == NULL)
319 goto fail;
320
321 for (i = 0; i < num_counters; ++i) {
322 char buffer[10];
323 char *name;
324
325 if (i < num_gpes)
326 sprintf(buffer, "gpe%02X", i);
327 else if (i == num_gpes + ACPI_EVENT_PMTIMER)
328 sprintf(buffer, "ff_pmtimer");
329 else if (i == num_gpes + ACPI_EVENT_GLOBAL)
330 sprintf(buffer, "ff_gbl_lock");
331 else if (i == num_gpes + ACPI_EVENT_POWER_BUTTON)
332 sprintf(buffer, "ff_pwr_btn");
333 else if (i == num_gpes + ACPI_EVENT_SLEEP_BUTTON)
334 sprintf(buffer, "ff_slp_btn");
335 else if (i == num_gpes + ACPI_EVENT_RTC)
336 sprintf(buffer, "ff_rt_clk");
337 else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE)
338 sprintf(buffer, "gpe_all");
339 else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI)
340 sprintf(buffer, "sci");
341 else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR)
342 sprintf(buffer, "error");
343 else
344 sprintf(buffer, "bug%02X", i);
345
346 name = kzalloc(strlen(buffer) + 1, GFP_KERNEL);
347 if (name == NULL)
348 goto fail;
349 strncpy(name, buffer, strlen(buffer) + 1);
350
351 counter_attrs[i].attr.name = name;
352 counter_attrs[i].attr.mode = 0644;
353 counter_attrs[i].show = counter_show;
354 counter_attrs[i].store = counter_set;
355
356 all_attrs[i] = &counter_attrs[i].attr;
357 }
358
359 interrupt_stats_attr_group.attrs = all_attrs;
360 sysfs_create_group(acpi_kobj, &interrupt_stats_attr_group);
361 return;
362
363fail:
364 delete_gpe_attr_array();
365 return;
366}
367
368static void __exit interrupt_stats_exit(void)
369{
370 sysfs_remove_group(acpi_kobj, &interrupt_stats_attr_group);
371
372 delete_gpe_attr_array();
373
374 return;
375}
376
169/* -------------------------------------------------------------------------- 377/* --------------------------------------------------------------------------
170 FS Interface (/proc) 378 FS Interface (/proc)
171 -------------------------------------------------------------------------- */ 379 -------------------------------------------------------------------------- */
diff --git a/drivers/acpi/tables/Makefile b/drivers/acpi/tables/Makefile
index 0a7d7afac255..7385efa61622 100644
--- a/drivers/acpi/tables/Makefile
+++ b/drivers/acpi/tables/Makefile
@@ -2,6 +2,6 @@
2# Makefile for all Linux ACPI interpreter subdirectories 2# Makefile for all Linux ACPI interpreter subdirectories
3# 3#
4 4
5obj-y := tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o 5obj-y := tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
6 6
7EXTRA_CFLAGS += $(ACPI_CFLAGS) 7EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
index cf8fa514189f..9ecb4b6c1e7d 100644
--- a/drivers/acpi/tables/tbxfroot.c
+++ b/drivers/acpi/tables/tbxfroot.c
@@ -100,7 +100,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
100 100
101/******************************************************************************* 101/*******************************************************************************
102 * 102 *
103 * FUNCTION: acpi_tb_find_rsdp 103 * FUNCTION: acpi_find_root_pointer
104 * 104 *
105 * PARAMETERS: table_address - Where the table pointer is returned 105 * PARAMETERS: table_address - Where the table pointer is returned
106 * 106 *
@@ -219,8 +219,6 @@ acpi_status acpi_find_root_pointer(acpi_native_uint * table_address)
219 return_ACPI_STATUS(AE_NOT_FOUND); 219 return_ACPI_STATUS(AE_NOT_FOUND);
220} 220}
221 221
222ACPI_EXPORT_SYMBOL(acpi_find_root_pointer)
223
224/******************************************************************************* 222/*******************************************************************************
225 * 223 *
226 * FUNCTION: acpi_tb_scan_memory_for_rsdp 224 * FUNCTION: acpi_tb_scan_memory_for_rsdp
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 73f276bc6e4f..8d4b79b4f933 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -539,7 +539,7 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
539 539
540static int acpi_thermal_critical(struct acpi_thermal *tz) 540static int acpi_thermal_critical(struct acpi_thermal *tz)
541{ 541{
542 if (!tz || !tz->trips.critical.flags.valid || nocrt) 542 if (!tz || !tz->trips.critical.flags.valid)
543 return -EINVAL; 543 return -EINVAL;
544 544
545 if (tz->temperature >= tz->trips.critical.temperature) { 545 if (tz->temperature >= tz->trips.critical.temperature) {
@@ -548,9 +548,6 @@ static int acpi_thermal_critical(struct acpi_thermal *tz)
548 } else if (tz->trips.critical.flags.enabled) 548 } else if (tz->trips.critical.flags.enabled)
549 tz->trips.critical.flags.enabled = 0; 549 tz->trips.critical.flags.enabled = 0;
550 550
551 printk(KERN_EMERG
552 "Critical temperature reached (%ld C), shutting down.\n",
553 KELVIN_TO_CELSIUS(tz->temperature));
554 acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, 551 acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
555 tz->trips.critical.flags.enabled); 552 tz->trips.critical.flags.enabled);
556 acpi_bus_generate_netlink_event(tz->device->pnp.device_class, 553 acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
@@ -558,14 +555,20 @@ static int acpi_thermal_critical(struct acpi_thermal *tz)
558 ACPI_THERMAL_NOTIFY_CRITICAL, 555 ACPI_THERMAL_NOTIFY_CRITICAL,
559 tz->trips.critical.flags.enabled); 556 tz->trips.critical.flags.enabled);
560 557
561 orderly_poweroff(true); 558 /* take no action if nocrt is set */
559 if(!nocrt) {
560 printk(KERN_EMERG
561 "Critical temperature reached (%ld C), shutting down.\n",
562 KELVIN_TO_CELSIUS(tz->temperature));
563 orderly_poweroff(true);
564 }
562 565
563 return 0; 566 return 0;
564} 567}
565 568
566static int acpi_thermal_hot(struct acpi_thermal *tz) 569static int acpi_thermal_hot(struct acpi_thermal *tz)
567{ 570{
568 if (!tz || !tz->trips.hot.flags.valid || nocrt) 571 if (!tz || !tz->trips.hot.flags.valid)
569 return -EINVAL; 572 return -EINVAL;
570 573
571 if (tz->temperature >= tz->trips.hot.temperature) { 574 if (tz->temperature >= tz->trips.hot.temperature) {
@@ -581,7 +584,7 @@ static int acpi_thermal_hot(struct acpi_thermal *tz)
581 ACPI_THERMAL_NOTIFY_HOT, 584 ACPI_THERMAL_NOTIFY_HOT,
582 tz->trips.hot.flags.enabled); 585 tz->trips.hot.flags.enabled);
583 586
584 /* TBD: Call user-mode "sleep(S4)" function */ 587 /* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */
585 588
586 return 0; 589 return 0;
587} 590}
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index 93ea8290b4f7..630c9a2c5b7b 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -671,7 +671,6 @@ void acpi_ut_init_globals(void)
671 671
672 /* GPE support */ 672 /* GPE support */
673 673
674 acpi_gpe_count = 0;
675 acpi_gbl_gpe_xrupt_list_head = NULL; 674 acpi_gbl_gpe_xrupt_list_head = NULL;
676 acpi_gbl_gpe_fadt_blocks[0] = NULL; 675 acpi_gbl_gpe_fadt_blocks[0] = NULL;
677 acpi_gbl_gpe_fadt_blocks[1] = NULL; 676 acpi_gbl_gpe_fadt_blocks[1] = NULL;
@@ -735,4 +734,3 @@ void acpi_ut_init_globals(void)
735 734
736ACPI_EXPORT_SYMBOL(acpi_dbg_level) 735ACPI_EXPORT_SYMBOL(acpi_dbg_level)
737 ACPI_EXPORT_SYMBOL(acpi_dbg_layer) 736 ACPI_EXPORT_SYMBOL(acpi_dbg_layer)
738 ACPI_EXPORT_SYMBOL(acpi_gpe_count)
diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c
index cbbd3315a1e2..b630ee137ee1 100644
--- a/drivers/acpi/utilities/utresrc.c
+++ b/drivers/acpi/utilities/utresrc.c
@@ -1,6 +1,6 @@
1/******************************************************************************* 1/*******************************************************************************
2 * 2 *
3 * Module Name: utresrc - Resource managment utilities 3 * Module Name: utresrc - Resource management utilities
4 * 4 *
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index eab9c4213b49..82815cff15a9 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -294,18 +294,26 @@ static int acpi_video_device_set_state(struct acpi_video_device *device, int sta
294static int acpi_video_get_brightness(struct backlight_device *bd) 294static int acpi_video_get_brightness(struct backlight_device *bd)
295{ 295{
296 unsigned long cur_level; 296 unsigned long cur_level;
297 int i;
297 struct acpi_video_device *vd = 298 struct acpi_video_device *vd =
298 (struct acpi_video_device *)bl_get_data(bd); 299 (struct acpi_video_device *)bl_get_data(bd);
299 acpi_video_device_lcd_get_level_current(vd, &cur_level); 300 acpi_video_device_lcd_get_level_current(vd, &cur_level);
300 return (int) cur_level; 301 for (i = 2; i < vd->brightness->count; i++) {
302 if (vd->brightness->levels[i] == cur_level)
303 /* The first two entries are special - see page 575
304 of the ACPI spec 3.0 */
305 return i-2;
306 }
307 return 0;
301} 308}
302 309
303static int acpi_video_set_brightness(struct backlight_device *bd) 310static int acpi_video_set_brightness(struct backlight_device *bd)
304{ 311{
305 int request_level = bd->props.brightness; 312 int request_level = bd->props.brightness+2;
306 struct acpi_video_device *vd = 313 struct acpi_video_device *vd =
307 (struct acpi_video_device *)bl_get_data(bd); 314 (struct acpi_video_device *)bl_get_data(bd);
308 acpi_video_device_lcd_set_level(vd, request_level); 315 acpi_video_device_lcd_set_level(vd,
316 vd->brightness->levels[request_level]);
309 return 0; 317 return 0;
310} 318}
311 319
@@ -702,7 +710,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
702 kfree(obj); 710 kfree(obj);
703 711
704 if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ 712 if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
705 unsigned long tmp;
706 int result; 713 int result;
707 static int count = 0; 714 static int count = 0;
708 char *name; 715 char *name;
@@ -711,11 +718,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
711 return; 718 return;
712 719
713 sprintf(name, "acpi_video%d", count++); 720 sprintf(name, "acpi_video%d", count++);
714 acpi_video_device_lcd_get_level_current(device, &tmp);
715 device->backlight = backlight_device_register(name, 721 device->backlight = backlight_device_register(name,
716 NULL, device, &acpi_backlight_ops); 722 NULL, device, &acpi_backlight_ops);
717 device->backlight->props.max_brightness = max_level; 723 device->backlight->props.max_brightness = device->brightness->count-3;
718 device->backlight->props.brightness = (int)tmp; 724 device->backlight->props.brightness = acpi_video_get_brightness(device->backlight);
719 backlight_update_status(device->backlight); 725 backlight_update_status(device->backlight);
720 kfree(name); 726 kfree(name);
721 727
@@ -1324,8 +1330,37 @@ acpi_video_bus_write_DOS(struct file *file,
1324 1330
1325static int acpi_video_bus_add_fs(struct acpi_device *device) 1331static int acpi_video_bus_add_fs(struct acpi_device *device)
1326{ 1332{
1333 long device_id;
1334 int status;
1327 struct proc_dir_entry *entry = NULL; 1335 struct proc_dir_entry *entry = NULL;
1328 struct acpi_video_bus *video; 1336 struct acpi_video_bus *video;
1337 struct device *dev;
1338
1339 status =
1340 acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
1341
1342 if (!ACPI_SUCCESS(status))
1343 return -ENODEV;
1344
1345 /* We need to attempt to determine whether the _ADR refers to a
1346 PCI device or not. There's no terribly good way to do this,
1347 so the best we can hope for is to assume that there'll never
1348 be a video device in the host bridge */
1349 if (device_id >= 0x10000) {
1350 /* It looks like a PCI device. Does it exist? */
1351 dev = acpi_get_physical_device(device->handle);
1352 } else {
1353 /* It doesn't look like a PCI device. Does its parent
1354 exist? */
1355 acpi_handle phandle;
1356 if (acpi_get_parent(device->handle, &phandle))
1357 return -ENODEV;
1358 dev = acpi_get_physical_device(phandle);
1359 }
1360 if (!dev)
1361 return -ENODEV;
1362 put_device(dev);
1363
1329 1364
1330 1365
1331 video = acpi_driver_data(device); 1366 video = acpi_driver_data(device);