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

Merge branch 'pm-cpufreq'

* pm-cpufreq: (46 commits)
intel_pstate: provide option to only use intel_pstate with HWP
cpufreq-dt: Drop unnecessary check before cpufreq_cooling_unregister() invocation
cpufreq: Create for_each_governor()
cpufreq: Create for_each_policy()
cpufreq: Drop cpufreq_disabled() check from cpufreq_cpu_{get|put}()
cpufreq: Set cpufreq_cpu_data to NULL before putting kobject
intel_pstate: honor user space min_perf_pct override on resume
intel_pstate: respect cpufreq policy request
intel_pstate: Add num_pstates to sysfs
intel_pstate: expose turbo range to sysfs
intel_pstate: Add support for SkyLake
cpufreq: stats: drop unnecessary locking
cpufreq: stats: don't update stats on false notifiers
cpufreq: stats: don't update stats from show_trans_table()
cpufreq: stats: time_in_state can't be NULL in cpufreq_stats_update()
cpufreq: stats: create sysfs group once we are ready
cpufreq: remove CPUFREQ_UPDATE_POLICY_CPU notifications
cpufreq: stats: drop 'cpu' field of struct cpufreq_stats
cpufreq: Remove (now) unused 'last_cpu' from struct cpufreq_policy
cpufreq: stats: rename 'struct cpufreq_stats' objects as 'stats'
...

