diff options
-rw-r--r-- | drivers/acpi/processor_driver.c | 5 | ||||
-rw-r--r-- | drivers/acpi/processor_throttling.c | 52 | ||||
-rw-r--r-- | include/acpi/processor.h | 6 |
3 files changed, 63 insertions, 0 deletions
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 85e48047d7b0..c8a0ca2af839 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -478,8 +478,13 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, | |||
478 | if (action == CPU_ONLINE && pr) { | 478 | if (action == CPU_ONLINE && pr) { |
479 | acpi_processor_ppc_has_changed(pr, 0); | 479 | acpi_processor_ppc_has_changed(pr, 0); |
480 | acpi_processor_cst_has_changed(pr); | 480 | acpi_processor_cst_has_changed(pr); |
481 | acpi_processor_reevaluate_tstate(pr, action); | ||
481 | acpi_processor_tstate_has_changed(pr); | 482 | acpi_processor_tstate_has_changed(pr); |
482 | } | 483 | } |
484 | if (action == CPU_DEAD && pr) { | ||
485 | /* invalidate the flag.throttling after one CPU is offline */ | ||
486 | acpi_processor_reevaluate_tstate(pr, action); | ||
487 | } | ||
483 | return NOTIFY_OK; | 488 | return NOTIFY_OK; |
484 | } | 489 | } |
485 | 490 | ||
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index ffc859c61393..4305d560b065 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -370,6 +370,58 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr) | |||
370 | } | 370 | } |
371 | 371 | ||
372 | /* | 372 | /* |
373 | * This function is used to reevaluate whether the T-state is valid | ||
374 | * after one CPU is onlined/offlined. | ||
375 | * It is noted that it won't reevaluate the following properties for | ||
376 | * the T-state. | ||
377 | * 1. Control method. | ||
378 | * 2. the number of supported T-state | ||
379 | * 3. TSD domain | ||
380 | */ | ||
381 | void acpi_processor_reevaluate_tstate(struct acpi_processor *pr, | ||
382 | unsigned long action) | ||
383 | { | ||
384 | int result = 0; | ||
385 | |||
386 | if (action == CPU_DEAD) { | ||
387 | /* When one CPU is offline, the T-state throttling | ||
388 | * will be invalidated. | ||
389 | */ | ||
390 | pr->flags.throttling = 0; | ||
391 | return; | ||
392 | } | ||
393 | /* the following is to recheck whether the T-state is valid for | ||
394 | * the online CPU | ||
395 | */ | ||
396 | if (!pr->throttling.state_count) { | ||
397 | /* If the number of T-state is invalid, it is | ||
398 | * invalidated. | ||
399 | */ | ||
400 | pr->flags.throttling = 0; | ||
401 | return; | ||
402 | } | ||
403 | pr->flags.throttling = 1; | ||
404 | |||
405 | /* Disable throttling (if enabled). We'll let subsequent | ||
406 | * policy (e.g.thermal) decide to lower performance if it | ||
407 | * so chooses, but for now we'll crank up the speed. | ||
408 | */ | ||
409 | |||
410 | result = acpi_processor_get_throttling(pr); | ||
411 | if (result) | ||
412 | goto end; | ||
413 | |||
414 | if (pr->throttling.state) { | ||
415 | result = acpi_processor_set_throttling(pr, 0, false); | ||
416 | if (result) | ||
417 | goto end; | ||
418 | } | ||
419 | |||
420 | end: | ||
421 | if (result) | ||
422 | pr->flags.throttling = 0; | ||
423 | } | ||
424 | /* | ||
373 | * _PTC - Processor Throttling Control (and status) register location | 425 | * _PTC - Processor Throttling Control (and status) register location |
374 | */ | 426 | */ |
375 | static int acpi_processor_get_throttling_control(struct acpi_processor *pr) | 427 | static int acpi_processor_get_throttling_control(struct acpi_processor *pr) |
diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 1b62102fbb67..55192ac0cede 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h | |||
@@ -324,6 +324,12 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr); | |||
324 | int acpi_processor_get_throttling_info(struct acpi_processor *pr); | 324 | int acpi_processor_get_throttling_info(struct acpi_processor *pr); |
325 | extern int acpi_processor_set_throttling(struct acpi_processor *pr, | 325 | extern int acpi_processor_set_throttling(struct acpi_processor *pr, |
326 | int state, bool force); | 326 | int state, bool force); |
327 | /* | ||
328 | * Reevaluate whether the T-state is invalid after one cpu is | ||
329 | * onlined/offlined. In such case the flags.throttling will be updated. | ||
330 | */ | ||
331 | extern void acpi_processor_reevaluate_tstate(struct acpi_processor *pr, | ||
332 | unsigned long action); | ||
327 | extern const struct file_operations acpi_processor_throttling_fops; | 333 | extern const struct file_operations acpi_processor_throttling_fops; |
328 | extern void acpi_processor_throttling_init(void); | 334 | extern void acpi_processor_throttling_init(void); |
329 | /* in processor_idle.c */ | 335 | /* in processor_idle.c */ |