diff options
Diffstat (limited to 'drivers')
46 files changed, 1062 insertions, 516 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index d42eeef9d928..1cbb88d938e5 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -782,7 +782,7 @@ static int acpi_battery_update(struct acpi_battery *battery, bool resume) | |||
782 | if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) || | 782 | if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) || |
783 | (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) && | 783 | (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) && |
784 | (battery->capacity_now <= battery->alarm))) | 784 | (battery->capacity_now <= battery->alarm))) |
785 | pm_wakeup_event(&battery->device->dev, 0); | 785 | acpi_pm_wakeup_event(&battery->device->dev); |
786 | 786 | ||
787 | return result; | 787 | return result; |
788 | } | 788 | } |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index e19f530f1083..91cfdf377df7 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -217,7 +217,7 @@ static int acpi_lid_notify_state(struct acpi_device *device, int state) | |||
217 | } | 217 | } |
218 | 218 | ||
219 | if (state) | 219 | if (state) |
220 | pm_wakeup_event(&device->dev, 0); | 220 | acpi_pm_wakeup_event(&device->dev); |
221 | 221 | ||
222 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); | 222 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); |
223 | if (ret == NOTIFY_DONE) | 223 | if (ret == NOTIFY_DONE) |
@@ -402,7 +402,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) | |||
402 | } else { | 402 | } else { |
403 | int keycode; | 403 | int keycode; |
404 | 404 | ||
405 | pm_wakeup_event(&device->dev, 0); | 405 | acpi_pm_wakeup_event(&device->dev); |
406 | if (button->suspended) | 406 | if (button->suspended) |
407 | break; | 407 | break; |
408 | 408 | ||
@@ -534,6 +534,7 @@ static int acpi_button_add(struct acpi_device *device) | |||
534 | lid_device = device; | 534 | lid_device = device; |
535 | } | 535 | } |
536 | 536 | ||
537 | device_init_wakeup(&device->dev, true); | ||
537 | printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); | 538 | printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); |
538 | return 0; | 539 | return 0; |
539 | 540 | ||
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 993fd31394c8..28938b5a334e 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/pm_qos.h> | 24 | #include <linux/pm_qos.h> |
25 | #include <linux/pm_domain.h> | 25 | #include <linux/pm_domain.h> |
26 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
27 | #include <linux/suspend.h> | ||
27 | 28 | ||
28 | #include "internal.h" | 29 | #include "internal.h" |
29 | 30 | ||
@@ -385,6 +386,12 @@ EXPORT_SYMBOL(acpi_bus_power_manageable); | |||
385 | #ifdef CONFIG_PM | 386 | #ifdef CONFIG_PM |
386 | static DEFINE_MUTEX(acpi_pm_notifier_lock); | 387 | static DEFINE_MUTEX(acpi_pm_notifier_lock); |
387 | 388 | ||
389 | void acpi_pm_wakeup_event(struct device *dev) | ||
390 | { | ||
391 | pm_wakeup_dev_event(dev, 0, acpi_s2idle_wakeup()); | ||
392 | } | ||
393 | EXPORT_SYMBOL_GPL(acpi_pm_wakeup_event); | ||
394 | |||
388 | static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) | 395 | static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) |
389 | { | 396 | { |
390 | struct acpi_device *adev; | 397 | struct acpi_device *adev; |
@@ -399,9 +406,9 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) | |||
399 | mutex_lock(&acpi_pm_notifier_lock); | 406 | mutex_lock(&acpi_pm_notifier_lock); |
400 | 407 | ||
401 | if (adev->wakeup.flags.notifier_present) { | 408 | if (adev->wakeup.flags.notifier_present) { |
402 | __pm_wakeup_event(adev->wakeup.ws, 0); | 409 | pm_wakeup_ws_event(adev->wakeup.ws, 0, acpi_s2idle_wakeup()); |
403 | if (adev->wakeup.context.work.func) | 410 | if (adev->wakeup.context.func) |
404 | queue_pm_work(&adev->wakeup.context.work); | 411 | adev->wakeup.context.func(&adev->wakeup.context); |
405 | } | 412 | } |
406 | 413 | ||
407 | mutex_unlock(&acpi_pm_notifier_lock); | 414 | mutex_unlock(&acpi_pm_notifier_lock); |
@@ -413,7 +420,7 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) | |||
413 | * acpi_add_pm_notifier - Register PM notify handler for given ACPI device. | 420 | * acpi_add_pm_notifier - Register PM notify handler for given ACPI device. |
414 | * @adev: ACPI device to add the notify handler for. | 421 | * @adev: ACPI device to add the notify handler for. |
415 | * @dev: Device to generate a wakeup event for while handling the notification. | 422 | * @dev: Device to generate a wakeup event for while handling the notification. |
416 | * @work_func: Work function to execute when handling the notification. | 423 | * @func: Work function to execute when handling the notification. |
417 | * | 424 | * |
418 | * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of | 425 | * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of |
419 | * PM wakeup events. For example, wakeup events may be generated for bridges | 426 | * PM wakeup events. For example, wakeup events may be generated for bridges |
@@ -421,11 +428,11 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) | |||
421 | * bridge itself doesn't have a wakeup GPE associated with it. | 428 | * bridge itself doesn't have a wakeup GPE associated with it. |
422 | */ | 429 | */ |
423 | acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev, | 430 | acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev, |
424 | void (*work_func)(struct work_struct *work)) | 431 | void (*func)(struct acpi_device_wakeup_context *context)) |
425 | { | 432 | { |
426 | acpi_status status = AE_ALREADY_EXISTS; | 433 | acpi_status status = AE_ALREADY_EXISTS; |
427 | 434 | ||
428 | if (!dev && !work_func) | 435 | if (!dev && !func) |
429 | return AE_BAD_PARAMETER; | 436 | return AE_BAD_PARAMETER; |
430 | 437 | ||
431 | mutex_lock(&acpi_pm_notifier_lock); | 438 | mutex_lock(&acpi_pm_notifier_lock); |
@@ -435,8 +442,7 @@ acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev, | |||
435 | 442 | ||
436 | adev->wakeup.ws = wakeup_source_register(dev_name(&adev->dev)); | 443 | adev->wakeup.ws = wakeup_source_register(dev_name(&adev->dev)); |
437 | adev->wakeup.context.dev = dev; | 444 | adev->wakeup.context.dev = dev; |
438 | if (work_func) | 445 | adev->wakeup.context.func = func; |
439 | INIT_WORK(&adev->wakeup.context.work, work_func); | ||
440 | 446 | ||
441 | status = acpi_install_notify_handler(adev->handle, ACPI_SYSTEM_NOTIFY, | 447 | status = acpi_install_notify_handler(adev->handle, ACPI_SYSTEM_NOTIFY, |
442 | acpi_pm_notify_handler, NULL); | 448 | acpi_pm_notify_handler, NULL); |
@@ -469,10 +475,7 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev) | |||
469 | if (ACPI_FAILURE(status)) | 475 | if (ACPI_FAILURE(status)) |
470 | goto out; | 476 | goto out; |
471 | 477 | ||
472 | if (adev->wakeup.context.work.func) { | 478 | adev->wakeup.context.func = NULL; |
473 | cancel_work_sync(&adev->wakeup.context.work); | ||
474 | adev->wakeup.context.work.func = NULL; | ||
475 | } | ||
476 | adev->wakeup.context.dev = NULL; | 479 | adev->wakeup.context.dev = NULL; |
477 | wakeup_source_unregister(adev->wakeup.ws); | 480 | wakeup_source_unregister(adev->wakeup.ws); |
478 | 481 | ||
@@ -493,6 +496,13 @@ bool acpi_bus_can_wakeup(acpi_handle handle) | |||
493 | } | 496 | } |
494 | EXPORT_SYMBOL(acpi_bus_can_wakeup); | 497 | EXPORT_SYMBOL(acpi_bus_can_wakeup); |
495 | 498 | ||
499 | bool acpi_pm_device_can_wakeup(struct device *dev) | ||
500 | { | ||
501 | struct acpi_device *adev = ACPI_COMPANION(dev); | ||
502 | |||
503 | return adev ? acpi_device_can_wakeup(adev) : false; | ||
504 | } | ||
505 | |||
496 | /** | 506 | /** |
497 | * acpi_dev_pm_get_state - Get preferred power state of ACPI device. | 507 | * acpi_dev_pm_get_state - Get preferred power state of ACPI device. |
498 | * @dev: Device whose preferred target power state to return. | 508 | * @dev: Device whose preferred target power state to return. |
@@ -658,16 +668,15 @@ EXPORT_SYMBOL(acpi_pm_device_sleep_state); | |||
658 | 668 | ||
659 | /** | 669 | /** |
660 | * acpi_pm_notify_work_func - ACPI devices wakeup notification work function. | 670 | * acpi_pm_notify_work_func - ACPI devices wakeup notification work function. |
661 | * @work: Work item to handle. | 671 | * @context: Device wakeup context. |
662 | */ | 672 | */ |
663 | static void acpi_pm_notify_work_func(struct work_struct *work) | 673 | static void acpi_pm_notify_work_func(struct acpi_device_wakeup_context *context) |
664 | { | 674 | { |
665 | struct device *dev; | 675 | struct device *dev = context->dev; |
666 | 676 | ||
667 | dev = container_of(work, struct acpi_device_wakeup_context, work)->dev; | ||
668 | if (dev) { | 677 | if (dev) { |
669 | pm_wakeup_event(dev, 0); | 678 | pm_wakeup_event(dev, 0); |
670 | pm_runtime_resume(dev); | 679 | pm_request_resume(dev); |
671 | } | 680 | } |
672 | } | 681 | } |
673 | 682 | ||
@@ -693,80 +702,53 @@ static int acpi_device_wakeup(struct acpi_device *adev, u32 target_state, | |||
693 | acpi_status res; | 702 | acpi_status res; |
694 | int error; | 703 | int error; |
695 | 704 | ||
705 | if (adev->wakeup.flags.enabled) | ||
706 | return 0; | ||
707 | |||
696 | error = acpi_enable_wakeup_device_power(adev, target_state); | 708 | error = acpi_enable_wakeup_device_power(adev, target_state); |
697 | if (error) | 709 | if (error) |
698 | return error; | 710 | return error; |
699 | 711 | ||
700 | if (adev->wakeup.flags.enabled) | ||
701 | return 0; | ||
702 | |||
703 | res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); | 712 | res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); |
704 | if (ACPI_SUCCESS(res)) { | 713 | if (ACPI_FAILURE(res)) { |
705 | adev->wakeup.flags.enabled = 1; | ||
706 | } else { | ||
707 | acpi_disable_wakeup_device_power(adev); | 714 | acpi_disable_wakeup_device_power(adev); |
708 | return -EIO; | 715 | return -EIO; |
709 | } | 716 | } |
710 | } else { | 717 | adev->wakeup.flags.enabled = 1; |
711 | if (adev->wakeup.flags.enabled) { | 718 | } else if (adev->wakeup.flags.enabled) { |
712 | acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); | 719 | acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); |
713 | adev->wakeup.flags.enabled = 0; | ||
714 | } | ||
715 | acpi_disable_wakeup_device_power(adev); | 720 | acpi_disable_wakeup_device_power(adev); |
721 | adev->wakeup.flags.enabled = 0; | ||
716 | } | 722 | } |
717 | return 0; | 723 | return 0; |
718 | } | 724 | } |
719 | 725 | ||
720 | /** | 726 | /** |
721 | * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. | 727 | * acpi_pm_set_device_wakeup - Enable/disable remote wakeup for given device. |
722 | * @dev: Device to enable/disable the platform to wake up. | 728 | * @dev: Device to enable/disable to generate wakeup events. |
723 | * @enable: Whether to enable or disable the wakeup functionality. | 729 | * @enable: Whether to enable or disable the wakeup functionality. |
724 | */ | 730 | */ |
725 | int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) | 731 | int acpi_pm_set_device_wakeup(struct device *dev, bool enable) |
726 | { | ||
727 | struct acpi_device *adev; | ||
728 | |||
729 | if (!device_run_wake(phys_dev)) | ||
730 | return -EINVAL; | ||
731 | |||
732 | adev = ACPI_COMPANION(phys_dev); | ||
733 | if (!adev) { | ||
734 | dev_dbg(phys_dev, "ACPI companion missing in %s!\n", __func__); | ||
735 | return -ENODEV; | ||
736 | } | ||
737 | |||
738 | return acpi_device_wakeup(adev, ACPI_STATE_S0, enable); | ||
739 | } | ||
740 | EXPORT_SYMBOL(acpi_pm_device_run_wake); | ||
741 | |||
742 | #ifdef CONFIG_PM_SLEEP | ||
743 | /** | ||
744 | * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system. | ||
745 | * @dev: Device to enable/desible to wake up the system from sleep states. | ||
746 | * @enable: Whether to enable or disable @dev to wake up the system. | ||
747 | */ | ||
748 | int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | ||
749 | { | 732 | { |
750 | struct acpi_device *adev; | 733 | struct acpi_device *adev; |
751 | int error; | 734 | int error; |
752 | 735 | ||
753 | if (!device_can_wakeup(dev)) | ||
754 | return -EINVAL; | ||
755 | |||
756 | adev = ACPI_COMPANION(dev); | 736 | adev = ACPI_COMPANION(dev); |
757 | if (!adev) { | 737 | if (!adev) { |
758 | dev_dbg(dev, "ACPI companion missing in %s!\n", __func__); | 738 | dev_dbg(dev, "ACPI companion missing in %s!\n", __func__); |
759 | return -ENODEV; | 739 | return -ENODEV; |
760 | } | 740 | } |
761 | 741 | ||
742 | if (!acpi_device_can_wakeup(adev)) | ||
743 | return -EINVAL; | ||
744 | |||
762 | error = acpi_device_wakeup(adev, acpi_target_system_state(), enable); | 745 | error = acpi_device_wakeup(adev, acpi_target_system_state(), enable); |
763 | if (!error) | 746 | if (!error) |
764 | dev_info(dev, "System wakeup %s by ACPI\n", | 747 | dev_dbg(dev, "Wakeup %s by ACPI\n", enable ? "enabled" : "disabled"); |
765 | enable ? "enabled" : "disabled"); | ||
766 | 748 | ||
767 | return error; | 749 | return error; |
768 | } | 750 | } |
769 | #endif /* CONFIG_PM_SLEEP */ | 751 | EXPORT_SYMBOL(acpi_pm_set_device_wakeup); |
770 | 752 | ||
771 | /** | 753 | /** |
772 | * acpi_dev_pm_low_power - Put ACPI device into a low-power state. | 754 | * acpi_dev_pm_low_power - Put ACPI device into a low-power state. |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index c24235d8fb52..156e15c35ffa 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -1835,7 +1835,7 @@ static int acpi_ec_suspend(struct device *dev) | |||
1835 | struct acpi_ec *ec = | 1835 | struct acpi_ec *ec = |
1836 | acpi_driver_data(to_acpi_device(dev)); | 1836 | acpi_driver_data(to_acpi_device(dev)); |
1837 | 1837 | ||
1838 | if (ec_freeze_events) | 1838 | if (acpi_sleep_no_ec_events() && ec_freeze_events) |
1839 | acpi_ec_disable_event(ec); | 1839 | acpi_ec_disable_event(ec); |
1840 | return 0; | 1840 | return 0; |
1841 | } | 1841 | } |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 66229ffa909b..be79f7db1850 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -198,8 +198,12 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit); | |||
198 | Suspend/Resume | 198 | Suspend/Resume |
199 | -------------------------------------------------------------------------- */ | 199 | -------------------------------------------------------------------------- */ |
200 | #ifdef CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT | 200 | #ifdef CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT |
201 | extern bool acpi_s2idle_wakeup(void); | ||
202 | extern bool acpi_sleep_no_ec_events(void); | ||
201 | extern int acpi_sleep_init(void); | 203 | extern int acpi_sleep_init(void); |
202 | #else | 204 | #else |
205 | static inline bool acpi_s2idle_wakeup(void) { return false; } | ||
206 | static inline bool acpi_sleep_no_ec_events(void) { return true; } | ||
203 | static inline int acpi_sleep_init(void) { return -ENXIO; } | 207 | static inline int acpi_sleep_init(void) { return -ENXIO; } |
204 | #endif | 208 | #endif |
205 | 209 | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 240544253ccd..9eec3095e6c3 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -608,8 +608,7 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
608 | pcie_no_aspm(); | 608 | pcie_no_aspm(); |
609 | 609 | ||
610 | pci_acpi_add_bus_pm_notifier(device); | 610 | pci_acpi_add_bus_pm_notifier(device); |
611 | if (device->wakeup.flags.run_wake) | 611 | device_set_wakeup_capable(root->bus->bridge, device->wakeup.flags.valid); |
612 | device_set_run_wake(root->bus->bridge, true); | ||
613 | 612 | ||
614 | if (hotadd) { | 613 | if (hotadd) { |
615 | pcibios_resource_survey_bus(root->bus); | 614 | pcibios_resource_survey_bus(root->bus); |
@@ -649,7 +648,7 @@ static void acpi_pci_root_remove(struct acpi_device *device) | |||
649 | pci_stop_root_bus(root->bus); | 648 | pci_stop_root_bus(root->bus); |
650 | 649 | ||
651 | pci_ioapic_remove(root); | 650 | pci_ioapic_remove(root); |
652 | device_set_run_wake(root->bus->bridge, false); | 651 | device_set_wakeup_capable(root->bus->bridge, false); |
653 | pci_acpi_remove_bus_pm_notifier(device); | 652 | pci_acpi_remove_bus_pm_notifier(device); |
654 | 653 | ||
655 | pci_remove_root_bus(root->bus); | 654 | pci_remove_root_bus(root->bus); |
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index a34669cc823b..85ac848ac6ab 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
@@ -42,7 +42,7 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) | |||
42 | 42 | ||
43 | if (!dev->physical_node_count) { | 43 | if (!dev->physical_node_count) { |
44 | seq_printf(seq, "%c%-8s\n", | 44 | seq_printf(seq, "%c%-8s\n", |
45 | dev->wakeup.flags.run_wake ? '*' : ' ', | 45 | dev->wakeup.flags.valid ? '*' : ' ', |
46 | device_may_wakeup(&dev->dev) ? | 46 | device_may_wakeup(&dev->dev) ? |
47 | "enabled" : "disabled"); | 47 | "enabled" : "disabled"); |
48 | } else { | 48 | } else { |
@@ -58,7 +58,7 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) | |||
58 | seq_printf(seq, "\t\t"); | 58 | seq_printf(seq, "\t\t"); |
59 | 59 | ||
60 | seq_printf(seq, "%c%-8s %s:%s\n", | 60 | seq_printf(seq, "%c%-8s %s:%s\n", |
61 | dev->wakeup.flags.run_wake ? '*' : ' ', | 61 | dev->wakeup.flags.valid ? '*' : ' ', |
62 | (device_may_wakeup(&dev->dev) || | 62 | (device_may_wakeup(&dev->dev) || |
63 | device_may_wakeup(ldev)) ? | 63 | device_may_wakeup(ldev)) ? |
64 | "enabled" : "disabled", | 64 | "enabled" : "disabled", |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index d53162997f32..09f65f57bebe 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -835,7 +835,7 @@ static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, | |||
835 | return err; | 835 | return err; |
836 | } | 836 | } |
837 | 837 | ||
838 | static void acpi_wakeup_gpe_init(struct acpi_device *device) | 838 | static bool acpi_wakeup_gpe_init(struct acpi_device *device) |
839 | { | 839 | { |
840 | static const struct acpi_device_id button_device_ids[] = { | 840 | static const struct acpi_device_id button_device_ids[] = { |
841 | {"PNP0C0C", 0}, | 841 | {"PNP0C0C", 0}, |
@@ -845,13 +845,11 @@ static void acpi_wakeup_gpe_init(struct acpi_device *device) | |||
845 | }; | 845 | }; |
846 | struct acpi_device_wakeup *wakeup = &device->wakeup; | 846 | struct acpi_device_wakeup *wakeup = &device->wakeup; |
847 | acpi_status status; | 847 | acpi_status status; |
848 | acpi_event_status event_status; | ||
849 | 848 | ||
850 | wakeup->flags.notifier_present = 0; | 849 | wakeup->flags.notifier_present = 0; |
851 | 850 | ||
852 | /* Power button, Lid switch always enable wakeup */ | 851 | /* Power button, Lid switch always enable wakeup */ |
853 | if (!acpi_match_device_ids(device, button_device_ids)) { | 852 | if (!acpi_match_device_ids(device, button_device_ids)) { |
854 | wakeup->flags.run_wake = 1; | ||
855 | if (!acpi_match_device_ids(device, &button_device_ids[1])) { | 853 | if (!acpi_match_device_ids(device, &button_device_ids[1])) { |
856 | /* Do not use Lid/sleep button for S5 wakeup */ | 854 | /* Do not use Lid/sleep button for S5 wakeup */ |
857 | if (wakeup->sleep_state == ACPI_STATE_S5) | 855 | if (wakeup->sleep_state == ACPI_STATE_S5) |
@@ -859,17 +857,12 @@ static void acpi_wakeup_gpe_init(struct acpi_device *device) | |||
859 | } | 857 | } |
860 | acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number); | 858 | acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number); |
861 | device_set_wakeup_capable(&device->dev, true); | 859 | device_set_wakeup_capable(&device->dev, true); |
862 | return; | 860 | return true; |
863 | } | 861 | } |
864 | 862 | ||
865 | acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device, | 863 | status = acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device, |
866 | wakeup->gpe_number); | 864 | wakeup->gpe_number); |
867 | status = acpi_get_gpe_status(wakeup->gpe_device, wakeup->gpe_number, | 865 | return ACPI_SUCCESS(status); |
868 | &event_status); | ||
869 | if (ACPI_FAILURE(status)) | ||
870 | return; | ||
871 | |||
872 | wakeup->flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HAS_HANDLER); | ||
873 | } | 866 | } |
874 | 867 | ||
875 | static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | 868 | static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) |
@@ -887,10 +880,10 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
887 | return; | 880 | return; |
888 | } | 881 | } |
889 | 882 | ||
890 | device->wakeup.flags.valid = 1; | 883 | device->wakeup.flags.valid = acpi_wakeup_gpe_init(device); |
891 | device->wakeup.prepare_count = 0; | 884 | device->wakeup.prepare_count = 0; |
892 | acpi_wakeup_gpe_init(device); | 885 | /* |
893 | /* Call _PSW/_DSW object to disable its ability to wake the sleeping | 886 | * Call _PSW/_DSW object to disable its ability to wake the sleeping |
894 | * system for the ACPI device with the _PRW object. | 887 | * system for the ACPI device with the _PRW object. |
895 | * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. | 888 | * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. |
896 | * So it is necessary to call _DSW object first. Only when it is not | 889 | * So it is necessary to call _DSW object first. Only when it is not |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 097d630ab886..be17664736b2 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -650,38 +650,165 @@ static const struct platform_suspend_ops acpi_suspend_ops_old = { | |||
650 | .recover = acpi_pm_finish, | 650 | .recover = acpi_pm_finish, |
651 | }; | 651 | }; |
652 | 652 | ||
653 | static bool s2idle_in_progress; | ||
654 | static bool s2idle_wakeup; | ||
655 | |||
656 | /* | ||
657 | * On platforms supporting the Low Power S0 Idle interface there is an ACPI | ||
658 | * device object with the PNP0D80 compatible device ID (System Power Management | ||
659 | * Controller) and a specific _DSM method under it. That method, if present, | ||
660 | * can be used to indicate to the platform that the OS is transitioning into a | ||
661 | * low-power state in which certain types of activity are not desirable or that | ||
662 | * it is leaving such a state, which allows the platform to adjust its operation | ||
663 | * mode accordingly. | ||
664 | */ | ||
665 | static const struct acpi_device_id lps0_device_ids[] = { | ||
666 | {"PNP0D80", }, | ||
667 | {"", }, | ||
668 | }; | ||
669 | |||
670 | #define ACPI_LPS0_DSM_UUID "c4eb40a0-6cd2-11e2-bcfd-0800200c9a66" | ||
671 | |||
672 | #define ACPI_LPS0_SCREEN_OFF 3 | ||
673 | #define ACPI_LPS0_SCREEN_ON 4 | ||
674 | #define ACPI_LPS0_ENTRY 5 | ||
675 | #define ACPI_LPS0_EXIT 6 | ||
676 | |||
677 | #define ACPI_S2IDLE_FUNC_MASK ((1 << ACPI_LPS0_ENTRY) | (1 << ACPI_LPS0_EXIT)) | ||
678 | |||
679 | static acpi_handle lps0_device_handle; | ||
680 | static guid_t lps0_dsm_guid; | ||
681 | static char lps0_dsm_func_mask; | ||
682 | |||
683 | static void acpi_sleep_run_lps0_dsm(unsigned int func) | ||
684 | { | ||
685 | union acpi_object *out_obj; | ||
686 | |||
687 | if (!(lps0_dsm_func_mask & (1 << func))) | ||
688 | return; | ||
689 | |||
690 | out_obj = acpi_evaluate_dsm(lps0_device_handle, &lps0_dsm_guid, 1, func, NULL); | ||
691 | ACPI_FREE(out_obj); | ||
692 | |||
693 | acpi_handle_debug(lps0_device_handle, "_DSM function %u evaluation %s\n", | ||
694 | func, out_obj ? "successful" : "failed"); | ||
695 | } | ||
696 | |||
697 | static int lps0_device_attach(struct acpi_device *adev, | ||
698 | const struct acpi_device_id *not_used) | ||
699 | { | ||
700 | union acpi_object *out_obj; | ||
701 | |||
702 | if (lps0_device_handle) | ||
703 | return 0; | ||
704 | |||
705 | if (!(acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0)) | ||
706 | return 0; | ||
707 | |||
708 | guid_parse(ACPI_LPS0_DSM_UUID, &lps0_dsm_guid); | ||
709 | /* Check if the _DSM is present and as expected. */ | ||
710 | out_obj = acpi_evaluate_dsm(adev->handle, &lps0_dsm_guid, 1, 0, NULL); | ||
711 | if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) { | ||
712 | char bitmask = *(char *)out_obj->buffer.pointer; | ||
713 | |||
714 | if ((bitmask & ACPI_S2IDLE_FUNC_MASK) == ACPI_S2IDLE_FUNC_MASK) { | ||
715 | lps0_dsm_func_mask = bitmask; | ||
716 | lps0_device_handle = adev->handle; | ||
717 | } | ||
718 | |||
719 | acpi_handle_debug(adev->handle, "_DSM function mask: 0x%x\n", | ||
720 | bitmask); | ||
721 | } else { | ||
722 | acpi_handle_debug(adev->handle, | ||
723 | "_DSM function 0 evaluation failed\n"); | ||
724 | } | ||
725 | ACPI_FREE(out_obj); | ||
726 | return 0; | ||
727 | } | ||
728 | |||
729 | static struct acpi_scan_handler lps0_handler = { | ||
730 | .ids = lps0_device_ids, | ||
731 | .attach = lps0_device_attach, | ||
732 | }; | ||
733 | |||
653 | static int acpi_freeze_begin(void) | 734 | static int acpi_freeze_begin(void) |
654 | { | 735 | { |
655 | acpi_scan_lock_acquire(); | 736 | acpi_scan_lock_acquire(); |
737 | s2idle_in_progress = true; | ||
656 | return 0; | 738 | return 0; |
657 | } | 739 | } |
658 | 740 | ||
659 | static int acpi_freeze_prepare(void) | 741 | static int acpi_freeze_prepare(void) |
660 | { | 742 | { |
661 | acpi_enable_wakeup_devices(ACPI_STATE_S0); | 743 | if (lps0_device_handle) { |
662 | acpi_enable_all_wakeup_gpes(); | 744 | acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF); |
663 | acpi_os_wait_events_complete(); | 745 | acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY); |
746 | } else { | ||
747 | /* | ||
748 | * The configuration of GPEs is changed here to avoid spurious | ||
749 | * wakeups, but that should not be necessary if this is a | ||
750 | * "low-power S0" platform and the low-power S0 _DSM is present. | ||
751 | */ | ||
752 | acpi_enable_all_wakeup_gpes(); | ||
753 | acpi_os_wait_events_complete(); | ||
754 | } | ||
664 | if (acpi_sci_irq_valid()) | 755 | if (acpi_sci_irq_valid()) |
665 | enable_irq_wake(acpi_sci_irq); | 756 | enable_irq_wake(acpi_sci_irq); |
757 | |||
666 | return 0; | 758 | return 0; |
667 | } | 759 | } |
668 | 760 | ||
761 | static void acpi_freeze_wake(void) | ||
762 | { | ||
763 | /* | ||
764 | * If IRQD_WAKEUP_ARMED is not set for the SCI at this point, it means | ||
765 | * that the SCI has triggered while suspended, so cancel the wakeup in | ||
766 | * case it has not been a wakeup event (the GPEs will be checked later). | ||
767 | */ | ||
768 | if (acpi_sci_irq_valid() && | ||
769 | !irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq))) { | ||
770 | pm_system_cancel_wakeup(); | ||
771 | s2idle_wakeup = true; | ||
772 | } | ||
773 | } | ||
774 | |||
775 | static void acpi_freeze_sync(void) | ||
776 | { | ||
777 | /* | ||
778 | * Process all pending events in case there are any wakeup ones. | ||
779 | * | ||
780 | * The EC driver uses the system workqueue, so that one needs to be | ||
781 | * flushed too. | ||
782 | */ | ||
783 | acpi_os_wait_events_complete(); | ||
784 | flush_scheduled_work(); | ||
785 | s2idle_wakeup = false; | ||
786 | } | ||
787 | |||
669 | static void acpi_freeze_restore(void) | 788 | static void acpi_freeze_restore(void) |
670 | { | 789 | { |
671 | acpi_disable_wakeup_devices(ACPI_STATE_S0); | ||
672 | if (acpi_sci_irq_valid()) | 790 | if (acpi_sci_irq_valid()) |
673 | disable_irq_wake(acpi_sci_irq); | 791 | disable_irq_wake(acpi_sci_irq); |
674 | acpi_enable_all_runtime_gpes(); | 792 | |
793 | if (lps0_device_handle) { | ||
794 | acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT); | ||
795 | acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON); | ||
796 | } else { | ||
797 | acpi_enable_all_runtime_gpes(); | ||
798 | } | ||
675 | } | 799 | } |
676 | 800 | ||
677 | static void acpi_freeze_end(void) | 801 | static void acpi_freeze_end(void) |
678 | { | 802 | { |
803 | s2idle_in_progress = false; | ||
679 | acpi_scan_lock_release(); | 804 | acpi_scan_lock_release(); |
680 | } | 805 | } |
681 | 806 | ||
682 | static const struct platform_freeze_ops acpi_freeze_ops = { | 807 | static const struct platform_freeze_ops acpi_freeze_ops = { |
683 | .begin = acpi_freeze_begin, | 808 | .begin = acpi_freeze_begin, |
684 | .prepare = acpi_freeze_prepare, | 809 | .prepare = acpi_freeze_prepare, |
810 | .wake = acpi_freeze_wake, | ||
811 | .sync = acpi_freeze_sync, | ||
685 | .restore = acpi_freeze_restore, | 812 | .restore = acpi_freeze_restore, |
686 | .end = acpi_freeze_end, | 813 | .end = acpi_freeze_end, |
687 | }; | 814 | }; |
@@ -696,13 +823,28 @@ static void acpi_sleep_suspend_setup(void) | |||
696 | 823 | ||
697 | suspend_set_ops(old_suspend_ordering ? | 824 | suspend_set_ops(old_suspend_ordering ? |
698 | &acpi_suspend_ops_old : &acpi_suspend_ops); | 825 | &acpi_suspend_ops_old : &acpi_suspend_ops); |
826 | |||
827 | acpi_scan_add_handler(&lps0_handler); | ||
699 | freeze_set_ops(&acpi_freeze_ops); | 828 | freeze_set_ops(&acpi_freeze_ops); |
700 | } | 829 | } |
701 | 830 | ||
702 | #else /* !CONFIG_SUSPEND */ | 831 | #else /* !CONFIG_SUSPEND */ |
832 | #define s2idle_in_progress (false) | ||
833 | #define s2idle_wakeup (false) | ||
834 | #define lps0_device_handle (NULL) | ||
703 | static inline void acpi_sleep_suspend_setup(void) {} | 835 | static inline void acpi_sleep_suspend_setup(void) {} |
704 | #endif /* !CONFIG_SUSPEND */ | 836 | #endif /* !CONFIG_SUSPEND */ |
705 | 837 | ||
838 | bool acpi_s2idle_wakeup(void) | ||
839 | { | ||
840 | return s2idle_wakeup; | ||
841 | } | ||
842 | |||
843 | bool acpi_sleep_no_ec_events(void) | ||
844 | { | ||
845 | return !s2idle_in_progress || !lps0_device_handle; | ||
846 | } | ||
847 | |||
706 | #ifdef CONFIG_PM_SLEEP | 848 | #ifdef CONFIG_PM_SLEEP |
707 | static u32 saved_bm_rld; | 849 | static u32 saved_bm_rld; |
708 | 850 | ||
diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c index f3a65a3140d3..8a01d09ac4db 100644 --- a/drivers/ata/libata-zpodd.c +++ b/drivers/ata/libata-zpodd.c | |||
@@ -174,8 +174,7 @@ void zpodd_enable_run_wake(struct ata_device *dev) | |||
174 | sdev_disable_disk_events(dev->sdev); | 174 | sdev_disable_disk_events(dev->sdev); |
175 | 175 | ||
176 | zpodd->powered_off = true; | 176 | zpodd->powered_off = true; |
177 | device_set_run_wake(&dev->tdev, true); | 177 | acpi_pm_set_device_wakeup(&dev->tdev, true); |
178 | acpi_pm_device_run_wake(&dev->tdev, true); | ||
179 | } | 178 | } |
180 | 179 | ||
181 | /* Disable runtime wake capability if it is enabled */ | 180 | /* Disable runtime wake capability if it is enabled */ |
@@ -183,10 +182,8 @@ void zpodd_disable_run_wake(struct ata_device *dev) | |||
183 | { | 182 | { |
184 | struct zpodd *zpodd = dev->zpodd; | 183 | struct zpodd *zpodd = dev->zpodd; |
185 | 184 | ||
186 | if (zpodd->powered_off) { | 185 | if (zpodd->powered_off) |
187 | acpi_pm_device_run_wake(&dev->tdev, false); | 186 | acpi_pm_set_device_wakeup(&dev->tdev, false); |
188 | device_set_run_wake(&dev->tdev, false); | ||
189 | } | ||
190 | } | 187 | } |
191 | 188 | ||
192 | /* | 189 | /* |
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index da49a8383dc3..b8e4b966c74d 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -126,7 +126,7 @@ static const struct genpd_lock_ops genpd_spin_ops = { | |||
126 | #define genpd_is_always_on(genpd) (genpd->flags & GENPD_FLAG_ALWAYS_ON) | 126 | #define genpd_is_always_on(genpd) (genpd->flags & GENPD_FLAG_ALWAYS_ON) |
127 | 127 | ||
128 | static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev, | 128 | static inline bool irq_safe_dev_in_no_sleep_domain(struct device *dev, |
129 | struct generic_pm_domain *genpd) | 129 | const struct generic_pm_domain *genpd) |
130 | { | 130 | { |
131 | bool ret; | 131 | bool ret; |
132 | 132 | ||
@@ -181,12 +181,14 @@ static struct generic_pm_domain *dev_to_genpd(struct device *dev) | |||
181 | return pd_to_genpd(dev->pm_domain); | 181 | return pd_to_genpd(dev->pm_domain); |
182 | } | 182 | } |
183 | 183 | ||
184 | static int genpd_stop_dev(struct generic_pm_domain *genpd, struct device *dev) | 184 | static int genpd_stop_dev(const struct generic_pm_domain *genpd, |
185 | struct device *dev) | ||
185 | { | 186 | { |
186 | return GENPD_DEV_CALLBACK(genpd, int, stop, dev); | 187 | return GENPD_DEV_CALLBACK(genpd, int, stop, dev); |
187 | } | 188 | } |
188 | 189 | ||
189 | static int genpd_start_dev(struct generic_pm_domain *genpd, struct device *dev) | 190 | static int genpd_start_dev(const struct generic_pm_domain *genpd, |
191 | struct device *dev) | ||
190 | { | 192 | { |
191 | return GENPD_DEV_CALLBACK(genpd, int, start, dev); | 193 | return GENPD_DEV_CALLBACK(genpd, int, start, dev); |
192 | } | 194 | } |
@@ -443,7 +445,7 @@ static int genpd_dev_pm_qos_notifier(struct notifier_block *nb, | |||
443 | 445 | ||
444 | pdd = dev->power.subsys_data ? | 446 | pdd = dev->power.subsys_data ? |
445 | dev->power.subsys_data->domain_data : NULL; | 447 | dev->power.subsys_data->domain_data : NULL; |
446 | if (pdd && pdd->dev) { | 448 | if (pdd) { |
447 | to_gpd_data(pdd)->td.constraint_changed = true; | 449 | to_gpd_data(pdd)->td.constraint_changed = true; |
448 | genpd = dev_to_genpd(dev); | 450 | genpd = dev_to_genpd(dev); |
449 | } else { | 451 | } else { |
@@ -738,7 +740,7 @@ static bool pm_genpd_present(const struct generic_pm_domain *genpd) | |||
738 | 740 | ||
739 | #ifdef CONFIG_PM_SLEEP | 741 | #ifdef CONFIG_PM_SLEEP |
740 | 742 | ||
741 | static bool genpd_dev_active_wakeup(struct generic_pm_domain *genpd, | 743 | static bool genpd_dev_active_wakeup(const struct generic_pm_domain *genpd, |
742 | struct device *dev) | 744 | struct device *dev) |
743 | { | 745 | { |
744 | return GENPD_DEV_CALLBACK(genpd, bool, active_wakeup, dev); | 746 | return GENPD_DEV_CALLBACK(genpd, bool, active_wakeup, dev); |
@@ -840,7 +842,8 @@ static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock, | |||
840 | * signal remote wakeup from the system's working state as needed by runtime PM. | 842 | * signal remote wakeup from the system's working state as needed by runtime PM. |
841 | * Return 'true' in either of the above cases. | 843 | * Return 'true' in either of the above cases. |
842 | */ | 844 | */ |
843 | static bool resume_needed(struct device *dev, struct generic_pm_domain *genpd) | 845 | static bool resume_needed(struct device *dev, |
846 | const struct generic_pm_domain *genpd) | ||
844 | { | 847 | { |
845 | bool active_wakeup; | 848 | bool active_wakeup; |
846 | 849 | ||
@@ -899,19 +902,19 @@ static int pm_genpd_prepare(struct device *dev) | |||
899 | } | 902 | } |
900 | 903 | ||
901 | /** | 904 | /** |
902 | * pm_genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain. | 905 | * genpd_finish_suspend - Completion of suspend or hibernation of device in an |
906 | * I/O pm domain. | ||
903 | * @dev: Device to suspend. | 907 | * @dev: Device to suspend. |
908 | * @poweroff: Specifies if this is a poweroff_noirq or suspend_noirq callback. | ||
904 | * | 909 | * |
905 | * Stop the device and remove power from the domain if all devices in it have | 910 | * Stop the device and remove power from the domain if all devices in it have |
906 | * been stopped. | 911 | * been stopped. |
907 | */ | 912 | */ |
908 | static int pm_genpd_suspend_noirq(struct device *dev) | 913 | static int genpd_finish_suspend(struct device *dev, bool poweroff) |
909 | { | 914 | { |
910 | struct generic_pm_domain *genpd; | 915 | struct generic_pm_domain *genpd; |
911 | int ret; | 916 | int ret; |
912 | 917 | ||
913 | dev_dbg(dev, "%s()\n", __func__); | ||
914 | |||
915 | genpd = dev_to_genpd(dev); | 918 | genpd = dev_to_genpd(dev); |
916 | if (IS_ERR(genpd)) | 919 | if (IS_ERR(genpd)) |
917 | return -EINVAL; | 920 | return -EINVAL; |
@@ -919,6 +922,13 @@ static int pm_genpd_suspend_noirq(struct device *dev) | |||
919 | if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)) | 922 | if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)) |
920 | return 0; | 923 | return 0; |
921 | 924 | ||
925 | if (poweroff) | ||
926 | ret = pm_generic_poweroff_noirq(dev); | ||
927 | else | ||
928 | ret = pm_generic_suspend_noirq(dev); | ||
929 | if (ret) | ||
930 | return ret; | ||
931 | |||
922 | if (genpd->dev_ops.stop && genpd->dev_ops.start) { | 932 | if (genpd->dev_ops.stop && genpd->dev_ops.start) { |
923 | ret = pm_runtime_force_suspend(dev); | 933 | ret = pm_runtime_force_suspend(dev); |
924 | if (ret) | 934 | if (ret) |
@@ -934,6 +944,20 @@ static int pm_genpd_suspend_noirq(struct device *dev) | |||
934 | } | 944 | } |
935 | 945 | ||
936 | /** | 946 | /** |
947 | * pm_genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain. | ||
948 | * @dev: Device to suspend. | ||
949 | * | ||
950 | * Stop the device and remove power from the domain if all devices in it have | ||
951 | * been stopped. | ||
952 | */ | ||
953 | static int pm_genpd_suspend_noirq(struct device *dev) | ||
954 | { | ||
955 | dev_dbg(dev, "%s()\n", __func__); | ||
956 | |||
957 | return genpd_finish_suspend(dev, false); | ||
958 | } | ||
959 | |||
960 | /** | ||
937 | * pm_genpd_resume_noirq - Start of resume of device in an I/O PM domain. | 961 | * pm_genpd_resume_noirq - Start of resume of device in an I/O PM domain. |
938 | * @dev: Device to resume. | 962 | * @dev: Device to resume. |
939 | * | 963 | * |
@@ -961,6 +985,10 @@ static int pm_genpd_resume_noirq(struct device *dev) | |||
961 | if (genpd->dev_ops.stop && genpd->dev_ops.start) | 985 | if (genpd->dev_ops.stop && genpd->dev_ops.start) |
962 | ret = pm_runtime_force_resume(dev); | 986 | ret = pm_runtime_force_resume(dev); |
963 | 987 | ||
988 | ret = pm_generic_resume_noirq(dev); | ||
989 | if (ret) | ||
990 | return ret; | ||
991 | |||
964 | return ret; | 992 | return ret; |
965 | } | 993 | } |
966 | 994 | ||
@@ -975,7 +1003,7 @@ static int pm_genpd_resume_noirq(struct device *dev) | |||
975 | */ | 1003 | */ |
976 | static int pm_genpd_freeze_noirq(struct device *dev) | 1004 | static int pm_genpd_freeze_noirq(struct device *dev) |
977 | { | 1005 | { |
978 | struct generic_pm_domain *genpd; | 1006 | const struct generic_pm_domain *genpd; |
979 | int ret = 0; | 1007 | int ret = 0; |
980 | 1008 | ||
981 | dev_dbg(dev, "%s()\n", __func__); | 1009 | dev_dbg(dev, "%s()\n", __func__); |
@@ -984,6 +1012,10 @@ static int pm_genpd_freeze_noirq(struct device *dev) | |||
984 | if (IS_ERR(genpd)) | 1012 | if (IS_ERR(genpd)) |
985 | return -EINVAL; | 1013 | return -EINVAL; |
986 | 1014 | ||
1015 | ret = pm_generic_freeze_noirq(dev); | ||
1016 | if (ret) | ||
1017 | return ret; | ||
1018 | |||
987 | if (genpd->dev_ops.stop && genpd->dev_ops.start) | 1019 | if (genpd->dev_ops.stop && genpd->dev_ops.start) |
988 | ret = pm_runtime_force_suspend(dev); | 1020 | ret = pm_runtime_force_suspend(dev); |
989 | 1021 | ||
@@ -999,7 +1031,7 @@ static int pm_genpd_freeze_noirq(struct device *dev) | |||
999 | */ | 1031 | */ |
1000 | static int pm_genpd_thaw_noirq(struct device *dev) | 1032 | static int pm_genpd_thaw_noirq(struct device *dev) |
1001 | { | 1033 | { |
1002 | struct generic_pm_domain *genpd; | 1034 | const struct generic_pm_domain *genpd; |
1003 | int ret = 0; | 1035 | int ret = 0; |
1004 | 1036 | ||
1005 | dev_dbg(dev, "%s()\n", __func__); | 1037 | dev_dbg(dev, "%s()\n", __func__); |
@@ -1008,10 +1040,28 @@ static int pm_genpd_thaw_noirq(struct device *dev) | |||
1008 | if (IS_ERR(genpd)) | 1040 | if (IS_ERR(genpd)) |
1009 | return -EINVAL; | 1041 | return -EINVAL; |
1010 | 1042 | ||
1011 | if (genpd->dev_ops.stop && genpd->dev_ops.start) | 1043 | if (genpd->dev_ops.stop && genpd->dev_ops.start) { |
1012 | ret = pm_runtime_force_resume(dev); | 1044 | ret = pm_runtime_force_resume(dev); |
1045 | if (ret) | ||
1046 | return ret; | ||
1047 | } | ||
1013 | 1048 | ||
1014 | return ret; | 1049 | return pm_generic_thaw_noirq(dev); |
1050 | } | ||
1051 | |||
1052 | /** | ||
1053 | * pm_genpd_poweroff_noirq - Completion of hibernation of device in an | ||
1054 | * I/O PM domain. | ||
1055 | * @dev: Device to poweroff. | ||
1056 | * | ||
1057 | * Stop the device and remove power from the domain if all devices in it have | ||
1058 | * been stopped. | ||
1059 | */ | ||
1060 | static int pm_genpd_poweroff_noirq(struct device *dev) | ||
1061 | { | ||
1062 | dev_dbg(dev, "%s()\n", __func__); | ||
1063 | |||
1064 | return genpd_finish_suspend(dev, true); | ||
1015 | } | 1065 | } |
1016 | 1066 | ||
1017 | /** | 1067 | /** |
@@ -1048,10 +1098,13 @@ static int pm_genpd_restore_noirq(struct device *dev) | |||
1048 | genpd_sync_power_on(genpd, true, 0); | 1098 | genpd_sync_power_on(genpd, true, 0); |
1049 | genpd_unlock(genpd); | 1099 | genpd_unlock(genpd); |
1050 | 1100 | ||
1051 | if (genpd->dev_ops.stop && genpd->dev_ops.start) | 1101 | if (genpd->dev_ops.stop && genpd->dev_ops.start) { |
1052 | ret = pm_runtime_force_resume(dev); | 1102 | ret = pm_runtime_force_resume(dev); |
1103 | if (ret) | ||
1104 | return ret; | ||
1105 | } | ||
1053 | 1106 | ||
1054 | return ret; | 1107 | return pm_generic_restore_noirq(dev); |
1055 | } | 1108 | } |
1056 | 1109 | ||
1057 | /** | 1110 | /** |
@@ -1095,8 +1148,8 @@ static void genpd_syscore_switch(struct device *dev, bool suspend) | |||
1095 | { | 1148 | { |
1096 | struct generic_pm_domain *genpd; | 1149 | struct generic_pm_domain *genpd; |
1097 | 1150 | ||
1098 | genpd = dev_to_genpd(dev); | 1151 | genpd = genpd_lookup_dev(dev); |
1099 | if (!pm_genpd_present(genpd)) | 1152 | if (!genpd) |
1100 | return; | 1153 | return; |
1101 | 1154 | ||
1102 | if (suspend) { | 1155 | if (suspend) { |
@@ -1393,7 +1446,7 @@ EXPORT_SYMBOL_GPL(pm_genpd_add_subdomain); | |||
1393 | int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, | 1446 | int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, |
1394 | struct generic_pm_domain *subdomain) | 1447 | struct generic_pm_domain *subdomain) |
1395 | { | 1448 | { |
1396 | struct gpd_link *link; | 1449 | struct gpd_link *l, *link; |
1397 | int ret = -EINVAL; | 1450 | int ret = -EINVAL; |
1398 | 1451 | ||
1399 | if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)) | 1452 | if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)) |
@@ -1409,7 +1462,7 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, | |||
1409 | goto out; | 1462 | goto out; |
1410 | } | 1463 | } |
1411 | 1464 | ||
1412 | list_for_each_entry(link, &genpd->master_links, master_node) { | 1465 | list_for_each_entry_safe(link, l, &genpd->master_links, master_node) { |
1413 | if (link->slave != subdomain) | 1466 | if (link->slave != subdomain) |
1414 | continue; | 1467 | continue; |
1415 | 1468 | ||
@@ -1493,7 +1546,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd, | |||
1493 | genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq; | 1546 | genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq; |
1494 | genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq; | 1547 | genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq; |
1495 | genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq; | 1548 | genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq; |
1496 | genpd->domain.ops.poweroff_noirq = pm_genpd_suspend_noirq; | 1549 | genpd->domain.ops.poweroff_noirq = pm_genpd_poweroff_noirq; |
1497 | genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq; | 1550 | genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq; |
1498 | genpd->domain.ops.complete = pm_genpd_complete; | 1551 | genpd->domain.ops.complete = pm_genpd_complete; |
1499 | 1552 | ||
@@ -1780,12 +1833,12 @@ EXPORT_SYMBOL_GPL(of_genpd_add_provider_onecell); | |||
1780 | */ | 1833 | */ |
1781 | void of_genpd_del_provider(struct device_node *np) | 1834 | void of_genpd_del_provider(struct device_node *np) |
1782 | { | 1835 | { |
1783 | struct of_genpd_provider *cp; | 1836 | struct of_genpd_provider *cp, *tmp; |
1784 | struct generic_pm_domain *gpd; | 1837 | struct generic_pm_domain *gpd; |
1785 | 1838 | ||
1786 | mutex_lock(&gpd_list_lock); | 1839 | mutex_lock(&gpd_list_lock); |
1787 | mutex_lock(&of_genpd_mutex); | 1840 | mutex_lock(&of_genpd_mutex); |
1788 | list_for_each_entry(cp, &of_genpd_providers, link) { | 1841 | list_for_each_entry_safe(cp, tmp, &of_genpd_providers, link) { |
1789 | if (cp->node == np) { | 1842 | if (cp->node == np) { |
1790 | /* | 1843 | /* |
1791 | * For each PM domain associated with the | 1844 | * For each PM domain associated with the |
@@ -1925,14 +1978,14 @@ EXPORT_SYMBOL_GPL(of_genpd_add_subdomain); | |||
1925 | */ | 1978 | */ |
1926 | struct generic_pm_domain *of_genpd_remove_last(struct device_node *np) | 1979 | struct generic_pm_domain *of_genpd_remove_last(struct device_node *np) |
1927 | { | 1980 | { |
1928 | struct generic_pm_domain *gpd, *genpd = ERR_PTR(-ENOENT); | 1981 | struct generic_pm_domain *gpd, *tmp, *genpd = ERR_PTR(-ENOENT); |
1929 | int ret; | 1982 | int ret; |
1930 | 1983 | ||
1931 | if (IS_ERR_OR_NULL(np)) | 1984 | if (IS_ERR_OR_NULL(np)) |
1932 | return ERR_PTR(-EINVAL); | 1985 | return ERR_PTR(-EINVAL); |
1933 | 1986 | ||
1934 | mutex_lock(&gpd_list_lock); | 1987 | mutex_lock(&gpd_list_lock); |
1935 | list_for_each_entry(gpd, &gpd_list, gpd_list_node) { | 1988 | list_for_each_entry_safe(gpd, tmp, &gpd_list, gpd_list_node) { |
1936 | if (gpd->provider == &np->fwnode) { | 1989 | if (gpd->provider == &np->fwnode) { |
1937 | ret = genpd_remove(gpd); | 1990 | ret = genpd_remove(gpd); |
1938 | genpd = ret ? ERR_PTR(ret) : gpd; | 1991 | genpd = ret ? ERR_PTR(ret) : gpd; |
diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c index 2e0fce711135..281f949c5ffe 100644 --- a/drivers/base/power/domain_governor.c +++ b/drivers/base/power/domain_governor.c | |||
@@ -92,12 +92,6 @@ static bool default_suspend_ok(struct device *dev) | |||
92 | return td->cached_suspend_ok; | 92 | return td->cached_suspend_ok; |
93 | } | 93 | } |
94 | 94 | ||
95 | /** | ||
96 | * default_power_down_ok - Default generic PM domain power off governor routine. | ||
97 | * @pd: PM domain to check. | ||
98 | * | ||
99 | * This routine must be executed under the PM domain's lock. | ||
100 | */ | ||
101 | static bool __default_power_down_ok(struct dev_pm_domain *pd, | 95 | static bool __default_power_down_ok(struct dev_pm_domain *pd, |
102 | unsigned int state) | 96 | unsigned int state) |
103 | { | 97 | { |
@@ -187,6 +181,12 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd, | |||
187 | return true; | 181 | return true; |
188 | } | 182 | } |
189 | 183 | ||
184 | /** | ||
185 | * default_power_down_ok - Default generic PM domain power off governor routine. | ||
186 | * @pd: PM domain to check. | ||
187 | * | ||
188 | * This routine must be executed under the PM domain's lock. | ||
189 | */ | ||
190 | static bool default_power_down_ok(struct dev_pm_domain *pd) | 190 | static bool default_power_down_ok(struct dev_pm_domain *pd) |
191 | { | 191 | { |
192 | struct generic_pm_domain *genpd = pd_to_genpd(pd); | 192 | struct generic_pm_domain *genpd = pd_to_genpd(pd); |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 9faee1c893e5..c99f8730de82 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -62,7 +62,7 @@ static pm_message_t pm_transition; | |||
62 | 62 | ||
63 | static int async_error; | 63 | static int async_error; |
64 | 64 | ||
65 | static char *pm_verb(int event) | 65 | static const char *pm_verb(int event) |
66 | { | 66 | { |
67 | switch (event) { | 67 | switch (event) { |
68 | case PM_EVENT_SUSPEND: | 68 | case PM_EVENT_SUSPEND: |
@@ -208,7 +208,8 @@ static ktime_t initcall_debug_start(struct device *dev) | |||
208 | } | 208 | } |
209 | 209 | ||
210 | static void initcall_debug_report(struct device *dev, ktime_t calltime, | 210 | static void initcall_debug_report(struct device *dev, ktime_t calltime, |
211 | int error, pm_message_t state, char *info) | 211 | int error, pm_message_t state, |
212 | const char *info) | ||
212 | { | 213 | { |
213 | ktime_t rettime; | 214 | ktime_t rettime; |
214 | s64 nsecs; | 215 | s64 nsecs; |
@@ -403,21 +404,23 @@ static pm_callback_t pm_noirq_op(const struct dev_pm_ops *ops, pm_message_t stat | |||
403 | return NULL; | 404 | return NULL; |
404 | } | 405 | } |
405 | 406 | ||
406 | static void pm_dev_dbg(struct device *dev, pm_message_t state, char *info) | 407 | static void pm_dev_dbg(struct device *dev, pm_message_t state, const char *info) |
407 | { | 408 | { |
408 | dev_dbg(dev, "%s%s%s\n", info, pm_verb(state.event), | 409 | dev_dbg(dev, "%s%s%s\n", info, pm_verb(state.event), |
409 | ((state.event & PM_EVENT_SLEEP) && device_may_wakeup(dev)) ? | 410 | ((state.event & PM_EVENT_SLEEP) && device_may_wakeup(dev)) ? |
410 | ", may wakeup" : ""); | 411 | ", may wakeup" : ""); |
411 | } | 412 | } |
412 | 413 | ||
413 | static void pm_dev_err(struct device *dev, pm_message_t state, char *info, | 414 | static void pm_dev_err(struct device *dev, pm_message_t state, const char *info, |
414 | int error) | 415 | int error) |
415 | { | 416 | { |
416 | printk(KERN_ERR "PM: Device %s failed to %s%s: error %d\n", | 417 | printk(KERN_ERR "PM: Device %s failed to %s%s: error %d\n", |
417 | dev_name(dev), pm_verb(state.event), info, error); | 418 | dev_name(dev), pm_verb(state.event), info, error); |
418 | } | 419 | } |
419 | 420 | ||
420 | static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info) | 421 | #ifdef CONFIG_PM_DEBUG |
422 | static void dpm_show_time(ktime_t starttime, pm_message_t state, | ||
423 | const char *info) | ||
421 | { | 424 | { |
422 | ktime_t calltime; | 425 | ktime_t calltime; |
423 | u64 usecs64; | 426 | u64 usecs64; |
@@ -433,9 +436,13 @@ static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info) | |||
433 | info ?: "", info ? " " : "", pm_verb(state.event), | 436 | info ?: "", info ? " " : "", pm_verb(state.event), |
434 | usecs / USEC_PER_MSEC, usecs % USEC_PER_MSEC); | 437 | usecs / USEC_PER_MSEC, usecs % USEC_PER_MSEC); |
435 | } | 438 | } |
439 | #else | ||
440 | static inline void dpm_show_time(ktime_t starttime, pm_message_t state, | ||
441 | const char *info) {} | ||
442 | #endif /* CONFIG_PM_DEBUG */ | ||
436 | 443 | ||
437 | static int dpm_run_callback(pm_callback_t cb, struct device *dev, | 444 | static int dpm_run_callback(pm_callback_t cb, struct device *dev, |
438 | pm_message_t state, char *info) | 445 | pm_message_t state, const char *info) |
439 | { | 446 | { |
440 | ktime_t calltime; | 447 | ktime_t calltime; |
441 | int error; | 448 | int error; |
@@ -535,7 +542,7 @@ static void dpm_watchdog_clear(struct dpm_watchdog *wd) | |||
535 | static int device_resume_noirq(struct device *dev, pm_message_t state, bool async) | 542 | static int device_resume_noirq(struct device *dev, pm_message_t state, bool async) |
536 | { | 543 | { |
537 | pm_callback_t callback = NULL; | 544 | pm_callback_t callback = NULL; |
538 | char *info = NULL; | 545 | const char *info = NULL; |
539 | int error = 0; | 546 | int error = 0; |
540 | 547 | ||
541 | TRACE_DEVICE(dev); | 548 | TRACE_DEVICE(dev); |
@@ -665,7 +672,7 @@ void dpm_resume_noirq(pm_message_t state) | |||
665 | static int device_resume_early(struct device *dev, pm_message_t state, bool async) | 672 | static int device_resume_early(struct device *dev, pm_message_t state, bool async) |
666 | { | 673 | { |
667 | pm_callback_t callback = NULL; | 674 | pm_callback_t callback = NULL; |
668 | char *info = NULL; | 675 | const char *info = NULL; |
669 | int error = 0; | 676 | int error = 0; |
670 | 677 | ||
671 | TRACE_DEVICE(dev); | 678 | TRACE_DEVICE(dev); |
@@ -793,7 +800,7 @@ EXPORT_SYMBOL_GPL(dpm_resume_start); | |||
793 | static int device_resume(struct device *dev, pm_message_t state, bool async) | 800 | static int device_resume(struct device *dev, pm_message_t state, bool async) |
794 | { | 801 | { |
795 | pm_callback_t callback = NULL; | 802 | pm_callback_t callback = NULL; |
796 | char *info = NULL; | 803 | const char *info = NULL; |
797 | int error = 0; | 804 | int error = 0; |
798 | DECLARE_DPM_WATCHDOG_ON_STACK(wd); | 805 | DECLARE_DPM_WATCHDOG_ON_STACK(wd); |
799 | 806 | ||
@@ -955,7 +962,7 @@ void dpm_resume(pm_message_t state) | |||
955 | static void device_complete(struct device *dev, pm_message_t state) | 962 | static void device_complete(struct device *dev, pm_message_t state) |
956 | { | 963 | { |
957 | void (*callback)(struct device *) = NULL; | 964 | void (*callback)(struct device *) = NULL; |
958 | char *info = NULL; | 965 | const char *info = NULL; |
959 | 966 | ||
960 | if (dev->power.syscore) | 967 | if (dev->power.syscore) |
961 | return; | 968 | return; |
@@ -1080,7 +1087,7 @@ static pm_message_t resume_event(pm_message_t sleep_state) | |||
1080 | static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool async) | 1087 | static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool async) |
1081 | { | 1088 | { |
1082 | pm_callback_t callback = NULL; | 1089 | pm_callback_t callback = NULL; |
1083 | char *info = NULL; | 1090 | const char *info = NULL; |
1084 | int error = 0; | 1091 | int error = 0; |
1085 | 1092 | ||
1086 | TRACE_DEVICE(dev); | 1093 | TRACE_DEVICE(dev); |
@@ -1091,11 +1098,6 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a | |||
1091 | if (async_error) | 1098 | if (async_error) |
1092 | goto Complete; | 1099 | goto Complete; |
1093 | 1100 | ||
1094 | if (pm_wakeup_pending()) { | ||
1095 | async_error = -EBUSY; | ||
1096 | goto Complete; | ||
1097 | } | ||
1098 | |||
1099 | if (dev->power.syscore || dev->power.direct_complete) | 1101 | if (dev->power.syscore || dev->power.direct_complete) |
1100 | goto Complete; | 1102 | goto Complete; |
1101 | 1103 | ||
@@ -1225,7 +1227,7 @@ int dpm_suspend_noirq(pm_message_t state) | |||
1225 | static int __device_suspend_late(struct device *dev, pm_message_t state, bool async) | 1227 | static int __device_suspend_late(struct device *dev, pm_message_t state, bool async) |
1226 | { | 1228 | { |
1227 | pm_callback_t callback = NULL; | 1229 | pm_callback_t callback = NULL; |
1228 | char *info = NULL; | 1230 | const char *info = NULL; |
1229 | int error = 0; | 1231 | int error = 0; |
1230 | 1232 | ||
1231 | TRACE_DEVICE(dev); | 1233 | TRACE_DEVICE(dev); |
@@ -1384,7 +1386,7 @@ EXPORT_SYMBOL_GPL(dpm_suspend_end); | |||
1384 | */ | 1386 | */ |
1385 | static int legacy_suspend(struct device *dev, pm_message_t state, | 1387 | static int legacy_suspend(struct device *dev, pm_message_t state, |
1386 | int (*cb)(struct device *dev, pm_message_t state), | 1388 | int (*cb)(struct device *dev, pm_message_t state), |
1387 | char *info) | 1389 | const char *info) |
1388 | { | 1390 | { |
1389 | int error; | 1391 | int error; |
1390 | ktime_t calltime; | 1392 | ktime_t calltime; |
@@ -1426,7 +1428,7 @@ static void dpm_clear_suppliers_direct_complete(struct device *dev) | |||
1426 | static int __device_suspend(struct device *dev, pm_message_t state, bool async) | 1428 | static int __device_suspend(struct device *dev, pm_message_t state, bool async) |
1427 | { | 1429 | { |
1428 | pm_callback_t callback = NULL; | 1430 | pm_callback_t callback = NULL; |
1429 | char *info = NULL; | 1431 | const char *info = NULL; |
1430 | int error = 0; | 1432 | int error = 0; |
1431 | DECLARE_DPM_WATCHDOG_ON_STACK(wd); | 1433 | DECLARE_DPM_WATCHDOG_ON_STACK(wd); |
1432 | 1434 | ||
diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index dae61720b314..a8cc14fd8ae4 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c | |||
@@ -180,7 +180,7 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) | |||
180 | { | 180 | { |
181 | struct opp_table *opp_table; | 181 | struct opp_table *opp_table; |
182 | struct dev_pm_opp *opp; | 182 | struct dev_pm_opp *opp; |
183 | struct regulator *reg, **regulators; | 183 | struct regulator *reg; |
184 | unsigned long latency_ns = 0; | 184 | unsigned long latency_ns = 0; |
185 | int ret, i, count; | 185 | int ret, i, count; |
186 | struct { | 186 | struct { |
@@ -198,15 +198,9 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) | |||
198 | if (!count) | 198 | if (!count) |
199 | goto put_opp_table; | 199 | goto put_opp_table; |
200 | 200 | ||
201 | regulators = kmalloc_array(count, sizeof(*regulators), GFP_KERNEL); | ||
202 | if (!regulators) | ||
203 | goto put_opp_table; | ||
204 | |||
205 | uV = kmalloc_array(count, sizeof(*uV), GFP_KERNEL); | 201 | uV = kmalloc_array(count, sizeof(*uV), GFP_KERNEL); |
206 | if (!uV) | 202 | if (!uV) |
207 | goto free_regulators; | 203 | goto put_opp_table; |
208 | |||
209 | memcpy(regulators, opp_table->regulators, count * sizeof(*regulators)); | ||
210 | 204 | ||
211 | mutex_lock(&opp_table->lock); | 205 | mutex_lock(&opp_table->lock); |
212 | 206 | ||
@@ -232,15 +226,13 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) | |||
232 | * isn't freed, while we are executing this routine. | 226 | * isn't freed, while we are executing this routine. |
233 | */ | 227 | */ |
234 | for (i = 0; i < count; i++) { | 228 | for (i = 0; i < count; i++) { |
235 | reg = regulators[i]; | 229 | reg = opp_table->regulators[i]; |
236 | ret = regulator_set_voltage_time(reg, uV[i].min, uV[i].max); | 230 | ret = regulator_set_voltage_time(reg, uV[i].min, uV[i].max); |
237 | if (ret > 0) | 231 | if (ret > 0) |
238 | latency_ns += ret * 1000; | 232 | latency_ns += ret * 1000; |
239 | } | 233 | } |
240 | 234 | ||
241 | kfree(uV); | 235 | kfree(uV); |
242 | free_regulators: | ||
243 | kfree(regulators); | ||
244 | put_opp_table: | 236 | put_opp_table: |
245 | dev_pm_opp_put_opp_table(opp_table); | 237 | dev_pm_opp_put_opp_table(opp_table); |
246 | 238 | ||
@@ -543,17 +535,18 @@ _generic_set_opp_clk_only(struct device *dev, struct clk *clk, | |||
543 | return ret; | 535 | return ret; |
544 | } | 536 | } |
545 | 537 | ||
546 | static int _generic_set_opp(struct dev_pm_set_opp_data *data) | 538 | static int _generic_set_opp_regulator(const struct opp_table *opp_table, |
539 | struct device *dev, | ||
540 | unsigned long old_freq, | ||
541 | unsigned long freq, | ||
542 | struct dev_pm_opp_supply *old_supply, | ||
543 | struct dev_pm_opp_supply *new_supply) | ||
547 | { | 544 | { |
548 | struct dev_pm_opp_supply *old_supply = data->old_opp.supplies; | 545 | struct regulator *reg = opp_table->regulators[0]; |
549 | struct dev_pm_opp_supply *new_supply = data->new_opp.supplies; | ||
550 | unsigned long old_freq = data->old_opp.rate, freq = data->new_opp.rate; | ||
551 | struct regulator *reg = data->regulators[0]; | ||
552 | struct device *dev= data->dev; | ||
553 | int ret; | 546 | int ret; |
554 | 547 | ||
555 | /* This function only supports single regulator per device */ | 548 | /* This function only supports single regulator per device */ |
556 | if (WARN_ON(data->regulator_count > 1)) { | 549 | if (WARN_ON(opp_table->regulator_count > 1)) { |
557 | dev_err(dev, "multiple regulators are not supported\n"); | 550 | dev_err(dev, "multiple regulators are not supported\n"); |
558 | return -EINVAL; | 551 | return -EINVAL; |
559 | } | 552 | } |
@@ -566,7 +559,7 @@ static int _generic_set_opp(struct dev_pm_set_opp_data *data) | |||
566 | } | 559 | } |
567 | 560 | ||
568 | /* Change frequency */ | 561 | /* Change frequency */ |
569 | ret = _generic_set_opp_clk_only(dev, data->clk, old_freq, freq); | 562 | ret = _generic_set_opp_clk_only(dev, opp_table->clk, old_freq, freq); |
570 | if (ret) | 563 | if (ret) |
571 | goto restore_voltage; | 564 | goto restore_voltage; |
572 | 565 | ||
@@ -580,12 +573,12 @@ static int _generic_set_opp(struct dev_pm_set_opp_data *data) | |||
580 | return 0; | 573 | return 0; |
581 | 574 | ||
582 | restore_freq: | 575 | restore_freq: |
583 | if (_generic_set_opp_clk_only(dev, data->clk, freq, old_freq)) | 576 | if (_generic_set_opp_clk_only(dev, opp_table->clk, freq, old_freq)) |
584 | dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n", | 577 | dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n", |
585 | __func__, old_freq); | 578 | __func__, old_freq); |
586 | restore_voltage: | 579 | restore_voltage: |
587 | /* This shouldn't harm even if the voltages weren't updated earlier */ | 580 | /* This shouldn't harm even if the voltages weren't updated earlier */ |
588 | if (old_supply->u_volt) | 581 | if (old_supply) |
589 | _set_opp_voltage(dev, reg, old_supply); | 582 | _set_opp_voltage(dev, reg, old_supply); |
590 | 583 | ||
591 | return ret; | 584 | return ret; |
@@ -603,10 +596,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) | |||
603 | { | 596 | { |
604 | struct opp_table *opp_table; | 597 | struct opp_table *opp_table; |
605 | unsigned long freq, old_freq; | 598 | unsigned long freq, old_freq; |
606 | int (*set_opp)(struct dev_pm_set_opp_data *data); | ||
607 | struct dev_pm_opp *old_opp, *opp; | 599 | struct dev_pm_opp *old_opp, *opp; |
608 | struct regulator **regulators; | ||
609 | struct dev_pm_set_opp_data *data; | ||
610 | struct clk *clk; | 600 | struct clk *clk; |
611 | int ret, size; | 601 | int ret, size; |
612 | 602 | ||
@@ -661,38 +651,35 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) | |||
661 | dev_dbg(dev, "%s: switching OPP: %lu Hz --> %lu Hz\n", __func__, | 651 | dev_dbg(dev, "%s: switching OPP: %lu Hz --> %lu Hz\n", __func__, |
662 | old_freq, freq); | 652 | old_freq, freq); |
663 | 653 | ||
664 | regulators = opp_table->regulators; | ||
665 | |||
666 | /* Only frequency scaling */ | 654 | /* Only frequency scaling */ |
667 | if (!regulators) { | 655 | if (!opp_table->regulators) { |
668 | ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); | 656 | ret = _generic_set_opp_clk_only(dev, clk, old_freq, freq); |
669 | goto put_opps; | 657 | } else if (!opp_table->set_opp) { |
670 | } | 658 | ret = _generic_set_opp_regulator(opp_table, dev, old_freq, freq, |
659 | IS_ERR(old_opp) ? NULL : old_opp->supplies, | ||
660 | opp->supplies); | ||
661 | } else { | ||
662 | struct dev_pm_set_opp_data *data; | ||
671 | 663 | ||
672 | if (opp_table->set_opp) | 664 | data = opp_table->set_opp_data; |
673 | set_opp = opp_table->set_opp; | 665 | data->regulators = opp_table->regulators; |
674 | else | 666 | data->regulator_count = opp_table->regulator_count; |
675 | set_opp = _generic_set_opp; | 667 | data->clk = clk; |
676 | 668 | data->dev = dev; | |
677 | data = opp_table->set_opp_data; | ||
678 | data->regulators = regulators; | ||
679 | data->regulator_count = opp_table->regulator_count; | ||
680 | data->clk = clk; | ||
681 | data->dev = dev; | ||
682 | |||
683 | data->old_opp.rate = old_freq; | ||
684 | size = sizeof(*opp->supplies) * opp_table->regulator_count; | ||
685 | if (IS_ERR(old_opp)) | ||
686 | memset(data->old_opp.supplies, 0, size); | ||
687 | else | ||
688 | memcpy(data->old_opp.supplies, old_opp->supplies, size); | ||
689 | 669 | ||
690 | data->new_opp.rate = freq; | 670 | data->old_opp.rate = old_freq; |
691 | memcpy(data->new_opp.supplies, opp->supplies, size); | 671 | size = sizeof(*opp->supplies) * opp_table->regulator_count; |
672 | if (IS_ERR(old_opp)) | ||
673 | memset(data->old_opp.supplies, 0, size); | ||
674 | else | ||
675 | memcpy(data->old_opp.supplies, old_opp->supplies, size); | ||
692 | 676 | ||
693 | ret = set_opp(data); | 677 | data->new_opp.rate = freq; |
678 | memcpy(data->new_opp.supplies, opp->supplies, size); | ||
679 | |||
680 | ret = opp_table->set_opp(data); | ||
681 | } | ||
694 | 682 | ||
695 | put_opps: | ||
696 | dev_pm_opp_put(opp); | 683 | dev_pm_opp_put(opp); |
697 | put_old_opp: | 684 | put_old_opp: |
698 | if (!IS_ERR(old_opp)) | 685 | if (!IS_ERR(old_opp)) |
@@ -1376,6 +1363,73 @@ void dev_pm_opp_put_regulators(struct opp_table *opp_table) | |||
1376 | EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulators); | 1363 | EXPORT_SYMBOL_GPL(dev_pm_opp_put_regulators); |
1377 | 1364 | ||
1378 | /** | 1365 | /** |
1366 | * dev_pm_opp_set_clkname() - Set clk name for the device | ||
1367 | * @dev: Device for which clk name is being set. | ||
1368 | * @name: Clk name. | ||
1369 | * | ||
1370 | * In order to support OPP switching, OPP layer needs to get pointer to the | ||
1371 | * clock for the device. Simple cases work fine without using this routine (i.e. | ||
1372 | * by passing connection-id as NULL), but for a device with multiple clocks | ||
1373 | * available, the OPP core needs to know the exact name of the clk to use. | ||
1374 | * | ||
1375 | * This must be called before any OPPs are initialized for the device. | ||
1376 | */ | ||
1377 | struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char *name) | ||
1378 | { | ||
1379 | struct opp_table *opp_table; | ||
1380 | int ret; | ||
1381 | |||
1382 | opp_table = dev_pm_opp_get_opp_table(dev); | ||
1383 | if (!opp_table) | ||
1384 | return ERR_PTR(-ENOMEM); | ||
1385 | |||
1386 | /* This should be called before OPPs are initialized */ | ||
1387 | if (WARN_ON(!list_empty(&opp_table->opp_list))) { | ||
1388 | ret = -EBUSY; | ||
1389 | goto err; | ||
1390 | } | ||
1391 | |||
1392 | /* Already have default clk set, free it */ | ||
1393 | if (!IS_ERR(opp_table->clk)) | ||
1394 | clk_put(opp_table->clk); | ||
1395 | |||
1396 | /* Find clk for the device */ | ||
1397 | opp_table->clk = clk_get(dev, name); | ||
1398 | if (IS_ERR(opp_table->clk)) { | ||
1399 | ret = PTR_ERR(opp_table->clk); | ||
1400 | if (ret != -EPROBE_DEFER) { | ||
1401 | dev_err(dev, "%s: Couldn't find clock: %d\n", __func__, | ||
1402 | ret); | ||
1403 | } | ||
1404 | goto err; | ||
1405 | } | ||
1406 | |||
1407 | return opp_table; | ||
1408 | |||
1409 | err: | ||
1410 | dev_pm_opp_put_opp_table(opp_table); | ||
1411 | |||
1412 | return ERR_PTR(ret); | ||
1413 | } | ||
1414 | EXPORT_SYMBOL_GPL(dev_pm_opp_set_clkname); | ||
1415 | |||
1416 | /** | ||
1417 | * dev_pm_opp_put_clkname() - Releases resources blocked for clk. | ||
1418 | * @opp_table: OPP table returned from dev_pm_opp_set_clkname(). | ||
1419 | */ | ||
1420 | void dev_pm_opp_put_clkname(struct opp_table *opp_table) | ||
1421 | { | ||
1422 | /* Make sure there are no concurrent readers while updating opp_table */ | ||
1423 | WARN_ON(!list_empty(&opp_table->opp_list)); | ||
1424 | |||
1425 | clk_put(opp_table->clk); | ||
1426 | opp_table->clk = ERR_PTR(-EINVAL); | ||
1427 | |||
1428 | dev_pm_opp_put_opp_table(opp_table); | ||
1429 | } | ||
1430 | EXPORT_SYMBOL_GPL(dev_pm_opp_put_clkname); | ||
1431 | |||
1432 | /** | ||
1379 | * dev_pm_opp_register_set_opp_helper() - Register custom set OPP helper | 1433 | * dev_pm_opp_register_set_opp_helper() - Register custom set OPP helper |
1380 | * @dev: Device for which the helper is getting registered. | 1434 | * @dev: Device for which the helper is getting registered. |
1381 | * @set_opp: Custom set OPP helper. | 1435 | * @set_opp: Custom set OPP helper. |
diff --git a/drivers/base/power/opp/debugfs.c b/drivers/base/power/opp/debugfs.c index 95f433db4ac7..81cf120fcf43 100644 --- a/drivers/base/power/opp/debugfs.c +++ b/drivers/base/power/opp/debugfs.c | |||
@@ -40,11 +40,10 @@ static bool opp_debug_create_supplies(struct dev_pm_opp *opp, | |||
40 | struct dentry *pdentry) | 40 | struct dentry *pdentry) |
41 | { | 41 | { |
42 | struct dentry *d; | 42 | struct dentry *d; |
43 | int i = 0; | 43 | int i; |
44 | char *name; | 44 | char *name; |
45 | 45 | ||
46 | /* Always create at least supply-0 directory */ | 46 | for (i = 0; i < opp_table->regulator_count; i++) { |
47 | do { | ||
48 | name = kasprintf(GFP_KERNEL, "supply-%d", i); | 47 | name = kasprintf(GFP_KERNEL, "supply-%d", i); |
49 | 48 | ||
50 | /* Create per-opp directory */ | 49 | /* Create per-opp directory */ |
@@ -70,7 +69,7 @@ static bool opp_debug_create_supplies(struct dev_pm_opp *opp, | |||
70 | if (!debugfs_create_ulong("u_amp", S_IRUGO, d, | 69 | if (!debugfs_create_ulong("u_amp", S_IRUGO, d, |
71 | &opp->supplies[i].u_amp)) | 70 | &opp->supplies[i].u_amp)) |
72 | return false; | 71 | return false; |
73 | } while (++i < opp_table->regulator_count); | 72 | } |
74 | 73 | ||
75 | return true; | 74 | return true; |
76 | } | 75 | } |
diff --git a/drivers/base/power/opp/of.c b/drivers/base/power/opp/of.c index 779428676f63..57eec1ca0569 100644 --- a/drivers/base/power/opp/of.c +++ b/drivers/base/power/opp/of.c | |||
@@ -131,8 +131,14 @@ static int opp_parse_supplies(struct dev_pm_opp *opp, struct device *dev, | |||
131 | prop = of_find_property(opp->np, name, NULL); | 131 | prop = of_find_property(opp->np, name, NULL); |
132 | 132 | ||
133 | /* Missing property isn't a problem, but an invalid entry is */ | 133 | /* Missing property isn't a problem, but an invalid entry is */ |
134 | if (!prop) | 134 | if (!prop) { |
135 | return 0; | 135 | if (!opp_table->regulator_count) |
136 | return 0; | ||
137 | |||
138 | dev_err(dev, "%s: opp-microvolt missing although OPP managing regulators\n", | ||
139 | __func__); | ||
140 | return -EINVAL; | ||
141 | } | ||
136 | } | 142 | } |
137 | 143 | ||
138 | vcount = of_property_count_u32_elems(opp->np, name); | 144 | vcount = of_property_count_u32_elems(opp->np, name); |
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index 33b4b902741a..185a52581cfa 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c | |||
@@ -607,7 +607,7 @@ static struct attribute *power_attrs[] = { | |||
607 | #endif /* CONFIG_PM_ADVANCED_DEBUG */ | 607 | #endif /* CONFIG_PM_ADVANCED_DEBUG */ |
608 | NULL, | 608 | NULL, |
609 | }; | 609 | }; |
610 | static struct attribute_group pm_attr_group = { | 610 | static const struct attribute_group pm_attr_group = { |
611 | .name = power_group_name, | 611 | .name = power_group_name, |
612 | .attrs = power_attrs, | 612 | .attrs = power_attrs, |
613 | }; | 613 | }; |
@@ -629,7 +629,7 @@ static struct attribute *wakeup_attrs[] = { | |||
629 | #endif | 629 | #endif |
630 | NULL, | 630 | NULL, |
631 | }; | 631 | }; |
632 | static struct attribute_group pm_wakeup_attr_group = { | 632 | static const struct attribute_group pm_wakeup_attr_group = { |
633 | .name = power_group_name, | 633 | .name = power_group_name, |
634 | .attrs = wakeup_attrs, | 634 | .attrs = wakeup_attrs, |
635 | }; | 635 | }; |
@@ -644,7 +644,7 @@ static struct attribute *runtime_attrs[] = { | |||
644 | &dev_attr_autosuspend_delay_ms.attr, | 644 | &dev_attr_autosuspend_delay_ms.attr, |
645 | NULL, | 645 | NULL, |
646 | }; | 646 | }; |
647 | static struct attribute_group pm_runtime_attr_group = { | 647 | static const struct attribute_group pm_runtime_attr_group = { |
648 | .name = power_group_name, | 648 | .name = power_group_name, |
649 | .attrs = runtime_attrs, | 649 | .attrs = runtime_attrs, |
650 | }; | 650 | }; |
@@ -653,7 +653,7 @@ static struct attribute *pm_qos_resume_latency_attrs[] = { | |||
653 | &dev_attr_pm_qos_resume_latency_us.attr, | 653 | &dev_attr_pm_qos_resume_latency_us.attr, |
654 | NULL, | 654 | NULL, |
655 | }; | 655 | }; |
656 | static struct attribute_group pm_qos_resume_latency_attr_group = { | 656 | static const struct attribute_group pm_qos_resume_latency_attr_group = { |
657 | .name = power_group_name, | 657 | .name = power_group_name, |
658 | .attrs = pm_qos_resume_latency_attrs, | 658 | .attrs = pm_qos_resume_latency_attrs, |
659 | }; | 659 | }; |
@@ -662,7 +662,7 @@ static struct attribute *pm_qos_latency_tolerance_attrs[] = { | |||
662 | &dev_attr_pm_qos_latency_tolerance_us.attr, | 662 | &dev_attr_pm_qos_latency_tolerance_us.attr, |
663 | NULL, | 663 | NULL, |
664 | }; | 664 | }; |
665 | static struct attribute_group pm_qos_latency_tolerance_attr_group = { | 665 | static const struct attribute_group pm_qos_latency_tolerance_attr_group = { |
666 | .name = power_group_name, | 666 | .name = power_group_name, |
667 | .attrs = pm_qos_latency_tolerance_attrs, | 667 | .attrs = pm_qos_latency_tolerance_attrs, |
668 | }; | 668 | }; |
@@ -672,7 +672,7 @@ static struct attribute *pm_qos_flags_attrs[] = { | |||
672 | &dev_attr_pm_qos_remote_wakeup.attr, | 672 | &dev_attr_pm_qos_remote_wakeup.attr, |
673 | NULL, | 673 | NULL, |
674 | }; | 674 | }; |
675 | static struct attribute_group pm_qos_flags_attr_group = { | 675 | static const struct attribute_group pm_qos_flags_attr_group = { |
676 | .name = power_group_name, | 676 | .name = power_group_name, |
677 | .attrs = pm_qos_flags_attrs, | 677 | .attrs = pm_qos_flags_attrs, |
678 | }; | 678 | }; |
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index c313b600d356..144e6d8fafc8 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c | |||
@@ -28,8 +28,8 @@ bool events_check_enabled __read_mostly; | |||
28 | /* First wakeup IRQ seen by the kernel in the last cycle. */ | 28 | /* First wakeup IRQ seen by the kernel in the last cycle. */ |
29 | unsigned int pm_wakeup_irq __read_mostly; | 29 | unsigned int pm_wakeup_irq __read_mostly; |
30 | 30 | ||
31 | /* If set and the system is suspending, terminate the suspend. */ | 31 | /* If greater than 0 and the system is suspending, terminate the suspend. */ |
32 | static bool pm_abort_suspend __read_mostly; | 32 | static atomic_t pm_abort_suspend __read_mostly; |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Combined counters of registered wakeup events and wakeup events in progress. | 35 | * Combined counters of registered wakeup events and wakeup events in progress. |
@@ -60,6 +60,8 @@ static LIST_HEAD(wakeup_sources); | |||
60 | 60 | ||
61 | static DECLARE_WAIT_QUEUE_HEAD(wakeup_count_wait_queue); | 61 | static DECLARE_WAIT_QUEUE_HEAD(wakeup_count_wait_queue); |
62 | 62 | ||
63 | DEFINE_STATIC_SRCU(wakeup_srcu); | ||
64 | |||
63 | static struct wakeup_source deleted_ws = { | 65 | static struct wakeup_source deleted_ws = { |
64 | .name = "deleted", | 66 | .name = "deleted", |
65 | .lock = __SPIN_LOCK_UNLOCKED(deleted_ws.lock), | 67 | .lock = __SPIN_LOCK_UNLOCKED(deleted_ws.lock), |
@@ -198,7 +200,7 @@ void wakeup_source_remove(struct wakeup_source *ws) | |||
198 | spin_lock_irqsave(&events_lock, flags); | 200 | spin_lock_irqsave(&events_lock, flags); |
199 | list_del_rcu(&ws->entry); | 201 | list_del_rcu(&ws->entry); |
200 | spin_unlock_irqrestore(&events_lock, flags); | 202 | spin_unlock_irqrestore(&events_lock, flags); |
201 | synchronize_rcu(); | 203 | synchronize_srcu(&wakeup_srcu); |
202 | } | 204 | } |
203 | EXPORT_SYMBOL_GPL(wakeup_source_remove); | 205 | EXPORT_SYMBOL_GPL(wakeup_source_remove); |
204 | 206 | ||
@@ -332,12 +334,12 @@ void device_wakeup_detach_irq(struct device *dev) | |||
332 | void device_wakeup_arm_wake_irqs(void) | 334 | void device_wakeup_arm_wake_irqs(void) |
333 | { | 335 | { |
334 | struct wakeup_source *ws; | 336 | struct wakeup_source *ws; |
337 | int srcuidx; | ||
335 | 338 | ||
336 | rcu_read_lock(); | 339 | srcuidx = srcu_read_lock(&wakeup_srcu); |
337 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) | 340 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) |
338 | dev_pm_arm_wake_irq(ws->wakeirq); | 341 | dev_pm_arm_wake_irq(ws->wakeirq); |
339 | 342 | srcu_read_unlock(&wakeup_srcu, srcuidx); | |
340 | rcu_read_unlock(); | ||
341 | } | 343 | } |
342 | 344 | ||
343 | /** | 345 | /** |
@@ -348,12 +350,12 @@ void device_wakeup_arm_wake_irqs(void) | |||
348 | void device_wakeup_disarm_wake_irqs(void) | 350 | void device_wakeup_disarm_wake_irqs(void) |
349 | { | 351 | { |
350 | struct wakeup_source *ws; | 352 | struct wakeup_source *ws; |
353 | int srcuidx; | ||
351 | 354 | ||
352 | rcu_read_lock(); | 355 | srcuidx = srcu_read_lock(&wakeup_srcu); |
353 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) | 356 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) |
354 | dev_pm_disarm_wake_irq(ws->wakeirq); | 357 | dev_pm_disarm_wake_irq(ws->wakeirq); |
355 | 358 | srcu_read_unlock(&wakeup_srcu, srcuidx); | |
356 | rcu_read_unlock(); | ||
357 | } | 359 | } |
358 | 360 | ||
359 | /** | 361 | /** |
@@ -804,10 +806,10 @@ EXPORT_SYMBOL_GPL(pm_wakeup_dev_event); | |||
804 | void pm_print_active_wakeup_sources(void) | 806 | void pm_print_active_wakeup_sources(void) |
805 | { | 807 | { |
806 | struct wakeup_source *ws; | 808 | struct wakeup_source *ws; |
807 | int active = 0; | 809 | int srcuidx, active = 0; |
808 | struct wakeup_source *last_activity_ws = NULL; | 810 | struct wakeup_source *last_activity_ws = NULL; |
809 | 811 | ||
810 | rcu_read_lock(); | 812 | srcuidx = srcu_read_lock(&wakeup_srcu); |
811 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) { | 813 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) { |
812 | if (ws->active) { | 814 | if (ws->active) { |
813 | pr_debug("active wakeup source: %s\n", ws->name); | 815 | pr_debug("active wakeup source: %s\n", ws->name); |
@@ -823,7 +825,7 @@ void pm_print_active_wakeup_sources(void) | |||
823 | if (!active && last_activity_ws) | 825 | if (!active && last_activity_ws) |
824 | pr_debug("last active wakeup source: %s\n", | 826 | pr_debug("last active wakeup source: %s\n", |
825 | last_activity_ws->name); | 827 | last_activity_ws->name); |
826 | rcu_read_unlock(); | 828 | srcu_read_unlock(&wakeup_srcu, srcuidx); |
827 | } | 829 | } |
828 | EXPORT_SYMBOL_GPL(pm_print_active_wakeup_sources); | 830 | EXPORT_SYMBOL_GPL(pm_print_active_wakeup_sources); |
829 | 831 | ||
@@ -855,20 +857,26 @@ bool pm_wakeup_pending(void) | |||
855 | pm_print_active_wakeup_sources(); | 857 | pm_print_active_wakeup_sources(); |
856 | } | 858 | } |
857 | 859 | ||
858 | return ret || pm_abort_suspend; | 860 | return ret || atomic_read(&pm_abort_suspend) > 0; |
859 | } | 861 | } |
860 | 862 | ||
861 | void pm_system_wakeup(void) | 863 | void pm_system_wakeup(void) |
862 | { | 864 | { |
863 | pm_abort_suspend = true; | 865 | atomic_inc(&pm_abort_suspend); |
864 | freeze_wake(); | 866 | freeze_wake(); |
865 | } | 867 | } |
866 | EXPORT_SYMBOL_GPL(pm_system_wakeup); | 868 | EXPORT_SYMBOL_GPL(pm_system_wakeup); |
867 | 869 | ||
868 | void pm_wakeup_clear(void) | 870 | void pm_system_cancel_wakeup(void) |
871 | { | ||
872 | atomic_dec(&pm_abort_suspend); | ||
873 | } | ||
874 | |||
875 | void pm_wakeup_clear(bool reset) | ||
869 | { | 876 | { |
870 | pm_abort_suspend = false; | ||
871 | pm_wakeup_irq = 0; | 877 | pm_wakeup_irq = 0; |
878 | if (reset) | ||
879 | atomic_set(&pm_abort_suspend, 0); | ||
872 | } | 880 | } |
873 | 881 | ||
874 | void pm_system_irq_wakeup(unsigned int irq_number) | 882 | void pm_system_irq_wakeup(unsigned int irq_number) |
@@ -950,8 +958,9 @@ void pm_wakep_autosleep_enabled(bool set) | |||
950 | { | 958 | { |
951 | struct wakeup_source *ws; | 959 | struct wakeup_source *ws; |
952 | ktime_t now = ktime_get(); | 960 | ktime_t now = ktime_get(); |
961 | int srcuidx; | ||
953 | 962 | ||
954 | rcu_read_lock(); | 963 | srcuidx = srcu_read_lock(&wakeup_srcu); |
955 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) { | 964 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) { |
956 | spin_lock_irq(&ws->lock); | 965 | spin_lock_irq(&ws->lock); |
957 | if (ws->autosleep_enabled != set) { | 966 | if (ws->autosleep_enabled != set) { |
@@ -965,7 +974,7 @@ void pm_wakep_autosleep_enabled(bool set) | |||
965 | } | 974 | } |
966 | spin_unlock_irq(&ws->lock); | 975 | spin_unlock_irq(&ws->lock); |
967 | } | 976 | } |
968 | rcu_read_unlock(); | 977 | srcu_read_unlock(&wakeup_srcu, srcuidx); |
969 | } | 978 | } |
970 | #endif /* CONFIG_PM_AUTOSLEEP */ | 979 | #endif /* CONFIG_PM_AUTOSLEEP */ |
971 | 980 | ||
@@ -1026,15 +1035,16 @@ static int print_wakeup_source_stats(struct seq_file *m, | |||
1026 | static int wakeup_sources_stats_show(struct seq_file *m, void *unused) | 1035 | static int wakeup_sources_stats_show(struct seq_file *m, void *unused) |
1027 | { | 1036 | { |
1028 | struct wakeup_source *ws; | 1037 | struct wakeup_source *ws; |
1038 | int srcuidx; | ||
1029 | 1039 | ||
1030 | seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t" | 1040 | seq_puts(m, "name\t\tactive_count\tevent_count\twakeup_count\t" |
1031 | "expire_count\tactive_since\ttotal_time\tmax_time\t" | 1041 | "expire_count\tactive_since\ttotal_time\tmax_time\t" |
1032 | "last_change\tprevent_suspend_time\n"); | 1042 | "last_change\tprevent_suspend_time\n"); |
1033 | 1043 | ||
1034 | rcu_read_lock(); | 1044 | srcuidx = srcu_read_lock(&wakeup_srcu); |
1035 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) | 1045 | list_for_each_entry_rcu(ws, &wakeup_sources, entry) |
1036 | print_wakeup_source_stats(m, ws); | 1046 | print_wakeup_source_stats(m, ws); |
1037 | rcu_read_unlock(); | 1047 | srcu_read_unlock(&wakeup_srcu, srcuidx); |
1038 | 1048 | ||
1039 | print_wakeup_source_stats(m, &deleted_ws); | 1049 | print_wakeup_source_stats(m, &deleted_ws); |
1040 | 1050 | ||
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index e82bb3c30b92..10be285c9055 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c | |||
@@ -144,10 +144,23 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
144 | 144 | ||
145 | cppc_dmi_max_khz = cppc_get_dmi_max_khz(); | 145 | cppc_dmi_max_khz = cppc_get_dmi_max_khz(); |
146 | 146 | ||
147 | policy->min = cpu->perf_caps.lowest_perf * cppc_dmi_max_khz / cpu->perf_caps.highest_perf; | 147 | /* |
148 | * Set min to lowest nonlinear perf to avoid any efficiency penalty (see | ||
149 | * Section 8.4.7.1.1.5 of ACPI 6.1 spec) | ||
150 | */ | ||
151 | policy->min = cpu->perf_caps.lowest_nonlinear_perf * cppc_dmi_max_khz / | ||
152 | cpu->perf_caps.highest_perf; | ||
148 | policy->max = cppc_dmi_max_khz; | 153 | policy->max = cppc_dmi_max_khz; |
149 | policy->cpuinfo.min_freq = policy->min; | 154 | |
150 | policy->cpuinfo.max_freq = policy->max; | 155 | /* |
156 | * Set cpuinfo.min_freq to Lowest to make the full range of performance | ||
157 | * available if userspace wants to use any perf between lowest & lowest | ||
158 | * nonlinear perf | ||
159 | */ | ||
160 | policy->cpuinfo.min_freq = cpu->perf_caps.lowest_perf * cppc_dmi_max_khz / | ||
161 | cpu->perf_caps.highest_perf; | ||
162 | policy->cpuinfo.max_freq = cppc_dmi_max_khz; | ||
163 | |||
151 | policy->cpuinfo.transition_latency = cppc_get_transition_latency(cpu_num); | 164 | policy->cpuinfo.transition_latency = cppc_get_transition_latency(cpu_num); |
152 | policy->shared_type = cpu->shared_type; | 165 | policy->shared_type = cpu->shared_type; |
153 | 166 | ||
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index 921b4a6c3d16..1c262923fe58 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c | |||
@@ -31,6 +31,7 @@ static const struct of_device_id machines[] __initconst = { | |||
31 | { .compatible = "arm,integrator-ap", }, | 31 | { .compatible = "arm,integrator-ap", }, |
32 | { .compatible = "arm,integrator-cp", }, | 32 | { .compatible = "arm,integrator-cp", }, |
33 | 33 | ||
34 | { .compatible = "hisilicon,hi3660", }, | ||
34 | { .compatible = "hisilicon,hi6220", }, | 35 | { .compatible = "hisilicon,hi6220", }, |
35 | 36 | ||
36 | { .compatible = "fsl,imx27", }, | 37 | { .compatible = "fsl,imx27", }, |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 29c5b0cbad96..9bf97a366029 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -632,11 +632,21 @@ show_one(cpuinfo_transition_latency, cpuinfo.transition_latency); | |||
632 | show_one(scaling_min_freq, min); | 632 | show_one(scaling_min_freq, min); |
633 | show_one(scaling_max_freq, max); | 633 | show_one(scaling_max_freq, max); |
634 | 634 | ||
635 | __weak unsigned int arch_freq_get_on_cpu(int cpu) | ||
636 | { | ||
637 | return 0; | ||
638 | } | ||
639 | |||
635 | static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf) | 640 | static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf) |
636 | { | 641 | { |
637 | ssize_t ret; | 642 | ssize_t ret; |
643 | unsigned int freq; | ||
638 | 644 | ||
639 | if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get) | 645 | freq = arch_freq_get_on_cpu(policy->cpu); |
646 | if (freq) | ||
647 | ret = sprintf(buf, "%u\n", freq); | ||
648 | else if (cpufreq_driver && cpufreq_driver->setpolicy && | ||
649 | cpufreq_driver->get) | ||
640 | ret = sprintf(buf, "%u\n", cpufreq_driver->get(policy->cpu)); | 650 | ret = sprintf(buf, "%u\n", cpufreq_driver->get(policy->cpu)); |
641 | else | 651 | else |
642 | ret = sprintf(buf, "%u\n", policy->cur); | 652 | ret = sprintf(buf, "%u\n", policy->cur); |
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index 9180d34cc9fc..b6b369c22272 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c | |||
@@ -173,12 +173,12 @@ static void exynos_enable_dvfs(unsigned int cur_frequency) | |||
173 | /* Enable PSTATE Change Event */ | 173 | /* Enable PSTATE Change Event */ |
174 | tmp = __raw_readl(dvfs_info->base + XMU_PMUEVTEN); | 174 | tmp = __raw_readl(dvfs_info->base + XMU_PMUEVTEN); |
175 | tmp |= (1 << PSTATE_CHANGED_EVTEN_SHIFT); | 175 | tmp |= (1 << PSTATE_CHANGED_EVTEN_SHIFT); |
176 | __raw_writel(tmp, dvfs_info->base + XMU_PMUEVTEN); | 176 | __raw_writel(tmp, dvfs_info->base + XMU_PMUEVTEN); |
177 | 177 | ||
178 | /* Enable PSTATE Change IRQ */ | 178 | /* Enable PSTATE Change IRQ */ |
179 | tmp = __raw_readl(dvfs_info->base + XMU_PMUIRQEN); | 179 | tmp = __raw_readl(dvfs_info->base + XMU_PMUIRQEN); |
180 | tmp |= (1 << PSTATE_CHANGED_IRQEN_SHIFT); | 180 | tmp |= (1 << PSTATE_CHANGED_IRQEN_SHIFT); |
181 | __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQEN); | 181 | __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQEN); |
182 | 182 | ||
183 | /* Set initial performance index */ | 183 | /* Set initial performance index */ |
184 | cpufreq_for_each_entry(pos, freq_table) | 184 | cpufreq_for_each_entry(pos, freq_table) |
@@ -330,7 +330,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
330 | struct resource res; | 330 | struct resource res; |
331 | unsigned int cur_frequency; | 331 | unsigned int cur_frequency; |
332 | 332 | ||
333 | np = pdev->dev.of_node; | 333 | np = pdev->dev.of_node; |
334 | if (!np) | 334 | if (!np) |
335 | return -ENODEV; | 335 | return -ENODEV; |
336 | 336 | ||
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index 9c13f097fd8c..b6edd3ccaa55 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c | |||
@@ -101,7 +101,8 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
101 | * - Reprogram pll1_sys_clk and reparent pll1_sw_clk back to it | 101 | * - Reprogram pll1_sys_clk and reparent pll1_sw_clk back to it |
102 | * - Disable pll2_pfd2_396m_clk | 102 | * - Disable pll2_pfd2_396m_clk |
103 | */ | 103 | */ |
104 | if (of_machine_is_compatible("fsl,imx6ul")) { | 104 | if (of_machine_is_compatible("fsl,imx6ul") || |
105 | of_machine_is_compatible("fsl,imx6ull")) { | ||
105 | /* | 106 | /* |
106 | * When changing pll1_sw_clk's parent to pll1_sys_clk, | 107 | * When changing pll1_sw_clk's parent to pll1_sys_clk, |
107 | * CPU may run at higher than 528MHz, this will lead to | 108 | * CPU may run at higher than 528MHz, this will lead to |
@@ -215,7 +216,8 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) | |||
215 | goto put_clk; | 216 | goto put_clk; |
216 | } | 217 | } |
217 | 218 | ||
218 | if (of_machine_is_compatible("fsl,imx6ul")) { | 219 | if (of_machine_is_compatible("fsl,imx6ul") || |
220 | of_machine_is_compatible("fsl,imx6ull")) { | ||
219 | pll2_bus_clk = clk_get(cpu_dev, "pll2_bus"); | 221 | pll2_bus_clk = clk_get(cpu_dev, "pll2_bus"); |
220 | secondary_sel_clk = clk_get(cpu_dev, "secondary_sel"); | 222 | secondary_sel_clk = clk_get(cpu_dev, "secondary_sel"); |
221 | if (IS_ERR(pll2_bus_clk) || IS_ERR(secondary_sel_clk)) { | 223 | if (IS_ERR(pll2_bus_clk) || IS_ERR(secondary_sel_clk)) { |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index eb1158532de3..48a98f11a84e 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -231,10 +231,8 @@ struct global_params { | |||
231 | * @prev_cummulative_iowait: IO Wait time difference from last and | 231 | * @prev_cummulative_iowait: IO Wait time difference from last and |
232 | * current sample | 232 | * current sample |
233 | * @sample: Storage for storing last Sample data | 233 | * @sample: Storage for storing last Sample data |
234 | * @min_perf: Minimum capacity limit as a fraction of the maximum | 234 | * @min_perf_ratio: Minimum capacity in terms of PERF or HWP ratios |
235 | * turbo P-state capacity. | 235 | * @max_perf_ratio: Maximum capacity in terms of PERF or HWP ratios |
236 | * @max_perf: Maximum capacity limit as a fraction of the maximum | ||
237 | * turbo P-state capacity. | ||
238 | * @acpi_perf_data: Stores ACPI perf information read from _PSS | 236 | * @acpi_perf_data: Stores ACPI perf information read from _PSS |
239 | * @valid_pss_table: Set to true for valid ACPI _PSS entries found | 237 | * @valid_pss_table: Set to true for valid ACPI _PSS entries found |
240 | * @epp_powersave: Last saved HWP energy performance preference | 238 | * @epp_powersave: Last saved HWP energy performance preference |
@@ -266,8 +264,8 @@ struct cpudata { | |||
266 | u64 prev_tsc; | 264 | u64 prev_tsc; |
267 | u64 prev_cummulative_iowait; | 265 | u64 prev_cummulative_iowait; |
268 | struct sample sample; | 266 | struct sample sample; |
269 | int32_t min_perf; | 267 | int32_t min_perf_ratio; |
270 | int32_t max_perf; | 268 | int32_t max_perf_ratio; |
271 | #ifdef CONFIG_ACPI | 269 | #ifdef CONFIG_ACPI |
272 | struct acpi_processor_performance acpi_perf_data; | 270 | struct acpi_processor_performance acpi_perf_data; |
273 | bool valid_pss_table; | 271 | bool valid_pss_table; |
@@ -653,6 +651,12 @@ static const char * const energy_perf_strings[] = { | |||
653 | "power", | 651 | "power", |
654 | NULL | 652 | NULL |
655 | }; | 653 | }; |
654 | static const unsigned int epp_values[] = { | ||
655 | HWP_EPP_PERFORMANCE, | ||
656 | HWP_EPP_BALANCE_PERFORMANCE, | ||
657 | HWP_EPP_BALANCE_POWERSAVE, | ||
658 | HWP_EPP_POWERSAVE | ||
659 | }; | ||
656 | 660 | ||
657 | static int intel_pstate_get_energy_pref_index(struct cpudata *cpu_data) | 661 | static int intel_pstate_get_energy_pref_index(struct cpudata *cpu_data) |
658 | { | 662 | { |
@@ -664,17 +668,14 @@ static int intel_pstate_get_energy_pref_index(struct cpudata *cpu_data) | |||
664 | return epp; | 668 | return epp; |
665 | 669 | ||
666 | if (static_cpu_has(X86_FEATURE_HWP_EPP)) { | 670 | if (static_cpu_has(X86_FEATURE_HWP_EPP)) { |
667 | /* | 671 | if (epp == HWP_EPP_PERFORMANCE) |
668 | * Range: | 672 | return 1; |
669 | * 0x00-0x3F : Performance | 673 | if (epp <= HWP_EPP_BALANCE_PERFORMANCE) |
670 | * 0x40-0x7F : Balance performance | 674 | return 2; |
671 | * 0x80-0xBF : Balance power | 675 | if (epp <= HWP_EPP_BALANCE_POWERSAVE) |
672 | * 0xC0-0xFF : Power | 676 | return 3; |
673 | * The EPP is a 8 bit value, but our ranges restrict the | 677 | else |
674 | * value which can be set. Here only using top two bits | 678 | return 4; |
675 | * effectively. | ||
676 | */ | ||
677 | index = (epp >> 6) + 1; | ||
678 | } else if (static_cpu_has(X86_FEATURE_EPB)) { | 679 | } else if (static_cpu_has(X86_FEATURE_EPB)) { |
679 | /* | 680 | /* |
680 | * Range: | 681 | * Range: |
@@ -712,15 +713,8 @@ static int intel_pstate_set_energy_pref_index(struct cpudata *cpu_data, | |||
712 | 713 | ||
713 | value &= ~GENMASK_ULL(31, 24); | 714 | value &= ~GENMASK_ULL(31, 24); |
714 | 715 | ||
715 | /* | ||
716 | * If epp is not default, convert from index into | ||
717 | * energy_perf_strings to epp value, by shifting 6 | ||
718 | * bits left to use only top two bits in epp. | ||
719 | * The resultant epp need to shifted by 24 bits to | ||
720 | * epp position in MSR_HWP_REQUEST. | ||
721 | */ | ||
722 | if (epp == -EINVAL) | 716 | if (epp == -EINVAL) |
723 | epp = (pref_index - 1) << 6; | 717 | epp = epp_values[pref_index - 1]; |
724 | 718 | ||
725 | value |= (u64)epp << 24; | 719 | value |= (u64)epp << 24; |
726 | ret = wrmsrl_on_cpu(cpu_data->cpu, MSR_HWP_REQUEST, value); | 720 | ret = wrmsrl_on_cpu(cpu_data->cpu, MSR_HWP_REQUEST, value); |
@@ -794,25 +788,32 @@ static struct freq_attr *hwp_cpufreq_attrs[] = { | |||
794 | NULL, | 788 | NULL, |
795 | }; | 789 | }; |
796 | 790 | ||
797 | static void intel_pstate_hwp_set(unsigned int cpu) | 791 | static void intel_pstate_get_hwp_max(unsigned int cpu, int *phy_max, |
792 | int *current_max) | ||
798 | { | 793 | { |
799 | struct cpudata *cpu_data = all_cpu_data[cpu]; | 794 | u64 cap; |
800 | int min, hw_min, max, hw_max; | ||
801 | u64 value, cap; | ||
802 | s16 epp; | ||
803 | 795 | ||
804 | rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap); | 796 | rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap); |
805 | hw_min = HWP_LOWEST_PERF(cap); | ||
806 | if (global.no_turbo) | 797 | if (global.no_turbo) |
807 | hw_max = HWP_GUARANTEED_PERF(cap); | 798 | *current_max = HWP_GUARANTEED_PERF(cap); |
808 | else | 799 | else |
809 | hw_max = HWP_HIGHEST_PERF(cap); | 800 | *current_max = HWP_HIGHEST_PERF(cap); |
801 | |||
802 | *phy_max = HWP_HIGHEST_PERF(cap); | ||
803 | } | ||
804 | |||
805 | static void intel_pstate_hwp_set(unsigned int cpu) | ||
806 | { | ||
807 | struct cpudata *cpu_data = all_cpu_data[cpu]; | ||
808 | int max, min; | ||
809 | u64 value; | ||
810 | s16 epp; | ||
811 | |||
812 | max = cpu_data->max_perf_ratio; | ||
813 | min = cpu_data->min_perf_ratio; | ||
810 | 814 | ||
811 | max = fp_ext_toint(hw_max * cpu_data->max_perf); | ||
812 | if (cpu_data->policy == CPUFREQ_POLICY_PERFORMANCE) | 815 | if (cpu_data->policy == CPUFREQ_POLICY_PERFORMANCE) |
813 | min = max; | 816 | min = max; |
814 | else | ||
815 | min = fp_ext_toint(hw_max * cpu_data->min_perf); | ||
816 | 817 | ||
817 | rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value); | 818 | rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value); |
818 | 819 | ||
@@ -1528,8 +1529,7 @@ static void intel_pstate_max_within_limits(struct cpudata *cpu) | |||
1528 | 1529 | ||
1529 | update_turbo_state(); | 1530 | update_turbo_state(); |
1530 | pstate = intel_pstate_get_base_pstate(cpu); | 1531 | pstate = intel_pstate_get_base_pstate(cpu); |
1531 | pstate = max(cpu->pstate.min_pstate, | 1532 | pstate = max(cpu->pstate.min_pstate, cpu->max_perf_ratio); |
1532 | fp_ext_toint(pstate * cpu->max_perf)); | ||
1533 | intel_pstate_set_pstate(cpu, pstate); | 1533 | intel_pstate_set_pstate(cpu, pstate); |
1534 | } | 1534 | } |
1535 | 1535 | ||
@@ -1616,9 +1616,6 @@ static inline int32_t get_target_pstate_use_cpu_load(struct cpudata *cpu) | |||
1616 | int32_t busy_frac, boost; | 1616 | int32_t busy_frac, boost; |
1617 | int target, avg_pstate; | 1617 | int target, avg_pstate; |
1618 | 1618 | ||
1619 | if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE) | ||
1620 | return cpu->pstate.turbo_pstate; | ||
1621 | |||
1622 | busy_frac = div_fp(sample->mperf, sample->tsc); | 1619 | busy_frac = div_fp(sample->mperf, sample->tsc); |
1623 | 1620 | ||
1624 | boost = cpu->iowait_boost; | 1621 | boost = cpu->iowait_boost; |
@@ -1655,9 +1652,6 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu) | |||
1655 | int32_t perf_scaled, max_pstate, current_pstate, sample_ratio; | 1652 | int32_t perf_scaled, max_pstate, current_pstate, sample_ratio; |
1656 | u64 duration_ns; | 1653 | u64 duration_ns; |
1657 | 1654 | ||
1658 | if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE) | ||
1659 | return cpu->pstate.turbo_pstate; | ||
1660 | |||
1661 | /* | 1655 | /* |
1662 | * perf_scaled is the ratio of the average P-state during the last | 1656 | * perf_scaled is the ratio of the average P-state during the last |
1663 | * sampling period to the P-state requested last time (in percent). | 1657 | * sampling period to the P-state requested last time (in percent). |
@@ -1695,9 +1689,8 @@ static int intel_pstate_prepare_request(struct cpudata *cpu, int pstate) | |||
1695 | int max_pstate = intel_pstate_get_base_pstate(cpu); | 1689 | int max_pstate = intel_pstate_get_base_pstate(cpu); |
1696 | int min_pstate; | 1690 | int min_pstate; |
1697 | 1691 | ||
1698 | min_pstate = max(cpu->pstate.min_pstate, | 1692 | min_pstate = max(cpu->pstate.min_pstate, cpu->min_perf_ratio); |
1699 | fp_ext_toint(max_pstate * cpu->min_perf)); | 1693 | max_pstate = max(min_pstate, cpu->max_perf_ratio); |
1700 | max_pstate = max(min_pstate, fp_ext_toint(max_pstate * cpu->max_perf)); | ||
1701 | return clamp_t(int, pstate, min_pstate, max_pstate); | 1694 | return clamp_t(int, pstate, min_pstate, max_pstate); |
1702 | } | 1695 | } |
1703 | 1696 | ||
@@ -1733,16 +1726,6 @@ static void intel_pstate_adjust_pstate(struct cpudata *cpu, int target_pstate) | |||
1733 | fp_toint(cpu->iowait_boost * 100)); | 1726 | fp_toint(cpu->iowait_boost * 100)); |
1734 | } | 1727 | } |
1735 | 1728 | ||
1736 | static void intel_pstate_update_util_hwp(struct update_util_data *data, | ||
1737 | u64 time, unsigned int flags) | ||
1738 | { | ||
1739 | struct cpudata *cpu = container_of(data, struct cpudata, update_util); | ||
1740 | u64 delta_ns = time - cpu->sample.time; | ||
1741 | |||
1742 | if ((s64)delta_ns >= INTEL_PSTATE_HWP_SAMPLING_INTERVAL) | ||
1743 | intel_pstate_sample(cpu, time); | ||
1744 | } | ||
1745 | |||
1746 | static void intel_pstate_update_util_pid(struct update_util_data *data, | 1729 | static void intel_pstate_update_util_pid(struct update_util_data *data, |
1747 | u64 time, unsigned int flags) | 1730 | u64 time, unsigned int flags) |
1748 | { | 1731 | { |
@@ -1934,6 +1917,9 @@ static void intel_pstate_set_update_util_hook(unsigned int cpu_num) | |||
1934 | { | 1917 | { |
1935 | struct cpudata *cpu = all_cpu_data[cpu_num]; | 1918 | struct cpudata *cpu = all_cpu_data[cpu_num]; |
1936 | 1919 | ||
1920 | if (hwp_active) | ||
1921 | return; | ||
1922 | |||
1937 | if (cpu->update_util_set) | 1923 | if (cpu->update_util_set) |
1938 | return; | 1924 | return; |
1939 | 1925 | ||
@@ -1967,52 +1953,61 @@ static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy, | |||
1967 | { | 1953 | { |
1968 | int max_freq = intel_pstate_get_max_freq(cpu); | 1954 | int max_freq = intel_pstate_get_max_freq(cpu); |
1969 | int32_t max_policy_perf, min_policy_perf; | 1955 | int32_t max_policy_perf, min_policy_perf; |
1956 | int max_state, turbo_max; | ||
1970 | 1957 | ||
1971 | max_policy_perf = div_ext_fp(policy->max, max_freq); | 1958 | /* |
1972 | max_policy_perf = clamp_t(int32_t, max_policy_perf, 0, int_ext_tofp(1)); | 1959 | * HWP needs some special consideration, because on BDX the |
1960 | * HWP_REQUEST uses abstract value to represent performance | ||
1961 | * rather than pure ratios. | ||
1962 | */ | ||
1963 | if (hwp_active) { | ||
1964 | intel_pstate_get_hwp_max(cpu->cpu, &turbo_max, &max_state); | ||
1965 | } else { | ||
1966 | max_state = intel_pstate_get_base_pstate(cpu); | ||
1967 | turbo_max = cpu->pstate.turbo_pstate; | ||
1968 | } | ||
1969 | |||
1970 | max_policy_perf = max_state * policy->max / max_freq; | ||
1973 | if (policy->max == policy->min) { | 1971 | if (policy->max == policy->min) { |
1974 | min_policy_perf = max_policy_perf; | 1972 | min_policy_perf = max_policy_perf; |
1975 | } else { | 1973 | } else { |
1976 | min_policy_perf = div_ext_fp(policy->min, max_freq); | 1974 | min_policy_perf = max_state * policy->min / max_freq; |
1977 | min_policy_perf = clamp_t(int32_t, min_policy_perf, | 1975 | min_policy_perf = clamp_t(int32_t, min_policy_perf, |
1978 | 0, max_policy_perf); | 1976 | 0, max_policy_perf); |
1979 | } | 1977 | } |
1980 | 1978 | ||
1979 | pr_debug("cpu:%d max_state %d min_policy_perf:%d max_policy_perf:%d\n", | ||
1980 | policy->cpu, max_state, | ||
1981 | min_policy_perf, max_policy_perf); | ||
1982 | |||
1981 | /* Normalize user input to [min_perf, max_perf] */ | 1983 | /* Normalize user input to [min_perf, max_perf] */ |
1982 | if (per_cpu_limits) { | 1984 | if (per_cpu_limits) { |
1983 | cpu->min_perf = min_policy_perf; | 1985 | cpu->min_perf_ratio = min_policy_perf; |
1984 | cpu->max_perf = max_policy_perf; | 1986 | cpu->max_perf_ratio = max_policy_perf; |
1985 | } else { | 1987 | } else { |
1986 | int32_t global_min, global_max; | 1988 | int32_t global_min, global_max; |
1987 | 1989 | ||
1988 | /* Global limits are in percent of the maximum turbo P-state. */ | 1990 | /* Global limits are in percent of the maximum turbo P-state. */ |
1989 | global_max = percent_ext_fp(global.max_perf_pct); | 1991 | global_max = DIV_ROUND_UP(turbo_max * global.max_perf_pct, 100); |
1990 | global_min = percent_ext_fp(global.min_perf_pct); | 1992 | global_min = DIV_ROUND_UP(turbo_max * global.min_perf_pct, 100); |
1991 | if (max_freq != cpu->pstate.turbo_freq) { | ||
1992 | int32_t turbo_factor; | ||
1993 | |||
1994 | turbo_factor = div_ext_fp(cpu->pstate.turbo_pstate, | ||
1995 | cpu->pstate.max_pstate); | ||
1996 | global_min = mul_ext_fp(global_min, turbo_factor); | ||
1997 | global_max = mul_ext_fp(global_max, turbo_factor); | ||
1998 | } | ||
1999 | global_min = clamp_t(int32_t, global_min, 0, global_max); | 1993 | global_min = clamp_t(int32_t, global_min, 0, global_max); |
2000 | 1994 | ||
2001 | cpu->min_perf = max(min_policy_perf, global_min); | 1995 | pr_debug("cpu:%d global_min:%d global_max:%d\n", policy->cpu, |
2002 | cpu->min_perf = min(cpu->min_perf, max_policy_perf); | 1996 | global_min, global_max); |
2003 | cpu->max_perf = min(max_policy_perf, global_max); | ||
2004 | cpu->max_perf = max(min_policy_perf, cpu->max_perf); | ||
2005 | 1997 | ||
2006 | /* Make sure min_perf <= max_perf */ | 1998 | cpu->min_perf_ratio = max(min_policy_perf, global_min); |
2007 | cpu->min_perf = min(cpu->min_perf, cpu->max_perf); | 1999 | cpu->min_perf_ratio = min(cpu->min_perf_ratio, max_policy_perf); |
2008 | } | 2000 | cpu->max_perf_ratio = min(max_policy_perf, global_max); |
2001 | cpu->max_perf_ratio = max(min_policy_perf, cpu->max_perf_ratio); | ||
2009 | 2002 | ||
2010 | cpu->max_perf = round_up(cpu->max_perf, EXT_FRAC_BITS); | 2003 | /* Make sure min_perf <= max_perf */ |
2011 | cpu->min_perf = round_up(cpu->min_perf, EXT_FRAC_BITS); | 2004 | cpu->min_perf_ratio = min(cpu->min_perf_ratio, |
2005 | cpu->max_perf_ratio); | ||
2012 | 2006 | ||
2013 | pr_debug("cpu:%d max_perf_pct:%d min_perf_pct:%d\n", policy->cpu, | 2007 | } |
2014 | fp_ext_toint(cpu->max_perf * 100), | 2008 | pr_debug("cpu:%d max_perf_ratio:%d min_perf_ratio:%d\n", policy->cpu, |
2015 | fp_ext_toint(cpu->min_perf * 100)); | 2009 | cpu->max_perf_ratio, |
2010 | cpu->min_perf_ratio); | ||
2016 | } | 2011 | } |
2017 | 2012 | ||
2018 | static int intel_pstate_set_policy(struct cpufreq_policy *policy) | 2013 | static int intel_pstate_set_policy(struct cpufreq_policy *policy) |
@@ -2039,10 +2034,10 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) | |||
2039 | */ | 2034 | */ |
2040 | intel_pstate_clear_update_util_hook(policy->cpu); | 2035 | intel_pstate_clear_update_util_hook(policy->cpu); |
2041 | intel_pstate_max_within_limits(cpu); | 2036 | intel_pstate_max_within_limits(cpu); |
2037 | } else { | ||
2038 | intel_pstate_set_update_util_hook(policy->cpu); | ||
2042 | } | 2039 | } |
2043 | 2040 | ||
2044 | intel_pstate_set_update_util_hook(policy->cpu); | ||
2045 | |||
2046 | if (hwp_active) | 2041 | if (hwp_active) |
2047 | intel_pstate_hwp_set(policy->cpu); | 2042 | intel_pstate_hwp_set(policy->cpu); |
2048 | 2043 | ||
@@ -2115,8 +2110,8 @@ static int __intel_pstate_cpu_init(struct cpufreq_policy *policy) | |||
2115 | 2110 | ||
2116 | cpu = all_cpu_data[policy->cpu]; | 2111 | cpu = all_cpu_data[policy->cpu]; |
2117 | 2112 | ||
2118 | cpu->max_perf = int_ext_tofp(1); | 2113 | cpu->max_perf_ratio = 0xFF; |
2119 | cpu->min_perf = 0; | 2114 | cpu->min_perf_ratio = 0; |
2120 | 2115 | ||
2121 | policy->min = cpu->pstate.min_pstate * cpu->pstate.scaling; | 2116 | policy->min = cpu->pstate.min_pstate * cpu->pstate.scaling; |
2122 | policy->max = cpu->pstate.turbo_pstate * cpu->pstate.scaling; | 2117 | policy->max = cpu->pstate.turbo_pstate * cpu->pstate.scaling; |
@@ -2558,7 +2553,6 @@ static int __init intel_pstate_init(void) | |||
2558 | } else { | 2553 | } else { |
2559 | hwp_active++; | 2554 | hwp_active++; |
2560 | intel_pstate.attr = hwp_cpufreq_attrs; | 2555 | intel_pstate.attr = hwp_cpufreq_attrs; |
2561 | pstate_funcs.update_util = intel_pstate_update_util_hwp; | ||
2562 | goto hwp_cpu_matched; | 2556 | goto hwp_cpu_matched; |
2563 | } | 2557 | } |
2564 | } else { | 2558 | } else { |
diff --git a/drivers/cpufreq/sfi-cpufreq.c b/drivers/cpufreq/sfi-cpufreq.c index 992ce6f9abec..3779742f86e3 100644 --- a/drivers/cpufreq/sfi-cpufreq.c +++ b/drivers/cpufreq/sfi-cpufreq.c | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #include <asm/msr.h> | 25 | #include <asm/msr.h> |
26 | 26 | ||
27 | struct cpufreq_frequency_table *freq_table; | 27 | static struct cpufreq_frequency_table *freq_table; |
28 | static struct sfi_freq_table_entry *sfi_cpufreq_array; | 28 | static struct sfi_freq_table_entry *sfi_cpufreq_array; |
29 | static int num_freq_table_entries; | 29 | static int num_freq_table_entries; |
30 | 30 | ||
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm index 21340e0be73e..f52144808455 100644 --- a/drivers/cpuidle/Kconfig.arm +++ b/drivers/cpuidle/Kconfig.arm | |||
@@ -4,6 +4,7 @@ | |||
4 | config ARM_CPUIDLE | 4 | config ARM_CPUIDLE |
5 | bool "Generic ARM/ARM64 CPU idle Driver" | 5 | bool "Generic ARM/ARM64 CPU idle Driver" |
6 | select DT_IDLE_STATES | 6 | select DT_IDLE_STATES |
7 | select CPU_IDLE_MULTIPLE_DRIVERS | ||
7 | help | 8 | help |
8 | Select this to enable generic cpuidle driver for ARM. | 9 | Select this to enable generic cpuidle driver for ARM. |
9 | It provides a generic idle driver whose idle states are configured | 10 | It provides a generic idle driver whose idle states are configured |
diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c index f440d385ed34..7080c384ad5d 100644 --- a/drivers/cpuidle/cpuidle-arm.c +++ b/drivers/cpuidle/cpuidle-arm.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/topology.h> | ||
21 | 22 | ||
22 | #include <asm/cpuidle.h> | 23 | #include <asm/cpuidle.h> |
23 | 24 | ||
@@ -44,7 +45,7 @@ static int arm_enter_idle_state(struct cpuidle_device *dev, | |||
44 | return CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, idx); | 45 | return CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, idx); |
45 | } | 46 | } |
46 | 47 | ||
47 | static struct cpuidle_driver arm_idle_driver = { | 48 | static struct cpuidle_driver arm_idle_driver __initdata = { |
48 | .name = "arm_idle", | 49 | .name = "arm_idle", |
49 | .owner = THIS_MODULE, | 50 | .owner = THIS_MODULE, |
50 | /* | 51 | /* |
@@ -80,30 +81,42 @@ static const struct of_device_id arm_idle_state_match[] __initconst = { | |||
80 | static int __init arm_idle_init(void) | 81 | static int __init arm_idle_init(void) |
81 | { | 82 | { |
82 | int cpu, ret; | 83 | int cpu, ret; |
83 | struct cpuidle_driver *drv = &arm_idle_driver; | 84 | struct cpuidle_driver *drv; |
84 | struct cpuidle_device *dev; | 85 | struct cpuidle_device *dev; |
85 | 86 | ||
86 | /* | ||
87 | * Initialize idle states data, starting at index 1. | ||
88 | * This driver is DT only, if no DT idle states are detected (ret == 0) | ||
89 | * let the driver initialization fail accordingly since there is no | ||
90 | * reason to initialize the idle driver if only wfi is supported. | ||
91 | */ | ||
92 | ret = dt_init_idle_driver(drv, arm_idle_state_match, 1); | ||
93 | if (ret <= 0) | ||
94 | return ret ? : -ENODEV; | ||
95 | |||
96 | ret = cpuidle_register_driver(drv); | ||
97 | if (ret) { | ||
98 | pr_err("Failed to register cpuidle driver\n"); | ||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * Call arch CPU operations in order to initialize | ||
104 | * idle states suspend back-end specific data | ||
105 | */ | ||
106 | for_each_possible_cpu(cpu) { | 87 | for_each_possible_cpu(cpu) { |
88 | |||
89 | drv = kmemdup(&arm_idle_driver, sizeof(*drv), GFP_KERNEL); | ||
90 | if (!drv) { | ||
91 | ret = -ENOMEM; | ||
92 | goto out_fail; | ||
93 | } | ||
94 | |||
95 | drv->cpumask = (struct cpumask *)cpumask_of(cpu); | ||
96 | |||
97 | /* | ||
98 | * Initialize idle states data, starting at index 1. This | ||
99 | * driver is DT only, if no DT idle states are detected (ret | ||
100 | * == 0) let the driver initialization fail accordingly since | ||
101 | * there is no reason to initialize the idle driver if only | ||
102 | * wfi is supported. | ||
103 | */ | ||
104 | ret = dt_init_idle_driver(drv, arm_idle_state_match, 1); | ||
105 | if (ret <= 0) { | ||
106 | ret = ret ? : -ENODEV; | ||
107 | goto out_fail; | ||
108 | } | ||
109 | |||
110 | ret = cpuidle_register_driver(drv); | ||
111 | if (ret) { | ||
112 | pr_err("Failed to register cpuidle driver\n"); | ||
113 | goto out_fail; | ||
114 | } | ||
115 | |||
116 | /* | ||
117 | * Call arch CPU operations in order to initialize | ||
118 | * idle states suspend back-end specific data | ||
119 | */ | ||
107 | ret = arm_cpuidle_init(cpu); | 120 | ret = arm_cpuidle_init(cpu); |
108 | 121 | ||
109 | /* | 122 | /* |
@@ -141,10 +154,11 @@ out_fail: | |||
141 | dev = per_cpu(cpuidle_devices, cpu); | 154 | dev = per_cpu(cpuidle_devices, cpu); |
142 | cpuidle_unregister_device(dev); | 155 | cpuidle_unregister_device(dev); |
143 | kfree(dev); | 156 | kfree(dev); |
157 | drv = cpuidle_get_driver(); | ||
158 | cpuidle_unregister_driver(drv); | ||
159 | kfree(drv); | ||
144 | } | 160 | } |
145 | 161 | ||
146 | cpuidle_unregister_driver(drv); | ||
147 | |||
148 | return ret; | 162 | return ret; |
149 | } | 163 | } |
150 | device_initcall(arm_idle_init); | 164 | device_initcall(arm_idle_init); |
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index b2330fd69e34..61b64c2b2cb8 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
@@ -286,6 +286,8 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
286 | struct device *device = get_cpu_device(dev->cpu); | 286 | struct device *device = get_cpu_device(dev->cpu); |
287 | int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); | 287 | int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); |
288 | int i; | 288 | int i; |
289 | int first_idx; | ||
290 | int idx; | ||
289 | unsigned int interactivity_req; | 291 | unsigned int interactivity_req; |
290 | unsigned int expected_interval; | 292 | unsigned int expected_interval; |
291 | unsigned long nr_iowaiters, cpu_load; | 293 | unsigned long nr_iowaiters, cpu_load; |
@@ -335,11 +337,11 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
335 | if (data->next_timer_us > polling_threshold && | 337 | if (data->next_timer_us > polling_threshold && |
336 | latency_req > s->exit_latency && !s->disabled && | 338 | latency_req > s->exit_latency && !s->disabled && |
337 | !dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable) | 339 | !dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable) |
338 | data->last_state_idx = CPUIDLE_DRIVER_STATE_START; | 340 | first_idx = CPUIDLE_DRIVER_STATE_START; |
339 | else | 341 | else |
340 | data->last_state_idx = CPUIDLE_DRIVER_STATE_START - 1; | 342 | first_idx = CPUIDLE_DRIVER_STATE_START - 1; |
341 | } else { | 343 | } else { |
342 | data->last_state_idx = CPUIDLE_DRIVER_STATE_START; | 344 | first_idx = 0; |
343 | } | 345 | } |
344 | 346 | ||
345 | /* | 347 | /* |
@@ -359,20 +361,28 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) | |||
359 | * Find the idle state with the lowest power while satisfying | 361 | * Find the idle state with the lowest power while satisfying |
360 | * our constraints. | 362 | * our constraints. |
361 | */ | 363 | */ |
362 | for (i = data->last_state_idx + 1; i < drv->state_count; i++) { | 364 | idx = -1; |
365 | for (i = first_idx; i < drv->state_count; i++) { | ||
363 | struct cpuidle_state *s = &drv->states[i]; | 366 | struct cpuidle_state *s = &drv->states[i]; |
364 | struct cpuidle_state_usage *su = &dev->states_usage[i]; | 367 | struct cpuidle_state_usage *su = &dev->states_usage[i]; |
365 | 368 | ||
366 | if (s->disabled || su->disable) | 369 | if (s->disabled || su->disable) |
367 | continue; | 370 | continue; |
371 | if (idx == -1) | ||
372 | idx = i; /* first enabled state */ | ||
368 | if (s->target_residency > data->predicted_us) | 373 | if (s->target_residency > data->predicted_us) |
369 | break; | 374 | break; |
370 | if (s->exit_latency > latency_req) | 375 | if (s->exit_latency > latency_req) |
371 | break; | 376 | break; |
372 | 377 | ||
373 | data->last_state_idx = i; | 378 | idx = i; |
374 | } | 379 | } |
375 | 380 | ||
381 | if (idx == -1) | ||
382 | idx = 0; /* No states enabled. Must use 0. */ | ||
383 | |||
384 | data->last_state_idx = idx; | ||
385 | |||
376 | return data->last_state_idx; | 386 | return data->last_state_idx; |
377 | } | 387 | } |
378 | 388 | ||
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 216d7ec88c0c..c2ae819a871c 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -51,6 +51,8 @@ | |||
51 | /* un-comment DEBUG to enable pr_debug() statements */ | 51 | /* un-comment DEBUG to enable pr_debug() statements */ |
52 | #define DEBUG | 52 | #define DEBUG |
53 | 53 | ||
54 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
55 | |||
54 | #include <linux/kernel.h> | 56 | #include <linux/kernel.h> |
55 | #include <linux/cpuidle.h> | 57 | #include <linux/cpuidle.h> |
56 | #include <linux/tick.h> | 58 | #include <linux/tick.h> |
@@ -65,7 +67,6 @@ | |||
65 | #include <asm/msr.h> | 67 | #include <asm/msr.h> |
66 | 68 | ||
67 | #define INTEL_IDLE_VERSION "0.4.1" | 69 | #define INTEL_IDLE_VERSION "0.4.1" |
68 | #define PREFIX "intel_idle: " | ||
69 | 70 | ||
70 | static struct cpuidle_driver intel_idle_driver = { | 71 | static struct cpuidle_driver intel_idle_driver = { |
71 | .name = "intel_idle", | 72 | .name = "intel_idle", |
@@ -1111,7 +1112,7 @@ static int __init intel_idle_probe(void) | |||
1111 | const struct x86_cpu_id *id; | 1112 | const struct x86_cpu_id *id; |
1112 | 1113 | ||
1113 | if (max_cstate == 0) { | 1114 | if (max_cstate == 0) { |
1114 | pr_debug(PREFIX "disabled\n"); | 1115 | pr_debug("disabled\n"); |
1115 | return -EPERM; | 1116 | return -EPERM; |
1116 | } | 1117 | } |
1117 | 1118 | ||
@@ -1119,8 +1120,8 @@ static int __init intel_idle_probe(void) | |||
1119 | if (!id) { | 1120 | if (!id) { |
1120 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | 1121 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && |
1121 | boot_cpu_data.x86 == 6) | 1122 | boot_cpu_data.x86 == 6) |
1122 | pr_debug(PREFIX "does not run on family %d model %d\n", | 1123 | pr_debug("does not run on family %d model %d\n", |
1123 | boot_cpu_data.x86, boot_cpu_data.x86_model); | 1124 | boot_cpu_data.x86, boot_cpu_data.x86_model); |
1124 | return -ENODEV; | 1125 | return -ENODEV; |
1125 | } | 1126 | } |
1126 | 1127 | ||
@@ -1134,13 +1135,13 @@ static int __init intel_idle_probe(void) | |||
1134 | !mwait_substates) | 1135 | !mwait_substates) |
1135 | return -ENODEV; | 1136 | return -ENODEV; |
1136 | 1137 | ||
1137 | pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); | 1138 | pr_debug("MWAIT substates: 0x%x\n", mwait_substates); |
1138 | 1139 | ||
1139 | icpu = (const struct idle_cpu *)id->driver_data; | 1140 | icpu = (const struct idle_cpu *)id->driver_data; |
1140 | cpuidle_state_table = icpu->state_table; | 1141 | cpuidle_state_table = icpu->state_table; |
1141 | 1142 | ||
1142 | pr_debug(PREFIX "v" INTEL_IDLE_VERSION | 1143 | pr_debug("v" INTEL_IDLE_VERSION " model 0x%X\n", |
1143 | " model 0x%X\n", boot_cpu_data.x86_model); | 1144 | boot_cpu_data.x86_model); |
1144 | 1145 | ||
1145 | return 0; | 1146 | return 0; |
1146 | } | 1147 | } |
@@ -1340,8 +1341,7 @@ static void __init intel_idle_cpuidle_driver_init(void) | |||
1340 | break; | 1341 | break; |
1341 | 1342 | ||
1342 | if (cstate + 1 > max_cstate) { | 1343 | if (cstate + 1 > max_cstate) { |
1343 | printk(PREFIX "max_cstate %d reached\n", | 1344 | pr_info("max_cstate %d reached\n", max_cstate); |
1344 | max_cstate); | ||
1345 | break; | 1345 | break; |
1346 | } | 1346 | } |
1347 | 1347 | ||
@@ -1358,8 +1358,8 @@ static void __init intel_idle_cpuidle_driver_init(void) | |||
1358 | 1358 | ||
1359 | /* if state marked as disabled, skip it */ | 1359 | /* if state marked as disabled, skip it */ |
1360 | if (cpuidle_state_table[cstate].disabled != 0) { | 1360 | if (cpuidle_state_table[cstate].disabled != 0) { |
1361 | pr_debug(PREFIX "state %s is disabled", | 1361 | pr_debug("state %s is disabled\n", |
1362 | cpuidle_state_table[cstate].name); | 1362 | cpuidle_state_table[cstate].name); |
1363 | continue; | 1363 | continue; |
1364 | } | 1364 | } |
1365 | 1365 | ||
@@ -1395,7 +1395,7 @@ static int intel_idle_cpu_init(unsigned int cpu) | |||
1395 | dev->cpu = cpu; | 1395 | dev->cpu = cpu; |
1396 | 1396 | ||
1397 | if (cpuidle_register_device(dev)) { | 1397 | if (cpuidle_register_device(dev)) { |
1398 | pr_debug(PREFIX "cpuidle_register_device %d failed!\n", cpu); | 1398 | pr_debug("cpuidle_register_device %d failed!\n", cpu); |
1399 | return -EIO; | 1399 | return -EIO; |
1400 | } | 1400 | } |
1401 | 1401 | ||
@@ -1447,8 +1447,8 @@ static int __init intel_idle_init(void) | |||
1447 | retval = cpuidle_register_driver(&intel_idle_driver); | 1447 | retval = cpuidle_register_driver(&intel_idle_driver); |
1448 | if (retval) { | 1448 | if (retval) { |
1449 | struct cpuidle_driver *drv = cpuidle_get_driver(); | 1449 | struct cpuidle_driver *drv = cpuidle_get_driver(); |
1450 | printk(KERN_DEBUG PREFIX "intel_idle yielding to %s", | 1450 | printk(KERN_DEBUG pr_fmt("intel_idle yielding to %s\n"), |
1451 | drv ? drv->name : "none"); | 1451 | drv ? drv->name : "none"); |
1452 | goto init_driver_fail; | 1452 | goto init_driver_fail; |
1453 | } | 1453 | } |
1454 | 1454 | ||
@@ -1460,8 +1460,8 @@ static int __init intel_idle_init(void) | |||
1460 | if (retval < 0) | 1460 | if (retval < 0) |
1461 | goto hp_setup_fail; | 1461 | goto hp_setup_fail; |
1462 | 1462 | ||
1463 | pr_debug(PREFIX "lapic_timer_reliable_states 0x%x\n", | 1463 | pr_debug("lapic_timer_reliable_states 0x%x\n", |
1464 | lapic_timer_reliable_states); | 1464 | lapic_timer_reliable_states); |
1465 | 1465 | ||
1466 | return 0; | 1466 | return 0; |
1467 | 1467 | ||
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 47070cff508c..e70c1c7ba1bf 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -394,29 +394,26 @@ bool pciehp_is_native(struct pci_dev *pdev) | |||
394 | 394 | ||
395 | /** | 395 | /** |
396 | * pci_acpi_wake_bus - Root bus wakeup notification fork function. | 396 | * pci_acpi_wake_bus - Root bus wakeup notification fork function. |
397 | * @work: Work item to handle. | 397 | * @context: Device wakeup context. |
398 | */ | 398 | */ |
399 | static void pci_acpi_wake_bus(struct work_struct *work) | 399 | static void pci_acpi_wake_bus(struct acpi_device_wakeup_context *context) |
400 | { | 400 | { |
401 | struct acpi_device *adev; | 401 | struct acpi_device *adev; |
402 | struct acpi_pci_root *root; | 402 | struct acpi_pci_root *root; |
403 | 403 | ||
404 | adev = container_of(work, struct acpi_device, wakeup.context.work); | 404 | adev = container_of(context, struct acpi_device, wakeup.context); |
405 | root = acpi_driver_data(adev); | 405 | root = acpi_driver_data(adev); |
406 | pci_pme_wakeup_bus(root->bus); | 406 | pci_pme_wakeup_bus(root->bus); |
407 | } | 407 | } |
408 | 408 | ||
409 | /** | 409 | /** |
410 | * pci_acpi_wake_dev - PCI device wakeup notification work function. | 410 | * pci_acpi_wake_dev - PCI device wakeup notification work function. |
411 | * @handle: ACPI handle of a device the notification is for. | 411 | * @context: Device wakeup context. |
412 | * @work: Work item to handle. | ||
413 | */ | 412 | */ |
414 | static void pci_acpi_wake_dev(struct work_struct *work) | 413 | static void pci_acpi_wake_dev(struct acpi_device_wakeup_context *context) |
415 | { | 414 | { |
416 | struct acpi_device_wakeup_context *context; | ||
417 | struct pci_dev *pci_dev; | 415 | struct pci_dev *pci_dev; |
418 | 416 | ||
419 | context = container_of(work, struct acpi_device_wakeup_context, work); | ||
420 | pci_dev = to_pci_dev(context->dev); | 417 | pci_dev = to_pci_dev(context->dev); |
421 | 418 | ||
422 | if (pci_dev->pme_poll) | 419 | if (pci_dev->pme_poll) |
@@ -424,7 +421,7 @@ static void pci_acpi_wake_dev(struct work_struct *work) | |||
424 | 421 | ||
425 | if (pci_dev->current_state == PCI_D3cold) { | 422 | if (pci_dev->current_state == PCI_D3cold) { |
426 | pci_wakeup_event(pci_dev); | 423 | pci_wakeup_event(pci_dev); |
427 | pm_runtime_resume(&pci_dev->dev); | 424 | pm_request_resume(&pci_dev->dev); |
428 | return; | 425 | return; |
429 | } | 426 | } |
430 | 427 | ||
@@ -433,7 +430,7 @@ static void pci_acpi_wake_dev(struct work_struct *work) | |||
433 | pci_check_pme_status(pci_dev); | 430 | pci_check_pme_status(pci_dev); |
434 | 431 | ||
435 | pci_wakeup_event(pci_dev); | 432 | pci_wakeup_event(pci_dev); |
436 | pm_runtime_resume(&pci_dev->dev); | 433 | pm_request_resume(&pci_dev->dev); |
437 | 434 | ||
438 | pci_pme_wakeup_bus(pci_dev->subordinate); | 435 | pci_pme_wakeup_bus(pci_dev->subordinate); |
439 | } | 436 | } |
@@ -572,67 +569,29 @@ static pci_power_t acpi_pci_get_power_state(struct pci_dev *dev) | |||
572 | return state_conv[state]; | 569 | return state_conv[state]; |
573 | } | 570 | } |
574 | 571 | ||
575 | static bool acpi_pci_can_wakeup(struct pci_dev *dev) | 572 | static int acpi_pci_propagate_wakeup(struct pci_bus *bus, bool enable) |
576 | { | ||
577 | struct acpi_device *adev = ACPI_COMPANION(&dev->dev); | ||
578 | return adev ? acpi_device_can_wakeup(adev) : false; | ||
579 | } | ||
580 | |||
581 | static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) | ||
582 | { | ||
583 | while (bus->parent) { | ||
584 | if (!acpi_pm_device_sleep_wake(&bus->self->dev, enable)) | ||
585 | return; | ||
586 | bus = bus->parent; | ||
587 | } | ||
588 | |||
589 | /* We have reached the root bus. */ | ||
590 | if (bus->bridge) | ||
591 | acpi_pm_device_sleep_wake(bus->bridge, enable); | ||
592 | } | ||
593 | |||
594 | static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) | ||
595 | { | ||
596 | if (acpi_pci_can_wakeup(dev)) | ||
597 | return acpi_pm_device_sleep_wake(&dev->dev, enable); | ||
598 | |||
599 | acpi_pci_propagate_wakeup_enable(dev->bus, enable); | ||
600 | return 0; | ||
601 | } | ||
602 | |||
603 | static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable) | ||
604 | { | 573 | { |
605 | while (bus->parent) { | 574 | while (bus->parent) { |
606 | struct pci_dev *bridge = bus->self; | 575 | if (acpi_pm_device_can_wakeup(&bus->self->dev)) |
576 | return acpi_pm_set_device_wakeup(&bus->self->dev, enable); | ||
607 | 577 | ||
608 | if (bridge->pme_interrupt) | ||
609 | return; | ||
610 | if (!acpi_pm_device_run_wake(&bridge->dev, enable)) | ||
611 | return; | ||
612 | bus = bus->parent; | 578 | bus = bus->parent; |
613 | } | 579 | } |
614 | 580 | ||
615 | /* We have reached the root bus. */ | 581 | /* We have reached the root bus. */ |
616 | if (bus->bridge) | 582 | if (bus->bridge) { |
617 | acpi_pm_device_run_wake(bus->bridge, enable); | 583 | if (acpi_pm_device_can_wakeup(bus->bridge)) |
584 | return acpi_pm_set_device_wakeup(bus->bridge, enable); | ||
585 | } | ||
586 | return 0; | ||
618 | } | 587 | } |
619 | 588 | ||
620 | static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) | 589 | static int acpi_pci_wakeup(struct pci_dev *dev, bool enable) |
621 | { | 590 | { |
622 | /* | 591 | if (acpi_pm_device_can_wakeup(&dev->dev)) |
623 | * Per PCI Express Base Specification Revision 2.0 section | 592 | return acpi_pm_set_device_wakeup(&dev->dev, enable); |
624 | * 5.3.3.2 Link Wakeup, platform support is needed for D3cold | ||
625 | * waking up to power on the main link even if there is PME | ||
626 | * support for D3cold | ||
627 | */ | ||
628 | if (dev->pme_interrupt && !dev->runtime_d3cold) | ||
629 | return 0; | ||
630 | |||
631 | if (!acpi_pm_device_run_wake(&dev->dev, enable)) | ||
632 | return 0; | ||
633 | 593 | ||
634 | acpi_pci_propagate_run_wake(dev->bus, enable); | 594 | return acpi_pci_propagate_wakeup(dev->bus, enable); |
635 | return 0; | ||
636 | } | 595 | } |
637 | 596 | ||
638 | static bool acpi_pci_need_resume(struct pci_dev *dev) | 597 | static bool acpi_pci_need_resume(struct pci_dev *dev) |
@@ -656,8 +615,7 @@ static const struct pci_platform_pm_ops acpi_pci_platform_pm = { | |||
656 | .set_state = acpi_pci_set_power_state, | 615 | .set_state = acpi_pci_set_power_state, |
657 | .get_state = acpi_pci_get_power_state, | 616 | .get_state = acpi_pci_get_power_state, |
658 | .choose_state = acpi_pci_choose_state, | 617 | .choose_state = acpi_pci_choose_state, |
659 | .sleep_wake = acpi_pci_sleep_wake, | 618 | .set_wakeup = acpi_pci_wakeup, |
660 | .run_wake = acpi_pci_run_wake, | ||
661 | .need_resume = acpi_pci_need_resume, | 619 | .need_resume = acpi_pci_need_resume, |
662 | }; | 620 | }; |
663 | 621 | ||
@@ -780,9 +738,7 @@ static void pci_acpi_setup(struct device *dev) | |||
780 | return; | 738 | return; |
781 | 739 | ||
782 | device_set_wakeup_capable(dev, true); | 740 | device_set_wakeup_capable(dev, true); |
783 | acpi_pci_sleep_wake(pci_dev, false); | 741 | acpi_pci_wakeup(pci_dev, false); |
784 | if (adev->wakeup.flags.run_wake) | ||
785 | device_set_run_wake(dev, true); | ||
786 | } | 742 | } |
787 | 743 | ||
788 | static void pci_acpi_cleanup(struct device *dev) | 744 | static void pci_acpi_cleanup(struct device *dev) |
@@ -793,10 +749,8 @@ static void pci_acpi_cleanup(struct device *dev) | |||
793 | return; | 749 | return; |
794 | 750 | ||
795 | pci_acpi_remove_pm_notifier(adev); | 751 | pci_acpi_remove_pm_notifier(adev); |
796 | if (adev->wakeup.flags.valid) { | 752 | if (adev->wakeup.flags.valid) |
797 | device_set_wakeup_capable(dev, false); | 753 | device_set_wakeup_capable(dev, false); |
798 | device_set_run_wake(dev, false); | ||
799 | } | ||
800 | } | 754 | } |
801 | 755 | ||
802 | static bool pci_acpi_bus_match(struct device *dev) | 756 | static bool pci_acpi_bus_match(struct device *dev) |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 00e10bf7f6a2..df4aead394f2 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -1219,7 +1219,7 @@ static int pci_pm_runtime_resume(struct device *dev) | |||
1219 | 1219 | ||
1220 | pci_restore_standard_config(pci_dev); | 1220 | pci_restore_standard_config(pci_dev); |
1221 | pci_fixup_device(pci_fixup_resume_early, pci_dev); | 1221 | pci_fixup_device(pci_fixup_resume_early, pci_dev); |
1222 | __pci_enable_wake(pci_dev, PCI_D0, true, false); | 1222 | pci_enable_wake(pci_dev, PCI_D0, false); |
1223 | pci_fixup_device(pci_fixup_resume, pci_dev); | 1223 | pci_fixup_device(pci_fixup_resume, pci_dev); |
1224 | 1224 | ||
1225 | rc = pm->runtime_resume(dev); | 1225 | rc = pm->runtime_resume(dev); |
diff --git a/drivers/pci/pci-mid.c b/drivers/pci/pci-mid.c index 1c4af7227bca..a4ac940c7696 100644 --- a/drivers/pci/pci-mid.c +++ b/drivers/pci/pci-mid.c | |||
@@ -39,12 +39,7 @@ static pci_power_t mid_pci_choose_state(struct pci_dev *pdev) | |||
39 | return PCI_D3hot; | 39 | return PCI_D3hot; |
40 | } | 40 | } |
41 | 41 | ||
42 | static int mid_pci_sleep_wake(struct pci_dev *dev, bool enable) | 42 | static int mid_pci_wakeup(struct pci_dev *dev, bool enable) |
43 | { | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | static int mid_pci_run_wake(struct pci_dev *dev, bool enable) | ||
48 | { | 43 | { |
49 | return 0; | 44 | return 0; |
50 | } | 45 | } |
@@ -59,8 +54,7 @@ static const struct pci_platform_pm_ops mid_pci_platform_pm = { | |||
59 | .set_state = mid_pci_set_power_state, | 54 | .set_state = mid_pci_set_power_state, |
60 | .get_state = mid_pci_get_power_state, | 55 | .get_state = mid_pci_get_power_state, |
61 | .choose_state = mid_pci_choose_state, | 56 | .choose_state = mid_pci_choose_state, |
62 | .sleep_wake = mid_pci_sleep_wake, | 57 | .set_wakeup = mid_pci_wakeup, |
63 | .run_wake = mid_pci_run_wake, | ||
64 | .need_resume = mid_pci_need_resume, | 58 | .need_resume = mid_pci_need_resume, |
65 | }; | 59 | }; |
66 | 60 | ||
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 563901cd9c06..0b5302a9fdae 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -574,8 +574,7 @@ static const struct pci_platform_pm_ops *pci_platform_pm; | |||
574 | int pci_set_platform_pm(const struct pci_platform_pm_ops *ops) | 574 | int pci_set_platform_pm(const struct pci_platform_pm_ops *ops) |
575 | { | 575 | { |
576 | if (!ops->is_manageable || !ops->set_state || !ops->get_state || | 576 | if (!ops->is_manageable || !ops->set_state || !ops->get_state || |
577 | !ops->choose_state || !ops->sleep_wake || !ops->run_wake || | 577 | !ops->choose_state || !ops->set_wakeup || !ops->need_resume) |
578 | !ops->need_resume) | ||
579 | return -EINVAL; | 578 | return -EINVAL; |
580 | pci_platform_pm = ops; | 579 | pci_platform_pm = ops; |
581 | return 0; | 580 | return 0; |
@@ -603,16 +602,10 @@ static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev) | |||
603 | pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR; | 602 | pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR; |
604 | } | 603 | } |
605 | 604 | ||
606 | static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) | 605 | static inline int platform_pci_set_wakeup(struct pci_dev *dev, bool enable) |
607 | { | 606 | { |
608 | return pci_platform_pm ? | 607 | return pci_platform_pm ? |
609 | pci_platform_pm->sleep_wake(dev, enable) : -ENODEV; | 608 | pci_platform_pm->set_wakeup(dev, enable) : -ENODEV; |
610 | } | ||
611 | |||
612 | static inline int platform_pci_run_wake(struct pci_dev *dev, bool enable) | ||
613 | { | ||
614 | return pci_platform_pm ? | ||
615 | pci_platform_pm->run_wake(dev, enable) : -ENODEV; | ||
616 | } | 609 | } |
617 | 610 | ||
618 | static inline bool platform_pci_need_resume(struct pci_dev *dev) | 611 | static inline bool platform_pci_need_resume(struct pci_dev *dev) |
@@ -1805,6 +1798,23 @@ static void __pci_pme_active(struct pci_dev *dev, bool enable) | |||
1805 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); | 1798 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); |
1806 | } | 1799 | } |
1807 | 1800 | ||
1801 | static void pci_pme_restore(struct pci_dev *dev) | ||
1802 | { | ||
1803 | u16 pmcsr; | ||
1804 | |||
1805 | if (!dev->pme_support) | ||
1806 | return; | ||
1807 | |||
1808 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); | ||
1809 | if (dev->wakeup_prepared) { | ||
1810 | pmcsr |= PCI_PM_CTRL_PME_ENABLE; | ||
1811 | } else { | ||
1812 | pmcsr &= ~PCI_PM_CTRL_PME_ENABLE; | ||
1813 | pmcsr |= PCI_PM_CTRL_PME_STATUS; | ||
1814 | } | ||
1815 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); | ||
1816 | } | ||
1817 | |||
1808 | /** | 1818 | /** |
1809 | * pci_pme_active - enable or disable PCI device's PME# function | 1819 | * pci_pme_active - enable or disable PCI device's PME# function |
1810 | * @dev: PCI device to handle. | 1820 | * @dev: PCI device to handle. |
@@ -1872,10 +1882,9 @@ void pci_pme_active(struct pci_dev *dev, bool enable) | |||
1872 | EXPORT_SYMBOL(pci_pme_active); | 1882 | EXPORT_SYMBOL(pci_pme_active); |
1873 | 1883 | ||
1874 | /** | 1884 | /** |
1875 | * __pci_enable_wake - enable PCI device as wakeup event source | 1885 | * pci_enable_wake - enable PCI device as wakeup event source |
1876 | * @dev: PCI device affected | 1886 | * @dev: PCI device affected |
1877 | * @state: PCI state from which device will issue wakeup events | 1887 | * @state: PCI state from which device will issue wakeup events |
1878 | * @runtime: True if the events are to be generated at run time | ||
1879 | * @enable: True to enable event generation; false to disable | 1888 | * @enable: True to enable event generation; false to disable |
1880 | * | 1889 | * |
1881 | * This enables the device as a wakeup event source, or disables it. | 1890 | * This enables the device as a wakeup event source, or disables it. |
@@ -1891,17 +1900,18 @@ EXPORT_SYMBOL(pci_pme_active); | |||
1891 | * Error code depending on the platform is returned if both the platform and | 1900 | * Error code depending on the platform is returned if both the platform and |
1892 | * the native mechanism fail to enable the generation of wake-up events | 1901 | * the native mechanism fail to enable the generation of wake-up events |
1893 | */ | 1902 | */ |
1894 | int __pci_enable_wake(struct pci_dev *dev, pci_power_t state, | 1903 | int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable) |
1895 | bool runtime, bool enable) | ||
1896 | { | 1904 | { |
1897 | int ret = 0; | 1905 | int ret = 0; |
1898 | 1906 | ||
1899 | if (enable && !runtime && !device_may_wakeup(&dev->dev)) | 1907 | /* |
1900 | return -EINVAL; | 1908 | * Don't do the same thing twice in a row for one device, but restore |
1901 | 1909 | * PME Enable in case it has been updated by config space restoration. | |
1902 | /* Don't do the same thing twice in a row for one device. */ | 1910 | */ |
1903 | if (!!enable == !!dev->wakeup_prepared) | 1911 | if (!!enable == !!dev->wakeup_prepared) { |
1912 | pci_pme_restore(dev); | ||
1904 | return 0; | 1913 | return 0; |
1914 | } | ||
1905 | 1915 | ||
1906 | /* | 1916 | /* |
1907 | * According to "PCI System Architecture" 4th ed. by Tom Shanley & Don | 1917 | * According to "PCI System Architecture" 4th ed. by Tom Shanley & Don |
@@ -1916,24 +1926,20 @@ int __pci_enable_wake(struct pci_dev *dev, pci_power_t state, | |||
1916 | pci_pme_active(dev, true); | 1926 | pci_pme_active(dev, true); |
1917 | else | 1927 | else |
1918 | ret = 1; | 1928 | ret = 1; |
1919 | error = runtime ? platform_pci_run_wake(dev, true) : | 1929 | error = platform_pci_set_wakeup(dev, true); |
1920 | platform_pci_sleep_wake(dev, true); | ||
1921 | if (ret) | 1930 | if (ret) |
1922 | ret = error; | 1931 | ret = error; |
1923 | if (!ret) | 1932 | if (!ret) |
1924 | dev->wakeup_prepared = true; | 1933 | dev->wakeup_prepared = true; |
1925 | } else { | 1934 | } else { |
1926 | if (runtime) | 1935 | platform_pci_set_wakeup(dev, false); |
1927 | platform_pci_run_wake(dev, false); | ||
1928 | else | ||
1929 | platform_pci_sleep_wake(dev, false); | ||
1930 | pci_pme_active(dev, false); | 1936 | pci_pme_active(dev, false); |
1931 | dev->wakeup_prepared = false; | 1937 | dev->wakeup_prepared = false; |
1932 | } | 1938 | } |
1933 | 1939 | ||
1934 | return ret; | 1940 | return ret; |
1935 | } | 1941 | } |
1936 | EXPORT_SYMBOL(__pci_enable_wake); | 1942 | EXPORT_SYMBOL(pci_enable_wake); |
1937 | 1943 | ||
1938 | /** | 1944 | /** |
1939 | * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold | 1945 | * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold |
@@ -2075,12 +2081,12 @@ int pci_finish_runtime_suspend(struct pci_dev *dev) | |||
2075 | 2081 | ||
2076 | dev->runtime_d3cold = target_state == PCI_D3cold; | 2082 | dev->runtime_d3cold = target_state == PCI_D3cold; |
2077 | 2083 | ||
2078 | __pci_enable_wake(dev, target_state, true, pci_dev_run_wake(dev)); | 2084 | pci_enable_wake(dev, target_state, pci_dev_run_wake(dev)); |
2079 | 2085 | ||
2080 | error = pci_set_power_state(dev, target_state); | 2086 | error = pci_set_power_state(dev, target_state); |
2081 | 2087 | ||
2082 | if (error) { | 2088 | if (error) { |
2083 | __pci_enable_wake(dev, target_state, true, false); | 2089 | pci_enable_wake(dev, target_state, false); |
2084 | dev->runtime_d3cold = false; | 2090 | dev->runtime_d3cold = false; |
2085 | } | 2091 | } |
2086 | 2092 | ||
@@ -2099,7 +2105,7 @@ bool pci_dev_run_wake(struct pci_dev *dev) | |||
2099 | { | 2105 | { |
2100 | struct pci_bus *bus = dev->bus; | 2106 | struct pci_bus *bus = dev->bus; |
2101 | 2107 | ||
2102 | if (device_run_wake(&dev->dev)) | 2108 | if (device_can_wakeup(&dev->dev)) |
2103 | return true; | 2109 | return true; |
2104 | 2110 | ||
2105 | if (!dev->pme_support) | 2111 | if (!dev->pme_support) |
@@ -2112,7 +2118,7 @@ bool pci_dev_run_wake(struct pci_dev *dev) | |||
2112 | while (bus->parent) { | 2118 | while (bus->parent) { |
2113 | struct pci_dev *bridge = bus->self; | 2119 | struct pci_dev *bridge = bus->self; |
2114 | 2120 | ||
2115 | if (device_run_wake(&bridge->dev)) | 2121 | if (device_can_wakeup(&bridge->dev)) |
2116 | return true; | 2122 | return true; |
2117 | 2123 | ||
2118 | bus = bus->parent; | 2124 | bus = bus->parent; |
@@ -2120,7 +2126,7 @@ bool pci_dev_run_wake(struct pci_dev *dev) | |||
2120 | 2126 | ||
2121 | /* We have reached the root bus. */ | 2127 | /* We have reached the root bus. */ |
2122 | if (bus->bridge) | 2128 | if (bus->bridge) |
2123 | return device_run_wake(bus->bridge); | 2129 | return device_can_wakeup(bus->bridge); |
2124 | 2130 | ||
2125 | return false; | 2131 | return false; |
2126 | } | 2132 | } |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index f8113e5b9812..240b2c0fed4b 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -47,11 +47,7 @@ int pci_probe_reset_function(struct pci_dev *dev); | |||
47 | * platform; to be used during system-wide transitions from a | 47 | * platform; to be used during system-wide transitions from a |
48 | * sleeping state to the working state and vice versa | 48 | * sleeping state to the working state and vice versa |
49 | * | 49 | * |
50 | * @sleep_wake: enables/disables the system wake up capability of given device | 50 | * @set_wakeup: enables/disables wakeup capability for the device |
51 | * | ||
52 | * @run_wake: enables/disables the platform to generate run-time wake-up events | ||
53 | * for given device (the device's wake-up capability has to be | ||
54 | * enabled by @sleep_wake for this feature to work) | ||
55 | * | 51 | * |
56 | * @need_resume: returns 'true' if the given device (which is currently | 52 | * @need_resume: returns 'true' if the given device (which is currently |
57 | * suspended) needs to be resumed to be configured for system | 53 | * suspended) needs to be resumed to be configured for system |
@@ -65,8 +61,7 @@ struct pci_platform_pm_ops { | |||
65 | int (*set_state)(struct pci_dev *dev, pci_power_t state); | 61 | int (*set_state)(struct pci_dev *dev, pci_power_t state); |
66 | pci_power_t (*get_state)(struct pci_dev *dev); | 62 | pci_power_t (*get_state)(struct pci_dev *dev); |
67 | pci_power_t (*choose_state)(struct pci_dev *dev); | 63 | pci_power_t (*choose_state)(struct pci_dev *dev); |
68 | int (*sleep_wake)(struct pci_dev *dev, bool enable); | 64 | int (*set_wakeup)(struct pci_dev *dev, bool enable); |
69 | int (*run_wake)(struct pci_dev *dev, bool enable); | ||
70 | bool (*need_resume)(struct pci_dev *dev); | 65 | bool (*need_resume)(struct pci_dev *dev); |
71 | }; | 66 | }; |
72 | 67 | ||
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index 2dd1c68e6de8..80e58d25006d 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c | |||
@@ -294,31 +294,29 @@ static irqreturn_t pcie_pme_irq(int irq, void *context) | |||
294 | } | 294 | } |
295 | 295 | ||
296 | /** | 296 | /** |
297 | * pcie_pme_set_native - Set the PME interrupt flag for given device. | 297 | * pcie_pme_can_wakeup - Set the wakeup capability flag. |
298 | * @dev: PCI device to handle. | 298 | * @dev: PCI device to handle. |
299 | * @ign: Ignored. | 299 | * @ign: Ignored. |
300 | */ | 300 | */ |
301 | static int pcie_pme_set_native(struct pci_dev *dev, void *ign) | 301 | static int pcie_pme_can_wakeup(struct pci_dev *dev, void *ign) |
302 | { | 302 | { |
303 | device_set_run_wake(&dev->dev, true); | 303 | device_set_wakeup_capable(&dev->dev, true); |
304 | dev->pme_interrupt = true; | ||
305 | return 0; | 304 | return 0; |
306 | } | 305 | } |
307 | 306 | ||
308 | /** | 307 | /** |
309 | * pcie_pme_mark_devices - Set the PME interrupt flag for devices below a port. | 308 | * pcie_pme_mark_devices - Set the wakeup flag for devices below a port. |
310 | * @port: PCIe root port or event collector to handle. | 309 | * @port: PCIe root port or event collector to handle. |
311 | * | 310 | * |
312 | * For each device below given root port, including the port itself (or for each | 311 | * For each device below given root port, including the port itself (or for each |
313 | * root complex integrated endpoint if @port is a root complex event collector) | 312 | * root complex integrated endpoint if @port is a root complex event collector) |
314 | * set the flag indicating that it can signal run-time wake-up events via PCIe | 313 | * set the flag indicating that it can signal run-time wake-up events. |
315 | * PME interrupts. | ||
316 | */ | 314 | */ |
317 | static void pcie_pme_mark_devices(struct pci_dev *port) | 315 | static void pcie_pme_mark_devices(struct pci_dev *port) |
318 | { | 316 | { |
319 | pcie_pme_set_native(port, NULL); | 317 | pcie_pme_can_wakeup(port, NULL); |
320 | if (port->subordinate) | 318 | if (port->subordinate) |
321 | pci_walk_bus(port->subordinate, pcie_pme_set_native, NULL); | 319 | pci_walk_bus(port->subordinate, pcie_pme_can_wakeup, NULL); |
322 | } | 320 | } |
323 | 321 | ||
324 | /** | 322 | /** |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 8489020ecf44..a3ccc3c795a5 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -794,6 +794,25 @@ config INTEL_CHT_INT33FE | |||
794 | This driver instantiates i2c-clients for these, so that standard | 794 | This driver instantiates i2c-clients for these, so that standard |
795 | i2c drivers for these chips can bind to the them. | 795 | i2c drivers for these chips can bind to the them. |
796 | 796 | ||
797 | config INTEL_INT0002_VGPIO | ||
798 | tristate "Intel ACPI INT0002 Virtual GPIO driver" | ||
799 | depends on GPIOLIB && ACPI | ||
800 | select GPIOLIB_IRQCHIP | ||
801 | ---help--- | ||
802 | Some peripherals on Bay Trail and Cherry Trail platforms signal a | ||
803 | Power Management Event (PME) to the Power Management Controller (PMC) | ||
804 | to wakeup the system. When this happens software needs to explicitly | ||
805 | clear the PME bus 0 status bit in the GPE0a_STS register to avoid an | ||
806 | IRQ storm on IRQ 9. | ||
807 | |||
808 | This is modelled in ACPI through the INT0002 ACPI device, which is | ||
809 | called a "Virtual GPIO controller" in ACPI because it defines the | ||
810 | event handler to call when the PME triggers through _AEI and _L02 | ||
811 | methods as would be done for a real GPIO interrupt in ACPI. | ||
812 | |||
813 | To compile this driver as a module, choose M here: the module will | ||
814 | be called intel_int0002_vgpio. | ||
815 | |||
797 | config INTEL_HID_EVENT | 816 | config INTEL_HID_EVENT |
798 | tristate "INTEL HID Event" | 817 | tristate "INTEL HID Event" |
799 | depends on ACPI | 818 | depends on ACPI |
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 182a3ed6605a..ab22ce77fb66 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile | |||
@@ -46,6 +46,7 @@ obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o | |||
46 | obj-$(CONFIG_TOSHIBA_HAPS) += toshiba_haps.o | 46 | obj-$(CONFIG_TOSHIBA_HAPS) += toshiba_haps.o |
47 | obj-$(CONFIG_TOSHIBA_WMI) += toshiba-wmi.o | 47 | obj-$(CONFIG_TOSHIBA_WMI) += toshiba-wmi.o |
48 | obj-$(CONFIG_INTEL_CHT_INT33FE) += intel_cht_int33fe.o | 48 | obj-$(CONFIG_INTEL_CHT_INT33FE) += intel_cht_int33fe.o |
49 | obj-$(CONFIG_INTEL_INT0002_VGPIO) += intel_int0002_vgpio.o | ||
49 | obj-$(CONFIG_INTEL_HID_EVENT) += intel-hid.o | 50 | obj-$(CONFIG_INTEL_HID_EVENT) += intel-hid.o |
50 | obj-$(CONFIG_INTEL_VBTN) += intel-vbtn.o | 51 | obj-$(CONFIG_INTEL_VBTN) += intel-vbtn.o |
51 | obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o | 52 | obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o |
diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c index 63ba2cbd04c2..8519e0f97bdd 100644 --- a/drivers/platform/x86/intel-hid.c +++ b/drivers/platform/x86/intel-hid.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/input/sparse-keymap.h> | 24 | #include <linux/input/sparse-keymap.h> |
25 | #include <linux/acpi.h> | 25 | #include <linux/acpi.h> |
26 | #include <linux/suspend.h> | ||
26 | #include <acpi/acpi_bus.h> | 27 | #include <acpi/acpi_bus.h> |
27 | 28 | ||
28 | MODULE_LICENSE("GPL"); | 29 | MODULE_LICENSE("GPL"); |
@@ -75,6 +76,7 @@ static const struct key_entry intel_array_keymap[] = { | |||
75 | struct intel_hid_priv { | 76 | struct intel_hid_priv { |
76 | struct input_dev *input_dev; | 77 | struct input_dev *input_dev; |
77 | struct input_dev *array; | 78 | struct input_dev *array; |
79 | bool wakeup_mode; | ||
78 | }; | 80 | }; |
79 | 81 | ||
80 | static int intel_hid_set_enable(struct device *device, bool enable) | 82 | static int intel_hid_set_enable(struct device *device, bool enable) |
@@ -116,23 +118,37 @@ static void intel_button_array_enable(struct device *device, bool enable) | |||
116 | dev_warn(device, "failed to set button capability\n"); | 118 | dev_warn(device, "failed to set button capability\n"); |
117 | } | 119 | } |
118 | 120 | ||
119 | static int intel_hid_pl_suspend_handler(struct device *device) | 121 | static int intel_hid_pm_prepare(struct device *device) |
120 | { | 122 | { |
121 | intel_hid_set_enable(device, false); | 123 | struct intel_hid_priv *priv = dev_get_drvdata(device); |
122 | intel_button_array_enable(device, false); | 124 | |
125 | priv->wakeup_mode = true; | ||
126 | return 0; | ||
127 | } | ||
123 | 128 | ||
129 | static int intel_hid_pl_suspend_handler(struct device *device) | ||
130 | { | ||
131 | if (pm_suspend_via_firmware()) { | ||
132 | intel_hid_set_enable(device, false); | ||
133 | intel_button_array_enable(device, false); | ||
134 | } | ||
124 | return 0; | 135 | return 0; |
125 | } | 136 | } |
126 | 137 | ||
127 | static int intel_hid_pl_resume_handler(struct device *device) | 138 | static int intel_hid_pl_resume_handler(struct device *device) |
128 | { | 139 | { |
129 | intel_hid_set_enable(device, true); | 140 | struct intel_hid_priv *priv = dev_get_drvdata(device); |
130 | intel_button_array_enable(device, true); | ||
131 | 141 | ||
142 | priv->wakeup_mode = false; | ||
143 | if (pm_resume_via_firmware()) { | ||
144 | intel_hid_set_enable(device, true); | ||
145 | intel_button_array_enable(device, true); | ||
146 | } | ||
132 | return 0; | 147 | return 0; |
133 | } | 148 | } |
134 | 149 | ||
135 | static const struct dev_pm_ops intel_hid_pl_pm_ops = { | 150 | static const struct dev_pm_ops intel_hid_pl_pm_ops = { |
151 | .prepare = intel_hid_pm_prepare, | ||
136 | .freeze = intel_hid_pl_suspend_handler, | 152 | .freeze = intel_hid_pl_suspend_handler, |
137 | .thaw = intel_hid_pl_resume_handler, | 153 | .thaw = intel_hid_pl_resume_handler, |
138 | .restore = intel_hid_pl_resume_handler, | 154 | .restore = intel_hid_pl_resume_handler, |
@@ -186,6 +202,19 @@ static void notify_handler(acpi_handle handle, u32 event, void *context) | |||
186 | unsigned long long ev_index; | 202 | unsigned long long ev_index; |
187 | acpi_status status; | 203 | acpi_status status; |
188 | 204 | ||
205 | if (priv->wakeup_mode) { | ||
206 | /* Wake up on 5-button array events only. */ | ||
207 | if (event == 0xc0 || !priv->array) | ||
208 | return; | ||
209 | |||
210 | if (sparse_keymap_entry_from_scancode(priv->array, event)) | ||
211 | pm_wakeup_hard_event(&device->dev); | ||
212 | else | ||
213 | dev_info(&device->dev, "unknown event 0x%x\n", event); | ||
214 | |||
215 | return; | ||
216 | } | ||
217 | |||
189 | /* 0xC0 is for HID events, other values are for 5 button array */ | 218 | /* 0xC0 is for HID events, other values are for 5 button array */ |
190 | if (event != 0xc0) { | 219 | if (event != 0xc0) { |
191 | if (!priv->array || | 220 | if (!priv->array || |
@@ -270,6 +299,7 @@ static int intel_hid_probe(struct platform_device *device) | |||
270 | "failed to enable HID power button\n"); | 299 | "failed to enable HID power button\n"); |
271 | } | 300 | } |
272 | 301 | ||
302 | device_init_wakeup(&device->dev, true); | ||
273 | return 0; | 303 | return 0; |
274 | 304 | ||
275 | err_remove_notify: | 305 | err_remove_notify: |
diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c index c2035e121ac2..61f106377661 100644 --- a/drivers/platform/x86/intel-vbtn.c +++ b/drivers/platform/x86/intel-vbtn.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/input/sparse-keymap.h> | 24 | #include <linux/input/sparse-keymap.h> |
25 | #include <linux/acpi.h> | 25 | #include <linux/acpi.h> |
26 | #include <linux/suspend.h> | ||
26 | #include <acpi/acpi_bus.h> | 27 | #include <acpi/acpi_bus.h> |
27 | 28 | ||
28 | MODULE_LICENSE("GPL"); | 29 | MODULE_LICENSE("GPL"); |
@@ -46,6 +47,7 @@ static const struct key_entry intel_vbtn_keymap[] = { | |||
46 | 47 | ||
47 | struct intel_vbtn_priv { | 48 | struct intel_vbtn_priv { |
48 | struct input_dev *input_dev; | 49 | struct input_dev *input_dev; |
50 | bool wakeup_mode; | ||
49 | }; | 51 | }; |
50 | 52 | ||
51 | static int intel_vbtn_input_setup(struct platform_device *device) | 53 | static int intel_vbtn_input_setup(struct platform_device *device) |
@@ -73,9 +75,15 @@ static void notify_handler(acpi_handle handle, u32 event, void *context) | |||
73 | struct platform_device *device = context; | 75 | struct platform_device *device = context; |
74 | struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev); | 76 | struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev); |
75 | 77 | ||
76 | if (!sparse_keymap_report_event(priv->input_dev, event, 1, true)) | 78 | if (priv->wakeup_mode) { |
77 | dev_info(&device->dev, "unknown event index 0x%x\n", | 79 | if (sparse_keymap_entry_from_scancode(priv->input_dev, event)) { |
78 | event); | 80 | pm_wakeup_hard_event(&device->dev); |
81 | return; | ||
82 | } | ||
83 | } else if (sparse_keymap_report_event(priv->input_dev, event, 1, true)) { | ||
84 | return; | ||
85 | } | ||
86 | dev_info(&device->dev, "unknown event index 0x%x\n", event); | ||
79 | } | 87 | } |
80 | 88 | ||
81 | static int intel_vbtn_probe(struct platform_device *device) | 89 | static int intel_vbtn_probe(struct platform_device *device) |
@@ -109,6 +117,7 @@ static int intel_vbtn_probe(struct platform_device *device) | |||
109 | if (ACPI_FAILURE(status)) | 117 | if (ACPI_FAILURE(status)) |
110 | return -EBUSY; | 118 | return -EBUSY; |
111 | 119 | ||
120 | device_init_wakeup(&device->dev, true); | ||
112 | return 0; | 121 | return 0; |
113 | } | 122 | } |
114 | 123 | ||
@@ -125,10 +134,34 @@ static int intel_vbtn_remove(struct platform_device *device) | |||
125 | return 0; | 134 | return 0; |
126 | } | 135 | } |
127 | 136 | ||
137 | static int intel_vbtn_pm_prepare(struct device *dev) | ||
138 | { | ||
139 | struct intel_vbtn_priv *priv = dev_get_drvdata(dev); | ||
140 | |||
141 | priv->wakeup_mode = true; | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int intel_vbtn_pm_resume(struct device *dev) | ||
146 | { | ||
147 | struct intel_vbtn_priv *priv = dev_get_drvdata(dev); | ||
148 | |||
149 | priv->wakeup_mode = false; | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static const struct dev_pm_ops intel_vbtn_pm_ops = { | ||
154 | .prepare = intel_vbtn_pm_prepare, | ||
155 | .resume = intel_vbtn_pm_resume, | ||
156 | .restore = intel_vbtn_pm_resume, | ||
157 | .thaw = intel_vbtn_pm_resume, | ||
158 | }; | ||
159 | |||
128 | static struct platform_driver intel_vbtn_pl_driver = { | 160 | static struct platform_driver intel_vbtn_pl_driver = { |
129 | .driver = { | 161 | .driver = { |
130 | .name = "intel-vbtn", | 162 | .name = "intel-vbtn", |
131 | .acpi_match_table = intel_vbtn_ids, | 163 | .acpi_match_table = intel_vbtn_ids, |
164 | .pm = &intel_vbtn_pm_ops, | ||
132 | }, | 165 | }, |
133 | .probe = intel_vbtn_probe, | 166 | .probe = intel_vbtn_probe, |
134 | .remove = intel_vbtn_remove, | 167 | .remove = intel_vbtn_remove, |
diff --git a/drivers/platform/x86/intel_int0002_vgpio.c b/drivers/platform/x86/intel_int0002_vgpio.c new file mode 100644 index 000000000000..92dc230ef5b2 --- /dev/null +++ b/drivers/platform/x86/intel_int0002_vgpio.c | |||
@@ -0,0 +1,219 @@ | |||
1 | /* | ||
2 | * Intel INT0002 "Virtual GPIO" driver | ||
3 | * | ||
4 | * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com> | ||
5 | * | ||
6 | * Loosely based on android x86 kernel code which is: | ||
7 | * | ||
8 | * Copyright (c) 2014, Intel Corporation. | ||
9 | * | ||
10 | * Author: Dyut Kumar Sil <dyut.k.sil@intel.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | * | ||
16 | * Some peripherals on Bay Trail and Cherry Trail platforms signal a Power | ||
17 | * Management Event (PME) to the Power Management Controller (PMC) to wakeup | ||
18 | * the system. When this happens software needs to clear the PME bus 0 status | ||
19 | * bit in the GPE0a_STS register to avoid an IRQ storm on IRQ 9. | ||
20 | * | ||
21 | * This is modelled in ACPI through the INT0002 ACPI device, which is | ||
22 | * called a "Virtual GPIO controller" in ACPI because it defines the event | ||
23 | * handler to call when the PME triggers through _AEI and _L02 / _E02 | ||
24 | * methods as would be done for a real GPIO interrupt in ACPI. Note this | ||
25 | * is a hack to define an AML event handler for the PME while using existing | ||
26 | * ACPI mechanisms, this is not a real GPIO at all. | ||
27 | * | ||
28 | * This driver will bind to the INT0002 device, and register as a GPIO | ||
29 | * controller, letting gpiolib-acpi.c call the _L02 handler as it would | ||
30 | * for a real GPIO controller. | ||
31 | */ | ||
32 | |||
33 | #include <linux/acpi.h> | ||
34 | #include <linux/bitmap.h> | ||
35 | #include <linux/gpio/driver.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | #include <linux/io.h> | ||
38 | #include <linux/kernel.h> | ||
39 | #include <linux/module.h> | ||
40 | #include <linux/platform_device.h> | ||
41 | #include <linux/slab.h> | ||
42 | #include <linux/suspend.h> | ||
43 | |||
44 | #include <asm/cpu_device_id.h> | ||
45 | #include <asm/intel-family.h> | ||
46 | |||
47 | #define DRV_NAME "INT0002 Virtual GPIO" | ||
48 | |||
49 | /* For some reason the virtual GPIO pin tied to the GPE is numbered pin 2 */ | ||
50 | #define GPE0A_PME_B0_VIRT_GPIO_PIN 2 | ||
51 | |||
52 | #define GPE0A_PME_B0_STS_BIT BIT(13) | ||
53 | #define GPE0A_PME_B0_EN_BIT BIT(13) | ||
54 | #define GPE0A_STS_PORT 0x420 | ||
55 | #define GPE0A_EN_PORT 0x428 | ||
56 | |||
57 | #define ICPU(model) { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, } | ||
58 | |||
59 | static const struct x86_cpu_id int0002_cpu_ids[] = { | ||
60 | /* | ||
61 | * Limit ourselves to Cherry Trail for now, until testing shows we | ||
62 | * need to handle the INT0002 device on Baytrail too. | ||
63 | * ICPU(INTEL_FAM6_ATOM_SILVERMONT1), * Valleyview, Bay Trail * | ||
64 | */ | ||
65 | ICPU(INTEL_FAM6_ATOM_AIRMONT), /* Braswell, Cherry Trail */ | ||
66 | {} | ||
67 | }; | ||
68 | |||
69 | /* | ||
70 | * As this is not a real GPIO at all, but just a hack to model an event in | ||
71 | * ACPI the get / set functions are dummy functions. | ||
72 | */ | ||
73 | |||
74 | static int int0002_gpio_get(struct gpio_chip *chip, unsigned int offset) | ||
75 | { | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static void int0002_gpio_set(struct gpio_chip *chip, unsigned int offset, | ||
80 | int value) | ||
81 | { | ||
82 | } | ||
83 | |||
84 | static int int0002_gpio_direction_output(struct gpio_chip *chip, | ||
85 | unsigned int offset, int value) | ||
86 | { | ||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static void int0002_irq_ack(struct irq_data *data) | ||
91 | { | ||
92 | outl(GPE0A_PME_B0_STS_BIT, GPE0A_STS_PORT); | ||
93 | } | ||
94 | |||
95 | static void int0002_irq_unmask(struct irq_data *data) | ||
96 | { | ||
97 | u32 gpe_en_reg; | ||
98 | |||
99 | gpe_en_reg = inl(GPE0A_EN_PORT); | ||
100 | gpe_en_reg |= GPE0A_PME_B0_EN_BIT; | ||
101 | outl(gpe_en_reg, GPE0A_EN_PORT); | ||
102 | } | ||
103 | |||
104 | static void int0002_irq_mask(struct irq_data *data) | ||
105 | { | ||
106 | u32 gpe_en_reg; | ||
107 | |||
108 | gpe_en_reg = inl(GPE0A_EN_PORT); | ||
109 | gpe_en_reg &= ~GPE0A_PME_B0_EN_BIT; | ||
110 | outl(gpe_en_reg, GPE0A_EN_PORT); | ||
111 | } | ||
112 | |||
113 | static irqreturn_t int0002_irq(int irq, void *data) | ||
114 | { | ||
115 | struct gpio_chip *chip = data; | ||
116 | u32 gpe_sts_reg; | ||
117 | |||
118 | gpe_sts_reg = inl(GPE0A_STS_PORT); | ||
119 | if (!(gpe_sts_reg & GPE0A_PME_B0_STS_BIT)) | ||
120 | return IRQ_NONE; | ||
121 | |||
122 | generic_handle_irq(irq_find_mapping(chip->irqdomain, | ||
123 | GPE0A_PME_B0_VIRT_GPIO_PIN)); | ||
124 | |||
125 | pm_system_wakeup(); | ||
126 | |||
127 | return IRQ_HANDLED; | ||
128 | } | ||
129 | |||
130 | static struct irq_chip int0002_irqchip = { | ||
131 | .name = DRV_NAME, | ||
132 | .irq_ack = int0002_irq_ack, | ||
133 | .irq_mask = int0002_irq_mask, | ||
134 | .irq_unmask = int0002_irq_unmask, | ||
135 | }; | ||
136 | |||
137 | static int int0002_probe(struct platform_device *pdev) | ||
138 | { | ||
139 | struct device *dev = &pdev->dev; | ||
140 | const struct x86_cpu_id *cpu_id; | ||
141 | struct gpio_chip *chip; | ||
142 | int irq, ret; | ||
143 | |||
144 | /* Menlow has a different INT0002 device? <sigh> */ | ||
145 | cpu_id = x86_match_cpu(int0002_cpu_ids); | ||
146 | if (!cpu_id) | ||
147 | return -ENODEV; | ||
148 | |||
149 | irq = platform_get_irq(pdev, 0); | ||
150 | if (irq < 0) { | ||
151 | dev_err(dev, "Error getting IRQ: %d\n", irq); | ||
152 | return irq; | ||
153 | } | ||
154 | |||
155 | chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); | ||
156 | if (!chip) | ||
157 | return -ENOMEM; | ||
158 | |||
159 | chip->label = DRV_NAME; | ||
160 | chip->parent = dev; | ||
161 | chip->owner = THIS_MODULE; | ||
162 | chip->get = int0002_gpio_get; | ||
163 | chip->set = int0002_gpio_set; | ||
164 | chip->direction_input = int0002_gpio_get; | ||
165 | chip->direction_output = int0002_gpio_direction_output; | ||
166 | chip->base = -1; | ||
167 | chip->ngpio = GPE0A_PME_B0_VIRT_GPIO_PIN + 1; | ||
168 | chip->irq_need_valid_mask = true; | ||
169 | |||
170 | ret = devm_gpiochip_add_data(&pdev->dev, chip, NULL); | ||
171 | if (ret) { | ||
172 | dev_err(dev, "Error adding gpio chip: %d\n", ret); | ||
173 | return ret; | ||
174 | } | ||
175 | |||
176 | bitmap_clear(chip->irq_valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN); | ||
177 | |||
178 | /* | ||
179 | * We manually request the irq here instead of passing a flow-handler | ||
180 | * to gpiochip_set_chained_irqchip, because the irq is shared. | ||
181 | */ | ||
182 | ret = devm_request_irq(dev, irq, int0002_irq, | ||
183 | IRQF_SHARED | IRQF_NO_THREAD, "INT0002", chip); | ||
184 | if (ret) { | ||
185 | dev_err(dev, "Error requesting IRQ %d: %d\n", irq, ret); | ||
186 | return ret; | ||
187 | } | ||
188 | |||
189 | ret = gpiochip_irqchip_add(chip, &int0002_irqchip, 0, handle_edge_irq, | ||
190 | IRQ_TYPE_NONE); | ||
191 | if (ret) { | ||
192 | dev_err(dev, "Error adding irqchip: %d\n", ret); | ||
193 | return ret; | ||
194 | } | ||
195 | |||
196 | gpiochip_set_chained_irqchip(chip, &int0002_irqchip, irq, NULL); | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | static const struct acpi_device_id int0002_acpi_ids[] = { | ||
202 | { "INT0002", 0 }, | ||
203 | { }, | ||
204 | }; | ||
205 | MODULE_DEVICE_TABLE(acpi, int0002_acpi_ids); | ||
206 | |||
207 | static struct platform_driver int0002_driver = { | ||
208 | .driver = { | ||
209 | .name = DRV_NAME, | ||
210 | .acpi_match_table = int0002_acpi_ids, | ||
211 | }, | ||
212 | .probe = int0002_probe, | ||
213 | }; | ||
214 | |||
215 | module_platform_driver(int0002_driver); | ||
216 | |||
217 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | ||
218 | MODULE_DESCRIPTION("Intel INT0002 Virtual GPIO driver"); | ||
219 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 9113876487ed..3a4c1aa0201e 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -149,8 +149,8 @@ static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) | |||
149 | } | 149 | } |
150 | 150 | ||
151 | if (device_can_wakeup(&dev->dev)) { | 151 | if (device_can_wakeup(&dev->dev)) { |
152 | error = acpi_pm_device_sleep_wake(&dev->dev, | 152 | error = acpi_pm_set_device_wakeup(&dev->dev, |
153 | device_may_wakeup(&dev->dev)); | 153 | device_may_wakeup(&dev->dev)); |
154 | if (error) | 154 | if (error) |
155 | return error; | 155 | return error; |
156 | } | 156 | } |
@@ -185,7 +185,7 @@ static int pnpacpi_resume(struct pnp_dev *dev) | |||
185 | } | 185 | } |
186 | 186 | ||
187 | if (device_may_wakeup(&dev->dev)) | 187 | if (device_may_wakeup(&dev->dev)) |
188 | acpi_pm_device_sleep_wake(&dev->dev, false); | 188 | acpi_pm_set_device_wakeup(&dev->dev, false); |
189 | 189 | ||
190 | if (acpi_device_power_manageable(acpi_dev)) | 190 | if (acpi_device_power_manageable(acpi_dev)) |
191 | error = acpi_device_set_power(acpi_dev, ACPI_STATE_D0); | 191 | error = acpi_device_set_power(acpi_dev, ACPI_STATE_D0); |
diff --git a/drivers/power/avs/rockchip-io-domain.c b/drivers/power/avs/rockchip-io-domain.c index 85812521b6ba..031a34372191 100644 --- a/drivers/power/avs/rockchip-io-domain.c +++ b/drivers/power/avs/rockchip-io-domain.c | |||
@@ -253,6 +253,16 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3188 = { | |||
253 | }, | 253 | }, |
254 | }; | 254 | }; |
255 | 255 | ||
256 | static const struct rockchip_iodomain_soc_data soc_data_rk3228 = { | ||
257 | .grf_offset = 0x418, | ||
258 | .supply_names = { | ||
259 | "vccio1", | ||
260 | "vccio2", | ||
261 | "vccio3", | ||
262 | "vccio4", | ||
263 | }, | ||
264 | }; | ||
265 | |||
256 | static const struct rockchip_iodomain_soc_data soc_data_rk3288 = { | 266 | static const struct rockchip_iodomain_soc_data soc_data_rk3288 = { |
257 | .grf_offset = 0x380, | 267 | .grf_offset = 0x380, |
258 | .supply_names = { | 268 | .supply_names = { |
@@ -345,6 +355,10 @@ static const struct of_device_id rockchip_iodomain_match[] = { | |||
345 | .data = (void *)&soc_data_rk3188 | 355 | .data = (void *)&soc_data_rk3188 |
346 | }, | 356 | }, |
347 | { | 357 | { |
358 | .compatible = "rockchip,rk3228-io-voltage-domain", | ||
359 | .data = (void *)&soc_data_rk3228 | ||
360 | }, | ||
361 | { | ||
348 | .compatible = "rockchip,rk3288-io-voltage-domain", | 362 | .compatible = "rockchip,rk3288-io-voltage-domain", |
349 | .data = (void *)&soc_data_rk3288 | 363 | .data = (void *)&soc_data_rk3288 |
350 | }, | 364 | }, |
diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index 9ddad0815ba9..d1694f1def72 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c | |||
@@ -874,7 +874,9 @@ static int rapl_write_data_raw(struct rapl_domain *rd, | |||
874 | 874 | ||
875 | cpu = rd->rp->lead_cpu; | 875 | cpu = rd->rp->lead_cpu; |
876 | bits = rapl_unit_xlate(rd, rp->unit, value, 1); | 876 | bits = rapl_unit_xlate(rd, rp->unit, value, 1); |
877 | bits |= bits << rp->shift; | 877 | bits <<= rp->shift; |
878 | bits &= rp->mask; | ||
879 | |||
878 | memset(&ma, 0, sizeof(ma)); | 880 | memset(&ma, 0, sizeof(ma)); |
879 | 881 | ||
880 | ma.msr_no = rd->msrs[rp->id]; | 882 | ma.msr_no = rd->msrs[rp->id]; |
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 7859d738df41..ea829ad798c0 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
@@ -584,12 +584,7 @@ static int hcd_pci_suspend_noirq(struct device *dev) | |||
584 | 584 | ||
585 | static int hcd_pci_resume_noirq(struct device *dev) | 585 | static int hcd_pci_resume_noirq(struct device *dev) |
586 | { | 586 | { |
587 | struct pci_dev *pci_dev = to_pci_dev(dev); | 587 | powermac_set_asic(to_pci_dev(dev), 1); |
588 | |||
589 | powermac_set_asic(pci_dev, 1); | ||
590 | |||
591 | /* Go back to D0 and disable remote wakeup */ | ||
592 | pci_back_from_sleep(pci_dev); | ||
593 | return 0; | 588 | return 0; |
594 | } | 589 | } |
595 | 590 | ||
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index fe851544d7fb..7e995df7a797 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c | |||
@@ -230,7 +230,6 @@ static int dwc3_pci_probe(struct pci_dev *pci, | |||
230 | } | 230 | } |
231 | 231 | ||
232 | device_init_wakeup(dev, true); | 232 | device_init_wakeup(dev, true); |
233 | device_set_run_wake(dev, true); | ||
234 | pci_set_drvdata(pci, dwc); | 233 | pci_set_drvdata(pci, dwc); |
235 | pm_runtime_put(dev); | 234 | pm_runtime_put(dev); |
236 | 235 | ||
@@ -310,7 +309,7 @@ static int dwc3_pci_runtime_suspend(struct device *dev) | |||
310 | { | 309 | { |
311 | struct dwc3_pci *dwc = dev_get_drvdata(dev); | 310 | struct dwc3_pci *dwc = dev_get_drvdata(dev); |
312 | 311 | ||
313 | if (device_run_wake(dev)) | 312 | if (device_can_wakeup(dev)) |
314 | return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D3); | 313 | return dwc3_pci_dsm(dwc, PCI_INTEL_BXT_STATE_D3); |
315 | 314 | ||
316 | return -EBUSY; | 315 | return -EBUSY; |
diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c index 02260cfdedb1..49effdc0d857 100644 --- a/drivers/usb/host/uhci-pci.c +++ b/drivers/usb/host/uhci-pci.c | |||
@@ -131,7 +131,7 @@ static int uhci_pci_init(struct usb_hcd *hcd) | |||
131 | 131 | ||
132 | /* Intel controllers use non-PME wakeup signalling */ | 132 | /* Intel controllers use non-PME wakeup signalling */ |
133 | if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_INTEL) | 133 | if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_INTEL) |
134 | device_set_run_wake(uhci_dev(uhci), 1); | 134 | device_set_wakeup_capable(uhci_dev(uhci), true); |
135 | 135 | ||
136 | /* Set up pointers to PCI-specific functions */ | 136 | /* Set up pointers to PCI-specific functions */ |
137 | uhci->reset_hc = uhci_pci_reset_hc; | 137 | uhci->reset_hc = uhci_pci_reset_hc; |