+386 -239
+8
Documentation/cpu-freq/intel-pstate.txt
··· 37 37 no_turbo: limits the driver to selecting P states below the turbo 38 38 frequency range. 39 39 40 + turbo_pct: displays the percentage of the total performance that 41 + is supported by hardware that is in the turbo range. This number 42 + is independent of whether turbo has been disabled or not. 43 + 44 + num_pstates: displays the number of pstates that are supported 45 + by hardware. This number is independent of whether turbo has 46 + been disabled or not. 47 + 40 48 For contemporary Intel processors, the frequency is controlled by the 41 49 processor itself and the P-states exposed to software are related to 42 50 performance levels. The idea that frequency can be set to a single
+3
Documentation/kernel-parameters.txt
··· 1470 1470 no_hwp 1471 1471 Do not enable hardware P state control (HWP) 1472 1472 if available. 1473 + hwp_only 1474 + Only load intel_pstate on systems which support 1475 + hardware P state control (HWP) if available. 1473 1476 1474 1477 intremap= [X86-64, Intel-IOMMU] 1475 1478 on enable Interrupt Remapping (default)
+1
arch/x86/include/uapi/asm/msr-index.h
··· 358 358 359 359 #define MSR_IA32_PERF_STATUS 0x00000198 360 360 #define MSR_IA32_PERF_CTL 0x00000199 361 + #define INTEL_PERF_CTL_MASK 0xffff 361 362 #define MSR_AMD_PSTATE_DEF_BASE 0xc0010064 362 363 #define MSR_AMD_PERF_STATUS 0xc0010063 363 364 #define MSR_AMD_PERF_CTL 0xc0010062
+10
drivers/cpufreq/Kconfig.x86
··· 57 57 By enabling this option the acpi_cpufreq driver provides the old 58 58 entry in addition to the new boost ones, for compatibility reasons. 59 59 60 + config X86_SFI_CPUFREQ 61 + tristate "SFI Performance-States driver" 62 + depends on X86_INTEL_MID && SFI 63 + help 64 + This adds a CPUFreq driver for some Silvermont based Intel Atom 65 + architectures like Z34xx and Z35xx which enumerate processor 66 + performance states through SFI. 67 + 68 + If in doubt, say N. 69 + 60 70 config ELAN_CPUFREQ 61 71 tristate "AMD Elan SC400 and SC410" 62 72 depends on MELAN
+1
drivers/cpufreq/Makefile
··· 41 41 obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o 42 42 obj-$(CONFIG_X86_INTEL_PSTATE) += intel_pstate.o 43 43 obj-$(CONFIG_X86_AMD_FREQ_SENSITIVITY) += amd_freq_sensitivity.o 44 + obj-$(CONFIG_X86_SFI_CPUFREQ) += sfi-cpufreq.o 44 45 45 46 ################################################################################## 46 47 # ARM SoC drivers
+1 -2
drivers/cpufreq/cpufreq-dt.c
··· 320 320 { 321 321 struct private_data *priv = policy->driver_data; 322 322 323 - if (priv->cdev) 324 - cpufreq_cooling_unregister(priv->cdev); 323 + cpufreq_cooling_unregister(priv->cdev); 325 324 dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); 326 325 of_free_opp_table(priv->cpu_dev); 327 326 clk_put(policy->clk);
+71 -103
drivers/cpufreq/cpufreq.c
··· 27 27 #include <linux/mutex.h> 28 28 #include <linux/slab.h> 29 29 #include <linux/suspend.h> 30 + #include <linux/syscore_ops.h> 30 31 #include <linux/tick.h> 31 32 #include <trace/events/power.h> 33 + 34 + /* Macros to iterate over lists */ 35 + /* Iterate over online CPUs policies */ 36 + static LIST_HEAD(cpufreq_policy_list); 37 + #define for_each_policy(__policy) \ 38 + list_for_each_entry(__policy, &cpufreq_policy_list, policy_list) 39 + 40 + /* Iterate over governors */ 41 + static LIST_HEAD(cpufreq_governor_list); 42 + #define for_each_governor(__governor) \ 43 + list_for_each_entry(__governor, &cpufreq_governor_list, governor_list) 32 44 33 45 /** 34 46 * The "cpufreq driver" - the arch- or hardware-dependent low ··· 52 40 static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback); 53 41 static DEFINE_RWLOCK(cpufreq_driver_lock); 54 42 DEFINE_MUTEX(cpufreq_governor_lock); 55 - static LIST_HEAD(cpufreq_policy_list); 56 43 57 44 /* This one keeps track of the previously set governor of a removed CPU */ 58 45 static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); ··· 73 62 /* internal prototypes */ 74 63 static int __cpufreq_governor(struct cpufreq_policy *policy, 75 64 unsigned int event); 76 - static unsigned int __cpufreq_get(unsigned int cpu); 65 + static unsigned int __cpufreq_get(struct cpufreq_policy *policy); 77 66 static void handle_update(struct work_struct *work); 78 67 79 68 /** ··· 104 93 { 105 94 off = 1; 106 95 } 107 - static LIST_HEAD(cpufreq_governor_list); 108 96 static DEFINE_MUTEX(cpufreq_governor_mutex); 109 97 110 98 bool have_governor_per_policy(void) ··· 212 202 struct cpufreq_policy *policy = NULL; 213 203 unsigned long flags; 214 204 215 - if (cpufreq_disabled() || (cpu >= nr_cpu_ids)) 205 + if (cpu >= nr_cpu_ids) 216 206 return NULL; 217 207 218 208 if (!down_read_trylock(&cpufreq_rwsem)) ··· 239 229 240 230 void cpufreq_cpu_put(struct cpufreq_policy *policy) 241 231 { 242 - if (cpufreq_disabled()) 243 - return; 244 - 245 232 kobject_put(&policy->kobj); 246 233 up_read(&cpufreq_rwsem); 247 234 } ··· 256 249 * systems as each CPU might be scaled differently. So, use the arch 257 250 * per-CPU loops_per_jiffy value wherever possible. 258 251 */ 259 - #ifndef CONFIG_SMP 260 - static unsigned long l_p_j_ref; 261 - static unsigned int l_p_j_ref_freq; 262 - 263 252 static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) 264 253 { 254 + #ifndef CONFIG_SMP 255 + static unsigned long l_p_j_ref; 256 + static unsigned int l_p_j_ref_freq; 257 + 265 258 if (ci->flags & CPUFREQ_CONST_LOOPS) 266 259 return; 267 260 ··· 277 270 pr_debug("scaling loops_per_jiffy to %lu for frequency %u kHz\n", 278 271 loops_per_jiffy, ci->new); 279 272 } 280 - } 281 - #else 282 - static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) 283 - { 284 - return; 285 - } 286 273 #endif 274 + } 287 275 288 276 static void __cpufreq_notify_transition(struct cpufreq_policy *policy, 289 277 struct cpufreq_freqs *freqs, unsigned int state) ··· 434 432 } 435 433 define_one_global_rw(boost); 436 434 437 - static struct cpufreq_governor *__find_governor(const char *str_governor) 435 + static struct cpufreq_governor *find_governor(const char *str_governor) 438 436 { 439 437 struct cpufreq_governor *t; 440 438 441 - list_for_each_entry(t, &cpufreq_governor_list, governor_list) 439 + for_each_governor(t) 442 440 if (!strncasecmp(str_governor, t->name, CPUFREQ_NAME_LEN)) 443 441 return t; 444 442 ··· 465 463 *policy = CPUFREQ_POLICY_POWERSAVE; 466 464 err = 0; 467 465 } 468 - } else if (has_target()) { 466 + } else { 469 467 struct cpufreq_governor *t; 470 468 471 469 mutex_lock(&cpufreq_governor_mutex); 472 470 473 - t = __find_governor(str_governor); 471 + t = find_governor(str_governor); 474 472 475 473 if (t == NULL) { 476 474 int ret; ··· 480 478 mutex_lock(&cpufreq_governor_mutex); 481 479 482 480 if (ret == 0) 483 - t = __find_governor(str_governor); 481 + t = find_governor(str_governor); 484 482 } 485 483 486 484 if (t != NULL) { ··· 515 513 show_one(scaling_min_freq, min); 516 514 show_one(scaling_max_freq, max); 517 515 518 - static ssize_t show_scaling_cur_freq( 519 - struct cpufreq_policy *policy, char *buf) 516 + static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf) 520 517 { 521 518 ssize_t ret; 522 519 ··· 564 563 static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy, 565 564 char *buf) 566 565 { 567 - unsigned int cur_freq = __cpufreq_get(policy->cpu); 566 + unsigned int cur_freq = __cpufreq_get(policy); 568 567 if (!cur_freq) 569 568 return sprintf(buf, "<unknown>"); 570 569 return sprintf(buf, "%u\n", cur_freq); ··· 640 639 goto out; 641 640 } 642 641 643 - list_for_each_entry(t, &cpufreq_governor_list, governor_list) { 642 + for_each_governor(t) { 644 643 if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) 645 644 - (CPUFREQ_NAME_LEN + 2))) 646 645 goto out; ··· 903 902 904 903 /* set up files for this cpu device */ 905 904 drv_attr = cpufreq_driver->attr; 906 - while ((drv_attr) && (*drv_attr)) { 905 + while (drv_attr && *drv_attr) { 907 906 ret = sysfs_create_file(&policy->kobj, &((*drv_attr)->attr)); 908 907 if (ret) 909 908 return ret; ··· 937 936 memcpy(&new_policy, policy, sizeof(*policy)); 938 937 939 938 /* Update governor of new_policy to the governor used before hotplug */ 940 - gov = __find_governor(per_cpu(cpufreq_cpu_governor, policy->cpu)); 939 + gov = find_governor(per_cpu(cpufreq_cpu_governor, policy->cpu)); 941 940 if (gov) 942 941 pr_debug("Restoring governor %s for cpu %d\n", 943 942 policy->governor->name, policy->cpu); ··· 959 958 } 960 959 } 961 960 962 - #ifdef CONFIG_HOTPLUG_CPU 963 961 static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, 964 962 unsigned int cpu, struct device *dev) 965 963 { ··· 996 996 997 997 return sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); 998 998 } 999 - #endif 1000 999 1001 1000 static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu) 1002 1001 { ··· 1032 1033 init_rwsem(&policy->rwsem); 1033 1034 spin_lock_init(&policy->transition_lock); 1034 1035 init_waitqueue_head(&policy->transition_wait); 1036 + init_completion(&policy->kobj_unregister); 1037 + INIT_WORK(&policy->update, handle_update); 1035 1038 1036 1039 return policy; 1037 1040 ··· 1092 1091 } 1093 1092 1094 1093 down_write(&policy->rwsem); 1095 - 1096 - policy->last_cpu = policy->cpu; 1097 1094 policy->cpu = cpu; 1098 - 1099 1095 up_write(&policy->rwsem); 1100 - 1101 - blocking_notifier_call_chain(&cpufreq_policy_notifier_list, 1102 - CPUFREQ_UPDATE_POLICY_CPU, policy); 1103 1096 1104 1097 return 0; 1105 1098 } ··· 1105 1110 struct cpufreq_policy *policy; 1106 1111 unsigned long flags; 1107 1112 bool recover_policy = cpufreq_suspended; 1108 - #ifdef CONFIG_HOTPLUG_CPU 1109 - struct cpufreq_policy *tpolicy; 1110 - #endif 1111 1113 1112 1114 if (cpu_is_offline(cpu)) 1113 1115 return 0; 1114 1116 1115 1117 pr_debug("adding CPU %u\n", cpu); 1116 1118 1117 - #ifdef CONFIG_SMP 1118 1119 /* check whether a different CPU already registered this 1119 1120 * CPU because it is in the same boat. */ 1120 - policy = cpufreq_cpu_get(cpu); 1121 - if (unlikely(policy)) { 1122 - cpufreq_cpu_put(policy); 1121 + policy = cpufreq_cpu_get_raw(cpu); 1122 + if (unlikely(policy)) 1123 1123 return 0; 1124 - } 1125 - #endif 1126 1124 1127 1125 if (!down_read_trylock(&cpufreq_rwsem)) 1128 1126 return 0; 1129 1127 1130 - #ifdef CONFIG_HOTPLUG_CPU 1131 1128 /* Check if this cpu was hot-unplugged earlier and has siblings */ 1132 1129 read_lock_irqsave(&cpufreq_driver_lock, flags); 1133 - list_for_each_entry(tpolicy, &cpufreq_policy_list, policy_list) { 1134 - if (cpumask_test_cpu(cpu, tpolicy->related_cpus)) { 1130 + for_each_policy(policy) { 1131 + if (cpumask_test_cpu(cpu, policy->related_cpus)) { 1135 1132 read_unlock_irqrestore(&cpufreq_driver_lock, flags); 1136 - ret = cpufreq_add_policy_cpu(tpolicy, cpu, dev); 1133 + ret = cpufreq_add_policy_cpu(policy, cpu, dev); 1137 1134 up_read(&cpufreq_rwsem); 1138 1135 return ret; 1139 1136 } 1140 1137 } 1141 1138 read_unlock_irqrestore(&cpufreq_driver_lock, flags); 1142 - #endif 1143 1139 1144 1140 /* 1145 1141 * Restore the saved policy when doing light-weight init and fall back ··· 1156 1170 policy->cpu = cpu; 1157 1171 1158 1172 cpumask_copy(policy->cpus, cpumask_of(cpu)); 1159 - 1160 - init_completion(&policy->kobj_unregister); 1161 - INIT_WORK(&policy->update, handle_update); 1162 1173 1163 1174 /* call driver. From then on the cpufreq must be able 1164 1175 * to accept all calls to ->verify and ->setpolicy for this CPU ··· 1354 1371 pr_err("%s: Failed to stop governor\n", __func__); 1355 1372 return ret; 1356 1373 } 1357 - } 1358 1374 1359 - if (!cpufreq_driver->setpolicy) 1360 1375 strncpy(per_cpu(cpufreq_cpu_governor, cpu), 1361 1376 policy->governor->name, CPUFREQ_NAME_LEN); 1377 + } 1362 1378 1363 1379 down_read(&policy->rwsem); 1364 1380 cpus = cpumask_weight(policy->cpus); ··· 1398 1416 unsigned long flags; 1399 1417 struct cpufreq_policy *policy; 1400 1418 1401 - read_lock_irqsave(&cpufreq_driver_lock, flags); 1419 + write_lock_irqsave(&cpufreq_driver_lock, flags); 1402 1420 policy = per_cpu(cpufreq_cpu_data, cpu); 1403 - read_unlock_irqrestore(&cpufreq_driver_lock, flags); 1421 + per_cpu(cpufreq_cpu_data, cpu) = NULL; 1422 + write_unlock_irqrestore(&cpufreq_driver_lock, flags); 1404 1423 1405 1424 if (!policy) { 1406 1425 pr_debug("%s: No cpu_data found\n", __func__); ··· 1456 1473 } 1457 1474 } 1458 1475 1459 - per_cpu(cpufreq_cpu_data, cpu) = NULL; 1460 1476 return 0; 1461 1477 } 1462 1478 ··· 1492 1510 /** 1493 1511 * cpufreq_out_of_sync - If actual and saved CPU frequency differs, we're 1494 1512 * in deep trouble. 1495 - * @cpu: cpu number 1496 - * @old_freq: CPU frequency the kernel thinks the CPU runs at 1513 + * @policy: policy managing CPUs 1497 1514 * @new_freq: CPU frequency the CPU actually runs at 1498 1515 * 1499 1516 * We adjust to current frequency first, and need to clean up later. 1500 1517 * So either call to cpufreq_update_policy() or schedule handle_update()). 1501 1518 */ 1502 - static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, 1519 + static void cpufreq_out_of_sync(struct cpufreq_policy *policy, 1503 1520 unsigned int new_freq) 1504 1521 { 1505 - struct cpufreq_policy *policy; 1506 1522 struct cpufreq_freqs freqs; 1507 - unsigned long flags; 1508 1523 1509 1524 pr_debug("Warning: CPU frequency out of sync: cpufreq and timing core thinks of %u, is %u kHz\n", 1510 - old_freq, new_freq); 1525 + policy->cur, new_freq); 1511 1526 1512 - freqs.old = old_freq; 1527 + freqs.old = policy->cur; 1513 1528 freqs.new = new_freq; 1514 - 1515 - read_lock_irqsave(&cpufreq_driver_lock, flags); 1516 - policy = per_cpu(cpufreq_cpu_data, cpu); 1517 - read_unlock_irqrestore(&cpufreq_driver_lock, flags); 1518 1529 1519 1530 cpufreq_freq_transition_begin(policy, &freqs); 1520 1531 cpufreq_freq_transition_end(policy, &freqs, 0); ··· 1558 1583 } 1559 1584 EXPORT_SYMBOL(cpufreq_quick_get_max); 1560 1585 1561 - static unsigned int __cpufreq_get(unsigned int cpu) 1586 + static unsigned int __cpufreq_get(struct cpufreq_policy *policy) 1562 1587 { 1563 - struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); 1564 1588 unsigned int ret_freq = 0; 1565 1589 1566 1590 if (!cpufreq_driver->get) 1567 1591 return ret_freq; 1568 1592 1569 - ret_freq = cpufreq_driver->get(cpu); 1593 + ret_freq = cpufreq_driver->get(policy->cpu); 1570 1594 1571 1595 if (ret_freq && policy->cur && 1572 1596 !(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { 1573 1597 /* verify no discrepancy between actual and 1574 1598 saved value exists */ 1575 1599 if (unlikely(ret_freq != policy->cur)) { 1576 - cpufreq_out_of_sync(cpu, policy->cur, ret_freq); 1600 + cpufreq_out_of_sync(policy, ret_freq); 1577 1601 schedule_work(&policy->update); 1578 1602 } 1579 1603 } ··· 1593 1619 1594 1620 if (policy) { 1595 1621 down_read(&policy->rwsem); 1596 - ret_freq = __cpufreq_get(cpu); 1622 + ret_freq = __cpufreq_get(policy); 1597 1623 up_read(&policy->rwsem); 1598 1624 1599 1625 cpufreq_cpu_put(policy); ··· 1656 1682 1657 1683 pr_debug("%s: Suspending Governors\n", __func__); 1658 1684 1659 - list_for_each_entry(policy, &cpufreq_policy_list, policy_list) { 1685 + for_each_policy(policy) { 1660 1686 if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP)) 1661 1687 pr_err("%s: Failed to stop governor for policy: %p\n", 1662 1688 __func__, policy); ··· 1690 1716 1691 1717 pr_debug("%s: Resuming Governors\n", __func__); 1692 1718 1693 - list_for_each_entry(policy, &cpufreq_policy_list, policy_list) { 1719 + for_each_policy(policy) { 1694 1720 if (cpufreq_driver->resume && cpufreq_driver->resume(policy)) 1695 1721 pr_err("%s: Failed to resume driver: %p\n", __func__, 1696 1722 policy); ··· 1980 2006 } 1981 2007 EXPORT_SYMBOL_GPL(cpufreq_driver_target); 1982 2008 1983 - /* 1984 - * when "event" is CPUFREQ_GOV_LIMITS 1985 - */ 1986 - 1987 2009 static int __cpufreq_governor(struct cpufreq_policy *policy, 1988 2010 unsigned int event) 1989 2011 { ··· 2077 2107 2078 2108 governor->initialized = 0; 2079 2109 err = -EBUSY; 2080 - if (__find_governor(governor->name) == NULL) { 2110 + if (!find_governor(governor->name)) { 2081 2111 err = 0; 2082 2112 list_add(&governor->governor_list, &cpufreq_governor_list); 2083 2113 } ··· 2277 2307 policy->cur = new_policy.cur; 2278 2308 } else { 2279 2309 if (policy->cur != new_policy.cur && has_target()) 2280 - cpufreq_out_of_sync(cpu, policy->cur, 2281 - new_policy.cur); 2310 + cpufreq_out_of_sync(policy, new_policy.cur); 2282 2311 } 2283 2312 } 2284 2313 ··· 2333 2364 struct cpufreq_policy *policy; 2334 2365 int ret = -EINVAL; 2335 2366 2336 - list_for_each_entry(policy, &cpufreq_policy_list, policy_list) { 2367 + for_each_policy(policy) { 2337 2368 freq_table = cpufreq_frequency_get_table(policy->cpu); 2338 2369 if (freq_table) { 2339 2370 ret = cpufreq_frequency_table_cpuinfo(policy, ··· 2423 2454 2424 2455 pr_debug("trying to register driver %s\n", driver_data->name); 2425 2456 2426 - if (driver_data->setpolicy) 2427 - driver_data->flags |= CPUFREQ_CONST_LOOPS; 2428 - 2429 2457 write_lock_irqsave(&cpufreq_driver_lock, flags); 2430 2458 if (cpufreq_driver) { 2431 2459 write_unlock_irqrestore(&cpufreq_driver_lock, flags); ··· 2430 2464 } 2431 2465 cpufreq_driver = driver_data; 2432 2466 write_unlock_irqrestore(&cpufreq_driver_lock, flags); 2467 + 2468 + if (driver_data->setpolicy) 2469 + driver_data->flags |= CPUFREQ_CONST_LOOPS; 2433 2470 2434 2471 if (cpufreq_boost_supported()) { 2435 2472 /* ··· 2454 2485 if (ret) 2455 2486 goto err_boost_unreg; 2456 2487 2457 - if (!(cpufreq_driver->flags & CPUFREQ_STICKY)) { 2458 - int i; 2459 - ret = -ENODEV; 2460 - 2461 - /* check for at least one working CPU */ 2462 - for (i = 0; i < nr_cpu_ids; i++) 2463 - if (cpu_possible(i) && per_cpu(cpufreq_cpu_data, i)) { 2464 - ret = 0; 2465 - break; 2466 - } 2467 - 2488 + if (!(cpufreq_driver->flags & CPUFREQ_STICKY) && 2489 + list_empty(&cpufreq_policy_list)) { 2468 2490 /* if all ->init() calls failed, unregister */ 2469 - if (ret) { 2470 - pr_debug("no CPU initialized for driver %s\n", 2471 - driver_data->name); 2472 - goto err_if_unreg; 2473 - } 2491 + pr_debug("%s: No CPU initialized for driver %s\n", __func__, 2492 + driver_data->name); 2493 + goto err_if_unreg; 2474 2494 } 2475 2495 2476 2496 register_hotcpu_notifier(&cpufreq_cpu_notifier); ··· 2514 2556 } 2515 2557 EXPORT_SYMBOL_GPL(cpufreq_unregister_driver); 2516 2558 2559 + /* 2560 + * Stop cpufreq at shutdown to make sure it isn't holding any locks 2561 + * or mutexes when secondary CPUs are halted. 2562 + */ 2563 + static struct syscore_ops cpufreq_syscore_ops = { 2564 + .shutdown = cpufreq_suspend, 2565 + }; 2566 + 2517 2567 static int __init cpufreq_core_init(void) 2518 2568 { 2519 2569 if (cpufreq_disabled()) ··· 2529 2563 2530 2564 cpufreq_global_kobject = kobject_create(); 2531 2565 BUG_ON(!cpufreq_global_kobject); 2566 + 2567 + register_syscore_ops(&cpufreq_syscore_ops); 2532 2568 2533 2569 return 0; 2534 2570 }
+97 -122
drivers/cpufreq/cpufreq_stats.c
··· 18 18 static spinlock_t cpufreq_stats_lock; 19 19 20 20 struct cpufreq_stats { 21 - unsigned int cpu; 22 21 unsigned int total_trans; 23 22 unsigned long long last_time; 24 23 unsigned int max_state; ··· 30 31 #endif 31 32 }; 32 33 33 - static DEFINE_PER_CPU(struct cpufreq_stats *, cpufreq_stats_table); 34 - 35 - struct cpufreq_stats_attribute { 36 - struct attribute attr; 37 - ssize_t(*show) (struct cpufreq_stats *, char *); 38 - }; 39 - 40 - static int cpufreq_stats_update(unsigned int cpu) 34 + static int cpufreq_stats_update(struct cpufreq_stats *stats) 41 35 { 42 - struct cpufreq_stats *stat; 43 - unsigned long long cur_time; 36 + unsigned long long cur_time = get_jiffies_64(); 44 37 45 - cur_time = get_jiffies_64(); 46 38 spin_lock(&cpufreq_stats_lock); 47 - stat = per_cpu(cpufreq_stats_table, cpu); 48 - if (stat->time_in_state) 49 - stat->time_in_state[stat->last_index] += 50 - cur_time - stat->last_time; 51 - stat->last_time = cur_time; 39 + stats->time_in_state[stats->last_index] += cur_time - stats->last_time; 40 + stats->last_time = cur_time; 52 41 spin_unlock(&cpufreq_stats_lock); 53 42 return 0; 54 43 } 55 44 56 45 static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf) 57 46 { 58 - struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); 59 - if (!stat) 60 - return 0; 61 - return sprintf(buf, "%d\n", 62 - per_cpu(cpufreq_stats_table, stat->cpu)->total_trans); 47 + return sprintf(buf, "%d\n", policy->stats->total_trans); 63 48 } 64 49 65 50 static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf) 66 51 { 52 + struct cpufreq_stats *stats = policy->stats; 67 53 ssize_t len = 0; 68 54 int i; 69 - struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); 70 - if (!stat) 71 - return 0; 72 - cpufreq_stats_update(stat->cpu); 73 - for (i = 0; i < stat->state_num; i++) { 74 - len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], 55 + 56 + cpufreq_stats_update(stats); 57 + for (i = 0; i < stats->state_num; i++) { 58 + len += sprintf(buf + len, "%u %llu\n", stats->freq_table[i], 75 59 (unsigned long long) 76 - jiffies_64_to_clock_t(stat->time_in_state[i])); 60 + jiffies_64_to_clock_t(stats->time_in_state[i])); 77 61 } 78 62 return len; 79 63 } ··· 64 82 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS 65 83 static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf) 66 84 { 85 + struct cpufreq_stats *stats = policy->stats; 67 86 ssize_t len = 0; 68 87 int i, j; 69 88 70 - struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); 71 - if (!stat) 72 - return 0; 73 - cpufreq_stats_update(stat->cpu); 74 89 len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); 75 90 len += snprintf(buf + len, PAGE_SIZE - len, " : "); 76 - for (i = 0; i < stat->state_num; i++) { 91 + for (i = 0; i < stats->state_num; i++) { 77 92 if (len >= PAGE_SIZE) 78 93 break; 79 94 len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", 80 - stat->freq_table[i]); 95 + stats->freq_table[i]); 81 96 } 82 97 if (len >= PAGE_SIZE) 83 98 return PAGE_SIZE; 84 99 85 100 len += snprintf(buf + len, PAGE_SIZE - len, "\n"); 86 101 87 - for (i = 0; i < stat->state_num; i++) { 102 + for (i = 0; i < stats->state_num; i++) { 88 103 if (len >= PAGE_SIZE) 89 104 break; 90 105 91 106 len += snprintf(buf + len, PAGE_SIZE - len, "%9u: ", 92 - stat->freq_table[i]); 107 + stats->freq_table[i]); 93 108 94 - for (j = 0; j < stat->state_num; j++) { 109 + for (j = 0; j < stats->state_num; j++) { 95 110 if (len >= PAGE_SIZE) 96 111 break; 97 112 len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", 98 - stat->trans_table[i*stat->max_state+j]); 113 + stats->trans_table[i*stats->max_state+j]); 99 114 } 100 115 if (len >= PAGE_SIZE) 101 116 break; ··· 121 142 .name = "stats" 122 143 }; 123 144 124 - static int freq_table_get_index(struct cpufreq_stats *stat, unsigned int freq) 145 + static int freq_table_get_index(struct cpufreq_stats *stats, unsigned int freq) 125 146 { 126 147 int index; 127 - for (index = 0; index < stat->max_state; index++) 128 - if (stat->freq_table[index] == freq) 148 + for (index = 0; index < stats->max_state; index++) 149 + if (stats->freq_table[index] == freq) 129 150 return index; 130 151 return -1; 131 152 } 132 153 133 154 static void __cpufreq_stats_free_table(struct cpufreq_policy *policy) 134 155 { 135 - struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, policy->cpu); 156 + struct cpufreq_stats *stats = policy->stats; 136 157 137 - if (!stat) 158 + /* Already freed */ 159 + if (!stats) 138 160 return; 139 161 140 - pr_debug("%s: Free stat table\n", __func__); 162 + pr_debug("%s: Free stats table\n", __func__); 141 163 142 164 sysfs_remove_group(&policy->kobj, &stats_attr_group); 143 - kfree(stat->time_in_state); 144 - kfree(stat); 145 - per_cpu(cpufreq_stats_table, policy->cpu) = NULL; 165 + kfree(stats->time_in_state); 166 + kfree(stats); 167 + policy->stats = NULL; 146 168 } 147 169 148 170 static void cpufreq_stats_free_table(unsigned int cpu) ··· 154 174 if (!policy) 155 175 return; 156 176 157 - if (cpufreq_frequency_get_table(policy->cpu)) 158 - __cpufreq_stats_free_table(policy); 177 + __cpufreq_stats_free_table(policy); 159 178 160 179 cpufreq_cpu_put(policy); 161 180 } 162 181 163 182 static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) 164 183 { 165 - unsigned int i, count = 0, ret = 0; 166 - struct cpufreq_stats *stat; 184 + unsigned int i = 0, count = 0, ret = -ENOMEM; 185 + struct cpufreq_stats *stats; 167 186 unsigned int alloc_size; 168 187 unsigned int cpu = policy->cpu; 169 188 struct cpufreq_frequency_table *pos, *table; 170 189 190 + /* We need cpufreq table for creating stats table */ 171 191 table = cpufreq_frequency_get_table(cpu); 172 192 if (unlikely(!table)) 173 193 return 0; 174 194 175 - if (per_cpu(cpufreq_stats_table, cpu)) 176 - return -EBUSY; 177 - stat = kzalloc(sizeof(*stat), GFP_KERNEL); 178 - if ((stat) == NULL) 195 + /* stats already initialized */ 196 + if (policy->stats) 197 + return -EEXIST; 198 + 199 + stats = kzalloc(sizeof(*stats), GFP_KERNEL); 200 + if (!stats) 179 201 return -ENOMEM; 180 202 181 - ret = sysfs_create_group(&policy->kobj, &stats_attr_group); 182 - if (ret) 183 - goto error_out; 184 - 185 - stat->cpu = cpu; 186 - per_cpu(cpufreq_stats_table, cpu) = stat; 187 - 203 + /* Find total allocation size */ 188 204 cpufreq_for_each_valid_entry(pos, table) 189 205 count++; 190 206 ··· 189 213 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS 190 214 alloc_size += count * count * sizeof(int); 191 215 #endif 192 - stat->max_state = count; 193 - stat->time_in_state = kzalloc(alloc_size, GFP_KERNEL); 194 - if (!stat->time_in_state) { 195 - ret = -ENOMEM; 196 - goto error_alloc; 197 - } 198 - stat->freq_table = (unsigned int *)(stat->time_in_state + count); 216 + 217 + /* Allocate memory for time_in_state/freq_table/trans_table in one go */ 218 + stats->time_in_state = kzalloc(alloc_size, GFP_KERNEL); 219 + if (!stats->time_in_state) 220 + goto free_stat; 221 + 222 + stats->freq_table = (unsigned int *)(stats->time_in_state + count); 199 223 200 224 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS 201 - stat->trans_table = stat->freq_table + count; 225 + stats->trans_table = stats->freq_table + count; 202 226 #endif 203 - i = 0; 227 + 228 + stats->max_state = count; 229 + 230 + /* Find valid-unique entries */ 204 231 cpufreq_for_each_valid_entry(pos, table) 205 - if (freq_table_get_index(stat, pos->frequency) == -1) 206 - stat->freq_table[i++] = pos->frequency; 207 - stat->state_num = i; 208 - spin_lock(&cpufreq_stats_lock); 209 - stat->last_time = get_jiffies_64(); 210 - stat->last_index = freq_table_get_index(stat, policy->cur); 211 - spin_unlock(&cpufreq_stats_lock); 212 - return 0; 213 - error_alloc: 214 - sysfs_remove_group(&policy->kobj, &stats_attr_group); 215 - error_out: 216 - kfree(stat); 217 - per_cpu(cpufreq_stats_table, cpu) = NULL; 232 + if (freq_table_get_index(stats, pos->frequency) == -1) 233 + stats->freq_table[i++] = pos->frequency; 234 + 235 + stats->state_num = i; 236 + stats->last_time = get_jiffies_64(); 237 + stats->last_index = freq_table_get_index(stats, policy->cur); 238 + 239 + policy->stats = stats; 240 + ret = sysfs_create_group(&policy->kobj, &stats_attr_group); 241 + if (!ret) 242 + return 0; 243 + 244 + /* We failed, release resources */ 245 + policy->stats = NULL; 246 + kfree(stats->time_in_state); 247 + free_stat: 248 + kfree(stats); 249 + 218 250 return ret; 219 251 } 220 252 ··· 243 259 cpufreq_cpu_put(policy); 244 260 } 245 261 246 - static void cpufreq_stats_update_policy_cpu(struct cpufreq_policy *policy) 247 - { 248 - struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, 249 - policy->last_cpu); 250 - 251 - pr_debug("Updating stats_table for new_cpu %u from last_cpu %u\n", 252 - policy->cpu, policy->last_cpu); 253 - per_cpu(cpufreq_stats_table, policy->cpu) = per_cpu(cpufreq_stats_table, 254 - policy->last_cpu); 255 - per_cpu(cpufreq_stats_table, policy->last_cpu) = NULL; 256 - stat->cpu = policy->cpu; 257 - } 258 - 259 262 static int cpufreq_stat_notifier_policy(struct notifier_block *nb, 260 263 unsigned long val, void *data) 261 264 { 262 265 int ret = 0; 263 266 struct cpufreq_policy *policy = data; 264 - 265 - if (val == CPUFREQ_UPDATE_POLICY_CPU) { 266 - cpufreq_stats_update_policy_cpu(policy); 267 - return 0; 268 - } 269 267 270 268 if (val == CPUFREQ_CREATE_POLICY) 271 269 ret = __cpufreq_stats_create_table(policy); ··· 261 295 unsigned long val, void *data) 262 296 { 263 297 struct cpufreq_freqs *freq = data; 264 - struct cpufreq_stats *stat; 298 + struct cpufreq_policy *policy = cpufreq_cpu_get(freq->cpu); 299 + struct cpufreq_stats *stats; 265 300 int old_index, new_index; 266 301 302 + if (!policy) { 303 + pr_err("%s: No policy found\n", __func__); 304 + return 0; 305 + } 306 + 267 307 if (val != CPUFREQ_POSTCHANGE) 268 - return 0; 308 + goto put_policy; 269 309 270 - stat = per_cpu(cpufreq_stats_table, freq->cpu); 271 - if (!stat) 272 - return 0; 310 + if (!policy->stats) { 311 + pr_debug("%s: No stats found\n", __func__); 312 + goto put_policy; 313 + } 273 314 274 - old_index = stat->last_index; 275 - new_index = freq_table_get_index(stat, freq->new); 315 + stats = policy->stats; 276 316 277 - /* We can't do stat->time_in_state[-1]= .. */ 317 + old_index = stats->last_index; 318 + new_index = freq_table_get_index(stats, freq->new); 319 + 320 + /* We can't do stats->time_in_state[-1]= .. */ 278 321 if (old_index == -1 || new_index == -1) 279 - return 0; 280 - 281 - cpufreq_stats_update(freq->cpu); 322 + goto put_policy; 282 323 283 324 if (old_index == new_index) 284 - return 0; 325 + goto put_policy; 285 326 286 - spin_lock(&cpufreq_stats_lock); 287 - stat->last_index = new_index; 327 + cpufreq_stats_update(stats); 328 + 329 + stats->last_index = new_index; 288 330 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS 289 - stat->trans_table[old_index * stat->max_state + new_index]++; 331 + stats->trans_table[old_index * stats->max_state + new_index]++; 290 332 #endif 291 - stat->total_trans++; 292 - spin_unlock(&cpufreq_stats_lock); 333 + stats->total_trans++; 334 + 335 + put_policy: 336 + cpufreq_cpu_put(policy); 293 337 return 0; 294 338 } 295 339 ··· 350 374 } 351 375 352 376 MODULE_AUTHOR("Zou Nan hai <nanhai.zou@intel.com>"); 353 - MODULE_DESCRIPTION("'cpufreq_stats' - A driver to export cpufreq stats " 354 - "through sysfs filesystem"); 377 + MODULE_DESCRIPTION("Export cpufreq stats via sysfs"); 355 378 MODULE_LICENSE("GPL"); 356 379 357 380 module_init(cpufreq_stats_init);
+51 -4
drivers/cpufreq/intel_pstate.c
··· 148 148 int32_t min_perf; 149 149 int max_policy_pct; 150 150 int max_sysfs_pct; 151 + int min_policy_pct; 152 + int min_sysfs_pct; 151 153 }; 152 154 153 155 static struct perf_limits limits = { ··· 161 159 .min_perf = 0, 162 160 .max_policy_pct = 100, 163 161 .max_sysfs_pct = 100, 162 + .min_policy_pct = 0, 163 + .min_sysfs_pct = 0, 164 164 }; 165 165 166 166 static inline void pid_reset(struct _pid *pid, int setpoint, int busy, ··· 342 338 return sprintf(buf, "%u\n", limits.object); \ 343 339 } 344 340 341 + static ssize_t show_turbo_pct(struct kobject *kobj, 342 + struct attribute *attr, char *buf) 343 + { 344 + struct cpudata *cpu; 345 + int total, no_turbo, turbo_pct; 346 + uint32_t turbo_fp; 347 + 348 + cpu = all_cpu_data[0]; 349 + 350 + total = cpu->pstate.turbo_pstate - cpu->pstate.min_pstate + 1; 351 + no_turbo = cpu->pstate.max_pstate - cpu->pstate.min_pstate + 1; 352 + turbo_fp = div_fp(int_tofp(no_turbo), int_tofp(total)); 353 + turbo_pct = 100 - fp_toint(mul_fp(turbo_fp, int_tofp(100))); 354 + return sprintf(buf, "%u\n", turbo_pct); 355 + } 356 + 357 + static ssize_t show_num_pstates(struct kobject *kobj, 358 + struct attribute *attr, char *buf) 359 + { 360 + struct cpudata *cpu; 361 + int total; 362 + 363 + cpu = all_cpu_data[0]; 364 + total = cpu->pstate.turbo_pstate - cpu->pstate.min_pstate + 1; 365 + return sprintf(buf, "%u\n", total); 366 + } 367 + 345 368 static ssize_t show_no_turbo(struct kobject *kobj, 346 369 struct attribute *attr, char *buf) 347 370 { ··· 435 404 ret = sscanf(buf, "%u", &input); 436 405 if (ret != 1) 437 406 return -EINVAL; 438 - limits.min_perf_pct = clamp_t(int, input, 0 , 100); 407 + 408 + limits.min_sysfs_pct = clamp_t(int, input, 0 , 100); 409 + limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct); 439 410 limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); 440 411 441 412 if (hwp_active) ··· 451 418 define_one_global_rw(no_turbo); 452 419 define_one_global_rw(max_perf_pct); 453 420 define_one_global_rw(min_perf_pct); 421 + define_one_global_ro(turbo_pct); 422 + define_one_global_ro(num_pstates); 454 423 455 424 static struct attribute *intel_pstate_attributes[] = { 456 425 &no_turbo.attr, 457 426 &max_perf_pct.attr, 458 427 &min_perf_pct.attr, 428 + &turbo_pct.attr, 429 + &num_pstates.attr, 459 430 NULL 460 431 }; 461 432 ··· 862 825 ICPU(0x46, core_params), 863 826 ICPU(0x47, core_params), 864 827 ICPU(0x4c, byt_params), 828 + ICPU(0x4e, core_params), 865 829 ICPU(0x4f, core_params), 866 830 ICPU(0x56, core_params), 867 831 {} ··· 925 887 if (!policy->cpuinfo.max_freq) 926 888 return -ENODEV; 927 889 928 - if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { 890 + if (policy->policy == CPUFREQ_POLICY_PERFORMANCE && 891 + policy->max >= policy->cpuinfo.max_freq) { 892 + limits.min_policy_pct = 100; 929 893 limits.min_perf_pct = 100; 930 894 limits.min_perf = int_tofp(1); 931 895 limits.max_policy_pct = 100; ··· 937 897 return 0; 938 898 } 939 899 940 - limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq; 941 - limits.min_perf_pct = clamp_t(int, limits.min_perf_pct, 0 , 100); 900 + limits.min_policy_pct = (policy->min * 100) / policy->cpuinfo.max_freq; 901 + limits.min_policy_pct = clamp_t(int, limits.min_policy_pct, 0 , 100); 902 + limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct); 942 903 limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100)); 943 904 944 905 limits.max_policy_pct = (policy->max * 100) / policy->cpuinfo.max_freq; ··· 1019 978 1020 979 static int __initdata no_load; 1021 980 static int __initdata no_hwp; 981 + static int __initdata hwp_only; 1022 982 static unsigned int force_load; 1023 983 1024 984 static int intel_pstate_msrs_not_valid(void) ··· 1217 1175 if (cpu_has(c,X86_FEATURE_HWP) && !no_hwp) 1218 1176 intel_pstate_hwp_enable(); 1219 1177 1178 + if (!hwp_active && hwp_only) 1179 + goto out; 1180 + 1220 1181 rc = cpufreq_register_driver(&intel_pstate_driver); 1221 1182 if (rc) 1222 1183 goto out; ··· 1254 1209 no_hwp = 1; 1255 1210 if (!strcmp(str, "force")) 1256 1211 force_load = 1; 1212 + if (!strcmp(str, "hwp_only")) 1213 + hwp_only = 1; 1257 1214 return 0; 1258 1215 } 1259 1216 early_param("intel_pstate", intel_pstate_setup);
-1
drivers/cpufreq/ls1x-cpufreq.c
··· 210 210 static struct platform_driver ls1x_cpufreq_platdrv = { 211 211 .driver = { 212 212 .name = "ls1x-cpufreq", 213 - .owner = THIS_MODULE, 214 213 }, 215 214 .probe = ls1x_cpufreq_probe, 216 215 .remove = ls1x_cpufreq_remove,
+136
drivers/cpufreq/sfi-cpufreq.c
··· 1 + /* 2 + * SFI Performance States Driver 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License. 7 + * 8 + * This program is distributed in the hope that it will be useful, but 9 + * WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 + * General Public License for more details. 12 + * 13 + * Author: Vishwesh M Rudramuni <vishwesh.m.rudramuni@intel.com> 14 + * Author: Srinidhi Kasagar <srinidhi.kasagar@intel.com> 15 + */ 16 + 17 + #include <linux/cpufreq.h> 18 + #include <linux/init.h> 19 + #include <linux/kernel.h> 20 + #include <linux/module.h> 21 + #include <linux/sfi.h> 22 + #include <linux/slab.h> 23 + #include <linux/smp.h> 24 + 25 + #include <asm/msr.h> 26 + 27 + struct cpufreq_frequency_table *freq_table; 28 + static struct sfi_freq_table_entry *sfi_cpufreq_array; 29 + static int num_freq_table_entries; 30 + 31 + static int sfi_parse_freq(struct sfi_table_header *table) 32 + { 33 + struct sfi_table_simple *sb; 34 + struct sfi_freq_table_entry *pentry; 35 + int totallen; 36 + 37 + sb = (struct sfi_table_simple *)table; 38 + num_freq_table_entries = SFI_GET_NUM_ENTRIES(sb, 39 + struct sfi_freq_table_entry); 40 + if (num_freq_table_entries <= 1) { 41 + pr_err("No p-states discovered\n"); 42 + return -ENODEV; 43 + } 44 + 45 + pentry = (struct sfi_freq_table_entry *)sb->pentry; 46 + totallen = num_freq_table_entries * sizeof(*pentry); 47 + 48 + sfi_cpufreq_array = kzalloc(totallen, GFP_KERNEL); 49 + if (!sfi_cpufreq_array) 50 + return -ENOMEM; 51 + 52 + memcpy(sfi_cpufreq_array, pentry, totallen); 53 + 54 + return 0; 55 + } 56 + 57 + static int sfi_cpufreq_target(struct cpufreq_policy *policy, unsigned int index) 58 + { 59 + unsigned int next_perf_state = 0; /* Index into perf table */ 60 + u32 lo, hi; 61 + 62 + next_perf_state = policy->freq_table[index].driver_data; 63 + 64 + rdmsr_on_cpu(policy->cpu, MSR_IA32_PERF_CTL, &lo, &hi); 65 + lo = (lo & ~INTEL_PERF_CTL_MASK) | 66 + ((u32) sfi_cpufreq_array[next_perf_state].ctrl_val & 67 + INTEL_PERF_CTL_MASK); 68 + wrmsr_on_cpu(policy->cpu, MSR_IA32_PERF_CTL, lo, hi); 69 + 70 + return 0; 71 + } 72 + 73 + static int sfi_cpufreq_cpu_init(struct cpufreq_policy *policy) 74 + { 75 + policy->shared_type = CPUFREQ_SHARED_TYPE_HW; 76 + policy->cpuinfo.transition_latency = 100000; /* 100us */ 77 + 78 + return cpufreq_table_validate_and_show(policy, freq_table); 79 + } 80 + 81 + static struct cpufreq_driver sfi_cpufreq_driver = { 82 + .flags = CPUFREQ_CONST_LOOPS, 83 + .verify = cpufreq_generic_frequency_table_verify, 84 + .target_index = sfi_cpufreq_target, 85 + .init = sfi_cpufreq_cpu_init, 86 + .name = "sfi-cpufreq", 87 + .attr = cpufreq_generic_attr, 88 + }; 89 + 90 + static int __init sfi_cpufreq_init(void) 91 + { 92 + int ret, i; 93 + 94 + /* parse the freq table from SFI */ 95 + ret = sfi_table_parse(SFI_SIG_FREQ, NULL, NULL, sfi_parse_freq); 96 + if (ret) 97 + return ret; 98 + 99 + freq_table = kzalloc(sizeof(*freq_table) * 100 + (num_freq_table_entries + 1), GFP_KERNEL); 101 + if (!freq_table) { 102 + ret = -ENOMEM; 103 + goto err_free_array; 104 + } 105 + 106 + for (i = 0; i < num_freq_table_entries; i++) { 107 + freq_table[i].driver_data = i; 108 + freq_table[i].frequency = sfi_cpufreq_array[i].freq_mhz * 1000; 109 + } 110 + freq_table[i].frequency = CPUFREQ_TABLE_END; 111 + 112 + ret = cpufreq_register_driver(&sfi_cpufreq_driver); 113 + if (ret) 114 + goto err_free_tbl; 115 + 116 + return ret; 117 + 118 + err_free_tbl: 119 + kfree(freq_table); 120 + err_free_array: 121 + kfree(sfi_cpufreq_array); 122 + return ret; 123 + } 124 + late_initcall(sfi_cpufreq_init); 125 + 126 + static void __exit sfi_cpufreq_exit(void) 127 + { 128 + cpufreq_unregister_driver(&sfi_cpufreq_driver); 129 + kfree(freq_table); 130 + kfree(sfi_cpufreq_array); 131 + } 132 + module_exit(sfi_cpufreq_exit); 133 + 134 + MODULE_AUTHOR("Vishwesh M Rudramuni <vishwesh.m.rudramuni@intel.com>"); 135 + MODULE_DESCRIPTION("SFI Performance-States Driver"); 136 + MODULE_LICENSE("GPL");
+2 -2
drivers/sfi/sfi_core.c
··· 161 161 * Check for common case that we can re-use mapping to SYST, 162 162 * which requires syst_pa, syst_va to be initialized. 163 163 */ 164 - struct sfi_table_header *sfi_map_table(u64 pa) 164 + static struct sfi_table_header *sfi_map_table(u64 pa) 165 165 { 166 166 struct sfi_table_header *th; 167 167 u32 length; ··· 189 189 * Undoes effect of sfi_map_table() by unmapping table 190 190 * if it did not completely fit on same page as SYST. 191 191 */ 192 - void sfi_unmap_table(struct sfi_table_header *th) 192 + static void sfi_unmap_table(struct sfi_table_header *th) 193 193 { 194 194 if (!TABLE_ON_PAGE(syst_va, th, th->len)) 195 195 sfi_unmap_memory(th, TABLE_ON_PAGE(th, th, th->len) ?
+5 -5
include/linux/cpufreq.h
··· 66 66 unsigned int shared_type; /* ACPI: ANY or ALL affected CPUs 67 67 should set cpufreq */ 68 68 unsigned int cpu; /* cpu nr of CPU managing this policy */ 69 - unsigned int last_cpu; /* cpu nr of previous CPU that managed 70 - * this policy */ 71 69 struct clk *clk; 72 70 struct cpufreq_cpuinfo cpuinfo;/* see above */ 73 71 ··· 110 112 spinlock_t transition_lock; 111 113 wait_queue_head_t transition_wait; 112 114 struct task_struct *transition_task; /* Task which is doing the transition */ 115 + 116 + /* cpufreq-stats */ 117 + struct cpufreq_stats *stats; 113 118 114 119 /* For cpufreq driver's internal use */ 115 120 void *driver_data; ··· 368 367 #define CPUFREQ_INCOMPATIBLE (1) 369 368 #define CPUFREQ_NOTIFY (2) 370 369 #define CPUFREQ_START (3) 371 - #define CPUFREQ_UPDATE_POLICY_CPU (4) 372 - #define CPUFREQ_CREATE_POLICY (5) 373 - #define CPUFREQ_REMOVE_POLICY (6) 370 + #define CPUFREQ_CREATE_POLICY (4) 371 + #define CPUFREQ_REMOVE_POLICY (5) 374 372 375 373 #ifdef CONFIG_CPU_FREQ 376 374 int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list);