History

Merge tag 'pm+acpi-3.19-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management and ACPI material from Rafael J Wysocki: "These are fixes (operating performance points library, cpufreq-dt driver, cpufreq core, ACPI backlight, cpupower tool), cleanups (cpuidle), new processor IDs for the RAPL (Running Average Power Limit) power capping driver, and a modification of the generic power domains framework allowing modular drivers to call one of its helper functions. Specifics: - Fix for a potential NULL pointer dereference in the cpufreq core due to an initialization race condition (Ethan Zhao). - Fixes for abuse of the OPP (Operating Performance Points) API related to RCU and other minor issues in the OPP library and the cpufreq-dt driver (Dmitry Torokhov). - cpuidle governors cleanup making them measure idle duration in a better way without using the CPUIDLE_FLAG_TIME_INVALID flag which allows that flag to be dropped from the ACPI cpuidle driver and from the core too (Len Brown). - New ACPI backlight blacklist entries for Samsung machines without a working native backlight interface that need to use the ACPI backlight instead (Aaron Lu). - New CPU IDs of future Intel Xeon CPUs for the Intel RAPL power capping driver (Jacob Pan). - Generic power domains framework modification to export the of_genpd_get_from_provider() function to modular drivers that will allow future driver modifications to be based on the mainline (Amit Daniel Kachhap). - Two fixes for the cpupower tool (Michal Privoznik, Prarit Bhargava)" * tag 'pm+acpi-3.19-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI / video: Add some Samsung models to disable_native_backlight list tools / cpupower: Fix no idle state information return value tools / cpupower: Correctly detect if running as root cpufreq: fix a NULL pointer dereference in __cpufreq_governor() cpufreq-dt: defer probing if OPP table is not ready PM / OPP: take RCU lock in dev_pm_opp_get_opp_count PM / OPP: fix warning in of_free_opp_table() PM / OPP: add some lockdep annotations powercap / RAPL: add IDs for future Xeon CPUs PM / Domains: Export of_genpd_get_from_provider function cpuidle / ACPI: remove unused CPUIDLE_FLAG_TIME_INVALID cpuidle: ladder: Better idle duration measurement without using CPUIDLE_FLAG_TIME_INVALID cpuidle: menu: Better idle duration measurement without using CPUIDLE_FLAG_TIME_INVALID

Linus Torvalds committed 11 years ago

Commit df90dcd2 parents 346eef2 651c32913 files · +89 −37Browse files

Unified · Split

13 files
  1. drivers/acpi/processor_idle.c +0 −2
  2. drivers/acpi/video.c +17 −0
  3. drivers/base/power/domain.c +2 −1
  4. drivers/base/power/opp.c +31 −8
  5. drivers/cpufreq/cpufreq-dt.c +11 −0
  6. drivers/cpufreq/cpufreq.c +6 −0
  7. drivers/cpuidle/governors/ladder.c +1 −6
  8. drivers/cpuidle/governors/menu.c +10 −15
  9. drivers/powercap/intel_rapl.c +1 −0
  10. include/linux/cpuidle.h +0 −3
  11. include/linux/pm_domain.h +8 −0
  12. tools/power/cpupower/utils/cpupower.c +1 −1
  13. tools/power/cpupower/utils/helpers/sysfs.c +1 −1
