Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branches 'pm-devfreq' and 'pm-tools'

* pm-devfreq:
PM / devfreq: Define the constant governor name
PM / devfreq: Remove unneeded conditional statement
PM / devfreq: Show the all available frequencies
PM / devfreq: Change return type of devfreq_set_freq_table()
PM / devfreq: Use the available min/max frequency
Revert "PM / devfreq: Add show_one macro to delete the duplicate code"
PM / devfreq: Set min/max_freq when adding the devfreq device

* pm-tools:
tools/power/cpupower: add libcpupower.so.0.0.1 to .gitignore
tools/power/cpupower: Add 64 bit library detection
MAINTAINERS: add maintainer for tools/power/cpupower
cpupower: Fix no-rounding MHz frequency output

+133 -54
+2
MAINTAINERS
··· 3636 3636 3637 3637 CPU POWER MONITORING SUBSYSTEM 3638 3638 M: Thomas Renninger <trenn@suse.com> 3639 + M: Shuah Khan <shuahkh@osg.samsung.com> 3640 + M: Shuah Khan <shuah@kernel.org> 3639 3641 L: linux-pm@vger.kernel.org 3640 3642 S: Maintained 3641 3643 F: tools/power/cpupower/
+101 -40
drivers/devfreq/devfreq.c
··· 28 28 #include <linux/of.h> 29 29 #include "governor.h" 30 30 31 + #define MAX(a,b) ((a > b) ? a : b) 32 + #define MIN(a,b) ((a < b) ? a : b) 33 + 31 34 static struct class *devfreq_class; 32 35 33 36 /* ··· 72 69 return ERR_PTR(-ENODEV); 73 70 } 74 71 72 + static unsigned long find_available_min_freq(struct devfreq *devfreq) 73 + { 74 + struct dev_pm_opp *opp; 75 + unsigned long min_freq = 0; 76 + 77 + opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &min_freq); 78 + if (IS_ERR(opp)) 79 + min_freq = 0; 80 + else 81 + dev_pm_opp_put(opp); 82 + 83 + return min_freq; 84 + } 85 + 86 + static unsigned long find_available_max_freq(struct devfreq *devfreq) 87 + { 88 + struct dev_pm_opp *opp; 89 + unsigned long max_freq = ULONG_MAX; 90 + 91 + opp = dev_pm_opp_find_freq_floor(devfreq->dev.parent, &max_freq); 92 + if (IS_ERR(opp)) 93 + max_freq = 0; 94 + else 95 + dev_pm_opp_put(opp); 96 + 97 + return max_freq; 98 + } 99 + 75 100 /** 76 101 * devfreq_get_freq_level() - Lookup freq_table for the frequency 77 102 * @devfreq: the devfreq instance ··· 116 85 return -EINVAL; 117 86 } 118 87 119 - /** 120 - * devfreq_set_freq_table() - Initialize freq_table for the frequency 121 - * @devfreq: the devfreq instance 122 - */ 123 - static void devfreq_set_freq_table(struct devfreq *devfreq) 88 + static int set_freq_table(struct devfreq *devfreq) 124 89 { 125 90 struct devfreq_dev_profile *profile = devfreq->profile; 126 91 struct dev_pm_opp *opp; ··· 126 99 /* Initialize the freq_table from OPP table */ 127 100 count = dev_pm_opp_get_opp_count(devfreq->dev.parent); 128 101 if (count <= 0) 129 - return; 102 + return -EINVAL; 130 103 131 104 profile->max_state = count; 132 105 profile->freq_table = devm_kcalloc(devfreq->dev.parent, ··· 135 108 GFP_KERNEL); 136 109 if (!profile->freq_table) { 137 110 profile->max_state = 0; 138 - return; 111 + return -ENOMEM; 139 112 } 140 113 141 114 for (i = 0, freq = 0; i < profile->max_state; i++, freq++) { ··· 143 116 if (IS_ERR(opp)) { 144 117 devm_kfree(devfreq->dev.parent, profile->freq_table); 145 118 profile->max_state = 0; 146 - return; 119 + return PTR_ERR(opp); 147 120 } 148 121 dev_pm_opp_put(opp); 149 122 profile->freq_table[i] = freq; 150 123 } 124 + 125 + return 0; 151 126 } 152 127 153 128 /** ··· 256 227 int update_devfreq(struct devfreq *devfreq) 257 228 { 258 229 struct devfreq_freqs freqs; 259 - unsigned long freq, cur_freq; 230 + unsigned long freq, cur_freq, min_freq, max_freq; 260 231 int err = 0; 261 232 u32 flags = 0; 262 233 ··· 274 245 return err; 275 246 276 247 /* 277 - * Adjust the frequency with user freq and QoS. 248 + * Adjust the frequency with user freq, QoS and available freq. 278 249 * 279 250 * List from the highest priority 280 251 * max_freq 281 252 * min_freq 282 253 */ 254 + max_freq = MIN(devfreq->scaling_max_freq, devfreq->max_freq); 255 + min_freq = MAX(devfreq->scaling_min_freq, devfreq->min_freq); 283 256 284 - if (devfreq->min_freq && freq < devfreq->min_freq) { 285 - freq = devfreq->min_freq; 257 + if (min_freq && freq < min_freq) { 258 + freq = min_freq; 286 259 flags &= ~DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use GLB */ 287 260 } 288 - if (devfreq->max_freq && freq > devfreq->max_freq) { 289 - freq = devfreq->max_freq; 261 + if (max_freq && freq > max_freq) { 262 + freq = max_freq; 290 263 flags |= DEVFREQ_FLAG_LEAST_UPPER_BOUND; /* Use LUB */ 291 264 } 292 265 ··· 311 280 freqs.new = freq; 312 281 devfreq_notify_transition(devfreq, &freqs, DEVFREQ_POSTCHANGE); 313 282 314 - if (devfreq->profile->freq_table) 315 - if (devfreq_update_status(devfreq, freq)) 316 - dev_err(&devfreq->dev, 317 - "Couldn't update frequency transition information.\n"); 283 + if (devfreq_update_status(devfreq, freq)) 284 + dev_err(&devfreq->dev, 285 + "Couldn't update frequency transition information.\n"); 318 286 319 287 devfreq->previous_freq = freq; 320 288 return err; ··· 496 466 int ret; 497 467 498 468 mutex_lock(&devfreq->lock); 469 + 470 + devfreq->scaling_min_freq = find_available_min_freq(devfreq); 471 + if (!devfreq->scaling_min_freq) { 472 + mutex_unlock(&devfreq->lock); 473 + return -EINVAL; 474 + } 475 + 476 + devfreq->scaling_max_freq = find_available_max_freq(devfreq); 477 + if (!devfreq->scaling_max_freq) { 478 + mutex_unlock(&devfreq->lock); 479 + return -EINVAL; 480 + } 481 + 499 482 ret = update_devfreq(devfreq); 500 483 mutex_unlock(&devfreq->lock); 501 484 ··· 598 555 599 556 if (!devfreq->profile->max_state && !devfreq->profile->freq_table) { 600 557 mutex_unlock(&devfreq->lock); 601 - devfreq_set_freq_table(devfreq); 558 + err = set_freq_table(devfreq); 559 + if (err < 0) 560 + goto err_out; 602 561 mutex_lock(&devfreq->lock); 603 562 } 563 + 564 + devfreq->min_freq = find_available_min_freq(devfreq); 565 + if (!devfreq->min_freq) { 566 + mutex_unlock(&devfreq->lock); 567 + err = -EINVAL; 568 + goto err_dev; 569 + } 570 + devfreq->scaling_min_freq = devfreq->min_freq; 571 + 572 + devfreq->max_freq = find_available_max_freq(devfreq); 573 + if (!devfreq->max_freq) { 574 + mutex_unlock(&devfreq->lock); 575 + err = -EINVAL; 576 + goto err_dev; 577 + } 578 + devfreq->scaling_max_freq = devfreq->max_freq; 604 579 605 580 dev_set_name(&devfreq->dev, "devfreq%d", 606 581 atomic_inc_return(&devfreq_no)); ··· 1143 1082 return ret; 1144 1083 } 1145 1084 1085 + static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr, 1086 + char *buf) 1087 + { 1088 + struct devfreq *df = to_devfreq(dev); 1089 + 1090 + return sprintf(buf, "%lu\n", MAX(df->scaling_min_freq, df->min_freq)); 1091 + } 1092 + 1146 1093 static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr, 1147 1094 const char *buf, size_t count) 1148 1095 { ··· 1177 1108 mutex_unlock(&df->lock); 1178 1109 return ret; 1179 1110 } 1180 - 1181 - #define show_one(name) \ 1182 - static ssize_t name##_show \ 1183 - (struct device *dev, struct device_attribute *attr, char *buf) \ 1184 - { \ 1185 - return sprintf(buf, "%lu\n", to_devfreq(dev)->name); \ 1186 - } 1187 - show_one(min_freq); 1188 - show_one(max_freq); 1189 - 1190 1111 static DEVICE_ATTR_RW(min_freq); 1112 + 1113 + static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr, 1114 + char *buf) 1115 + { 1116 + struct devfreq *df = to_devfreq(dev); 1117 + 1118 + return sprintf(buf, "%lu\n", MIN(df->scaling_max_freq, df->max_freq)); 1119 + } 1191 1120 static DEVICE_ATTR_RW(max_freq); 1192 1121 1193 1122 static ssize_t available_frequencies_show(struct device *d, ··· 1193 1126 char *buf) 1194 1127 { 1195 1128 struct devfreq *df = to_devfreq(d); 1196 - struct device *dev = df->dev.parent; 1197 - struct dev_pm_opp *opp; 1198 1129 ssize_t count = 0; 1199 - unsigned long freq = 0; 1130 + int i; 1200 1131 1201 - do { 1202 - opp = dev_pm_opp_find_freq_ceil(dev, &freq); 1203 - if (IS_ERR(opp)) 1204 - break; 1132 + mutex_lock(&df->lock); 1205 1133 1206 - dev_pm_opp_put(opp); 1134 + for (i = 0; i < df->profile->max_state; i++) 1207 1135 count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), 1208 - "%lu ", freq); 1209 - freq++; 1210 - } while (1); 1136 + "%lu ", df->profile->freq_table[i]); 1211 1137 1138 + mutex_unlock(&df->lock); 1212 1139 /* Truncate the trailing space */ 1213 1140 if (count) 1214 1141 count--;
+3 -2
drivers/devfreq/exynos-bus.c
··· 436 436 ondemand_data->downdifferential = 5; 437 437 438 438 /* Add devfreq device to monitor and handle the exynos bus */ 439 - bus->devfreq = devm_devfreq_add_device(dev, profile, "simple_ondemand", 439 + bus->devfreq = devm_devfreq_add_device(dev, profile, 440 + DEVFREQ_GOV_SIMPLE_ONDEMAND, 440 441 ondemand_data); 441 442 if (IS_ERR(bus->devfreq)) { 442 443 dev_err(dev, "failed to add devfreq device\n"); ··· 489 488 passive_data->parent = parent_devfreq; 490 489 491 490 /* Add devfreq device for exynos bus with passive governor */ 492 - bus->devfreq = devm_devfreq_add_device(dev, profile, "passive", 491 + bus->devfreq = devm_devfreq_add_device(dev, profile, DEVFREQ_GOV_PASSIVE, 493 492 passive_data); 494 493 if (IS_ERR(bus->devfreq)) { 495 494 dev_err(dev,
+1 -1
drivers/devfreq/governor_passive.c
··· 183 183 } 184 184 185 185 static struct devfreq_governor devfreq_passive = { 186 - .name = "passive", 186 + .name = DEVFREQ_GOV_PASSIVE, 187 187 .immutable = 1, 188 188 .get_target_freq = devfreq_passive_get_target_freq, 189 189 .event_handler = devfreq_passive_event_handler,
+1 -1
drivers/devfreq/governor_performance.c
··· 42 42 } 43 43 44 44 static struct devfreq_governor devfreq_performance = { 45 - .name = "performance", 45 + .name = DEVFREQ_GOV_PERFORMANCE, 46 46 .get_target_freq = devfreq_performance_func, 47 47 .event_handler = devfreq_performance_handler, 48 48 };
+1 -1
drivers/devfreq/governor_powersave.c
··· 39 39 } 40 40 41 41 static struct devfreq_governor devfreq_powersave = { 42 - .name = "powersave", 42 + .name = DEVFREQ_GOV_POWERSAVE, 43 43 .get_target_freq = devfreq_powersave_func, 44 44 .event_handler = devfreq_powersave_handler, 45 45 };
+1 -1
drivers/devfreq/governor_simpleondemand.c
··· 125 125 } 126 126 127 127 static struct devfreq_governor devfreq_simple_ondemand = { 128 - .name = "simple_ondemand", 128 + .name = DEVFREQ_GOV_SIMPLE_ONDEMAND, 129 129 .get_target_freq = devfreq_simple_ondemand_func, 130 130 .event_handler = devfreq_simple_ondemand_handler, 131 131 };
+1 -1
drivers/devfreq/governor_userspace.c
··· 87 87 NULL, 88 88 }; 89 89 static const struct attribute_group dev_attr_group = { 90 - .name = "userspace", 90 + .name = DEVFREQ_GOV_USERSPACE, 91 91 .attrs = dev_entries, 92 92 }; 93 93
+1 -1
drivers/devfreq/rk3399_dmc.c
··· 431 431 432 432 data->devfreq = devm_devfreq_add_device(dev, 433 433 &rk3399_devfreq_dmc_profile, 434 - "simple_ondemand", 434 + DEVFREQ_GOV_SIMPLE_ONDEMAND, 435 435 &data->ondemand_data); 436 436 if (IS_ERR(data->devfreq)) 437 437 return PTR_ERR(data->devfreq);
+14 -2
include/linux/devfreq.h
··· 19 19 20 20 #define DEVFREQ_NAME_LEN 16 21 21 22 + /* DEVFREQ governor name */ 23 + #define DEVFREQ_GOV_SIMPLE_ONDEMAND "simple_ondemand" 24 + #define DEVFREQ_GOV_PERFORMANCE "performance" 25 + #define DEVFREQ_GOV_POWERSAVE "powersave" 26 + #define DEVFREQ_GOV_USERSPACE "userspace" 27 + #define DEVFREQ_GOV_PASSIVE "passive" 28 + 22 29 /* DEVFREQ notifier interface */ 23 30 #define DEVFREQ_TRANSITION_NOTIFIER (0) 24 31 ··· 91 84 * from devfreq_remove_device() call. If the user 92 85 * has registered devfreq->nb at a notifier-head, 93 86 * this is the time to unregister it. 94 - * @freq_table: Optional list of frequencies to support statistics. 95 - * @max_state: The size of freq_table. 87 + * @freq_table: Optional list of frequencies to support statistics 88 + * and freq_table must be generated in ascending order. 89 + * @max_state: The size of freq_table. 96 90 */ 97 91 struct devfreq_dev_profile { 98 92 unsigned long initial_freq; ··· 128 120 * touch this. 129 121 * @min_freq: Limit minimum frequency requested by user (0: none) 130 122 * @max_freq: Limit maximum frequency requested by user (0: none) 123 + * @scaling_min_freq: Limit minimum frequency requested by OPP interface 124 + * @scaling_max_freq: Limit maximum frequency requested by OPP interface 131 125 * @stop_polling: devfreq polling status of a device. 132 126 * @total_trans: Number of devfreq transitions 133 127 * @trans_table: Statistics of devfreq transitions ··· 163 153 164 154 unsigned long min_freq; 165 155 unsigned long max_freq; 156 + unsigned long scaling_min_freq; 157 + unsigned long scaling_max_freq; 166 158 bool stop_polling; 167 159 168 160 /* information for device frequency transition */
+1 -2
tools/power/cpupower/.gitignore
··· 1 1 .libs 2 2 libcpupower.so 3 - libcpupower.so.0 4 - libcpupower.so.0.0.0 3 + libcpupower.so.* 5 4 build/ccdv 6 5 cpufreq-info 7 6 cpufreq-set
+6
tools/power/cpupower/Makefile
··· 30 30 $(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist)) 31 31 endif 32 32 33 + include ../../scripts/Makefile.arch 34 + 33 35 # --- CONFIGURATION BEGIN --- 34 36 35 37 # Set the following to `true' to make a unstripped, unoptimized ··· 81 79 sbindir ?= /usr/sbin 82 80 mandir ?= /usr/man 83 81 includedir ?= /usr/include 82 + ifeq ($(IS_64_BIT), 1) 83 + libdir ?= /usr/lib64 84 + else 84 85 libdir ?= /usr/lib 86 + endif 85 87 localedir ?= /usr/share/locale 86 88 docdir ?= /usr/share/doc/packages/cpupower 87 89 confdir ?= /etc/
-2
tools/power/cpupower/utils/cpufreq-info.c
··· 93 93 if (speed > 1000000) 94 94 printf("%u.%06u GHz", ((unsigned int) speed/1000000), 95 95 ((unsigned int) speed%1000000)); 96 - else if (speed > 100000) 97 - printf("%u MHz", (unsigned int) speed); 98 96 else if (speed > 1000) 99 97 printf("%u.%03u MHz", ((unsigned int) speed/1000), 100 98 (unsigned int) (speed%1000));