diff options
| -rw-r--r-- | drivers/base/power/domain.c | 20 | ||||
| -rw-r--r-- | drivers/base/power/domain_governor.c | 1 | ||||
| -rw-r--r-- | drivers/base/power/main.c | 21 | ||||
| -rw-r--r-- | drivers/base/power/power.h | 1 | ||||
| -rw-r--r-- | drivers/base/power/qos.c | 2 | ||||
| -rw-r--r-- | drivers/base/power/runtime.c | 16 | ||||
| -rw-r--r-- | drivers/base/power/sysfs.c | 12 | ||||
| -rw-r--r-- | drivers/base/power/trace.c | 2 | ||||
| -rw-r--r-- | drivers/base/power/wakeup.c | 30 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 24 | ||||
| -rw-r--r-- | drivers/cpufreq/intel_pstate.c | 2 | ||||
| -rw-r--r-- | drivers/cpufreq/pxa2xx-cpufreq.c | 4 | ||||
| -rw-r--r-- | drivers/cpuidle/governor.c | 1 | ||||
| -rw-r--r-- | drivers/cpuidle/governors/menu.c | 2 | ||||
| -rw-r--r-- | drivers/opp/core.c | 2 | ||||
| -rw-r--r-- | drivers/opp/of.c | 16 | ||||
| -rw-r--r-- | include/linux/pm.h | 1 | ||||
| -rw-r--r-- | include/linux/pm_wakeup.h | 9 | ||||
| -rw-r--r-- | tools/power/cpupower/lib/cpufreq.c | 19 | ||||
| -rw-r--r-- | tools/power/cpupower/lib/cpufreq.h | 16 | ||||
| -rw-r--r-- | tools/power/cpupower/utils/cpufreq-info.c | 42 |
21 files changed, 131 insertions, 112 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 2c334c01fc43..76c9969b7124 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
| @@ -6,6 +6,8 @@ | |||
| 6 | * This file is released under the GPLv2. | 6 | * This file is released under the GPLv2. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #define pr_fmt(fmt) "PM: " fmt | ||
| 10 | |||
| 9 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
| 10 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
| 11 | #include <linux/io.h> | 13 | #include <linux/io.h> |
| @@ -457,19 +459,19 @@ static int _genpd_power_off(struct generic_pm_domain *genpd, bool timed) | |||
| 457 | 459 | ||
| 458 | time_start = ktime_get(); | 460 | time_start = ktime_get(); |
| 459 | ret = genpd->power_off(genpd); | 461 | ret = genpd->power_off(genpd); |
| 460 | if (ret == -EBUSY) | 462 | if (ret) |
| 461 | return ret; | 463 | return ret; |
| 462 | 464 | ||
| 463 | elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start)); | 465 | elapsed_ns = ktime_to_ns(ktime_sub(ktime_get(), time_start)); |
| 464 | if (elapsed_ns <= genpd->states[state_idx].power_off_latency_ns) | 466 | if (elapsed_ns <= genpd->states[state_idx].power_off_latency_ns) |
| 465 | return ret; | 467 | return 0; |
| 466 | 468 | ||
| 467 | genpd->states[state_idx].power_off_latency_ns = elapsed_ns; | 469 | genpd->states[state_idx].power_off_latency_ns = elapsed_ns; |
| 468 | genpd->max_off_time_changed = true; | 470 | genpd->max_off_time_changed = true; |
| 469 | pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n", | 471 | pr_debug("%s: Power-%s latency exceeded, new value %lld ns\n", |
| 470 | genpd->name, "off", elapsed_ns); | 472 | genpd->name, "off", elapsed_ns); |
| 471 | 473 | ||
| 472 | return ret; | 474 | return 0; |
| 473 | } | 475 | } |
| 474 | 476 | ||
| 475 | /** | 477 | /** |
| @@ -1657,8 +1659,8 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, | |||
| 1657 | genpd_lock_nested(genpd, SINGLE_DEPTH_NESTING); | 1659 | genpd_lock_nested(genpd, SINGLE_DEPTH_NESTING); |
| 1658 | 1660 | ||
| 1659 | if (!list_empty(&subdomain->master_links) || subdomain->device_count) { | 1661 | if (!list_empty(&subdomain->master_links) || subdomain->device_count) { |
| 1660 | pr_warn("%s: unable to remove subdomain %s\n", genpd->name, | 1662 | pr_warn("%s: unable to remove subdomain %s\n", |
| 1661 | subdomain->name); | 1663 | genpd->name, subdomain->name); |
| 1662 | ret = -EBUSY; | 1664 | ret = -EBUSY; |
| 1663 | goto out; | 1665 | goto out; |
| 1664 | } | 1666 | } |
| @@ -1766,8 +1768,8 @@ int pm_genpd_init(struct generic_pm_domain *genpd, | |||
| 1766 | ret = genpd_set_default_power_state(genpd); | 1768 | ret = genpd_set_default_power_state(genpd); |
| 1767 | if (ret) | 1769 | if (ret) |
| 1768 | return ret; | 1770 | return ret; |
| 1769 | } else if (!gov) { | 1771 | } else if (!gov && genpd->state_count > 1) { |
| 1770 | pr_warn("%s : no governor for states\n", genpd->name); | 1772 | pr_warn("%s: no governor for states\n", genpd->name); |
| 1771 | } | 1773 | } |
| 1772 | 1774 | ||
| 1773 | device_initialize(&genpd->dev); | 1775 | device_initialize(&genpd->dev); |
| @@ -2514,7 +2516,7 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state, | |||
| 2514 | &entry_latency); | 2516 | &entry_latency); |
| 2515 | if (err) { | 2517 | if (err) { |
| 2516 | pr_debug(" * %pOF missing entry-latency-us property\n", | 2518 | pr_debug(" * %pOF missing entry-latency-us property\n", |
| 2517 | state_node); | 2519 | state_node); |
| 2518 | return -EINVAL; | 2520 | return -EINVAL; |
| 2519 | } | 2521 | } |
| 2520 | 2522 | ||
| @@ -2522,7 +2524,7 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state, | |||
| 2522 | &exit_latency); | 2524 | &exit_latency); |
| 2523 | if (err) { | 2525 | if (err) { |
| 2524 | pr_debug(" * %pOF missing exit-latency-us property\n", | 2526 | pr_debug(" * %pOF missing exit-latency-us property\n", |
| 2525 | state_node); | 2527 | state_node); |
| 2526 | return -EINVAL; | 2528 | return -EINVAL; |
| 2527 | } | 2529 | } |
| 2528 | 2530 | ||
diff --git a/drivers/base/power/domain_governor.c b/drivers/base/power/domain_governor.c index 99896fbf18e4..4d07e38a8247 100644 --- a/drivers/base/power/domain_governor.c +++ b/drivers/base/power/domain_governor.c | |||
| @@ -128,7 +128,6 @@ static bool __default_power_down_ok(struct dev_pm_domain *pd, | |||
| 128 | off_on_time_ns = genpd->states[state].power_off_latency_ns + | 128 | off_on_time_ns = genpd->states[state].power_off_latency_ns + |
| 129 | genpd->states[state].power_on_latency_ns; | 129 | genpd->states[state].power_on_latency_ns; |
| 130 | 130 | ||
| 131 | |||
| 132 | min_off_time_ns = -1; | 131 | min_off_time_ns = -1; |
| 133 | /* | 132 | /* |
| 134 | * Check if subdomains can be off for enough time. | 133 | * Check if subdomains can be off for enough time. |
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 5a8149829ab3..f80d298de3fa 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | * subsystem list maintains. | 17 | * subsystem list maintains. |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #define pr_fmt(fmt) "PM: " fmt | ||
| 21 | |||
| 20 | #include <linux/device.h> | 22 | #include <linux/device.h> |
| 21 | #include <linux/export.h> | 23 | #include <linux/export.h> |
| 22 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
| @@ -128,7 +130,7 @@ void device_pm_add(struct device *dev) | |||
| 128 | if (device_pm_not_required(dev)) | 130 | if (device_pm_not_required(dev)) |
| 129 | return; | 131 | return; |
| 130 | 132 | ||
| 131 | pr_debug("PM: Adding info for %s:%s\n", | 133 | pr_debug("Adding info for %s:%s\n", |
| 132 | dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); | 134 | dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); |
| 133 | device_pm_check_callbacks(dev); | 135 | device_pm_check_callbacks(dev); |
| 134 | mutex_lock(&dpm_list_mtx); | 136 | mutex_lock(&dpm_list_mtx); |
| @@ -149,7 +151,7 @@ void device_pm_remove(struct device *dev) | |||
| 149 | if (device_pm_not_required(dev)) | 151 | if (device_pm_not_required(dev)) |
| 150 | return; | 152 | return; |
| 151 | 153 | ||
| 152 | pr_debug("PM: Removing info for %s:%s\n", | 154 | pr_debug("Removing info for %s:%s\n", |
| 153 | dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); | 155 | dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); |
| 154 | complete_all(&dev->power.completion); | 156 | complete_all(&dev->power.completion); |
| 155 | mutex_lock(&dpm_list_mtx); | 157 | mutex_lock(&dpm_list_mtx); |
| @@ -168,7 +170,7 @@ void device_pm_remove(struct device *dev) | |||
| 168 | */ | 170 | */ |
| 169 | void device_pm_move_before(struct device *deva, struct device *devb) | 171 | void device_pm_move_before(struct device *deva, struct device *devb) |
| 170 | { | 172 | { |
| 171 | pr_debug("PM: Moving %s:%s before %s:%s\n", | 173 | pr_debug("Moving %s:%s before %s:%s\n", |
| 172 | deva->bus ? deva->bus->name : "No Bus", dev_name(deva), | 174 | deva->bus ? deva->bus->name : "No Bus", dev_name(deva), |
| 173 | devb->bus ? devb->bus->name : "No Bus", dev_name(devb)); | 175 | devb->bus ? devb->bus->name : "No Bus", dev_name(devb)); |
| 174 | /* Delete deva from dpm_list and reinsert before devb. */ | 176 | /* Delete deva from dpm_list and reinsert before devb. */ |
| @@ -182,7 +184,7 @@ void device_pm_move_before(struct device *deva, struct device *devb) | |||
| 182 | */ | 184 | */ |
| 183 | void device_pm_move_after(struct device *deva, struct device *devb) | 185 | void device_pm_move_after(struct device *deva, struct device *devb) |
| 184 | { | 186 | { |
| 185 | pr_debug("PM: Moving %s:%s after %s:%s\n", | 187 | pr_debug("Moving %s:%s after %s:%s\n", |
| 186 | deva->bus ? deva->bus->name : "No Bus", dev_name(deva), | 188 | deva->bus ? deva->bus->name : "No Bus", dev_name(deva), |
| 187 | devb->bus ? devb->bus->name : "No Bus", dev_name(devb)); | 189 | devb->bus ? devb->bus->name : "No Bus", dev_name(devb)); |
| 188 | /* Delete deva from dpm_list and reinsert after devb. */ | 190 | /* Delete deva from dpm_list and reinsert after devb. */ |
| @@ -195,7 +197,7 @@ void device_pm_move_after(struct device *deva, struct device *devb) | |||
| 195 | */ | 197 | */ |
| 196 | void device_pm_move_last(struct device *dev) | 198 | void device_pm_move_last(struct device *dev) |
| 197 | { | 199 | { |
| 198 | pr_debug("PM: Moving %s:%s to end of list\n", | 200 | pr_debug("Moving %s:%s to end of list\n", |
| 199 | dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); | 201 | dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); |
| 200 | list_move_tail(&dev->power.entry, &dpm_list); | 202 | list_move_tail(&dev->power.entry, &dpm_list); |
| 201 | } | 203 | } |
| @@ -418,8 +420,8 @@ static void pm_dev_dbg(struct device *dev, pm_message_t state, const char *info) | |||
| 418 | static void pm_dev_err(struct device *dev, pm_message_t state, const char *info, | 420 | static void pm_dev_err(struct device *dev, pm_message_t state, const char *info, |
| 419 | int error) | 421 | int error) |
| 420 | { | 422 | { |
| 421 | printk(KERN_ERR "PM: Device %s failed to %s%s: error %d\n", | 423 | pr_err("Device %s failed to %s%s: error %d\n", |
| 422 | dev_name(dev), pm_verb(state.event), info, error); | 424 | dev_name(dev), pm_verb(state.event), info, error); |
| 423 | } | 425 | } |
| 424 | 426 | ||
| 425 | static void dpm_show_time(ktime_t starttime, pm_message_t state, int error, | 427 | static void dpm_show_time(ktime_t starttime, pm_message_t state, int error, |
| @@ -2022,8 +2024,7 @@ int dpm_prepare(pm_message_t state) | |||
| 2022 | error = 0; | 2024 | error = 0; |
| 2023 | continue; | 2025 | continue; |
| 2024 | } | 2026 | } |
| 2025 | printk(KERN_INFO "PM: Device %s not prepared " | 2027 | pr_info("Device %s not prepared for power transition: code %d\n", |
| 2026 | "for power transition: code %d\n", | ||
| 2027 | dev_name(dev), error); | 2028 | dev_name(dev), error); |
| 2028 | put_device(dev); | 2029 | put_device(dev); |
| 2029 | break; | 2030 | break; |
| @@ -2062,7 +2063,7 @@ EXPORT_SYMBOL_GPL(dpm_suspend_start); | |||
| 2062 | void __suspend_report_result(const char *function, void *fn, int ret) | 2063 | void __suspend_report_result(const char *function, void *fn, int ret) |
| 2063 | { | 2064 | { |
| 2064 | if (ret) | 2065 | if (ret) |
| 2065 | printk(KERN_ERR "%s(): %pF returns %d\n", function, fn, ret); | 2066 | pr_err("%s(): %pF returns %d\n", function, fn, ret); |
| 2066 | } | 2067 | } |
| 2067 | EXPORT_SYMBOL_GPL(__suspend_report_result); | 2068 | EXPORT_SYMBOL_GPL(__suspend_report_result); |
| 2068 | 2069 | ||
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index c511def48b48..ec33fbdb919b 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h | |||
| @@ -21,6 +21,7 @@ static inline void pm_runtime_early_init(struct device *dev) | |||
| 21 | extern void pm_runtime_init(struct device *dev); | 21 | extern void pm_runtime_init(struct device *dev); |
| 22 | extern void pm_runtime_reinit(struct device *dev); | 22 | extern void pm_runtime_reinit(struct device *dev); |
| 23 | extern void pm_runtime_remove(struct device *dev); | 23 | extern void pm_runtime_remove(struct device *dev); |
| 24 | extern u64 pm_runtime_active_time(struct device *dev); | ||
| 24 | 25 | ||
| 25 | #define WAKE_IRQ_DEDICATED_ALLOCATED BIT(0) | 26 | #define WAKE_IRQ_DEDICATED_ALLOCATED BIT(0) |
| 26 | #define WAKE_IRQ_DEDICATED_MANAGED BIT(1) | 27 | #define WAKE_IRQ_DEDICATED_MANAGED BIT(1) |
diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 3382542b39b7..f80e402ef778 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | * per-device constraint data struct. | 22 | * per-device constraint data struct. |
| 23 | * | 23 | * |
| 24 | * Note about the per-device constraint data struct allocation: | 24 | * Note about the per-device constraint data struct allocation: |
| 25 | * . The per-device constraints data struct ptr is tored into the device | 25 | * . The per-device constraints data struct ptr is stored into the device |
| 26 | * dev_pm_info. | 26 | * dev_pm_info. |
| 27 | * . To minimize the data usage by the per-device constraints, the data struct | 27 | * . To minimize the data usage by the per-device constraints, the data struct |
| 28 | * is only allocated at the first call to dev_pm_qos_add_request. | 28 | * is only allocated at the first call to dev_pm_qos_add_request. |
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index a80dbf08a99c..977db40378b0 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
| @@ -64,7 +64,7 @@ static int rpm_suspend(struct device *dev, int rpmflags); | |||
| 64 | * runtime_status field is updated, to account the time in the old state | 64 | * runtime_status field is updated, to account the time in the old state |
| 65 | * correctly. | 65 | * correctly. |
| 66 | */ | 66 | */ |
| 67 | void update_pm_runtime_accounting(struct device *dev) | 67 | static void update_pm_runtime_accounting(struct device *dev) |
| 68 | { | 68 | { |
| 69 | u64 now, last, delta; | 69 | u64 now, last, delta; |
| 70 | 70 | ||
| @@ -98,7 +98,7 @@ static void __update_runtime_status(struct device *dev, enum rpm_status status) | |||
| 98 | dev->power.runtime_status = status; | 98 | dev->power.runtime_status = status; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | u64 pm_runtime_suspended_time(struct device *dev) | 101 | static u64 rpm_get_accounted_time(struct device *dev, bool suspended) |
| 102 | { | 102 | { |
| 103 | u64 time; | 103 | u64 time; |
| 104 | unsigned long flags; | 104 | unsigned long flags; |
| @@ -106,12 +106,22 @@ u64 pm_runtime_suspended_time(struct device *dev) | |||
| 106 | spin_lock_irqsave(&dev->power.lock, flags); | 106 | spin_lock_irqsave(&dev->power.lock, flags); |
| 107 | 107 | ||
| 108 | update_pm_runtime_accounting(dev); | 108 | update_pm_runtime_accounting(dev); |
| 109 | time = dev->power.suspended_time; | 109 | time = suspended ? dev->power.suspended_time : dev->power.active_time; |
| 110 | 110 | ||
| 111 | spin_unlock_irqrestore(&dev->power.lock, flags); | 111 | spin_unlock_irqrestore(&dev->power.lock, flags); |
| 112 | 112 | ||
| 113 | return time; | 113 | return time; |
| 114 | } | 114 | } |
| 115 | |||
| 116 | u64 pm_runtime_active_time(struct device *dev) | ||
| 117 | { | ||
| 118 | return rpm_get_accounted_time(dev, false); | ||
| 119 | } | ||
| 120 | |||
| 121 | u64 pm_runtime_suspended_time(struct device *dev) | ||
| 122 | { | ||
| 123 | return rpm_get_accounted_time(dev, true); | ||
| 124 | } | ||
| 115 | EXPORT_SYMBOL_GPL(pm_runtime_suspended_time); | 125 | EXPORT_SYMBOL_GPL(pm_runtime_suspended_time); |
| 116 | 126 | ||
| 117 | /** | 127 | /** |
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index c6bf76124184..1226e441ddfe 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c | |||
| @@ -125,13 +125,9 @@ static ssize_t runtime_active_time_show(struct device *dev, | |||
| 125 | struct device_attribute *attr, char *buf) | 125 | struct device_attribute *attr, char *buf) |
| 126 | { | 126 | { |
| 127 | int ret; | 127 | int ret; |
| 128 | u64 tmp; | 128 | u64 tmp = pm_runtime_active_time(dev); |
| 129 | spin_lock_irq(&dev->power.lock); | ||
| 130 | update_pm_runtime_accounting(dev); | ||
| 131 | tmp = dev->power.active_time; | ||
| 132 | do_div(tmp, NSEC_PER_MSEC); | 129 | do_div(tmp, NSEC_PER_MSEC); |
| 133 | ret = sprintf(buf, "%llu\n", tmp); | 130 | ret = sprintf(buf, "%llu\n", tmp); |
| 134 | spin_unlock_irq(&dev->power.lock); | ||
| 135 | return ret; | 131 | return ret; |
| 136 | } | 132 | } |
| 137 | 133 | ||
| @@ -141,13 +137,9 @@ static ssize_t runtime_suspended_time_show(struct device *dev, | |||
| 141 | struct device_attribute *attr, char *buf) | 137 | struct device_attribute *attr, char *buf) |
| 142 | { | 138 | { |
| 143 | int ret; | 139 | int ret; |
| 144 | u64 tmp; | 140 | u64 tmp = pm_runtime_suspended_time(dev); |
| 145 | spin_lock_irq(&dev->power.lock); | ||
| 146 | update_pm_runtime_accounting(dev); | ||
| 147 | tmp = dev->power.suspended_time; | ||
| 148 | do_div(tmp, NSEC_PER_MSEC); | 141 | do_div(tmp, NSEC_PER_MSEC); |
| 149 | ret = sprintf(buf, "%llu\n", tmp); | 142 | ret = sprintf(buf, "%llu\n", tmp); |
| 150 | spin_unlock_irq(&dev->power.lock); | ||
| 151 | return ret; | 143 | return ret; |
| 152 | } | 144 | } |
| 153 | 145 | ||
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c index b11f47a1e819..2bd9d2c744ca 100644 --- a/drivers/base/power/trace.c +++ b/drivers/base/power/trace.c | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | * devices may be working. | 7 | * devices may be working. |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #define pr_fmt(fmt) "PM: " fmt | ||
| 11 | |||
| 10 | #include <linux/pm-trace.h> | 12 | #include <linux/pm-trace.h> |
| 11 | #include <linux/export.h> | 13 | #include <linux/export.h> |
| 12 | #include <linux/rtc.h> | 14 | #include <linux/rtc.h> |
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index f1fee72ed970..bb1ae175fae1 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c | |||
| @@ -6,6 +6,8 @@ | |||
| 6 | * This file is released under the GPLv2. | 6 | * This file is released under the GPLv2. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #define pr_fmt(fmt) "PM: " fmt | ||
| 10 | |||
| 9 | #include <linux/device.h> | 11 | #include <linux/device.h> |
| 10 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
| 11 | #include <linux/sched/signal.h> | 13 | #include <linux/sched/signal.h> |
| @@ -106,23 +108,6 @@ struct wakeup_source *wakeup_source_create(const char *name) | |||
| 106 | } | 108 | } |
| 107 | EXPORT_SYMBOL_GPL(wakeup_source_create); | 109 | EXPORT_SYMBOL_GPL(wakeup_source_create); |
| 108 | 110 | ||
| 109 | /** | ||
| 110 | * wakeup_source_drop - Prepare a struct wakeup_source object for destruction. | ||
| 111 | * @ws: Wakeup source to prepare for destruction. | ||
| 112 | * | ||
| 113 | * Callers must ensure that __pm_stay_awake() or __pm_wakeup_event() will never | ||
| 114 | * be run in parallel with this function for the same wakeup source object. | ||
| 115 | */ | ||
| 116 | void wakeup_source_drop(struct wakeup_source *ws) | ||
| 117 | { | ||
| 118 | if (!ws) | ||
| 119 | return; | ||
| 120 | |||
| 121 | del_timer_sync(&ws->timer); | ||
| 122 | __pm_relax(ws); | ||
| 123 | } | ||
| 124 | EXPORT_SYMBOL_GPL(wakeup_source_drop); | ||
| 125 | |||
| 126 | /* | 111 | /* |
| 127 | * Record wakeup_source statistics being deleted into a dummy wakeup_source. | 112 | * Record wakeup_source statistics being deleted into a dummy wakeup_source. |
| 128 | */ | 113 | */ |
| @@ -162,7 +147,7 @@ void wakeup_source_destroy(struct wakeup_source *ws) | |||
| 162 | if (!ws) | 147 | if (!ws) |
| 163 | return; | 148 | return; |
| 164 | 149 | ||
| 165 | wakeup_source_drop(ws); | 150 | __pm_relax(ws); |
| 166 | wakeup_source_record(ws); | 151 | wakeup_source_record(ws); |
| 167 | kfree_const(ws->name); | 152 | kfree_const(ws->name); |
| 168 | kfree(ws); | 153 | kfree(ws); |
| @@ -205,6 +190,13 @@ void wakeup_source_remove(struct wakeup_source *ws) | |||
| 205 | list_del_rcu(&ws->entry); | 190 | list_del_rcu(&ws->entry); |
| 206 | raw_spin_unlock_irqrestore(&events_lock, flags); | 191 | raw_spin_unlock_irqrestore(&events_lock, flags); |
| 207 | synchronize_srcu(&wakeup_srcu); | 192 | synchronize_srcu(&wakeup_srcu); |
| 193 | |||
| 194 | del_timer_sync(&ws->timer); | ||
| 195 | /* | ||
| 196 | * Clear timer.function to make wakeup_source_not_registered() treat | ||
| 197 | * this wakeup source as not registered. | ||
| 198 | */ | ||
| 199 | ws->timer.function = NULL; | ||
| 208 | } | 200 | } |
| 209 | EXPORT_SYMBOL_GPL(wakeup_source_remove); | 201 | EXPORT_SYMBOL_GPL(wakeup_source_remove); |
| 210 | 202 | ||
| @@ -853,7 +845,7 @@ bool pm_wakeup_pending(void) | |||
| 853 | raw_spin_unlock_irqrestore(&events_lock, flags); | 845 | raw_spin_unlock_irqrestore(&events_lock, flags); |
| 854 | 846 | ||
| 855 | if (ret) { | 847 | if (ret) { |
| 856 | pr_debug("PM: Wakeup pending, aborting suspend\n"); | 848 | pr_debug("Wakeup pending, aborting suspend\n"); |
| 857 | pm_print_active_wakeup_sources(); | 849 | pm_print_active_wakeup_sources(); |
| 858 | } | 850 | } |
| 859 | 851 | ||
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 0e626b00053b..e10922709d13 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -206,17 +206,15 @@ unsigned int cpufreq_generic_get(unsigned int cpu) | |||
| 206 | EXPORT_SYMBOL_GPL(cpufreq_generic_get); | 206 | EXPORT_SYMBOL_GPL(cpufreq_generic_get); |
| 207 | 207 | ||
| 208 | /** | 208 | /** |
| 209 | * cpufreq_cpu_get: returns policy for a cpu and marks it busy. | 209 | * cpufreq_cpu_get - Return policy for a CPU and mark it as busy. |
| 210 | * @cpu: CPU to find the policy for. | ||
| 210 | * | 211 | * |
| 211 | * @cpu: cpu to find policy for. | 212 | * Call cpufreq_cpu_get_raw() to obtain a cpufreq policy for @cpu and increment |
| 213 | * the kobject reference counter of that policy. Return a valid policy on | ||
| 214 | * success or NULL on failure. | ||
| 212 | * | 215 | * |
| 213 | * This returns policy for 'cpu', returns NULL if it doesn't exist. | 216 | * The policy returned by this function has to be released with the help of |
| 214 | * It also increments the kobject reference count to mark it busy and so would | 217 | * cpufreq_cpu_put() to balance its kobject reference counter properly. |
| 215 | * require a corresponding call to cpufreq_cpu_put() to decrement it back. | ||
| 216 | * If corresponding call cpufreq_cpu_put() isn't made, the policy wouldn't be | ||
| 217 | * freed as that depends on the kobj count. | ||
| 218 | * | ||
| 219 | * Return: A valid policy on success, otherwise NULL on failure. | ||
| 220 | */ | 218 | */ |
| 221 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) | 219 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) |
| 222 | { | 220 | { |
| @@ -243,12 +241,8 @@ struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) | |||
| 243 | EXPORT_SYMBOL_GPL(cpufreq_cpu_get); | 241 | EXPORT_SYMBOL_GPL(cpufreq_cpu_get); |
| 244 | 242 | ||
| 245 | /** | 243 | /** |
| 246 | * cpufreq_cpu_put: Decrements the usage count of a policy | 244 | * cpufreq_cpu_put - Decrement kobject usage counter for cpufreq policy. |
| 247 | * | 245 | * @policy: cpufreq policy returned by cpufreq_cpu_get(). |
| 248 | * @policy: policy earlier returned by cpufreq_cpu_get(). | ||
| 249 | * | ||
| 250 | * This decrements the kobject reference count incremented earlier by calling | ||
| 251 | * cpufreq_cpu_get(). | ||
| 252 | */ | 246 | */ |
| 253 | void cpufreq_cpu_put(struct cpufreq_policy *policy) | 247 | void cpufreq_cpu_put(struct cpufreq_policy *policy) |
| 254 | { | 248 | { |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 002f5169d4eb..e22f0dbaebb1 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
| @@ -1762,7 +1762,7 @@ static void intel_pstate_update_util(struct update_util_data *data, u64 time, | |||
| 1762 | /* Start over if the CPU may have been idle. */ | 1762 | /* Start over if the CPU may have been idle. */ |
| 1763 | if (delta_ns > TICK_NSEC) { | 1763 | if (delta_ns > TICK_NSEC) { |
| 1764 | cpu->iowait_boost = ONE_EIGHTH_FP; | 1764 | cpu->iowait_boost = ONE_EIGHTH_FP; |
| 1765 | } else if (cpu->iowait_boost) { | 1765 | } else if (cpu->iowait_boost >= ONE_EIGHTH_FP) { |
| 1766 | cpu->iowait_boost <<= 1; | 1766 | cpu->iowait_boost <<= 1; |
| 1767 | if (cpu->iowait_boost > int_tofp(1)) | 1767 | if (cpu->iowait_boost > int_tofp(1)) |
| 1768 | cpu->iowait_boost = int_tofp(1); | 1768 | cpu->iowait_boost = int_tofp(1); |
diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c index 46254e583982..74e0e0c20c46 100644 --- a/drivers/cpufreq/pxa2xx-cpufreq.c +++ b/drivers/cpufreq/pxa2xx-cpufreq.c | |||
| @@ -143,7 +143,7 @@ static int pxa_cpufreq_change_voltage(const struct pxa_freqs *pxa_freq) | |||
| 143 | return ret; | 143 | return ret; |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | static void __init pxa_cpufreq_init_voltages(void) | 146 | static void pxa_cpufreq_init_voltages(void) |
| 147 | { | 147 | { |
| 148 | vcc_core = regulator_get(NULL, "vcc_core"); | 148 | vcc_core = regulator_get(NULL, "vcc_core"); |
| 149 | if (IS_ERR(vcc_core)) { | 149 | if (IS_ERR(vcc_core)) { |
| @@ -159,7 +159,7 @@ static int pxa_cpufreq_change_voltage(const struct pxa_freqs *pxa_freq) | |||
| 159 | return 0; | 159 | return 0; |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | static void __init pxa_cpufreq_init_voltages(void) { } | 162 | static void pxa_cpufreq_init_voltages(void) { } |
| 163 | #endif | 163 | #endif |
| 164 | 164 | ||
| 165 | static void find_freq_tables(struct cpufreq_frequency_table **freq_table, | 165 | static void find_freq_tables(struct cpufreq_frequency_table **freq_table, |
diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c index bb93e5cf6a4a..9fddf828a76f 100644 --- a/drivers/cpuidle/governor.c +++ b/drivers/cpuidle/governor.c | |||
| @@ -89,6 +89,7 @@ int cpuidle_register_governor(struct cpuidle_governor *gov) | |||
| 89 | mutex_lock(&cpuidle_lock); | 89 | mutex_lock(&cpuidle_lock); |
| 90 | if (__cpuidle_find_governor(gov->name) == NULL) { | 90 | if (__cpuidle_find_governor(gov->name) == NULL) { |
| 91 | ret = 0; | 91 | ret = 0; |
| 92 | list_add_tail(&gov->governor_list, &cpuidle_governors); | ||
| 92 | if (!cpuidle_curr_governor || | 93 | if (!cpuidle_curr_governor || |
| 93 | !strncasecmp(param_governor, gov->name, CPUIDLE_NAME_LEN) || | 94 | !strncasecmp(param_governor, gov->name, CPUIDLE_NAME_LEN) || |
| 94 | (cpuidle_curr_governor->rating < gov->rating && | 95 | (cpuidle_curr_governor->rating < gov->rating && |
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 61316fc51548..5951604e7d5c 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c | |||
| @@ -186,7 +186,7 @@ static unsigned int get_typical_interval(struct menu_device *data, | |||
| 186 | unsigned int min, max, thresh, avg; | 186 | unsigned int min, max, thresh, avg; |
| 187 | uint64_t sum, variance; | 187 | uint64_t sum, variance; |
| 188 | 188 | ||
| 189 | thresh = UINT_MAX; /* Discard outliers above this value */ | 189 | thresh = INT_MAX; /* Discard outliers above this value */ |
| 190 | 190 | ||
| 191 | again: | 191 | again: |
| 192 | 192 | ||
diff --git a/drivers/opp/core.c b/drivers/opp/core.c index d7f97167cac3..0420f7e8ad5b 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c | |||
| @@ -760,7 +760,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) | |||
| 760 | old_freq, freq); | 760 | old_freq, freq); |
| 761 | 761 | ||
| 762 | /* Scaling up? Configure required OPPs before frequency */ | 762 | /* Scaling up? Configure required OPPs before frequency */ |
| 763 | if (freq > old_freq) { | 763 | if (freq >= old_freq) { |
| 764 | ret = _set_required_opps(dev, opp_table, opp); | 764 | ret = _set_required_opps(dev, opp_table, opp); |
| 765 | if (ret) | 765 | if (ret) |
| 766 | goto put_opp; | 766 | goto put_opp; |
diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 62504b18f198..c10c782d15aa 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c | |||
| @@ -173,7 +173,7 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table, | |||
| 173 | struct opp_table **required_opp_tables; | 173 | struct opp_table **required_opp_tables; |
| 174 | struct device **genpd_virt_devs = NULL; | 174 | struct device **genpd_virt_devs = NULL; |
| 175 | struct device_node *required_np, *np; | 175 | struct device_node *required_np, *np; |
| 176 | int count, i; | 176 | int count, count_pd, i; |
| 177 | 177 | ||
| 178 | /* Traversing the first OPP node is all we need */ | 178 | /* Traversing the first OPP node is all we need */ |
| 179 | np = of_get_next_available_child(opp_np, NULL); | 179 | np = of_get_next_available_child(opp_np, NULL); |
| @@ -186,7 +186,19 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table, | |||
| 186 | if (!count) | 186 | if (!count) |
| 187 | goto put_np; | 187 | goto put_np; |
| 188 | 188 | ||
| 189 | if (count > 1) { | 189 | /* |
| 190 | * Check the number of power-domains to know if we need to deal | ||
| 191 | * with virtual devices. In some cases we have devices with multiple | ||
| 192 | * power domains but with only one of them being scalable, hence | ||
| 193 | * 'count' could be 1, but we still have to deal with multiple genpds | ||
| 194 | * and virtual devices. | ||
| 195 | */ | ||
| 196 | count_pd = of_count_phandle_with_args(dev->of_node, "power-domains", | ||
| 197 | "#power-domain-cells"); | ||
| 198 | if (!count_pd) | ||
| 199 | goto put_np; | ||
| 200 | |||
| 201 | if (count_pd > 1) { | ||
| 190 | genpd_virt_devs = kcalloc(count, sizeof(*genpd_virt_devs), | 202 | genpd_virt_devs = kcalloc(count, sizeof(*genpd_virt_devs), |
| 191 | GFP_KERNEL); | 203 | GFP_KERNEL); |
| 192 | if (!genpd_virt_devs) | 204 | if (!genpd_virt_devs) |
diff --git a/include/linux/pm.h b/include/linux/pm.h index 06f7ed893928..66c19a65a514 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
| @@ -643,7 +643,6 @@ struct dev_pm_info { | |||
| 643 | struct dev_pm_qos *qos; | 643 | struct dev_pm_qos *qos; |
| 644 | }; | 644 | }; |
| 645 | 645 | ||
| 646 | extern void update_pm_runtime_accounting(struct device *dev); | ||
| 647 | extern int dev_pm_get_subsys_data(struct device *dev); | 646 | extern int dev_pm_get_subsys_data(struct device *dev); |
| 648 | extern void dev_pm_put_subsys_data(struct device *dev); | 647 | extern void dev_pm_put_subsys_data(struct device *dev); |
| 649 | 648 | ||
diff --git a/include/linux/pm_wakeup.h b/include/linux/pm_wakeup.h index 4238dde0aaf0..0ff134d6575a 100644 --- a/include/linux/pm_wakeup.h +++ b/include/linux/pm_wakeup.h | |||
| @@ -96,7 +96,6 @@ static inline void device_set_wakeup_path(struct device *dev) | |||
| 96 | /* drivers/base/power/wakeup.c */ | 96 | /* drivers/base/power/wakeup.c */ |
| 97 | extern void wakeup_source_prepare(struct wakeup_source *ws, const char *name); | 97 | extern void wakeup_source_prepare(struct wakeup_source *ws, const char *name); |
| 98 | extern struct wakeup_source *wakeup_source_create(const char *name); | 98 | extern struct wakeup_source *wakeup_source_create(const char *name); |
| 99 | extern void wakeup_source_drop(struct wakeup_source *ws); | ||
| 100 | extern void wakeup_source_destroy(struct wakeup_source *ws); | 99 | extern void wakeup_source_destroy(struct wakeup_source *ws); |
| 101 | extern void wakeup_source_add(struct wakeup_source *ws); | 100 | extern void wakeup_source_add(struct wakeup_source *ws); |
| 102 | extern void wakeup_source_remove(struct wakeup_source *ws); | 101 | extern void wakeup_source_remove(struct wakeup_source *ws); |
| @@ -134,8 +133,6 @@ static inline struct wakeup_source *wakeup_source_create(const char *name) | |||
| 134 | return NULL; | 133 | return NULL; |
| 135 | } | 134 | } |
| 136 | 135 | ||
| 137 | static inline void wakeup_source_drop(struct wakeup_source *ws) {} | ||
| 138 | |||
| 139 | static inline void wakeup_source_destroy(struct wakeup_source *ws) {} | 136 | static inline void wakeup_source_destroy(struct wakeup_source *ws) {} |
| 140 | 137 | ||
| 141 | static inline void wakeup_source_add(struct wakeup_source *ws) {} | 138 | static inline void wakeup_source_add(struct wakeup_source *ws) {} |
| @@ -204,12 +201,6 @@ static inline void wakeup_source_init(struct wakeup_source *ws, | |||
| 204 | wakeup_source_add(ws); | 201 | wakeup_source_add(ws); |
| 205 | } | 202 | } |
| 206 | 203 | ||
| 207 | static inline void wakeup_source_trash(struct wakeup_source *ws) | ||
| 208 | { | ||
| 209 | wakeup_source_remove(ws); | ||
| 210 | wakeup_source_drop(ws); | ||
| 211 | } | ||
| 212 | |||
| 213 | static inline void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec) | 204 | static inline void __pm_wakeup_event(struct wakeup_source *ws, unsigned int msec) |
| 214 | { | 205 | { |
| 215 | return pm_wakeup_ws_event(ws, msec, false); | 206 | return pm_wakeup_ws_event(ws, msec, false); |
diff --git a/tools/power/cpupower/lib/cpufreq.c b/tools/power/cpupower/lib/cpufreq.c index 0c0f3e3f0d80..80650497fb80 100644 --- a/tools/power/cpupower/lib/cpufreq.c +++ b/tools/power/cpupower/lib/cpufreq.c | |||
| @@ -333,17 +333,20 @@ void cpufreq_put_available_governors(struct cpufreq_available_governors *any) | |||
| 333 | } | 333 | } |
| 334 | 334 | ||
| 335 | 335 | ||
| 336 | struct cpufreq_available_frequencies | 336 | struct cpufreq_frequencies |
| 337 | *cpufreq_get_available_frequencies(unsigned int cpu) | 337 | *cpufreq_get_frequencies(const char *type, unsigned int cpu) |
| 338 | { | 338 | { |
| 339 | struct cpufreq_available_frequencies *first = NULL; | 339 | struct cpufreq_frequencies *first = NULL; |
| 340 | struct cpufreq_available_frequencies *current = NULL; | 340 | struct cpufreq_frequencies *current = NULL; |
| 341 | char one_value[SYSFS_PATH_MAX]; | 341 | char one_value[SYSFS_PATH_MAX]; |
| 342 | char linebuf[MAX_LINE_LEN]; | 342 | char linebuf[MAX_LINE_LEN]; |
| 343 | char fname[MAX_LINE_LEN]; | ||
| 343 | unsigned int pos, i; | 344 | unsigned int pos, i; |
| 344 | unsigned int len; | 345 | unsigned int len; |
| 345 | 346 | ||
| 346 | len = sysfs_cpufreq_read_file(cpu, "scaling_available_frequencies", | 347 | snprintf(fname, MAX_LINE_LEN, "scaling_%s_frequencies", type); |
| 348 | |||
| 349 | len = sysfs_cpufreq_read_file(cpu, fname, | ||
| 347 | linebuf, sizeof(linebuf)); | 350 | linebuf, sizeof(linebuf)); |
| 348 | if (len == 0) | 351 | if (len == 0) |
| 349 | return NULL; | 352 | return NULL; |
| @@ -389,9 +392,9 @@ struct cpufreq_available_frequencies | |||
| 389 | return NULL; | 392 | return NULL; |
| 390 | } | 393 | } |
| 391 | 394 | ||
| 392 | void cpufreq_put_available_frequencies(struct cpufreq_available_frequencies | 395 | void cpufreq_put_frequencies(struct cpufreq_frequencies *any) |
| 393 | *any) { | 396 | { |
| 394 | struct cpufreq_available_frequencies *tmp, *next; | 397 | struct cpufreq_frequencies *tmp, *next; |
| 395 | 398 | ||
| 396 | if (!any) | 399 | if (!any) |
| 397 | return; | 400 | return; |
diff --git a/tools/power/cpupower/lib/cpufreq.h b/tools/power/cpupower/lib/cpufreq.h index 60beaf5ed2ea..775738269cbf 100644 --- a/tools/power/cpupower/lib/cpufreq.h +++ b/tools/power/cpupower/lib/cpufreq.h | |||
| @@ -28,10 +28,10 @@ struct cpufreq_available_governors { | |||
| 28 | struct cpufreq_available_governors *first; | 28 | struct cpufreq_available_governors *first; |
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | struct cpufreq_available_frequencies { | 31 | struct cpufreq_frequencies { |
| 32 | unsigned long frequency; | 32 | unsigned long frequency; |
| 33 | struct cpufreq_available_frequencies *next; | 33 | struct cpufreq_frequencies *next; |
| 34 | struct cpufreq_available_frequencies *first; | 34 | struct cpufreq_frequencies *first; |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | 37 | ||
| @@ -129,14 +129,14 @@ void cpufreq_put_available_governors( | |||
| 129 | * | 129 | * |
| 130 | * Only present on _some_ ->target() cpufreq drivers. For information purposes | 130 | * Only present on _some_ ->target() cpufreq drivers. For information purposes |
| 131 | * only. Please free allocated memory by calling | 131 | * only. Please free allocated memory by calling |
| 132 | * cpufreq_put_available_frequencies after use. | 132 | * cpufreq_put_frequencies after use. |
| 133 | */ | 133 | */ |
| 134 | 134 | ||
| 135 | struct cpufreq_available_frequencies | 135 | struct cpufreq_frequencies |
| 136 | *cpufreq_get_available_frequencies(unsigned int cpu); | 136 | *cpufreq_get_frequencies(const char *type, unsigned int cpu); |
| 137 | 137 | ||
| 138 | void cpufreq_put_available_frequencies( | 138 | void cpufreq_put_frequencies( |
| 139 | struct cpufreq_available_frequencies *first); | 139 | struct cpufreq_frequencies *first); |
| 140 | 140 | ||
| 141 | 141 | ||
| 142 | /* determine affected CPUs | 142 | /* determine affected CPUs |
diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c index c3f39d5128ee..10290b308797 100644 --- a/tools/power/cpupower/utils/cpufreq-info.c +++ b/tools/power/cpupower/utils/cpufreq-info.c | |||
| @@ -161,19 +161,12 @@ static void print_duration(unsigned long duration) | |||
| 161 | return; | 161 | return; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | /* --boost / -b */ | 164 | static int get_boost_mode_x86(unsigned int cpu) |
| 165 | |||
| 166 | static int get_boost_mode(unsigned int cpu) | ||
| 167 | { | 165 | { |
| 168 | int support, active, b_states = 0, ret, pstate_no, i; | 166 | int support, active, b_states = 0, ret, pstate_no, i; |
| 169 | /* ToDo: Make this more global */ | 167 | /* ToDo: Make this more global */ |
| 170 | unsigned long pstates[MAX_HW_PSTATES] = {0,}; | 168 | unsigned long pstates[MAX_HW_PSTATES] = {0,}; |
| 171 | 169 | ||
| 172 | if (cpupower_cpu_info.vendor != X86_VENDOR_AMD && | ||
| 173 | cpupower_cpu_info.vendor != X86_VENDOR_HYGON && | ||
| 174 | cpupower_cpu_info.vendor != X86_VENDOR_INTEL) | ||
| 175 | return 0; | ||
| 176 | |||
| 177 | ret = cpufreq_has_boost_support(cpu, &support, &active, &b_states); | 170 | ret = cpufreq_has_boost_support(cpu, &support, &active, &b_states); |
| 178 | if (ret) { | 171 | if (ret) { |
| 179 | printf(_("Error while evaluating Boost Capabilities" | 172 | printf(_("Error while evaluating Boost Capabilities" |
| @@ -248,6 +241,33 @@ static int get_boost_mode(unsigned int cpu) | |||
| 248 | return 0; | 241 | return 0; |
| 249 | } | 242 | } |
| 250 | 243 | ||
| 244 | /* --boost / -b */ | ||
| 245 | |||
| 246 | static int get_boost_mode(unsigned int cpu) | ||
| 247 | { | ||
| 248 | struct cpufreq_frequencies *freqs; | ||
| 249 | |||
| 250 | if (cpupower_cpu_info.vendor == X86_VENDOR_AMD || | ||
| 251 | cpupower_cpu_info.vendor == X86_VENDOR_HYGON || | ||
| 252 | cpupower_cpu_info.vendor == X86_VENDOR_INTEL) | ||
| 253 | return get_boost_mode_x86(cpu); | ||
| 254 | |||
| 255 | freqs = cpufreq_get_frequencies("boost", cpu); | ||
| 256 | if (freqs) { | ||
| 257 | printf(_(" boost frequency steps: ")); | ||
| 258 | while (freqs->next) { | ||
| 259 | print_speed(freqs->frequency); | ||
| 260 | printf(", "); | ||
| 261 | freqs = freqs->next; | ||
| 262 | } | ||
| 263 | print_speed(freqs->frequency); | ||
| 264 | printf("\n"); | ||
| 265 | cpufreq_put_frequencies(freqs); | ||
| 266 | } | ||
| 267 | |||
| 268 | return 0; | ||
| 269 | } | ||
| 270 | |||
| 251 | /* --freq / -f */ | 271 | /* --freq / -f */ |
| 252 | 272 | ||
| 253 | static int get_freq_kernel(unsigned int cpu, unsigned int human) | 273 | static int get_freq_kernel(unsigned int cpu, unsigned int human) |
| @@ -456,7 +476,7 @@ static int get_latency(unsigned int cpu, unsigned int human) | |||
| 456 | 476 | ||
| 457 | static void debug_output_one(unsigned int cpu) | 477 | static void debug_output_one(unsigned int cpu) |
| 458 | { | 478 | { |
| 459 | struct cpufreq_available_frequencies *freqs; | 479 | struct cpufreq_frequencies *freqs; |
| 460 | 480 | ||
| 461 | get_driver(cpu); | 481 | get_driver(cpu); |
| 462 | get_related_cpus(cpu); | 482 | get_related_cpus(cpu); |
| @@ -464,7 +484,7 @@ static void debug_output_one(unsigned int cpu) | |||
| 464 | get_latency(cpu, 1); | 484 | get_latency(cpu, 1); |
| 465 | get_hardware_limits(cpu, 1); | 485 | get_hardware_limits(cpu, 1); |
| 466 | 486 | ||
| 467 | freqs = cpufreq_get_available_frequencies(cpu); | 487 | freqs = cpufreq_get_frequencies("available", cpu); |
| 468 | if (freqs) { | 488 | if (freqs) { |
| 469 | printf(_(" available frequency steps: ")); | 489 | printf(_(" available frequency steps: ")); |
| 470 | while (freqs->next) { | 490 | while (freqs->next) { |
| @@ -474,7 +494,7 @@ static void debug_output_one(unsigned int cpu) | |||
| 474 | } | 494 | } |
| 475 | print_speed(freqs->frequency); | 495 | print_speed(freqs->frequency); |
| 476 | printf("\n"); | 496 | printf("\n"); |
| 477 | cpufreq_put_available_frequencies(freqs); | 497 | cpufreq_put_frequencies(freqs); |
| 478 | } | 498 | } |
| 479 | 499 | ||
| 480 | get_available_governors(cpu); | 500 | get_available_governors(cpu); |
