| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * processor_idle - idle state submodule to the ACPI processor driver |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 8 | 9 | * - Added processor hotplug support |
|---|
| 9 | 10 | * Copyright (C) 2005 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> |
|---|
| 10 | 11 | * - Added support for C3 on SMP |
|---|
| 11 | | - * |
|---|
| 12 | | - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 13 | | - * |
|---|
| 14 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 15 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 16 | | - * the Free Software Foundation; either version 2 of the License, or (at |
|---|
| 17 | | - * your option) any later version. |
|---|
| 18 | | - * |
|---|
| 19 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 20 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 21 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 22 | | - * General Public License for more details. |
|---|
| 23 | | - * |
|---|
| 24 | | - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 25 | 12 | */ |
|---|
| 26 | 13 | #define pr_fmt(fmt) "ACPI: " fmt |
|---|
| 27 | 14 | |
|---|
| .. | .. |
|---|
| 43 | 30 | */ |
|---|
| 44 | 31 | #ifdef CONFIG_X86 |
|---|
| 45 | 32 | #include <asm/apic.h> |
|---|
| 33 | +#include <asm/cpu.h> |
|---|
| 46 | 34 | #endif |
|---|
| 47 | 35 | |
|---|
| 48 | 36 | #define ACPI_PROCESSOR_CLASS "processor" |
|---|
| .. | .. |
|---|
| 175 | 163 | } |
|---|
| 176 | 164 | |
|---|
| 177 | 165 | /* Power(C) State timer broadcast control */ |
|---|
| 178 | | -static void lapic_timer_state_broadcast(struct acpi_processor *pr, |
|---|
| 179 | | - struct acpi_processor_cx *cx, |
|---|
| 180 | | - int broadcast) |
|---|
| 166 | +static bool lapic_timer_needs_broadcast(struct acpi_processor *pr, |
|---|
| 167 | + struct acpi_processor_cx *cx) |
|---|
| 181 | 168 | { |
|---|
| 182 | | - int state = cx - pr->power.states; |
|---|
| 183 | | - |
|---|
| 184 | | - if (state >= pr->power.timer_broadcast_on_state) { |
|---|
| 185 | | - if (broadcast) |
|---|
| 186 | | - tick_broadcast_enter(); |
|---|
| 187 | | - else |
|---|
| 188 | | - tick_broadcast_exit(); |
|---|
| 189 | | - } |
|---|
| 169 | + return cx - pr->power.states >= pr->power.timer_broadcast_on_state; |
|---|
| 190 | 170 | } |
|---|
| 191 | 171 | |
|---|
| 192 | 172 | #else |
|---|
| .. | .. |
|---|
| 194 | 174 | static void lapic_timer_check_state(int state, struct acpi_processor *pr, |
|---|
| 195 | 175 | struct acpi_processor_cx *cstate) { } |
|---|
| 196 | 176 | static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) { } |
|---|
| 197 | | -static void lapic_timer_state_broadcast(struct acpi_processor *pr, |
|---|
| 198 | | - struct acpi_processor_cx *cx, |
|---|
| 199 | | - int broadcast) |
|---|
| 177 | + |
|---|
| 178 | +static bool lapic_timer_needs_broadcast(struct acpi_processor *pr, |
|---|
| 179 | + struct acpi_processor_cx *cx) |
|---|
| 200 | 180 | { |
|---|
| 181 | + return false; |
|---|
| 201 | 182 | } |
|---|
| 202 | 183 | |
|---|
| 203 | 184 | #endif |
|---|
| .. | .. |
|---|
| 206 | 187 | static void tsc_check_state(int state) |
|---|
| 207 | 188 | { |
|---|
| 208 | 189 | switch (boot_cpu_data.x86_vendor) { |
|---|
| 190 | + case X86_VENDOR_HYGON: |
|---|
| 209 | 191 | case X86_VENDOR_AMD: |
|---|
| 210 | 192 | case X86_VENDOR_INTEL: |
|---|
| 211 | 193 | case X86_VENDOR_CENTAUR: |
|---|
| 194 | + case X86_VENDOR_ZHAOXIN: |
|---|
| 212 | 195 | /* |
|---|
| 213 | 196 | * AMD Fam10h TSC will tick in all |
|---|
| 214 | 197 | * C/P/S0/S1 states when this bit is set. |
|---|
| 215 | 198 | */ |
|---|
| 216 | 199 | if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) |
|---|
| 217 | 200 | return; |
|---|
| 218 | | - |
|---|
| 219 | | - /*FALL THROUGH*/ |
|---|
| 201 | + fallthrough; |
|---|
| 220 | 202 | default: |
|---|
| 221 | 203 | /* TSC could halt in idle, so notify users */ |
|---|
| 222 | 204 | if (state > ACPI_STATE_C1) |
|---|
| .. | .. |
|---|
| 282 | 264 | pr->power.states[ACPI_STATE_C2].address, |
|---|
| 283 | 265 | pr->power.states[ACPI_STATE_C3].address)); |
|---|
| 284 | 266 | |
|---|
| 267 | + snprintf(pr->power.states[ACPI_STATE_C2].desc, |
|---|
| 268 | + ACPI_CX_DESC_LEN, "ACPI P_LVL2 IOPORT 0x%x", |
|---|
| 269 | + pr->power.states[ACPI_STATE_C2].address); |
|---|
| 270 | + snprintf(pr->power.states[ACPI_STATE_C3].desc, |
|---|
| 271 | + ACPI_CX_DESC_LEN, "ACPI P_LVL3 IOPORT 0x%x", |
|---|
| 272 | + pr->power.states[ACPI_STATE_C3].address); |
|---|
| 273 | + |
|---|
| 285 | 274 | return 0; |
|---|
| 286 | 275 | } |
|---|
| 287 | 276 | |
|---|
| .. | .. |
|---|
| 304 | 293 | |
|---|
| 305 | 294 | static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) |
|---|
| 306 | 295 | { |
|---|
| 307 | | - acpi_status status; |
|---|
| 308 | | - u64 count; |
|---|
| 309 | | - int current_count; |
|---|
| 310 | | - int i, ret = 0; |
|---|
| 311 | | - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
|---|
| 312 | | - union acpi_object *cst; |
|---|
| 296 | + int ret; |
|---|
| 313 | 297 | |
|---|
| 314 | 298 | if (nocst) |
|---|
| 315 | 299 | return -ENODEV; |
|---|
| 316 | 300 | |
|---|
| 317 | | - current_count = 0; |
|---|
| 301 | + ret = acpi_processor_evaluate_cst(pr->handle, pr->id, &pr->power); |
|---|
| 302 | + if (ret) |
|---|
| 303 | + return ret; |
|---|
| 318 | 304 | |
|---|
| 319 | | - status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); |
|---|
| 320 | | - if (ACPI_FAILURE(status)) { |
|---|
| 321 | | - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No _CST, giving up\n")); |
|---|
| 322 | | - return -ENODEV; |
|---|
| 323 | | - } |
|---|
| 305 | + if (!pr->power.count) |
|---|
| 306 | + return -EFAULT; |
|---|
| 324 | 307 | |
|---|
| 325 | | - cst = buffer.pointer; |
|---|
| 326 | | - |
|---|
| 327 | | - /* There must be at least 2 elements */ |
|---|
| 328 | | - if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) { |
|---|
| 329 | | - pr_err("not enough elements in _CST\n"); |
|---|
| 330 | | - ret = -EFAULT; |
|---|
| 331 | | - goto end; |
|---|
| 332 | | - } |
|---|
| 333 | | - |
|---|
| 334 | | - count = cst->package.elements[0].integer.value; |
|---|
| 335 | | - |
|---|
| 336 | | - /* Validate number of power states. */ |
|---|
| 337 | | - if (count < 1 || count != cst->package.count - 1) { |
|---|
| 338 | | - pr_err("count given by _CST is not valid\n"); |
|---|
| 339 | | - ret = -EFAULT; |
|---|
| 340 | | - goto end; |
|---|
| 341 | | - } |
|---|
| 342 | | - |
|---|
| 343 | | - /* Tell driver that at least _CST is supported. */ |
|---|
| 344 | 308 | pr->flags.has_cst = 1; |
|---|
| 345 | | - |
|---|
| 346 | | - for (i = 1; i <= count; i++) { |
|---|
| 347 | | - union acpi_object *element; |
|---|
| 348 | | - union acpi_object *obj; |
|---|
| 349 | | - struct acpi_power_register *reg; |
|---|
| 350 | | - struct acpi_processor_cx cx; |
|---|
| 351 | | - |
|---|
| 352 | | - memset(&cx, 0, sizeof(cx)); |
|---|
| 353 | | - |
|---|
| 354 | | - element = &(cst->package.elements[i]); |
|---|
| 355 | | - if (element->type != ACPI_TYPE_PACKAGE) |
|---|
| 356 | | - continue; |
|---|
| 357 | | - |
|---|
| 358 | | - if (element->package.count != 4) |
|---|
| 359 | | - continue; |
|---|
| 360 | | - |
|---|
| 361 | | - obj = &(element->package.elements[0]); |
|---|
| 362 | | - |
|---|
| 363 | | - if (obj->type != ACPI_TYPE_BUFFER) |
|---|
| 364 | | - continue; |
|---|
| 365 | | - |
|---|
| 366 | | - reg = (struct acpi_power_register *)obj->buffer.pointer; |
|---|
| 367 | | - |
|---|
| 368 | | - if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO && |
|---|
| 369 | | - (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) |
|---|
| 370 | | - continue; |
|---|
| 371 | | - |
|---|
| 372 | | - /* There should be an easy way to extract an integer... */ |
|---|
| 373 | | - obj = &(element->package.elements[1]); |
|---|
| 374 | | - if (obj->type != ACPI_TYPE_INTEGER) |
|---|
| 375 | | - continue; |
|---|
| 376 | | - |
|---|
| 377 | | - cx.type = obj->integer.value; |
|---|
| 378 | | - /* |
|---|
| 379 | | - * Some buggy BIOSes won't list C1 in _CST - |
|---|
| 380 | | - * Let acpi_processor_get_power_info_default() handle them later |
|---|
| 381 | | - */ |
|---|
| 382 | | - if (i == 1 && cx.type != ACPI_STATE_C1) |
|---|
| 383 | | - current_count++; |
|---|
| 384 | | - |
|---|
| 385 | | - cx.address = reg->address; |
|---|
| 386 | | - cx.index = current_count + 1; |
|---|
| 387 | | - |
|---|
| 388 | | - cx.entry_method = ACPI_CSTATE_SYSTEMIO; |
|---|
| 389 | | - if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { |
|---|
| 390 | | - if (acpi_processor_ffh_cstate_probe |
|---|
| 391 | | - (pr->id, &cx, reg) == 0) { |
|---|
| 392 | | - cx.entry_method = ACPI_CSTATE_FFH; |
|---|
| 393 | | - } else if (cx.type == ACPI_STATE_C1) { |
|---|
| 394 | | - /* |
|---|
| 395 | | - * C1 is a special case where FIXED_HARDWARE |
|---|
| 396 | | - * can be handled in non-MWAIT way as well. |
|---|
| 397 | | - * In that case, save this _CST entry info. |
|---|
| 398 | | - * Otherwise, ignore this info and continue. |
|---|
| 399 | | - */ |
|---|
| 400 | | - cx.entry_method = ACPI_CSTATE_HALT; |
|---|
| 401 | | - snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT"); |
|---|
| 402 | | - } else { |
|---|
| 403 | | - continue; |
|---|
| 404 | | - } |
|---|
| 405 | | - if (cx.type == ACPI_STATE_C1 && |
|---|
| 406 | | - (boot_option_idle_override == IDLE_NOMWAIT)) { |
|---|
| 407 | | - /* |
|---|
| 408 | | - * In most cases the C1 space_id obtained from |
|---|
| 409 | | - * _CST object is FIXED_HARDWARE access mode. |
|---|
| 410 | | - * But when the option of idle=halt is added, |
|---|
| 411 | | - * the entry_method type should be changed from |
|---|
| 412 | | - * CSTATE_FFH to CSTATE_HALT. |
|---|
| 413 | | - * When the option of idle=nomwait is added, |
|---|
| 414 | | - * the C1 entry_method type should be |
|---|
| 415 | | - * CSTATE_HALT. |
|---|
| 416 | | - */ |
|---|
| 417 | | - cx.entry_method = ACPI_CSTATE_HALT; |
|---|
| 418 | | - snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT"); |
|---|
| 419 | | - } |
|---|
| 420 | | - } else { |
|---|
| 421 | | - snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x", |
|---|
| 422 | | - cx.address); |
|---|
| 423 | | - } |
|---|
| 424 | | - |
|---|
| 425 | | - if (cx.type == ACPI_STATE_C1) { |
|---|
| 426 | | - cx.valid = 1; |
|---|
| 427 | | - } |
|---|
| 428 | | - |
|---|
| 429 | | - obj = &(element->package.elements[2]); |
|---|
| 430 | | - if (obj->type != ACPI_TYPE_INTEGER) |
|---|
| 431 | | - continue; |
|---|
| 432 | | - |
|---|
| 433 | | - cx.latency = obj->integer.value; |
|---|
| 434 | | - |
|---|
| 435 | | - obj = &(element->package.elements[3]); |
|---|
| 436 | | - if (obj->type != ACPI_TYPE_INTEGER) |
|---|
| 437 | | - continue; |
|---|
| 438 | | - |
|---|
| 439 | | - current_count++; |
|---|
| 440 | | - memcpy(&(pr->power.states[current_count]), &cx, sizeof(cx)); |
|---|
| 441 | | - |
|---|
| 442 | | - /* |
|---|
| 443 | | - * We support total ACPI_PROCESSOR_MAX_POWER - 1 |
|---|
| 444 | | - * (From 1 through ACPI_PROCESSOR_MAX_POWER - 1) |
|---|
| 445 | | - */ |
|---|
| 446 | | - if (current_count >= (ACPI_PROCESSOR_MAX_POWER - 1)) { |
|---|
| 447 | | - pr_warn("Limiting number of power states to max (%d)\n", |
|---|
| 448 | | - ACPI_PROCESSOR_MAX_POWER); |
|---|
| 449 | | - pr_warn("Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n"); |
|---|
| 450 | | - break; |
|---|
| 451 | | - } |
|---|
| 452 | | - } |
|---|
| 453 | | - |
|---|
| 454 | | - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d power states\n", |
|---|
| 455 | | - current_count)); |
|---|
| 456 | | - |
|---|
| 457 | | - /* Validate number of power states discovered */ |
|---|
| 458 | | - if (current_count < 2) |
|---|
| 459 | | - ret = -EFAULT; |
|---|
| 460 | | - |
|---|
| 461 | | - end: |
|---|
| 462 | | - kfree(buffer.pointer); |
|---|
| 463 | | - |
|---|
| 464 | | - return ret; |
|---|
| 309 | + return 0; |
|---|
| 465 | 310 | } |
|---|
| 466 | 311 | |
|---|
| 467 | 312 | static void acpi_processor_power_verify_c3(struct acpi_processor *pr, |
|---|
| .. | .. |
|---|
| 652 | 497 | for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { |
|---|
| 653 | 498 | if (pr->power.states[i].valid) { |
|---|
| 654 | 499 | pr->power.count = i; |
|---|
| 655 | | - if (pr->power.states[i].type >= ACPI_STATE_C2) |
|---|
| 656 | | - pr->flags.power = 1; |
|---|
| 500 | + pr->flags.power = 1; |
|---|
| 657 | 501 | } |
|---|
| 658 | 502 | } |
|---|
| 659 | 503 | |
|---|
| .. | .. |
|---|
| 686 | 530 | return bm_status; |
|---|
| 687 | 531 | } |
|---|
| 688 | 532 | |
|---|
| 533 | +static void wait_for_freeze(void) |
|---|
| 534 | +{ |
|---|
| 535 | +#ifdef CONFIG_X86 |
|---|
| 536 | + /* No delay is needed if we are in guest */ |
|---|
| 537 | + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) |
|---|
| 538 | + return; |
|---|
| 539 | +#endif |
|---|
| 540 | + /* Dummy wait op - must do something useless after P_LVL2 read |
|---|
| 541 | + because chipsets cannot guarantee that STPCLK# signal |
|---|
| 542 | + gets asserted in time to freeze execution properly. */ |
|---|
| 543 | + inl(acpi_gbl_FADT.xpm_timer_block.address); |
|---|
| 544 | +} |
|---|
| 545 | + |
|---|
| 689 | 546 | /** |
|---|
| 690 | 547 | * acpi_idle_do_entry - enter idle state using the appropriate method |
|---|
| 691 | 548 | * @cx: cstate data |
|---|
| .. | .. |
|---|
| 702 | 559 | } else { |
|---|
| 703 | 560 | /* IO port based C-state */ |
|---|
| 704 | 561 | inb(cx->address); |
|---|
| 705 | | - /* Dummy wait op - must do something useless after P_LVL2 read |
|---|
| 706 | | - because chipsets cannot guarantee that STPCLK# signal |
|---|
| 707 | | - gets asserted in time to freeze execution properly. */ |
|---|
| 708 | | - inl(acpi_gbl_FADT.xpm_timer_block.address); |
|---|
| 562 | + wait_for_freeze(); |
|---|
| 709 | 563 | } |
|---|
| 710 | 564 | } |
|---|
| 711 | 565 | |
|---|
| .. | .. |
|---|
| 726 | 580 | safe_halt(); |
|---|
| 727 | 581 | else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) { |
|---|
| 728 | 582 | inb(cx->address); |
|---|
| 729 | | - /* See comment in acpi_idle_do_entry() */ |
|---|
| 730 | | - inl(acpi_gbl_FADT.xpm_timer_block.address); |
|---|
| 583 | + wait_for_freeze(); |
|---|
| 731 | 584 | } else |
|---|
| 732 | 585 | return -ENODEV; |
|---|
| 586 | + |
|---|
| 587 | +#if defined(CONFIG_X86) && defined(CONFIG_HOTPLUG_CPU) |
|---|
| 588 | + cond_wakeup_cpu0(); |
|---|
| 589 | +#endif |
|---|
| 733 | 590 | } |
|---|
| 734 | 591 | |
|---|
| 735 | 592 | /* Never reached */ |
|---|
| .. | .. |
|---|
| 747 | 604 | |
|---|
| 748 | 605 | /** |
|---|
| 749 | 606 | * acpi_idle_enter_bm - enters C3 with proper BM handling |
|---|
| 607 | + * @drv: cpuidle driver |
|---|
| 750 | 608 | * @pr: Target processor |
|---|
| 751 | 609 | * @cx: Target state context |
|---|
| 752 | | - * @timer_bc: Whether or not to change timer mode to broadcast |
|---|
| 610 | + * @index: index of target state |
|---|
| 753 | 611 | */ |
|---|
| 754 | | -static void acpi_idle_enter_bm(struct acpi_processor *pr, |
|---|
| 755 | | - struct acpi_processor_cx *cx, bool timer_bc) |
|---|
| 612 | +static int __cpuidle acpi_idle_enter_bm(struct cpuidle_driver *drv, |
|---|
| 613 | + struct acpi_processor *pr, |
|---|
| 614 | + struct acpi_processor_cx *cx, |
|---|
| 615 | + int index) |
|---|
| 756 | 616 | { |
|---|
| 757 | | - acpi_unlazy_tlb(smp_processor_id()); |
|---|
| 758 | | - |
|---|
| 759 | | - /* |
|---|
| 760 | | - * Must be done before busmaster disable as we might need to |
|---|
| 761 | | - * access HPET ! |
|---|
| 762 | | - */ |
|---|
| 763 | | - if (timer_bc) |
|---|
| 764 | | - lapic_timer_state_broadcast(pr, cx, 1); |
|---|
| 617 | + static struct acpi_processor_cx safe_cx = { |
|---|
| 618 | + .entry_method = ACPI_CSTATE_HALT, |
|---|
| 619 | + }; |
|---|
| 765 | 620 | |
|---|
| 766 | 621 | /* |
|---|
| 767 | 622 | * disable bus master |
|---|
| 768 | 623 | * bm_check implies we need ARB_DIS |
|---|
| 769 | 624 | * bm_control implies whether we can do ARB_DIS |
|---|
| 770 | 625 | * |
|---|
| 771 | | - * That leaves a case where bm_check is set and bm_control is |
|---|
| 772 | | - * not set. In that case we cannot do much, we enter C3 |
|---|
| 773 | | - * without doing anything. |
|---|
| 626 | + * That leaves a case where bm_check is set and bm_control is not set. |
|---|
| 627 | + * In that case we cannot do much, we enter C3 without doing anything. |
|---|
| 774 | 628 | */ |
|---|
| 775 | | - if (pr->flags.bm_control) { |
|---|
| 629 | + bool dis_bm = pr->flags.bm_control; |
|---|
| 630 | + |
|---|
| 631 | + /* If we can skip BM, demote to a safe state. */ |
|---|
| 632 | + if (!cx->bm_sts_skip && acpi_idle_bm_check()) { |
|---|
| 633 | + dis_bm = false; |
|---|
| 634 | + index = drv->safe_state_index; |
|---|
| 635 | + if (index >= 0) { |
|---|
| 636 | + cx = this_cpu_read(acpi_cstate[index]); |
|---|
| 637 | + } else { |
|---|
| 638 | + cx = &safe_cx; |
|---|
| 639 | + index = -EBUSY; |
|---|
| 640 | + } |
|---|
| 641 | + } |
|---|
| 642 | + |
|---|
| 643 | + if (dis_bm) { |
|---|
| 776 | 644 | raw_spin_lock(&c3_lock); |
|---|
| 777 | 645 | c3_cpu_count++; |
|---|
| 778 | 646 | /* Disable bus master arbitration when all CPUs are in C3 */ |
|---|
| .. | .. |
|---|
| 781 | 649 | raw_spin_unlock(&c3_lock); |
|---|
| 782 | 650 | } |
|---|
| 783 | 651 | |
|---|
| 652 | + rcu_idle_enter(); |
|---|
| 653 | + |
|---|
| 784 | 654 | acpi_idle_do_entry(cx); |
|---|
| 785 | 655 | |
|---|
| 656 | + rcu_idle_exit(); |
|---|
| 657 | + |
|---|
| 786 | 658 | /* Re-enable bus master arbitration */ |
|---|
| 787 | | - if (pr->flags.bm_control) { |
|---|
| 659 | + if (dis_bm) { |
|---|
| 788 | 660 | raw_spin_lock(&c3_lock); |
|---|
| 789 | 661 | acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0); |
|---|
| 790 | 662 | c3_cpu_count--; |
|---|
| 791 | 663 | raw_spin_unlock(&c3_lock); |
|---|
| 792 | 664 | } |
|---|
| 793 | 665 | |
|---|
| 794 | | - if (timer_bc) |
|---|
| 795 | | - lapic_timer_state_broadcast(pr, cx, 0); |
|---|
| 666 | + return index; |
|---|
| 796 | 667 | } |
|---|
| 797 | 668 | |
|---|
| 798 | | -static int acpi_idle_enter(struct cpuidle_device *dev, |
|---|
| 669 | +static int __cpuidle acpi_idle_enter(struct cpuidle_device *dev, |
|---|
| 799 | 670 | struct cpuidle_driver *drv, int index) |
|---|
| 800 | 671 | { |
|---|
| 801 | 672 | struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); |
|---|
| .. | .. |
|---|
| 806 | 677 | return -EINVAL; |
|---|
| 807 | 678 | |
|---|
| 808 | 679 | if (cx->type != ACPI_STATE_C1) { |
|---|
| 680 | + if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check) |
|---|
| 681 | + return acpi_idle_enter_bm(drv, pr, cx, index); |
|---|
| 682 | + |
|---|
| 683 | + /* C2 to C1 demotion. */ |
|---|
| 809 | 684 | if (acpi_idle_fallback_to_c1(pr) && num_online_cpus() > 1) { |
|---|
| 810 | 685 | index = ACPI_IDLE_STATE_START; |
|---|
| 811 | 686 | cx = per_cpu(acpi_cstate[index], dev->cpu); |
|---|
| 812 | | - } else if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check) { |
|---|
| 813 | | - if (cx->bm_sts_skip || !acpi_idle_bm_check()) { |
|---|
| 814 | | - acpi_idle_enter_bm(pr, cx, true); |
|---|
| 815 | | - return index; |
|---|
| 816 | | - } else if (drv->safe_state_index >= 0) { |
|---|
| 817 | | - index = drv->safe_state_index; |
|---|
| 818 | | - cx = per_cpu(acpi_cstate[index], dev->cpu); |
|---|
| 819 | | - } else { |
|---|
| 820 | | - acpi_safe_halt(); |
|---|
| 821 | | - return -EBUSY; |
|---|
| 822 | | - } |
|---|
| 823 | 687 | } |
|---|
| 824 | 688 | } |
|---|
| 825 | | - |
|---|
| 826 | | - lapic_timer_state_broadcast(pr, cx, 1); |
|---|
| 827 | 689 | |
|---|
| 828 | 690 | if (cx->type == ACPI_STATE_C3) |
|---|
| 829 | 691 | ACPI_FLUSH_CPU_CACHE(); |
|---|
| 830 | 692 | |
|---|
| 831 | 693 | acpi_idle_do_entry(cx); |
|---|
| 832 | 694 | |
|---|
| 833 | | - lapic_timer_state_broadcast(pr, cx, 0); |
|---|
| 834 | | - |
|---|
| 835 | 695 | return index; |
|---|
| 836 | 696 | } |
|---|
| 837 | 697 | |
|---|
| 838 | | -static void acpi_idle_enter_s2idle(struct cpuidle_device *dev, |
|---|
| 839 | | - struct cpuidle_driver *drv, int index) |
|---|
| 698 | +static int __cpuidle acpi_idle_enter_s2idle(struct cpuidle_device *dev, |
|---|
| 699 | + struct cpuidle_driver *drv, int index) |
|---|
| 840 | 700 | { |
|---|
| 841 | 701 | struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); |
|---|
| 842 | 702 | |
|---|
| .. | .. |
|---|
| 844 | 704 | struct acpi_processor *pr = __this_cpu_read(processors); |
|---|
| 845 | 705 | |
|---|
| 846 | 706 | if (unlikely(!pr)) |
|---|
| 847 | | - return; |
|---|
| 707 | + return 0; |
|---|
| 848 | 708 | |
|---|
| 849 | 709 | if (pr->flags.bm_check) { |
|---|
| 850 | | - acpi_idle_enter_bm(pr, cx, false); |
|---|
| 851 | | - return; |
|---|
| 710 | + u8 bm_sts_skip = cx->bm_sts_skip; |
|---|
| 711 | + |
|---|
| 712 | + /* Don't check BM_STS, do an unconditional ARB_DIS for S2IDLE */ |
|---|
| 713 | + cx->bm_sts_skip = 1; |
|---|
| 714 | + acpi_idle_enter_bm(drv, pr, cx, index); |
|---|
| 715 | + cx->bm_sts_skip = bm_sts_skip; |
|---|
| 716 | + |
|---|
| 717 | + return 0; |
|---|
| 852 | 718 | } else { |
|---|
| 853 | 719 | ACPI_FLUSH_CPU_CACHE(); |
|---|
| 854 | 720 | } |
|---|
| 855 | 721 | } |
|---|
| 856 | 722 | acpi_idle_do_entry(cx); |
|---|
| 723 | + |
|---|
| 724 | + return 0; |
|---|
| 857 | 725 | } |
|---|
| 858 | 726 | |
|---|
| 859 | 727 | static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr, |
|---|
| .. | .. |
|---|
| 861 | 729 | { |
|---|
| 862 | 730 | int i, count = ACPI_IDLE_STATE_START; |
|---|
| 863 | 731 | struct acpi_processor_cx *cx; |
|---|
| 732 | + struct cpuidle_state *state; |
|---|
| 864 | 733 | |
|---|
| 865 | 734 | if (max_cstate == 0) |
|---|
| 866 | 735 | max_cstate = 1; |
|---|
| 867 | 736 | |
|---|
| 868 | 737 | for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { |
|---|
| 738 | + state = &acpi_idle_driver.states[count]; |
|---|
| 869 | 739 | cx = &pr->power.states[i]; |
|---|
| 870 | 740 | |
|---|
| 871 | 741 | if (!cx->valid) |
|---|
| 872 | 742 | continue; |
|---|
| 873 | 743 | |
|---|
| 874 | 744 | per_cpu(acpi_cstate[count], dev->cpu) = cx; |
|---|
| 745 | + |
|---|
| 746 | + if (lapic_timer_needs_broadcast(pr, cx)) |
|---|
| 747 | + state->flags |= CPUIDLE_FLAG_TIMER_STOP; |
|---|
| 748 | + |
|---|
| 749 | + if (cx->type == ACPI_STATE_C3) { |
|---|
| 750 | + state->flags |= CPUIDLE_FLAG_TLB_FLUSHED; |
|---|
| 751 | + if (pr->flags.bm_check) |
|---|
| 752 | + state->flags |= CPUIDLE_FLAG_RCU_IDLE; |
|---|
| 753 | + } |
|---|
| 875 | 754 | |
|---|
| 876 | 755 | count++; |
|---|
| 877 | 756 | if (count == CPUIDLE_STATE_MAX) |
|---|
| .. | .. |
|---|
| 944 | 823 | |
|---|
| 945 | 824 | static inline void acpi_processor_cstate_first_run_checks(void) |
|---|
| 946 | 825 | { |
|---|
| 947 | | - acpi_status status; |
|---|
| 948 | 826 | static int first_run; |
|---|
| 949 | 827 | |
|---|
| 950 | 828 | if (first_run) |
|---|
| .. | .. |
|---|
| 956 | 834 | max_cstate); |
|---|
| 957 | 835 | first_run++; |
|---|
| 958 | 836 | |
|---|
| 959 | | - if (acpi_gbl_FADT.cst_control && !nocst) { |
|---|
| 960 | | - status = acpi_os_write_port(acpi_gbl_FADT.smi_command, |
|---|
| 961 | | - acpi_gbl_FADT.cst_control, 8); |
|---|
| 962 | | - if (ACPI_FAILURE(status)) |
|---|
| 963 | | - ACPI_EXCEPTION((AE_INFO, status, |
|---|
| 964 | | - "Notifying BIOS of _CST ability failed")); |
|---|
| 965 | | - } |
|---|
| 837 | + if (nocst) |
|---|
| 838 | + return; |
|---|
| 839 | + |
|---|
| 840 | + acpi_processor_claim_cst_control(); |
|---|
| 966 | 841 | } |
|---|
| 967 | 842 | #else |
|---|
| 968 | 843 | |
|---|
| .. | .. |
|---|
| 1205 | 1080 | return 0; |
|---|
| 1206 | 1081 | } |
|---|
| 1207 | 1082 | |
|---|
| 1083 | +int __weak acpi_processor_ffh_lpi_probe(unsigned int cpu) |
|---|
| 1084 | +{ |
|---|
| 1085 | + return -EOPNOTSUPP; |
|---|
| 1086 | +} |
|---|
| 1087 | + |
|---|
| 1208 | 1088 | static int acpi_processor_get_lpi_info(struct acpi_processor *pr) |
|---|
| 1209 | 1089 | { |
|---|
| 1210 | 1090 | int ret, i; |
|---|
| .. | .. |
|---|
| 1212 | 1092 | acpi_handle handle = pr->handle, pr_ahandle; |
|---|
| 1213 | 1093 | struct acpi_device *d = NULL; |
|---|
| 1214 | 1094 | struct acpi_lpi_states_array info[2], *tmp, *prev, *curr; |
|---|
| 1095 | + |
|---|
| 1096 | + /* make sure our architecture has support */ |
|---|
| 1097 | + ret = acpi_processor_ffh_lpi_probe(pr->id); |
|---|
| 1098 | + if (ret == -EOPNOTSUPP) |
|---|
| 1099 | + return ret; |
|---|
| 1215 | 1100 | |
|---|
| 1216 | 1101 | if (!osc_pc_lpi_support_confirmed) |
|---|
| 1217 | 1102 | return -EOPNOTSUPP; |
|---|
| .. | .. |
|---|
| 1262 | 1147 | pr->flags.power = 1; |
|---|
| 1263 | 1148 | |
|---|
| 1264 | 1149 | return 0; |
|---|
| 1265 | | -} |
|---|
| 1266 | | - |
|---|
| 1267 | | -int __weak acpi_processor_ffh_lpi_probe(unsigned int cpu) |
|---|
| 1268 | | -{ |
|---|
| 1269 | | - return -ENODEV; |
|---|
| 1270 | 1150 | } |
|---|
| 1271 | 1151 | |
|---|
| 1272 | 1152 | int __weak acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi) |
|---|