diff options
| -rw-r--r-- | drivers/acpi/blacklist.c | 381 | ||||
| -rw-r--r-- | drivers/acpi/bus.c | 2 | ||||
| -rw-r--r-- | drivers/acpi/ec.c | 26 | ||||
| -rw-r--r-- | drivers/acpi/fan.c | 40 | ||||
| -rw-r--r-- | drivers/acpi/osl.c | 173 | ||||
| -rw-r--r-- | drivers/acpi/processor_throttling.c | 4 | ||||
| -rw-r--r-- | drivers/firmware/dmi-id.c | 2 | ||||
| -rw-r--r-- | drivers/firmware/dmi_scan.c | 8 | ||||
| -rw-r--r-- | include/acpi/acpi_bus.h | 3 | ||||
| -rw-r--r-- | include/linux/acpi.h | 7 | ||||
| -rw-r--r-- | include/linux/dmi.h | 4 |
11 files changed, 591 insertions, 59 deletions
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 3ec110ce00c8..8809654d6cc9 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Check to see if the given machine has a known bad ACPI BIOS | 4 | * Check to see if the given machine has a known bad ACPI BIOS |
| 5 | * or if the BIOS is too old. | 5 | * or if the BIOS is too old. |
| 6 | * Check given machine against acpi_osi_dmi_table[]. | ||
| 6 | * | 7 | * |
| 7 | * Copyright (C) 2004 Len Brown <len.brown@intel.com> | 8 | * Copyright (C) 2004 Len Brown <len.brown@intel.com> |
| 8 | * Copyright (C) 2002 Andy Grover <andrew.grover@intel.com> | 9 | * Copyright (C) 2002 Andy Grover <andrew.grover@intel.com> |
| @@ -50,6 +51,8 @@ struct acpi_blacklist_item { | |||
| 50 | u32 is_critical_error; | 51 | u32 is_critical_error; |
| 51 | }; | 52 | }; |
| 52 | 53 | ||
| 54 | static struct dmi_system_id acpi_osi_dmi_table[] __initdata; | ||
| 55 | |||
| 53 | /* | 56 | /* |
| 54 | * POLICY: If *anything* doesn't work, put it on the blacklist. | 57 | * POLICY: If *anything* doesn't work, put it on the blacklist. |
| 55 | * If they are critical errors, mark it critical, and abort driver load. | 58 | * If they are critical errors, mark it critical, and abort driver load. |
| @@ -165,5 +168,383 @@ int __init acpi_blacklisted(void) | |||
| 165 | 168 | ||
| 166 | blacklisted += blacklist_by_year(); | 169 | blacklisted += blacklist_by_year(); |
| 167 | 170 | ||
| 171 | dmi_check_system(acpi_osi_dmi_table); | ||
| 172 | |||
| 168 | return blacklisted; | 173 | return blacklisted; |
| 169 | } | 174 | } |
| 175 | #ifdef CONFIG_DMI | ||
| 176 | static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) | ||
| 177 | { | ||
| 178 | acpi_dmi_osi_linux(1, d); /* enable */ | ||
| 179 | return 0; | ||
| 180 | } | ||
| 181 | static int __init dmi_disable_osi_linux(const struct dmi_system_id *d) | ||
| 182 | { | ||
| 183 | acpi_dmi_osi_linux(0, d); /* disable */ | ||
| 184 | return 0; | ||
| 185 | } | ||
| 186 | static int __init dmi_unknown_osi_linux(const struct dmi_system_id *d) | ||
| 187 | { | ||
| 188 | acpi_dmi_osi_linux(-1, d); /* unknown */ | ||
| 189 | return 0; | ||
| 190 | } | ||
| 191 | |||
| 192 | /* | ||
| 193 | * Most BIOS that invoke OSI(Linux) do nothing with it. | ||
| 194 | * But some cause Linux to break. | ||
| 195 | * Only a couple use it to make Linux run better. | ||
| 196 | * | ||
| 197 | * Thus, Linux should continue to disable OSI(Linux) by default, | ||
| 198 | * should continue to discourage BIOS writers from using it, and | ||
| 199 | * should whitelist the few existing systems that require it. | ||
| 200 | * | ||
| 201 | * If it appears clear a vendor isn't using OSI(Linux) | ||
| 202 | * for anything constructive, blacklist them by name to disable | ||
| 203 | * unnecessary dmesg warnings on all of their products. | ||
| 204 | */ | ||
| 205 | |||
| 206 | static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | ||
| 207 | /* | ||
| 208 | * Disable OSI(Linux) warnings on all "Acer, inc." | ||
| 209 | * | ||
| 210 | * _OSI(Linux) disables the latest Windows BIOS code: | ||
| 211 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5050"), | ||
| 212 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5580"), | ||
| 213 | * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 3010"), | ||
| 214 | * _OSI(Linux) effect unknown: | ||
| 215 | * DMI_MATCH(DMI_PRODUCT_NAME, "Ferrari 5000"), | ||
| 216 | */ | ||
| 217 | { | ||
| 218 | .callback = dmi_disable_osi_linux, | ||
| 219 | .ident = "Acer, inc.", | ||
| 220 | .matches = { | ||
| 221 | DMI_MATCH(DMI_SYS_VENDOR, "Acer, inc."), | ||
| 222 | }, | ||
| 223 | }, | ||
| 224 | /* | ||
| 225 | * Disable OSI(Linux) warnings on all "Acer" | ||
| 226 | * | ||
| 227 | * _OSI(Linux) effect unknown: | ||
| 228 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), | ||
| 229 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), | ||
| 230 | * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720Z"), | ||
| 231 | * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5520"), | ||
| 232 | * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 6460"), | ||
| 233 | * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 7510"), | ||
| 234 | * DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5220"), | ||
| 235 | */ | ||
| 236 | { | ||
| 237 | .callback = dmi_unknown_osi_linux, | ||
| 238 | .ident = "Acer", | ||
| 239 | .matches = { | ||
| 240 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
| 241 | }, | ||
| 242 | }, | ||
| 243 | /* | ||
| 244 | * Disable OSI(Linux) warnings on all "Apple Computer, Inc." | ||
| 245 | * | ||
| 246 | * _OSI(Linux) confirmed to be a NOP: | ||
| 247 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"), | ||
| 248 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"), | ||
| 249 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2"), | ||
| 250 | * _OSI(Linux) effect unknown: | ||
| 251 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacPro2,1"), | ||
| 252 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,1"), | ||
| 253 | * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"), | ||
| 254 | */ | ||
| 255 | { | ||
| 256 | .callback = dmi_disable_osi_linux, | ||
| 257 | .ident = "Apple", | ||
| 258 | .matches = { | ||
| 259 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), | ||
| 260 | }, | ||
| 261 | }, | ||
| 262 | /* | ||
| 263 | * Disable OSI(Linux) warnings on all "BenQ" | ||
| 264 | * | ||
| 265 | * _OSI(Linux) confirmed to be a NOP: | ||
| 266 | * DMI_MATCH(DMI_PRODUCT_NAME, "Joybook S31"), | ||
| 267 | */ | ||
| 268 | { | ||
| 269 | .callback = dmi_disable_osi_linux, | ||
| 270 | .ident = "BenQ", | ||
| 271 | .matches = { | ||
| 272 | DMI_MATCH(DMI_SYS_VENDOR, "BenQ"), | ||
| 273 | }, | ||
| 274 | }, | ||
| 275 | /* | ||
| 276 | * Disable OSI(Linux) warnings on all "Clevo Co." | ||
| 277 | * | ||
| 278 | * _OSI(Linux) confirmed to be a NOP: | ||
| 279 | * DMI_MATCH(DMI_PRODUCT_NAME, "M570RU"), | ||
| 280 | */ | ||
| 281 | { | ||
| 282 | .callback = dmi_disable_osi_linux, | ||
| 283 | .ident = "Clevo", | ||
| 284 | .matches = { | ||
| 285 | DMI_MATCH(DMI_SYS_VENDOR, "Clevo Co."), | ||
| 286 | }, | ||
| 287 | }, | ||
| 288 | /* | ||
| 289 | * Disable OSI(Linux) warnings on all "COMPAL" | ||
| 290 | * | ||
| 291 | * _OSI(Linux) confirmed to be a NOP: | ||
| 292 | * DMI_MATCH(DMI_BOARD_NAME, "HEL8X"), | ||
| 293 | * _OSI(Linux) unknown effect: | ||
| 294 | * DMI_MATCH(DMI_BOARD_NAME, "IFL91"), | ||
| 295 | */ | ||
| 296 | { | ||
| 297 | .callback = dmi_unknown_osi_linux, | ||
| 298 | .ident = "Compal", | ||
| 299 | .matches = { | ||
| 300 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
| 301 | }, | ||
| 302 | }, | ||
| 303 | { /* OSI(Linux) touches USB, breaks suspend to disk */ | ||
| 304 | .callback = dmi_disable_osi_linux, | ||
| 305 | .ident = "Dell Dimension 5150", | ||
| 306 | .matches = { | ||
| 307 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 308 | DMI_MATCH(DMI_PRODUCT_NAME, "Dell DM051"), | ||
| 309 | }, | ||
| 310 | }, | ||
| 311 | { /* OSI(Linux) is a NOP */ | ||
| 312 | .callback = dmi_disable_osi_linux, | ||
| 313 | .ident = "Dell", | ||
| 314 | .matches = { | ||
| 315 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 316 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1501"), | ||
| 317 | }, | ||
| 318 | }, | ||
| 319 | { /* OSI(Linux) effect unknown */ | ||
| 320 | .callback = dmi_unknown_osi_linux, | ||
| 321 | .ident = "Dell", | ||
| 322 | .matches = { | ||
| 323 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 324 | DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D830"), | ||
| 325 | }, | ||
| 326 | }, | ||
| 327 | { /* OSI(Linux) effect unknown */ | ||
| 328 | .callback = dmi_unknown_osi_linux, | ||
| 329 | .ident = "Dell", | ||
| 330 | .matches = { | ||
| 331 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 332 | DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX620"), | ||
| 333 | }, | ||
| 334 | }, | ||
| 335 | { /* OSI(Linux) effect unknown */ | ||
| 336 | .callback = dmi_unknown_osi_linux, | ||
| 337 | .ident = "Dell", | ||
| 338 | .matches = { | ||
| 339 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 340 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1900"), | ||
| 341 | }, | ||
| 342 | }, | ||
| 343 | { /* OSI(Linux) touches USB */ | ||
| 344 | .callback = dmi_disable_osi_linux, | ||
| 345 | .ident = "Dell", | ||
| 346 | .matches = { | ||
| 347 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 348 | DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 390"), | ||
| 349 | }, | ||
| 350 | }, | ||
| 351 | { /* OSI(Linux) is a NOP */ | ||
| 352 | .callback = dmi_disable_osi_linux, | ||
| 353 | .ident = "Dell Vostro 1000", | ||
| 354 | .matches = { | ||
| 355 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 356 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1000"), | ||
| 357 | }, | ||
| 358 | }, | ||
| 359 | { /* OSI(Linux) effect unknown */ | ||
| 360 | .callback = dmi_unknown_osi_linux, | ||
| 361 | .ident = "Dell", | ||
| 362 | .matches = { | ||
| 363 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 364 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge SC440"), | ||
| 365 | }, | ||
| 366 | }, | ||
| 367 | { /* OSI(Linux) effect unknown */ | ||
| 368 | .callback = dmi_unknown_osi_linux, | ||
| 369 | .ident = "Dialogue Flybook V5", | ||
| 370 | .matches = { | ||
| 371 | DMI_MATCH(DMI_SYS_VENDOR, "Dialogue Technology Corporation"), | ||
| 372 | DMI_MATCH(DMI_PRODUCT_NAME, "Flybook V5"), | ||
| 373 | }, | ||
| 374 | }, | ||
| 375 | /* | ||
| 376 | * Disable OSI(Linux) warnings on all "FUJITSU SIEMENS" | ||
| 377 | * | ||
| 378 | * _OSI(Linux) disables latest Windows BIOS code: | ||
| 379 | * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 2510"), | ||
| 380 | * _OSI(Linux) confirmed to be a NOP: | ||
| 381 | * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1536"), | ||
| 382 | * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1556"), | ||
| 383 | * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 1546"), | ||
| 384 | * _OSI(Linux) unknown effect: | ||
| 385 | * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo M1425"), | ||
| 386 | * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo Si 1520"), | ||
| 387 | * DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), | ||
| 388 | */ | ||
| 389 | { | ||
| 390 | .callback = dmi_disable_osi_linux, | ||
| 391 | .ident = "Fujitsu Siemens", | ||
| 392 | .matches = { | ||
| 393 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
| 394 | }, | ||
| 395 | }, | ||
| 396 | /* | ||
| 397 | * Disable OSI(Linux) warnings on all "Hewlett-Packard" | ||
| 398 | * | ||
| 399 | * _OSI(Linux) confirmed to be a NOP: | ||
| 400 | * .ident = "HP Pavilion tx 1000" | ||
| 401 | * DMI_MATCH(DMI_BOARD_NAME, "30BF"), | ||
| 402 | * .ident = "HP Pavilion dv2000" | ||
| 403 | * DMI_MATCH(DMI_BOARD_NAME, "30B5"), | ||
| 404 | * .ident = "HP Pavilion dv5000", | ||
| 405 | * DMI_MATCH(DMI_BOARD_NAME, "30A7"), | ||
| 406 | * .ident = "HP Pavilion dv6300 30BC", | ||
| 407 | * DMI_MATCH(DMI_BOARD_NAME, "30BC"), | ||
| 408 | * .ident = "HP Pavilion dv6000", | ||
| 409 | * DMI_MATCH(DMI_BOARD_NAME, "30B7"), | ||
| 410 | * DMI_MATCH(DMI_BOARD_NAME, "30B8"), | ||
| 411 | * .ident = "HP Pavilion dv9000", | ||
| 412 | * DMI_MATCH(DMI_BOARD_NAME, "30B9"), | ||
| 413 | * .ident = "HP Pavilion dv9500", | ||
| 414 | * DMI_MATCH(DMI_BOARD_NAME, "30CB"), | ||
| 415 | * .ident = "HP/Compaq Presario C500", | ||
| 416 | * DMI_MATCH(DMI_BOARD_NAME, "30C6"), | ||
| 417 | * .ident = "HP/Compaq Presario F500", | ||
| 418 | * DMI_MATCH(DMI_BOARD_NAME, "30D3"), | ||
| 419 | * _OSI(Linux) unknown effect: | ||
| 420 | * .ident = "HP Pavilion dv6500", | ||
| 421 | * DMI_MATCH(DMI_BOARD_NAME, "30D0"), | ||
| 422 | */ | ||
| 423 | { | ||
| 424 | .callback = dmi_disable_osi_linux, | ||
| 425 | .ident = "Hewlett-Packard", | ||
| 426 | .matches = { | ||
| 427 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
| 428 | }, | ||
| 429 | }, | ||
| 430 | /* | ||
| 431 | * Lenovo has a mix of systems OSI(Linux) situations | ||
| 432 | * and thus we can not wildcard the vendor. | ||
| 433 | * | ||
| 434 | * _OSI(Linux) helps sound | ||
| 435 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"), | ||
| 436 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"), | ||
| 437 | * _OSI(Linux) is a NOP: | ||
| 438 | * DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), | ||
| 439 | */ | ||
| 440 | { | ||
| 441 | .callback = dmi_enable_osi_linux, | ||
| 442 | .ident = "Lenovo ThinkPad R61", | ||
| 443 | .matches = { | ||
| 444 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 445 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"), | ||
| 446 | }, | ||
| 447 | }, | ||
| 448 | { | ||
| 449 | .callback = dmi_enable_osi_linux, | ||
| 450 | .ident = "Lenovo ThinkPad T61", | ||
| 451 | .matches = { | ||
| 452 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 453 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"), | ||
| 454 | }, | ||
| 455 | }, | ||
| 456 | { | ||
| 457 | .callback = dmi_unknown_osi_linux, | ||
| 458 | .ident = "Lenovo 3000 V100", | ||
| 459 | .matches = { | ||
| 460 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 461 | DMI_MATCH(DMI_PRODUCT_VERSION, "LENOVO3000 V100"), | ||
| 462 | }, | ||
| 463 | }, | ||
| 464 | { | ||
| 465 | .callback = dmi_disable_osi_linux, | ||
| 466 | .ident = "Lenovo 3000 N100", | ||
| 467 | .matches = { | ||
| 468 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 469 | DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"), | ||
| 470 | }, | ||
| 471 | }, | ||
| 472 | /* | ||
| 473 | * Disable OSI(Linux) warnings on all "LG Electronics" | ||
| 474 | * | ||
| 475 | * _OSI(Linux) confirmed to be a NOP: | ||
| 476 | * DMI_MATCH(DMI_PRODUCT_NAME, "P1-J150B"), | ||
| 477 | */ | ||
| 478 | { | ||
| 479 | .callback = dmi_disable_osi_linux, | ||
| 480 | .ident = "LG", | ||
| 481 | .matches = { | ||
| 482 | DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), | ||
| 483 | }, | ||
| 484 | }, | ||
| 485 | /* NEC - OSI(Linux) effect unknown */ | ||
| 486 | { | ||
| 487 | .callback = dmi_unknown_osi_linux, | ||
| 488 | .ident = "NEC VERSA M360", | ||
| 489 | .matches = { | ||
| 490 | DMI_MATCH(DMI_SYS_VENDOR, "NEC Computers SAS"), | ||
| 491 | DMI_MATCH(DMI_PRODUCT_NAME, "NEC VERSA M360"), | ||
| 492 | }, | ||
| 493 | }, | ||
| 494 | /* | ||
| 495 | * Disable OSI(Linux) warnings on all "Samsung Electronics" | ||
| 496 | * | ||
| 497 | * OSI(Linux) disables PNP0C32 and other BIOS code for Windows: | ||
| 498 | * DMI_MATCH(DMI_PRODUCT_NAME, "R40P/R41P"), | ||
| 499 | * DMI_MATCH(DMI_PRODUCT_NAME, "R59P/R60P/R61P"), | ||
| 500 | */ | ||
| 501 | { | ||
| 502 | .callback = dmi_disable_osi_linux, | ||
| 503 | .ident = "Samsung", | ||
| 504 | .matches = { | ||
| 505 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
| 506 | }, | ||
| 507 | }, | ||
| 508 | /* | ||
| 509 | * Disable OSI(Linux) warnings on all "Sony Corporation" | ||
| 510 | * | ||
| 511 | * _OSI(Linux) is a NOP: | ||
| 512 | * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ650N"), | ||
| 513 | * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ38GP_C"), | ||
| 514 | * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-TZ21MN_N"), | ||
| 515 | * _OSI(Linux) unknown effect: | ||
| 516 | * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ11M"), | ||
| 517 | */ | ||
| 518 | { | ||
| 519 | .callback = dmi_unknown_osi_linux, | ||
| 520 | .ident = "Sony", | ||
| 521 | .matches = { | ||
| 522 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
| 523 | }, | ||
| 524 | }, | ||
| 525 | /* | ||
| 526 | * Disable OSI(Linux) warnings on all "TOSHIBA" | ||
| 527 | * | ||
| 528 | * _OSI(Linux) breaks sound (bugzilla 7787): | ||
| 529 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P100"), | ||
| 530 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P105"), | ||
| 531 | * _OSI(Linux) is a NOP: | ||
| 532 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A100"), | ||
| 533 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A210"), | ||
| 534 | * _OSI(Linux) unknown effect: | ||
| 535 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A135"), | ||
| 536 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A200"), | ||
| 537 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P205"), | ||
| 538 | * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U305"), | ||
| 539 | */ | ||
| 540 | { | ||
| 541 | .callback = dmi_disable_osi_linux, | ||
| 542 | .ident = "Toshiba", | ||
| 543 | .matches = { | ||
| 544 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
| 545 | }, | ||
| 546 | }, | ||
| 547 | {} | ||
| 548 | }; | ||
| 549 | |||
| 550 | #endif /* CONFIG_DMI */ | ||
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index d7a115c362d1..f4487c38d9f2 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
| @@ -200,7 +200,7 @@ int acpi_bus_set_power(acpi_handle handle, int state) | |||
| 200 | * Get device's current power state | 200 | * Get device's current power state |
| 201 | */ | 201 | */ |
| 202 | acpi_bus_get_power(device->handle, &device->power.state); | 202 | acpi_bus_get_power(device->handle, &device->power.state); |
| 203 | if (state == device->power.state) { | 203 | if ((state == device->power.state) && !device->flags.force_power_state) { |
| 204 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", | 204 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", |
| 205 | state)); | 205 | state)); |
| 206 | return 0; | 206 | return 0; |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 97dc16155a55..987b967c7467 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -26,6 +26,9 @@ | |||
| 26 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 26 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 27 | */ | 27 | */ |
| 28 | 28 | ||
| 29 | /* Uncomment next line to get verbose print outs*/ | ||
| 30 | /* #define DEBUG */ | ||
| 31 | |||
| 29 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
| 30 | #include <linux/module.h> | 33 | #include <linux/module.h> |
| 31 | #include <linux/init.h> | 34 | #include <linux/init.h> |
| @@ -47,9 +50,6 @@ | |||
| 47 | #undef PREFIX | 50 | #undef PREFIX |
| 48 | #define PREFIX "ACPI: EC: " | 51 | #define PREFIX "ACPI: EC: " |
| 49 | 52 | ||
| 50 | /* Uncomment next line to get verbose print outs*/ | ||
| 51 | /* #define DEBUG */ | ||
| 52 | |||
| 53 | /* EC status register */ | 53 | /* EC status register */ |
| 54 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ | 54 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ |
| 55 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ | 55 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ |
| @@ -82,6 +82,7 @@ enum { | |||
| 82 | EC_FLAGS_ADDRESS, /* Address is being written */ | 82 | EC_FLAGS_ADDRESS, /* Address is being written */ |
| 83 | EC_FLAGS_NO_WDATA_GPE, /* Don't expect WDATA GPE event */ | 83 | EC_FLAGS_NO_WDATA_GPE, /* Don't expect WDATA GPE event */ |
| 84 | EC_FLAGS_WDATA, /* Data is being written */ | 84 | EC_FLAGS_WDATA, /* Data is being written */ |
| 85 | EC_FLAGS_NO_OBF1_GPE, /* Don't expect GPE before read */ | ||
| 85 | }; | 86 | }; |
| 86 | 87 | ||
| 87 | static int acpi_ec_remove(struct acpi_device *device, int type); | 88 | static int acpi_ec_remove(struct acpi_device *device, int type); |
| @@ -138,26 +139,26 @@ static struct acpi_ec { | |||
| 138 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) | 139 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) |
| 139 | { | 140 | { |
| 140 | u8 x = inb(ec->command_addr); | 141 | u8 x = inb(ec->command_addr); |
| 141 | pr_debug(PREFIX "---> status = 0x%2x\n", x); | 142 | pr_debug(PREFIX "---> status = 0x%2.2x\n", x); |
| 142 | return x; | 143 | return x; |
| 143 | } | 144 | } |
| 144 | 145 | ||
| 145 | static inline u8 acpi_ec_read_data(struct acpi_ec *ec) | 146 | static inline u8 acpi_ec_read_data(struct acpi_ec *ec) |
| 146 | { | 147 | { |
| 147 | u8 x = inb(ec->data_addr); | 148 | u8 x = inb(ec->data_addr); |
| 148 | pr_debug(PREFIX "---> data = 0x%2x\n", x); | 149 | pr_debug(PREFIX "---> data = 0x%2.2x\n", x); |
| 149 | return inb(ec->data_addr); | 150 | return inb(ec->data_addr); |
| 150 | } | 151 | } |
| 151 | 152 | ||
| 152 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) | 153 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) |
| 153 | { | 154 | { |
| 154 | pr_debug(PREFIX "<--- command = 0x%2x\n", command); | 155 | pr_debug(PREFIX "<--- command = 0x%2.2x\n", command); |
| 155 | outb(command, ec->command_addr); | 156 | outb(command, ec->command_addr); |
| 156 | } | 157 | } |
| 157 | 158 | ||
| 158 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) | 159 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) |
| 159 | { | 160 | { |
| 160 | pr_debug(PREFIX "<--- data = 0x%2x\n", data); | 161 | pr_debug(PREFIX "<--- data = 0x%2.2x\n", data); |
| 161 | outb(data, ec->data_addr); | 162 | outb(data, ec->data_addr); |
| 162 | } | 163 | } |
| 163 | 164 | ||
| @@ -179,6 +180,10 @@ static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event) | |||
| 179 | static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) | 180 | static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) |
| 180 | { | 181 | { |
| 181 | int ret = 0; | 182 | int ret = 0; |
| 183 | |||
| 184 | if (unlikely(event == ACPI_EC_EVENT_OBF_1 && | ||
| 185 | test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags))) | ||
| 186 | force_poll = 1; | ||
| 182 | if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) && | 187 | if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) && |
| 183 | test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags))) | 188 | test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags))) |
| 184 | force_poll = 1; | 189 | force_poll = 1; |
| @@ -192,7 +197,12 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) | |||
| 192 | goto end; | 197 | goto end; |
| 193 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | 198 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
| 194 | if (acpi_ec_check_status(ec, event)) { | 199 | if (acpi_ec_check_status(ec, event)) { |
| 195 | if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) { | 200 | if (event == ACPI_EC_EVENT_OBF_1) { |
| 201 | /* miss OBF_1 GPE, don't expect it */ | ||
| 202 | pr_info(PREFIX "missing OBF confirmation, " | ||
| 203 | "don't expect it any longer.\n"); | ||
| 204 | set_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags); | ||
| 205 | } else if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) { | ||
| 196 | /* miss address GPE, don't expect it anymore */ | 206 | /* miss address GPE, don't expect it anymore */ |
| 197 | pr_info(PREFIX "missing address confirmation, " | 207 | pr_info(PREFIX "missing address confirmation, " |
| 198 | "don't expect it any longer.\n"); | 208 | "don't expect it any longer.\n"); |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index a5a5532db268..a6e149d692cb 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
| @@ -47,6 +47,8 @@ MODULE_LICENSE("GPL"); | |||
| 47 | 47 | ||
| 48 | static int acpi_fan_add(struct acpi_device *device); | 48 | static int acpi_fan_add(struct acpi_device *device); |
| 49 | static int acpi_fan_remove(struct acpi_device *device, int type); | 49 | static int acpi_fan_remove(struct acpi_device *device, int type); |
| 50 | static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state); | ||
| 51 | static int acpi_fan_resume(struct acpi_device *device); | ||
| 50 | 52 | ||
| 51 | static const struct acpi_device_id fan_device_ids[] = { | 53 | static const struct acpi_device_id fan_device_ids[] = { |
| 52 | {"PNP0C0B", 0}, | 54 | {"PNP0C0B", 0}, |
| @@ -61,6 +63,8 @@ static struct acpi_driver acpi_fan_driver = { | |||
| 61 | .ops = { | 63 | .ops = { |
| 62 | .add = acpi_fan_add, | 64 | .add = acpi_fan_add, |
| 63 | .remove = acpi_fan_remove, | 65 | .remove = acpi_fan_remove, |
| 66 | .suspend = acpi_fan_suspend, | ||
| 67 | .resume = acpi_fan_resume, | ||
| 64 | }, | 68 | }, |
| 65 | }; | 69 | }; |
| 66 | 70 | ||
| @@ -191,6 +195,10 @@ static int acpi_fan_add(struct acpi_device *device) | |||
| 191 | goto end; | 195 | goto end; |
| 192 | } | 196 | } |
| 193 | 197 | ||
| 198 | device->flags.force_power_state = 1; | ||
| 199 | acpi_bus_set_power(device->handle, state); | ||
| 200 | device->flags.force_power_state = 0; | ||
| 201 | |||
| 194 | result = acpi_fan_add_fs(device); | 202 | result = acpi_fan_add_fs(device); |
| 195 | if (result) | 203 | if (result) |
| 196 | goto end; | 204 | goto end; |
| @@ -216,6 +224,38 @@ static int acpi_fan_remove(struct acpi_device *device, int type) | |||
| 216 | return 0; | 224 | return 0; |
| 217 | } | 225 | } |
| 218 | 226 | ||
| 227 | static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state) | ||
| 228 | { | ||
| 229 | if (!device) | ||
| 230 | return -EINVAL; | ||
| 231 | |||
| 232 | acpi_bus_set_power(device->handle, ACPI_STATE_D0); | ||
| 233 | |||
| 234 | return AE_OK; | ||
| 235 | } | ||
| 236 | |||
| 237 | static int acpi_fan_resume(struct acpi_device *device) | ||
| 238 | { | ||
| 239 | int result = 0; | ||
| 240 | int power_state = 0; | ||
| 241 | |||
| 242 | if (!device) | ||
| 243 | return -EINVAL; | ||
| 244 | |||
| 245 | result = acpi_bus_get_power(device->handle, &power_state); | ||
| 246 | if (result) { | ||
| 247 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
| 248 | "Error reading fan power state\n")); | ||
| 249 | return result; | ||
| 250 | } | ||
| 251 | |||
| 252 | device->flags.force_power_state = 1; | ||
| 253 | acpi_bus_set_power(device->handle, power_state); | ||
| 254 | device->flags.force_power_state = 0; | ||
| 255 | |||
| 256 | return result; | ||
| 257 | } | ||
| 258 | |||
| 219 | static int __init acpi_fan_init(void) | 259 | static int __init acpi_fan_init(void) |
| 220 | { | 260 | { |
| 221 | int result = 0; | 261 | int result = 0; |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e3a673a00845..e53fb516f9d4 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
| @@ -77,11 +77,55 @@ static struct workqueue_struct *kacpi_notify_wq; | |||
| 77 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | 77 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ |
| 78 | static char osi_additional_string[OSI_STRING_LENGTH_MAX]; | 78 | static char osi_additional_string[OSI_STRING_LENGTH_MAX]; |
| 79 | 79 | ||
| 80 | static int osi_linux; /* disable _OSI(Linux) by default */ | 80 | /* |
| 81 | * "Ode to _OSI(Linux)" | ||
| 82 | * | ||
| 83 | * osi_linux -- Control response to BIOS _OSI(Linux) query. | ||
| 84 | * | ||
| 85 | * As Linux evolves, the features that it supports change. | ||
| 86 | * So an OSI string such as "Linux" is not specific enough | ||
| 87 | * to be useful across multiple versions of Linux. It | ||
| 88 | * doesn't identify any particular feature, interface, | ||
| 89 | * or even any particular version of Linux... | ||
| 90 | * | ||
| 91 | * Unfortunately, Linux-2.6.22 and earlier responded "yes" | ||
| 92 | * to a BIOS _OSI(Linux) query. When | ||
| 93 | * a reference mobile BIOS started using it, its use | ||
| 94 | * started to spread to many vendor platforms. | ||
| 95 | * As it is not supportable, we need to halt that spread. | ||
| 96 | * | ||
| 97 | * Today, most BIOS references to _OSI(Linux) are noise -- | ||
| 98 | * they have no functional effect and are just dead code | ||
| 99 | * carried over from the reference BIOS. | ||
| 100 | * | ||
| 101 | * The next most common case is that _OSI(Linux) harms Linux, | ||
| 102 | * usually by causing the BIOS to follow paths that are | ||
| 103 | * not tested during Windows validation. | ||
| 104 | * | ||
| 105 | * Finally, there is a short list of platforms | ||
| 106 | * where OSI(Linux) benefits Linux. | ||
| 107 | * | ||
| 108 | * In Linux-2.6.23, OSI(Linux) is first disabled by default. | ||
| 109 | * DMI is used to disable the dmesg warning about OSI(Linux) | ||
| 110 | * on platforms where it is known to have no effect. | ||
| 111 | * But a dmesg warning remains for systems where | ||
| 112 | * we do not know if OSI(Linux) is good or bad for the system. | ||
| 113 | * DMI is also used to enable OSI(Linux) for the machines | ||
| 114 | * that are known to need it. | ||
| 115 | * | ||
| 116 | * BIOS writers should NOT query _OSI(Linux) on future systems. | ||
| 117 | * It will be ignored by default, and to get Linux to | ||
| 118 | * not ignore it will require a kernel source update to | ||
| 119 | * add a DMI entry, or a boot-time "acpi_osi=Linux" invocation. | ||
| 120 | */ | ||
| 121 | #define OSI_LINUX_ENABLE 0 | ||
| 81 | 122 | ||
| 82 | #ifdef CONFIG_DMI | 123 | struct osi_linux { |
| 83 | static struct __initdata dmi_system_id acpi_osl_dmi_table[]; | 124 | unsigned int enable:1; |
| 84 | #endif | 125 | unsigned int dmi:1; |
| 126 | unsigned int cmdline:1; | ||
| 127 | unsigned int known:1; | ||
| 128 | } osi_linux = { OSI_LINUX_ENABLE, 0, 0, 0}; | ||
| 85 | 129 | ||
| 86 | static void __init acpi_request_region (struct acpi_generic_address *addr, | 130 | static void __init acpi_request_region (struct acpi_generic_address *addr, |
| 87 | unsigned int length, char *desc) | 131 | unsigned int length, char *desc) |
| @@ -133,7 +177,6 @@ device_initcall(acpi_reserve_resources); | |||
| 133 | 177 | ||
| 134 | acpi_status __init acpi_os_initialize(void) | 178 | acpi_status __init acpi_os_initialize(void) |
| 135 | { | 179 | { |
| 136 | dmi_check_system(acpi_osl_dmi_table); | ||
| 137 | return AE_OK; | 180 | return AE_OK; |
| 138 | } | 181 | } |
| 139 | 182 | ||
| @@ -964,13 +1007,37 @@ static int __init acpi_os_name_setup(char *str) | |||
| 964 | 1007 | ||
| 965 | __setup("acpi_os_name=", acpi_os_name_setup); | 1008 | __setup("acpi_os_name=", acpi_os_name_setup); |
| 966 | 1009 | ||
| 967 | static void enable_osi_linux(int enable) { | 1010 | static void __init set_osi_linux(unsigned int enable) |
| 1011 | { | ||
| 1012 | if (osi_linux.enable != enable) { | ||
| 1013 | osi_linux.enable = enable; | ||
| 1014 | printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", | ||
| 1015 | enable ? "Add": "Delet"); | ||
| 1016 | } | ||
| 1017 | return; | ||
| 1018 | } | ||
| 968 | 1019 | ||
| 969 | if (osi_linux != enable) | 1020 | static void __init acpi_cmdline_osi_linux(unsigned int enable) |
| 970 | printk(KERN_INFO PREFIX "%sabled _OSI(Linux)\n", | 1021 | { |
| 971 | enable ? "En": "Dis"); | 1022 | osi_linux.cmdline = 1; /* cmdline set the default */ |
| 1023 | set_osi_linux(enable); | ||
| 1024 | |||
| 1025 | return; | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) | ||
| 1029 | { | ||
| 1030 | osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ | ||
| 1031 | |||
| 1032 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); | ||
| 1033 | |||
| 1034 | if (enable == -1) | ||
| 1035 | return; | ||
| 1036 | |||
| 1037 | osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */ | ||
| 1038 | |||
| 1039 | set_osi_linux(enable); | ||
| 972 | 1040 | ||
| 973 | osi_linux = enable; | ||
| 974 | return; | 1041 | return; |
| 975 | } | 1042 | } |
| 976 | 1043 | ||
| @@ -987,12 +1054,12 @@ static int __init acpi_osi_setup(char *str) | |||
| 987 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | 1054 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); |
| 988 | acpi_gbl_create_osi_method = FALSE; | 1055 | acpi_gbl_create_osi_method = FALSE; |
| 989 | } else if (!strcmp("!Linux", str)) { | 1056 | } else if (!strcmp("!Linux", str)) { |
| 990 | enable_osi_linux(0); | 1057 | acpi_cmdline_osi_linux(0); /* !enable */ |
| 991 | } else if (*str == '!') { | 1058 | } else if (*str == '!') { |
| 992 | if (acpi_osi_invalidate(++str) == AE_OK) | 1059 | if (acpi_osi_invalidate(++str) == AE_OK) |
| 993 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | 1060 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); |
| 994 | } else if (!strcmp("Linux", str)) { | 1061 | } else if (!strcmp("Linux", str)) { |
| 995 | enable_osi_linux(1); | 1062 | acpi_cmdline_osi_linux(1); /* enable */ |
| 996 | } else if (*osi_additional_string == '\0') { | 1063 | } else if (*osi_additional_string == '\0') { |
| 997 | strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX); | 1064 | strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX); |
| 998 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); | 1065 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); |
| @@ -1141,6 +1208,34 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) | |||
| 1141 | return (AE_OK); | 1208 | return (AE_OK); |
| 1142 | } | 1209 | } |
| 1143 | 1210 | ||
| 1211 | /** | ||
| 1212 | * acpi_dmi_dump - dump DMI slots needed for blacklist entry | ||
| 1213 | * | ||
| 1214 | * Returns 0 on success | ||
| 1215 | */ | ||
| 1216 | int acpi_dmi_dump(void) | ||
| 1217 | { | ||
| 1218 | |||
| 1219 | if (!dmi_available) | ||
| 1220 | return -1; | ||
| 1221 | |||
| 1222 | printk(KERN_NOTICE PREFIX "DMI System Vendor: %s\n", | ||
| 1223 | dmi_get_slot(DMI_SYS_VENDOR)); | ||
| 1224 | printk(KERN_NOTICE PREFIX "DMI Product Name: %s\n", | ||
| 1225 | dmi_get_slot(DMI_PRODUCT_NAME)); | ||
| 1226 | printk(KERN_NOTICE PREFIX "DMI Product Version: %s\n", | ||
| 1227 | dmi_get_slot(DMI_PRODUCT_VERSION)); | ||
| 1228 | printk(KERN_NOTICE PREFIX "DMI Board Name: %s\n", | ||
| 1229 | dmi_get_slot(DMI_BOARD_NAME)); | ||
| 1230 | printk(KERN_NOTICE PREFIX "DMI BIOS Vendor: %s\n", | ||
| 1231 | dmi_get_slot(DMI_BIOS_VENDOR)); | ||
| 1232 | printk(KERN_NOTICE PREFIX "DMI BIOS Date: %s\n", | ||
| 1233 | dmi_get_slot(DMI_BIOS_DATE)); | ||
| 1234 | |||
| 1235 | return 0; | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | |||
| 1144 | /****************************************************************************** | 1239 | /****************************************************************************** |
| 1145 | * | 1240 | * |
| 1146 | * FUNCTION: acpi_os_validate_interface | 1241 | * FUNCTION: acpi_os_validate_interface |
| @@ -1160,13 +1255,29 @@ acpi_os_validate_interface (char *interface) | |||
| 1160 | if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX)) | 1255 | if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX)) |
| 1161 | return AE_OK; | 1256 | return AE_OK; |
| 1162 | if (!strcmp("Linux", interface)) { | 1257 | if (!strcmp("Linux", interface)) { |
| 1163 | printk(KERN_WARNING PREFIX | 1258 | |
| 1164 | "System BIOS is requesting _OSI(Linux)\n"); | 1259 | printk(KERN_NOTICE PREFIX |
| 1165 | printk(KERN_WARNING PREFIX | 1260 | "BIOS _OSI(Linux) query %s%s\n", |
| 1166 | "If \"acpi_osi=Linux\" works better,\n" | 1261 | osi_linux.enable ? "honored" : "ignored", |
| 1167 | "Please send dmidecode " | 1262 | osi_linux.cmdline ? " via cmdline" : |
| 1168 | "to linux-acpi@vger.kernel.org\n"); | 1263 | osi_linux.dmi ? " via DMI" : ""); |
| 1169 | if(osi_linux) | 1264 | |
| 1265 | if (!osi_linux.dmi) { | ||
| 1266 | if (acpi_dmi_dump()) | ||
| 1267 | printk(KERN_NOTICE PREFIX | ||
| 1268 | "[please extract dmidecode output]\n"); | ||
| 1269 | printk(KERN_NOTICE PREFIX | ||
| 1270 | "Please send DMI info above to " | ||
| 1271 | "linux-acpi@vger.kernel.org\n"); | ||
| 1272 | } | ||
| 1273 | if (!osi_linux.known && !osi_linux.cmdline) { | ||
| 1274 | printk(KERN_NOTICE PREFIX | ||
| 1275 | "If \"acpi_osi=%sLinux\" works better, " | ||
| 1276 | "please notify linux-acpi@vger.kernel.org\n", | ||
| 1277 | osi_linux.enable ? "!" : ""); | ||
| 1278 | } | ||
| 1279 | |||
| 1280 | if (osi_linux.enable) | ||
| 1170 | return AE_OK; | 1281 | return AE_OK; |
| 1171 | } | 1282 | } |
| 1172 | return AE_SUPPORT; | 1283 | return AE_SUPPORT; |
| @@ -1198,28 +1309,4 @@ acpi_os_validate_address ( | |||
| 1198 | return AE_OK; | 1309 | return AE_OK; |
| 1199 | } | 1310 | } |
| 1200 | 1311 | ||
| 1201 | #ifdef CONFIG_DMI | ||
| 1202 | static int dmi_osi_linux(const struct dmi_system_id *d) | ||
| 1203 | { | ||
| 1204 | printk(KERN_NOTICE "%s detected: enabling _OSI(Linux)\n", d->ident); | ||
| 1205 | enable_osi_linux(1); | ||
| 1206 | return 0; | ||
| 1207 | } | ||
| 1208 | |||
| 1209 | static struct dmi_system_id acpi_osl_dmi_table[] __initdata = { | ||
| 1210 | /* | ||
| 1211 | * Boxes that need _OSI(Linux) | ||
| 1212 | */ | ||
| 1213 | { | ||
| 1214 | .callback = dmi_osi_linux, | ||
| 1215 | .ident = "Intel Napa CRB", | ||
| 1216 | .matches = { | ||
| 1217 | DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), | ||
| 1218 | DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"), | ||
| 1219 | }, | ||
| 1220 | }, | ||
| 1221 | {} | ||
| 1222 | }; | ||
| 1223 | #endif /* CONFIG_DMI */ | ||
| 1224 | |||
| 1225 | #endif | 1312 | #endif |
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 6742d7bc4777..1685b40abda7 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
| @@ -775,12 +775,12 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) | |||
| 775 | acpi_processor_get_throttling_states(pr) || | 775 | acpi_processor_get_throttling_states(pr) || |
| 776 | acpi_processor_get_platform_limit(pr)) | 776 | acpi_processor_get_platform_limit(pr)) |
| 777 | { | 777 | { |
| 778 | if (acpi_processor_get_fadt_info(pr)) | ||
| 779 | return 0; | ||
| 780 | pr->throttling.acpi_processor_get_throttling = | 778 | pr->throttling.acpi_processor_get_throttling = |
| 781 | &acpi_processor_get_throttling_fadt; | 779 | &acpi_processor_get_throttling_fadt; |
| 782 | pr->throttling.acpi_processor_set_throttling = | 780 | pr->throttling.acpi_processor_set_throttling = |
| 783 | &acpi_processor_set_throttling_fadt; | 781 | &acpi_processor_set_throttling_fadt; |
| 782 | if (acpi_processor_get_fadt_info(pr)) | ||
| 783 | return 0; | ||
| 784 | } else { | 784 | } else { |
| 785 | pr->throttling.acpi_processor_get_throttling = | 785 | pr->throttling.acpi_processor_get_throttling = |
| 786 | &acpi_processor_get_throttling_ptc; | 786 | &acpi_processor_get_throttling_ptc; |
diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c index bc132d8f79cb..313c99cbdc62 100644 --- a/drivers/firmware/dmi-id.c +++ b/drivers/firmware/dmi-id.c | |||
| @@ -173,8 +173,6 @@ static struct device *dmi_dev; | |||
| 173 | if (dmi_get_system_info(_field)) \ | 173 | if (dmi_get_system_info(_field)) \ |
| 174 | sys_dmi_attributes[i++] = &sys_dmi_##_name##_attr.dev_attr.attr; | 174 | sys_dmi_attributes[i++] = &sys_dmi_##_name##_attr.dev_attr.attr; |
| 175 | 175 | ||
| 176 | extern int dmi_available; | ||
| 177 | |||
| 178 | /* In a separate function to keep gcc 3.2 happy - do NOT merge this in | 176 | /* In a separate function to keep gcc 3.2 happy - do NOT merge this in |
| 179 | dmi_id_init! */ | 177 | dmi_id_init! */ |
| 180 | static void __init dmi_id_init_attr_table(void) | 178 | static void __init dmi_id_init_attr_table(void) |
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 0cdadea7a40e..5e596a7e3601 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
| @@ -470,3 +470,11 @@ int dmi_get_year(int field) | |||
| 470 | return year; | 470 | return year; |
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | /** | ||
| 474 | * dmi_get_slot - return dmi_ident[slot] | ||
| 475 | * @slot: index into dmi_ident[] | ||
| 476 | */ | ||
| 477 | char *dmi_get_slot(int slot) | ||
| 478 | { | ||
| 479 | return(dmi_ident[slot]); | ||
| 480 | } | ||
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 19c3ead2a90b..7b74b60a68a4 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
| @@ -168,7 +168,8 @@ struct acpi_device_flags { | |||
| 168 | u32 power_manageable:1; | 168 | u32 power_manageable:1; |
| 169 | u32 performance_manageable:1; | 169 | u32 performance_manageable:1; |
| 170 | u32 wake_capable:1; /* Wakeup(_PRW) supported? */ | 170 | u32 wake_capable:1; /* Wakeup(_PRW) supported? */ |
| 171 | u32 reserved:20; | 171 | u32 force_power_state:1; |
| 172 | u32 reserved:19; | ||
| 172 | }; | 173 | }; |
| 173 | 174 | ||
| 174 | /* File System */ | 175 | /* File System */ |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index e3c16c981e46..63f2e6ed698f 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <acpi/acpi_drivers.h> | 40 | #include <acpi/acpi_drivers.h> |
| 41 | #include <acpi/acpi_numa.h> | 41 | #include <acpi/acpi_numa.h> |
| 42 | #include <asm/acpi.h> | 42 | #include <asm/acpi.h> |
| 43 | #include <linux/dmi.h> | ||
| 43 | 44 | ||
| 44 | 45 | ||
| 45 | #ifdef CONFIG_ACPI | 46 | #ifdef CONFIG_ACPI |
| @@ -192,7 +193,9 @@ extern int ec_transaction(u8 command, | |||
| 192 | #endif /*CONFIG_ACPI_EC*/ | 193 | #endif /*CONFIG_ACPI_EC*/ |
| 193 | 194 | ||
| 194 | extern int acpi_blacklisted(void); | 195 | extern int acpi_blacklisted(void); |
| 195 | extern void acpi_bios_year(char *s); | 196 | #ifdef CONFIG_DMI |
| 197 | extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d); | ||
| 198 | #endif | ||
| 196 | 199 | ||
| 197 | #ifdef CONFIG_ACPI_NUMA | 200 | #ifdef CONFIG_ACPI_NUMA |
| 198 | int acpi_get_pxm(acpi_handle handle); | 201 | int acpi_get_pxm(acpi_handle handle); |
| @@ -226,5 +229,5 @@ static inline int acpi_boot_table_init(void) | |||
| 226 | return 0; | 229 | return 0; |
| 227 | } | 230 | } |
| 228 | 231 | ||
| 229 | #endif /* CONFIG_ACPI */ | 232 | #endif /* !CONFIG_ACPI */ |
| 230 | #endif /*_LINUX_ACPI_H*/ | 233 | #endif /*_LINUX_ACPI_H*/ |
diff --git a/include/linux/dmi.h b/include/linux/dmi.h index 00fc7a9c35ec..5b42a659a308 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h | |||
| @@ -78,6 +78,8 @@ extern const struct dmi_device * dmi_find_device(int type, const char *name, | |||
| 78 | extern void dmi_scan_machine(void); | 78 | extern void dmi_scan_machine(void); |
| 79 | extern int dmi_get_year(int field); | 79 | extern int dmi_get_year(int field); |
| 80 | extern int dmi_name_in_vendors(const char *str); | 80 | extern int dmi_name_in_vendors(const char *str); |
| 81 | extern int dmi_available; | ||
| 82 | extern char *dmi_get_slot(int slot); | ||
| 81 | 83 | ||
| 82 | #else | 84 | #else |
| 83 | 85 | ||
| @@ -87,6 +89,8 @@ static inline const struct dmi_device * dmi_find_device(int type, const char *na | |||
| 87 | const struct dmi_device *from) { return NULL; } | 89 | const struct dmi_device *from) { return NULL; } |
| 88 | static inline int dmi_get_year(int year) { return 0; } | 90 | static inline int dmi_get_year(int year) { return 0; } |
| 89 | static inline int dmi_name_in_vendors(const char *s) { return 0; } | 91 | static inline int dmi_name_in_vendors(const char *s) { return 0; } |
| 92 | #define dmi_available 0 | ||
| 93 | static inline char *dmi_get_slot(int slot) { return NULL; } | ||
| 90 | 94 | ||
| 91 | #endif | 95 | #endif |
| 92 | 96 | ||