drivers/acpi/processor_idle.c+0−2
@@ -985,8 +985,6 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) · 984 unmodified lines
985985 state->flags = 0;
986986 switch (cx->type) {
987987 case ACPI_STATE_C1:
988− if (cx->entry_method != ACPI_CSTATE_FFH)
989− state->flags |= CPUIDLE_FLAG_TIME_INVALID;
990988
991989 state->enter = acpi_idle_enter_c1;
992990 state->enter_dead = acpi_idle_play_dead;
drivers/acpi/video.c+17−0
@@ -505,6 +505,23 @@ static struct dmi_system_id video_dmi_table[] __initdata = { · 504 unmodified lines
505505 DMI_MATCH(DMI_PRODUCT_NAME, "HP ENVY 15 Notebook PC"),
506506 },
507507 },
508+
509+ {
510+ .callback = video_disable_native_backlight,
511+ .ident = "SAMSUNG 870Z5E/880Z5E/680Z5E",
512+ .matches = {
513+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
514+ DMI_MATCH(DMI_PRODUCT_NAME, "870Z5E/880Z5E/680Z5E"),
515+ },
516+ },
517+ {
518+ .callback = video_disable_native_backlight,
519+ .ident = "SAMSUNG 370R4E/370R4V/370R5E/3570RE/370R5V",
520+ .matches = {
521+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
522+ DMI_MATCH(DMI_PRODUCT_NAME, "370R4E/370R4V/370R5E/3570RE/370R5V"),
523+ },
524+ },
508525 {}
509526 };
510527
drivers/base/power/domain.c+2−1
@@ -2088,7 +2088,7 @@ EXPORT_SYMBOL_GPL(of_genpd_del_provider); · 2087 unmodified lines
20882088 * Returns a valid pointer to struct generic_pm_domain on success or ERR_PTR()
20892089 * on failure.
20902090 */
2091−static struct generic_pm_domain *of_genpd_get_from_provider(
2091+struct generic_pm_domain *of_genpd_get_from_provider(
20922092 struct of_phandle_args *genpdspec)
20932093 {
20942094 struct generic_pm_domain *genpd = ERR_PTR(-ENOENT);
@@ -2108,6 +2108,7 @@ static struct generic_pm_domain *of_genpd_get_from_provider( · 13 unmodified lines
21082108
21092109 return genpd;
21102110 }
2111+EXPORT_SYMBOL_GPL(of_genpd_get_from_provider);
21112112
21122113 /**
21132114 * genpd_dev_pm_detach - Detach a device from its PM domain.
drivers/base/power/opp.c+31−8
@@ -108,6 +108,14 @@ static LIST_HEAD(dev_opp_list); · 107 unmodified lines
108108 /* Lock to allow exclusive modification to the device and opp lists */
109109 static DEFINE_MUTEX(dev_opp_list_lock);
110110
111+#define opp_rcu_lockdep_assert() \
112+do { \
113+ rcu_lockdep_assert(rcu_read_lock_held() || \
114+ lockdep_is_held(&dev_opp_list_lock), \
115+ "Missing rcu_read_lock() or " \
116+ "dev_opp_list_lock protection"); \
117+} while (0)
118+
111119 /**
112120 * find_device_opp() - find device_opp struct using device pointer
113121 * @dev: device pointer used to lookup device OPPs
@@ -208,9 +216,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq); · 94 unmodified lines
208216 * This function returns the number of available opps if there are any,
209217 * else returns 0 if none or the corresponding error value.
210218 *
211− * Locking: This function must be called under rcu_read_lock(). This function
212− * internally references two RCU protected structures: device_opp and opp which
213− * are safe as long as we are under a common RCU locked section.
219+ * Locking: This function takes rcu_read_lock().
214220 */
215221 int dev_pm_opp_get_opp_count(struct device *dev)
216222 {
@@ -218,11 +224,14 @@ int dev_pm_opp_get_opp_count(struct device *dev) · 1 unmodified line
218224 struct dev_pm_opp *temp_opp;
219225 int count = 0;
220226
227+ rcu_read_lock();
228+
221229 dev_opp = find_device_opp(dev);
222230 if (IS_ERR(dev_opp)) {
223− int r = PTR_ERR(dev_opp);
224− dev_err(dev, "%s: device OPP not found (%d)\n", __func__, r);
225− return r;
231+ count = PTR_ERR(dev_opp);
232+ dev_err(dev, "%s: device OPP not found (%d)\n",
233+ __func__, count);
234+ goto out_unlock;
226235 }
227236
228237 list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) {
@@ -230,6 +239,8 @@ int dev_pm_opp_get_opp_count(struct device *dev) · 1 unmodified line
230239 count++;
231240 }
232241
242+out_unlock:
243+ rcu_read_unlock();
233244 return count;
234245 }
235246 EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count);
@@ -267,6 +278,8 @@ struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, · 31 unmodified lines
267278 struct device_opp *dev_opp;
268279 struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE);
269280
281+ opp_rcu_lockdep_assert();
282+
270283 dev_opp = find_device_opp(dev);
271284 if (IS_ERR(dev_opp)) {
272285 int r = PTR_ERR(dev_opp);
@@ -313,6 +326,8 @@ struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, · 40 unmodified lines
313326 struct device_opp *dev_opp;
314327 struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE);
315328
329+ opp_rcu_lockdep_assert();
330+
316331 if (!dev || !freq) {
317332 dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq);
318333 return ERR_PTR(-EINVAL);
@@ -361,6 +376,8 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, · 42 unmodified lines
361376 struct device_opp *dev_opp;
362377 struct dev_pm_opp *temp_opp, *opp = ERR_PTR(-ERANGE);
363378
379+ opp_rcu_lockdep_assert();
380+
364381 if (!dev || !freq) {
365382 dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq);
366383 return ERR_PTR(-EINVAL);
@@ -783,9 +800,15 @@ void of_free_opp_table(struct device *dev) · 416 unmodified lines
783800
784801 /* Check for existing list for 'dev' */
785802 dev_opp = find_device_opp(dev);
786− if (WARN(IS_ERR(dev_opp), "%s: dev_opp: %ld\n", dev_name(dev),
787− PTR_ERR(dev_opp)))
803+ if (IS_ERR(dev_opp)) {
804+ int error = PTR_ERR(dev_opp);
805+ if (error != -ENODEV)
806+ WARN(1, "%s: dev_opp: %d\n",
807+ IS_ERR_OR_NULL(dev) ?
808+ "Invalid device" : dev_name(dev),
809+ error);
788810 return;
811+ }
789812
790813 /* Hold our list modification lock here */
791814 mutex_lock(&dev_opp_list_lock);
drivers/cpufreq/cpufreq-dt.c+11−0
@@ -211,6 +211,17 @@ static int cpufreq_init(struct cpufreq_policy *policy) · 210 unmodified lines
211211 /* OPPs might be populated at runtime, don't check for error here */
212212 of_init_opp_table(cpu_dev);
213213
214+ /*
215+ * But we need OPP table to function so if it is not there let's
216+ * give platform code chance to provide it for us.
217+ */
218+ ret = dev_pm_opp_get_opp_count(cpu_dev);
219+ if (ret <= 0) {
220+ pr_debug("OPP table is not ready, deferring probe\n");
221+ ret = -EPROBE_DEFER;
222+ goto out_free_opp;
223+ }
224+
214225 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
215226 if (!priv) {
216227 ret = -ENOMEM;
drivers/cpufreq/cpufreq.c+6−0
@@ -2028,6 +2028,12 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, · 2027 unmodified lines
20282028 /* Don't start any governor operations if we are entering suspend */
20292029 if (cpufreq_suspended)
20302030 return 0;
2031+ /*
2032+ * Governor might not be initiated here if ACPI _PPC changed
2033+ * notification happened, so check it.
2034+ */
2035+ if (!policy->governor)
2036+ return -EINVAL;
20312037
20322038 if (policy->governor->max_transition_latency &&
20332039 policy->cpuinfo.transition_latency >
drivers/cpuidle/governors/ladder.c+1−6
@@ -79,12 +79,7 @@ static int ladder_select_state(struct cpuidle_driver *drv, · 78 unmodified lines
7979
8080 last_state = &ldev->states[last_idx];
8181
82− if (!(drv->states[last_idx].flags & CPUIDLE_FLAG_TIME_INVALID)) {
83− last_residency = cpuidle_get_last_residency(dev) - \
84− drv->states[last_idx].exit_latency;
85− }
86− else
87− last_residency = last_state->threshold.promotion_time + 1;
82+ last_residency = cpuidle_get_last_residency(dev) - drv->states[last_idx].exit_latency;
8883
8984 /* consider promotion */
9085 if (last_idx < drv->state_count - 1 &&
drivers/cpuidle/governors/menu.c+10−15
@@ -396,8 +396,8 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) · 395 unmodified lines
396396 * power state and occurrence of the wakeup event.
397397 *
398398 * If the entered idle state didn't support residency measurements,
399− * we are basically lost in the dark how much time passed.
400− * As a compromise, assume we slept for the whole expected time.
399+ * we use them anyway if they are short, and if long,
400+ * truncate to the whole expected time.
401401 *
402402 * Any measured amount of time will include the exit latency.
403403 * Since we are interested in when the wakeup begun, not when it
@@ -405,22 +405,17 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev) · 1 unmodified line
405405 * the measured amount of time is less than the exit latency,
406406 * assume the state was never reached and the exit latency is 0.
407407 */
408− if (unlikely(target->flags & CPUIDLE_FLAG_TIME_INVALID)) {
409− /* Use timer value as is */
410− measured_us = data->next_timer_us;
411408
412− } else {
413− /* Use measured value */
414− measured_us = cpuidle_get_last_residency(dev);
409+ /* measured value */
410+ measured_us = cpuidle_get_last_residency(dev);
415411
416− /* Deduct exit latency */
417− if (measured_us > target->exit_latency)
418− measured_us -= target->exit_latency;
412+ /* Deduct exit latency */
413+ if (measured_us > target->exit_latency)
414+ measured_us -= target->exit_latency;
419415
420− /* Make sure our coefficients do not exceed unity */
421− if (measured_us > data->next_timer_us)
422− measured_us = data->next_timer_us;
423− }
416+ /* Make sure our coefficients do not exceed unity */
417+ if (measured_us > data->next_timer_us)
418+ measured_us = data->next_timer_us;
424419
425420 /* Update our correction ratio */
426421 new_factor = data->correction_factor[data->bucket];
drivers/powercap/intel_rapl.c+1−0
@@ -1041,6 +1041,7 @@ static const struct x86_cpu_id rapl_ids[] = { · 1040 unmodified lines
10411041 RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */
10421042 RAPL_CPU(0x4C, rapl_defaults_atom),/* Braswell */
10431043 RAPL_CPU(0x4A, rapl_defaults_atom),/* Tangier */
1044+ RAPL_CPU(0x56, rapl_defaults_core),/* Future Xeon */
10441045 RAPL_CPU(0x5A, rapl_defaults_atom),/* Annidale */
10451046 {}
10461047 };
include/linux/cpuidle.h+0−3
@@ -53,7 +53,6 @@ struct cpuidle_state { · 52 unmodified lines
5353 };
5454
5555 /* Idle State Flags */
56−#define CPUIDLE_FLAG_TIME_INVALID (0x01) /* is residency time measurable? */
5756 #define CPUIDLE_FLAG_COUPLED (0x02) /* state applies to multiple cpus */
5857 #define CPUIDLE_FLAG_TIMER_STOP (0x04) /* timer is stopped on this state */
5958
@@ -89,8 +88,6 @@ DECLARE_PER_CPU(struct cpuidle_device, cpuidle_dev); · 29 unmodified lines
8988 /**
9089 * cpuidle_get_last_residency - retrieves the last state's residency time
9190 * @dev: the target CPU
92− *
93− * NOTE: this value is invalid if CPUIDLE_FLAG_TIME_INVALID is set
9491 */
9592 static inline int cpuidle_get_last_residency(struct cpuidle_device *dev)
9693 {
include/linux/pm_domain.h+8−0
@@ -271,6 +271,8 @@ typedef struct generic_pm_domain *(*genpd_xlate_t)(struct of_phandle_args *args, · 270 unmodified lines
271271 int __of_genpd_add_provider(struct device_node *np, genpd_xlate_t xlate,
272272 void *data);
273273 void of_genpd_del_provider(struct device_node *np);
274+struct generic_pm_domain *of_genpd_get_from_provider(
275+ struct of_phandle_args *genpdspec);
274276
275277 struct generic_pm_domain *__of_genpd_xlate_simple(
276278 struct of_phandle_args *genpdspec,
@@ -288,6 +290,12 @@ static inline int __of_genpd_add_provider(struct device_node *np, · 11 unmodified lines
288290 }
289291 static inline void of_genpd_del_provider(struct device_node *np) {}
290292
293+static inline struct generic_pm_domain *of_genpd_get_from_provider(
294+ struct of_phandle_args *genpdspec)
295+{
296+ return NULL;
297+}
298+
291299 #define __of_genpd_xlate_simple NULL
292300 #define __of_genpd_xlate_onecell NULL
293301
tools/power/cpupower/utils/cpupower.c+1−1
@@ -199,7 +199,7 @@ int main(int argc, const char *argv[]) · 198 unmodified lines
199199 }
200200
201201 get_cpu_info(0, &cpupower_cpu_info);
202− run_as_root = !getuid();
202+ run_as_root = !geteuid();
203203 if (run_as_root) {
204204 ret = uname(&uts);
205205 if (!ret && !strcmp(uts.machine, "x86_64") &&
tools/power/cpupower/utils/helpers/sysfs.c+1−1
@@ -361,7 +361,7 @@ unsigned int sysfs_get_idlestate_count(unsigned int cpu) · 360 unmodified lines
361361
362362 snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpuidle");
363363 if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode))
364− return -ENODEV;
364+ return 0;
365365
366366 snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/cpuidle/state0", cpu);
367367 if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode))