From dfa5bb622555d9da0df21b50f46ebdeef390041b Mon Sep 17 00:00:00 2001 From: Stratos Karafotis Date: Wed, 5 Jun 2013 19:01:25 +0300 Subject: cpufreq: ondemand: Change the calculation of target frequency The ondemand governor calculates load in terms of frequency and increases it only if load_freq is greater than up_threshold multiplied by the current or average frequency. This appears to produce oscillations of frequency between min and max because, for example, a relatively small load can easily saturate minimum frequency and lead the CPU to the max. Then, it will decrease back to the min due to small load_freq. Change the calculation method of load and target frequency on the basis of the following two observations: - Load computation should not depend on the current or average measured frequency. For example, absolute load of 80% at 100MHz is not necessarily equivalent to 8% at 1000MHz in the next sampling interval. - It should be possible to increase the target frequency to any value present in the frequency table proportional to the absolute load, rather than to the max only, so that: Target frequency = C * load where we take C = policy->cpuinfo.max_freq / 100. Tested on Intel i7-3770 CPU @ 3.40GHz and on Quad core 1500MHz Krait. Phoronix benchmark of Linux Kernel Compilation 3.1 test shows an increase ~1.5% in performance. cpufreq_stats (time_in_state) shows that middle frequencies are used more, with this patch. Highest and lowest frequencies were used less by ~9%. [rjw: We have run multiple other tests on kernels with this change applied and in the vast majority of cases it turns out that the resulting performance improvement also leads to reduced consumption of energy. The change is additionally justified by the overall simplification of the code in question.] Signed-off-by: Stratos Karafotis Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq_governor.c | 10 +--------- drivers/cpufreq/cpufreq_governor.h | 1 - drivers/cpufreq/cpufreq_ondemand.c | 39 +++++++------------------------------- 3 files changed, 8 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 7b839a8db2a7..7409dbd1d897 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -53,7 +53,7 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) policy = cdbs->cur_policy; - /* Get Absolute Load (in terms of freq for ondemand gov) */ + /* Get Absolute Load */ for_each_cpu(j, policy->cpus) { struct cpu_dbs_common_info *j_cdbs; u64 cur_wall_time, cur_idle_time; @@ -104,14 +104,6 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) load = 100 * (wall_time - idle_time) / wall_time; - if (dbs_data->cdata->governor == GOV_ONDEMAND) { - int freq_avg = __cpufreq_driver_getavg(policy, j); - if (freq_avg <= 0) - freq_avg = policy->cur; - - load *= freq_avg; - } - if (load > max_load) max_load = load; } diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index 6663ec3b3056..0e0dd4c82020 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h @@ -169,7 +169,6 @@ struct od_dbs_tuners { unsigned int sampling_rate; unsigned int sampling_down_factor; unsigned int up_threshold; - unsigned int adj_up_threshold; unsigned int powersave_bias; unsigned int io_is_busy; }; diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 93eb5cbcc1f6..a3c5574f9b3a 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -29,11 +29,9 @@ #include "cpufreq_governor.h" /* On-demand governor macros */ -#define DEF_FREQUENCY_DOWN_DIFFERENTIAL (10) #define DEF_FREQUENCY_UP_THRESHOLD (80) #define DEF_SAMPLING_DOWN_FACTOR (1) #define MAX_SAMPLING_DOWN_FACTOR (100000) -#define MICRO_FREQUENCY_DOWN_DIFFERENTIAL (3) #define MICRO_FREQUENCY_UP_THRESHOLD (95) #define MICRO_FREQUENCY_MIN_SAMPLE_RATE (10000) #define MIN_FREQUENCY_UP_THRESHOLD (11) @@ -161,14 +159,10 @@ static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq) /* * Every sampling_rate, we check, if current idle time is less than 20% - * (default), then we try to increase frequency. Every sampling_rate, we look - * for the lowest frequency which can sustain the load while keeping idle time - * over 30%. If such a frequency exist, we try to decrease to this frequency. - * - * Any frequency increase takes it to the maximum frequency. Frequency reduction - * happens at minimum steps of 5% (default) of current frequency + * (default), then we try to increase frequency. Else, we adjust the frequency + * proportional to load. */ -static void od_check_cpu(int cpu, unsigned int load_freq) +static void od_check_cpu(int cpu, unsigned int load) { struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu); struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy; @@ -178,29 +172,17 @@ static void od_check_cpu(int cpu, unsigned int load_freq) dbs_info->freq_lo = 0; /* Check for frequency increase */ - if (load_freq > od_tuners->up_threshold * policy->cur) { + if (load > od_tuners->up_threshold) { /* If switching to max speed, apply sampling_down_factor */ if (policy->cur < policy->max) dbs_info->rate_mult = od_tuners->sampling_down_factor; dbs_freq_increase(policy, policy->max); return; - } - - /* Check for frequency decrease */ - /* if we cannot reduce the frequency anymore, break out early */ - if (policy->cur == policy->min) - return; - - /* - * The optimal frequency is the frequency that is the lowest that can - * support the current CPU usage without triggering the up policy. To be - * safe, we focus 10 points under the threshold. - */ - if (load_freq < od_tuners->adj_up_threshold - * policy->cur) { + } else { + /* Calculate the next frequency proportional to load */ unsigned int freq_next; - freq_next = load_freq / od_tuners->adj_up_threshold; + freq_next = load * policy->cpuinfo.max_freq / 100; /* No longer fully busy, reset rate_mult */ dbs_info->rate_mult = 1; @@ -374,9 +356,6 @@ static ssize_t store_up_threshold(struct dbs_data *dbs_data, const char *buf, input < MIN_FREQUENCY_UP_THRESHOLD) { return -EINVAL; } - /* Calculate the new adj_up_threshold */ - od_tuners->adj_up_threshold += input; - od_tuners->adj_up_threshold -= od_tuners->up_threshold; od_tuners->up_threshold = input; return count; @@ -525,8 +504,6 @@ static int od_init(struct dbs_data *dbs_data) if (idle_time != -1ULL) { /* Idle micro accounting is supported. Use finer thresholds */ tuners->up_threshold = MICRO_FREQUENCY_UP_THRESHOLD; - tuners->adj_up_threshold = MICRO_FREQUENCY_UP_THRESHOLD - - MICRO_FREQUENCY_DOWN_DIFFERENTIAL; /* * In nohz/micro accounting case we set the minimum frequency * not depending on HZ, but fixed (very low). The deferred @@ -535,8 +512,6 @@ static int od_init(struct dbs_data *dbs_data) dbs_data->min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE; } else { tuners->up_threshold = DEF_FREQUENCY_UP_THRESHOLD; - tuners->adj_up_threshold = DEF_FREQUENCY_UP_THRESHOLD - - DEF_FREQUENCY_DOWN_DIFFERENTIAL; /* For correct statistics, we need 10 ticks for each measure */ dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO * -- cgit v1.2.3-58-ga151 From 61c63e5ed3b9c472899d7152e961f2ffaafcf5a0 Mon Sep 17 00:00:00 2001 From: Stratos Karafotis Date: Wed, 5 Jun 2013 19:01:42 +0300 Subject: cpufreq: Remove unused APERF/MPERF support The target frequency calculation method in the ondemand governor has changed and it is now independent of the measured average frequency. Consequently, the APERF/MPERF support in cpufreq is not used any more, so drop it. [rjw: Changelog] Signed-off-by: Stratos Karafotis Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- arch/x86/include/asm/processor.h | 29 ----------------------- drivers/cpufreq/Makefile | 2 +- drivers/cpufreq/acpi-cpufreq.c | 5 ---- drivers/cpufreq/mperf.c | 51 ---------------------------------------- drivers/cpufreq/mperf.h | 9 ------- 5 files changed, 1 insertion(+), 95 deletions(-) delete mode 100644 drivers/cpufreq/mperf.c delete mode 100644 drivers/cpufreq/mperf.h (limited to 'drivers') diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 24cf5aefb704..4f4a3d98c170 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -942,35 +942,6 @@ extern int set_tsc_mode(unsigned int val); extern u16 amd_get_nb_id(int cpu); -struct aperfmperf { - u64 aperf, mperf; -}; - -static inline void get_aperfmperf(struct aperfmperf *am) -{ - WARN_ON_ONCE(!boot_cpu_has(X86_FEATURE_APERFMPERF)); - - rdmsrl(MSR_IA32_APERF, am->aperf); - rdmsrl(MSR_IA32_MPERF, am->mperf); -} - -#define APERFMPERF_SHIFT 10 - -static inline -unsigned long calc_aperfmperf_ratio(struct aperfmperf *old, - struct aperfmperf *new) -{ - u64 aperf = new->aperf - old->aperf; - u64 mperf = new->mperf - old->mperf; - unsigned long ratio = aperf; - - mperf >>= APERFMPERF_SHIFT; - if (mperf) - ratio = div64_u64(aperf, mperf); - - return ratio; -} - extern unsigned long arch_align_stack(unsigned long sp); extern void free_init_pages(char *what, unsigned long begin, unsigned long end); diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index d345b5a7aa71..ad5866c2ada0 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -23,7 +23,7 @@ obj-$(CONFIG_GENERIC_CPUFREQ_CPU0) += cpufreq-cpu0.o # powernow-k8 can load then. ACPI is preferred to all other hardware-specific drivers. # speedstep-* is preferred over p4-clockmod. -obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o mperf.o +obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o obj-$(CONFIG_X86_PCC_CPUFREQ) += pcc-cpufreq.o obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 39264020b88a..e673670d2321 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -45,7 +45,6 @@ #include #include #include -#include "mperf.h" MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski"); MODULE_DESCRIPTION("ACPI Processor P-States Driver"); @@ -861,10 +860,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) /* notify BIOS that we exist */ acpi_processor_notify_smm(THIS_MODULE); - /* Check for APERF/MPERF support in hardware */ - if (boot_cpu_has(X86_FEATURE_APERFMPERF)) - acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf; - pr_debug("CPU%u - ACPI performance management activated.\n", cpu); for (i = 0; i < perf->state_count; i++) pr_debug(" %cP%d: %d MHz, %d mW, %d uS\n", diff --git a/drivers/cpufreq/mperf.c b/drivers/cpufreq/mperf.c deleted file mode 100644 index 911e193018ae..000000000000 --- a/drivers/cpufreq/mperf.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "mperf.h" - -static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf); - -/* Called via smp_call_function_single(), on the target CPU */ -static void read_measured_perf_ctrs(void *_cur) -{ - struct aperfmperf *am = _cur; - - get_aperfmperf(am); -} - -/* - * Return the measured active (C0) frequency on this CPU since last call - * to this function. - * Input: cpu number - * Return: Average CPU frequency in terms of max frequency (zero on error) - * - * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance - * over a period of time, while CPU is in C0 state. - * IA32_MPERF counts at the rate of max advertised frequency - * IA32_APERF counts at the rate of actual CPU frequency - * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and - * no meaning should be associated with absolute values of these MSRs. - */ -unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy, - unsigned int cpu) -{ - struct aperfmperf perf; - unsigned long ratio; - unsigned int retval; - - if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1)) - return 0; - - ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf); - per_cpu(acfreq_old_perf, cpu) = perf; - - retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT; - - return retval; -} -EXPORT_SYMBOL_GPL(cpufreq_get_measured_perf); -MODULE_LICENSE("GPL"); diff --git a/drivers/cpufreq/mperf.h b/drivers/cpufreq/mperf.h deleted file mode 100644 index 5dbf2950dc22..000000000000 --- a/drivers/cpufreq/mperf.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * (c) 2010 Advanced Micro Devices, Inc. - * Your use of this code is subject to the terms and conditions of the - * GNU general public license version 2. See "COPYING" or - * http://www.gnu.org/licenses/gpl.html - */ - -unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy, - unsigned int cpu); -- cgit v1.2.3-58-ga151 From cffe4e0e7413eb29fb8bd035c8b12b33a4b8522a Mon Sep 17 00:00:00 2001 From: Stratos Karafotis Date: Wed, 5 Jun 2013 19:01:50 +0300 Subject: cpufreq: Remove unused function __cpufreq_driver_getavg() The target frequency calculation method in the ondemand governor has changed and it is now independent of the measured average frequency. Consequently, the __cpufreq_driver_getavg() function and getavg member of struct cpufreq_driver are not used any more, so drop them. [rjw: Changelog] Signed-off-by: Stratos Karafotis Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 12 ------------ include/linux/cpufreq.h | 6 ------ 2 files changed, 18 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index a4ad7339588d..9a9d8ee9faec 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1593,18 +1593,6 @@ fail: } EXPORT_SYMBOL_GPL(cpufreq_driver_target); -int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu) -{ - if (cpufreq_disabled()) - return 0; - - if (!cpufreq_driver->getavg) - return 0; - - return cpufreq_driver->getavg(policy, cpu); -} -EXPORT_SYMBOL_GPL(__cpufreq_driver_getavg); - /* * when "event" is CPUFREQ_GOV_LIMITS */ diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 90d5a15120d5..e1fd215e16c9 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -216,10 +216,6 @@ extern int cpufreq_driver_target(struct cpufreq_policy *policy, extern int __cpufreq_driver_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation); - -extern int __cpufreq_driver_getavg(struct cpufreq_policy *policy, - unsigned int cpu); - int cpufreq_register_governor(struct cpufreq_governor *governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor); @@ -258,8 +254,6 @@ struct cpufreq_driver { unsigned int (*get) (unsigned int cpu); /* optional */ - unsigned int (*getavg) (struct cpufreq_policy *policy, - unsigned int cpu); int (*bios_limit) (int cpu, unsigned int *limit); int (*exit) (struct cpufreq_policy *policy); -- cgit v1.2.3-58-ga151 From 23d328994b548d6822b88fe7e1903652afc354e0 Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Tue, 30 Jul 2013 04:23:56 +0530 Subject: cpufreq: Fix misplaced call to cpufreq_update_policy() The call to cpufreq_update_policy() is placed in the CPU hotplug callback of cpufreq_stats, which has a higher priority than the CPU hotplug callback of cpufreq-core. As a result, during CPU_ONLINE/CPU_ONLINE_FROZEN, we end up calling cpufreq_update_policy() *before* calling cpufreq_add_dev() ! And for uninitialized CPUs, it just returns silently, not doing anything. To add to that, cpufreq_stats is not even the right place to call cpufreq_update_policy() to begin with. The cpufreq core ought to handle this in its own callback, from an elegance/relevance perspective. So move the invocation of cpufreq_update_policy() to cpufreq_cpu_callback, and place it *after* cpufreq_add_dev(). Signed-off-by: Srivatsa S. Bhat Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 1 + drivers/cpufreq/cpufreq_stats.c | 6 ------ 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index f0a5e2b0eb8a..5b317b0db902 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1945,6 +1945,7 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, case CPU_ONLINE: case CPU_ONLINE_FROZEN: cpufreq_add_dev(dev, NULL); + cpufreq_update_policy(cpu); break; case CPU_DOWN_PREPARE: case CPU_DOWN_PREPARE_FROZEN: diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index d37568c5ca9c..bc73be225be5 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -348,10 +348,6 @@ static int cpufreq_stat_cpu_callback(struct notifier_block *nfb, unsigned int cpu = (unsigned long)hcpu; switch (action) { - case CPU_ONLINE: - case CPU_ONLINE_FROZEN: - cpufreq_update_policy(cpu); - break; case CPU_DOWN_PREPARE: case CPU_DOWN_PREPARE_FROZEN: cpufreq_stats_free_sysfs(cpu); @@ -390,8 +386,6 @@ static int __init cpufreq_stats_init(void) return ret; register_hotcpu_notifier(&cpufreq_stat_cpu_notifier); - for_each_online_cpu(cpu) - cpufreq_update_policy(cpu); ret = cpufreq_register_notifier(¬ifier_trans_block, CPUFREQ_TRANSITION_NOTIFIER); -- cgit v1.2.3-58-ga151 From e9698cc5d2749c5b74e137f94a95d7e505b097e8 Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Tue, 30 Jul 2013 04:24:11 +0530 Subject: cpufreq: Add helper to perform alloc/free of policy structure Separate out the allocation of the cpufreq policy structure (along with its error handling) to a helper function. This makes the code easier to read and also helps with some upcoming code reorganization. Signed-off-by: Srivatsa S. Bhat Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 49 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 5b317b0db902..18e58c1bfd66 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -944,6 +944,37 @@ static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling, } #endif +static struct cpufreq_policy *cpufreq_policy_alloc(void) +{ + struct cpufreq_policy *policy; + + policy = kzalloc(sizeof(*policy), GFP_KERNEL); + if (!policy) + return NULL; + + if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) + goto err_free_policy; + + if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) + goto err_free_cpumask; + + return policy; + +err_free_cpumask: + free_cpumask_var(policy->cpus); +err_free_policy: + kfree(policy); + + return NULL; +} + +static void cpufreq_policy_free(struct cpufreq_policy *policy) +{ + free_cpumask_var(policy->related_cpus); + free_cpumask_var(policy->cpus); + kfree(policy); +} + /** * cpufreq_add_dev - add a CPU device * @@ -997,16 +1028,10 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) goto module_out; } - policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL); + policy = cpufreq_policy_alloc(); if (!policy) goto nomem_out; - if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL)) - goto err_free_policy; - - if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) - goto err_free_cpumask; - policy->cpu = cpu; policy->governor = CPUFREQ_DEFAULT_GOVERNOR; cpumask_copy(policy->cpus, cpumask_of(cpu)); @@ -1071,11 +1096,7 @@ err_out_unregister: err_set_policy_cpu: per_cpu(cpufreq_policy_cpu, cpu) = -1; - free_cpumask_var(policy->related_cpus); -err_free_cpumask: - free_cpumask_var(policy->cpus); -err_free_policy: - kfree(policy); + cpufreq_policy_free(policy); nomem_out: module_put(cpufreq_driver->owner); module_out: @@ -1199,9 +1220,7 @@ static int __cpufreq_remove_dev(struct device *dev, if (cpufreq_driver->exit) cpufreq_driver->exit(data); - free_cpumask_var(data->related_cpus); - free_cpumask_var(data->cpus); - kfree(data); + cpufreq_policy_free(data); } else { pr_debug("%s: removing link, cpu: %d\n", __func__, cpu); cpufreq_cpu_put(data); -- cgit v1.2.3-58-ga151 From e18f1682bce701ddcf88ba3651e07c7ee9b3ed60 Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Tue, 30 Jul 2013 04:24:23 +0530 Subject: cpufreq: Extract non-interface related stuff from cpufreq_add_dev_interface cpufreq_add_dev_interface() includes the work of exposing the interface to the device, as well as a lot of unrelated stuff. Move the latter to cpufreq_add_dev(), where it is more appropriate. Signed-off-by: Srivatsa S. Bhat Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 18e58c1bfd66..f7c58c79217d 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -835,11 +835,8 @@ static int cpufreq_add_dev_interface(unsigned int cpu, struct cpufreq_policy *policy, struct device *dev) { - struct cpufreq_policy new_policy; struct freq_attr **drv_attr; - unsigned long flags; int ret = 0; - unsigned int j; /* prepare interface data */ ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, @@ -871,17 +868,23 @@ static int cpufreq_add_dev_interface(unsigned int cpu, goto err_out_kobj_put; } - write_lock_irqsave(&cpufreq_driver_lock, flags); - for_each_cpu(j, policy->cpus) { - per_cpu(cpufreq_cpu_data, j) = policy; - per_cpu(cpufreq_policy_cpu, j) = policy->cpu; - } - write_unlock_irqrestore(&cpufreq_driver_lock, flags); - ret = cpufreq_add_dev_symlink(cpu, policy); if (ret) goto err_out_kobj_put; + return ret; + +err_out_kobj_put: + kobject_put(&policy->kobj); + wait_for_completion(&policy->kobj_unregister); + return ret; +} + +static void cpufreq_init_policy(struct cpufreq_policy *policy) +{ + struct cpufreq_policy new_policy; + int ret = 0; + memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); /* assure that the starting sequence is run in __cpufreq_set_policy */ policy->governor = NULL; @@ -896,12 +899,6 @@ static int cpufreq_add_dev_interface(unsigned int cpu, if (cpufreq_driver->exit) cpufreq_driver->exit(policy); } - return ret; - -err_out_kobj_put: - kobject_put(&policy->kobj); - wait_for_completion(&policy->kobj_unregister); - return ret; } #ifdef CONFIG_HOTPLUG_CPU @@ -1075,10 +1072,19 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) } #endif + write_lock_irqsave(&cpufreq_driver_lock, flags); + for_each_cpu(j, policy->cpus) { + per_cpu(cpufreq_cpu_data, j) = policy; + per_cpu(cpufreq_policy_cpu, j) = policy->cpu; + } + write_unlock_irqrestore(&cpufreq_driver_lock, flags); + ret = cpufreq_add_dev_interface(cpu, policy, dev); if (ret) goto err_out_unregister; + cpufreq_init_policy(policy); + kobject_uevent(&policy->kobj, KOBJ_ADD); module_put(cpufreq_driver->owner); pr_debug("initialization complete\n"); @@ -1087,8 +1093,11 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) err_out_unregister: write_lock_irqsave(&cpufreq_driver_lock, flags); - for_each_cpu(j, policy->cpus) + for_each_cpu(j, policy->cpus) { per_cpu(cpufreq_cpu_data, j) = NULL; + if (j != cpu) + per_cpu(cpufreq_policy_cpu, j) = -1; + } write_unlock_irqrestore(&cpufreq_driver_lock, flags); kobject_put(&policy->kobj); -- cgit v1.2.3-58-ga151 From f9ba680d23ea7e2fc31b4b7106a482d90ec62a24 Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Tue, 30 Jul 2013 04:24:36 +0530 Subject: cpufreq: Extract the handover of policy cpu to a helper function During cpu offline, when the policy->cpu is going down, some other CPU present in the policy->cpus mask is nominated as the new policy->cpu. Extract this functionality from __cpufreq_remove_dev() and implement it in a helper function. This helps in upcoming code reorganization. Signed-off-by: Srivatsa S. Bhat Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 63 +++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index f7c58c79217d..0611ae48e767 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1129,6 +1129,38 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) CPUFREQ_UPDATE_POLICY_CPU, policy); } +static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *data, + unsigned int old_cpu) +{ + struct device *cpu_dev; + unsigned long flags; + int ret; + + /* first sibling now owns the new sysfs dir */ + cpu_dev = get_cpu_device(cpumask_first(data->cpus)); + sysfs_remove_link(&cpu_dev->kobj, "cpufreq"); + ret = kobject_move(&data->kobj, &cpu_dev->kobj); + if (ret) { + pr_err("%s: Failed to move kobj: %d", __func__, ret); + + WARN_ON(lock_policy_rwsem_write(old_cpu)); + cpumask_set_cpu(old_cpu, data->cpus); + + write_lock_irqsave(&cpufreq_driver_lock, flags); + per_cpu(cpufreq_cpu_data, old_cpu) = data; + write_unlock_irqrestore(&cpufreq_driver_lock, flags); + + unlock_policy_rwsem_write(old_cpu); + + ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj, + "cpufreq"); + + return -EINVAL; + } + + return cpu_dev->id; +} + /** * __cpufreq_remove_dev - remove a CPU device * @@ -1139,12 +1171,12 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) { - unsigned int cpu = dev->id, ret, cpus; + unsigned int cpu = dev->id, cpus; + int new_cpu; unsigned long flags; struct cpufreq_policy *data; struct kobject *kobj; struct completion *cmp; - struct device *cpu_dev; pr_debug("%s: unregistering CPU %u\n", __func__, cpu); @@ -1179,32 +1211,15 @@ static int __cpufreq_remove_dev(struct device *dev, if (cpu != data->cpu) { sysfs_remove_link(&dev->kobj, "cpufreq"); } else if (cpus > 1) { - /* first sibling now owns the new sysfs dir */ - cpu_dev = get_cpu_device(cpumask_first(data->cpus)); - sysfs_remove_link(&cpu_dev->kobj, "cpufreq"); - ret = kobject_move(&data->kobj, &cpu_dev->kobj); - if (ret) { - pr_err("%s: Failed to move kobj: %d", __func__, ret); + new_cpu = cpufreq_nominate_new_policy_cpu(data, cpu); + if (new_cpu >= 0) { WARN_ON(lock_policy_rwsem_write(cpu)); - cpumask_set_cpu(cpu, data->cpus); - - write_lock_irqsave(&cpufreq_driver_lock, flags); - per_cpu(cpufreq_cpu_data, cpu) = data; - write_unlock_irqrestore(&cpufreq_driver_lock, flags); - + update_policy_cpu(data, new_cpu); unlock_policy_rwsem_write(cpu); - - ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj, - "cpufreq"); - return -EINVAL; + pr_debug("%s: policy Kobject moved to cpu: %d " + "from: %d\n",__func__, new_cpu, cpu); } - - WARN_ON(lock_policy_rwsem_write(cpu)); - update_policy_cpu(data, cpu_dev->id); - unlock_policy_rwsem_write(cpu); - pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n", - __func__, cpu_dev->id, cpu); } /* If cpu is last user of policy, free policy */ -- cgit v1.2.3-58-ga151 From a82fab292898f88ea9ca99dd10c1773dcada08b6 Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Tue, 30 Jul 2013 04:24:49 +0530 Subject: cpufreq: Introduce a flag ('frozen') to separate full vs temporary init/teardown During suspend/resume we would like to do a light-weight init/teardown of CPUs in the cpufreq subsystem and preserve certain things such as sysfs files etc across suspend/resume transitions. Add a flag called 'frozen' to help distinguish the full init/teardown sequence from the light-weight one. Signed-off-by: Srivatsa S. Bhat Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 76 ++++++++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 0611ae48e767..1d041aff4d48 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -903,7 +903,7 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy) #ifdef CONFIG_HOTPLUG_CPU static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling, - struct device *dev) + struct device *dev, bool frozen) { struct cpufreq_policy *policy; int ret = 0, has_target = !!cpufreq_driver->target; @@ -931,13 +931,18 @@ static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling, __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); } - ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); - if (ret) { + /* Don't touch sysfs links during light-weight init */ + if (frozen) { + /* Drop the extra refcount that we took above */ cpufreq_cpu_put(policy); - return ret; + return 0; } - return 0; + ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); + if (ret) + cpufreq_cpu_put(policy); + + return ret; } #endif @@ -972,16 +977,8 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy) kfree(policy); } -/** - * cpufreq_add_dev - add a CPU device - * - * Adds the cpufreq interface for a CPU device. - * - * The Oracle says: try running cpufreq registration/unregistration concurrently - * with with cpu hotplugging and all hell will break loose. Tried to clean this - * mess up, but more thorough testing is needed. - Mathieu - */ -static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) +static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, + bool frozen) { unsigned int j, cpu = dev->id; int ret = -ENOMEM; @@ -1013,7 +1010,8 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling); if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) { read_unlock_irqrestore(&cpufreq_driver_lock, flags); - return cpufreq_add_policy_cpu(cpu, sibling, dev); + return cpufreq_add_policy_cpu(cpu, sibling, dev, + frozen); } } read_unlock_irqrestore(&cpufreq_driver_lock, flags); @@ -1079,9 +1077,11 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) } write_unlock_irqrestore(&cpufreq_driver_lock, flags); - ret = cpufreq_add_dev_interface(cpu, policy, dev); - if (ret) - goto err_out_unregister; + if (!frozen) { + ret = cpufreq_add_dev_interface(cpu, policy, dev); + if (ret) + goto err_out_unregister; + } cpufreq_init_policy(policy); @@ -1112,6 +1112,20 @@ module_out: return ret; } +/** + * cpufreq_add_dev - add a CPU device + * + * Adds the cpufreq interface for a CPU device. + * + * The Oracle says: try running cpufreq registration/unregistration concurrently + * with with cpu hotplugging and all hell will break loose. Tried to clean this + * mess up, but more thorough testing is needed. - Mathieu + */ +static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) +{ + return __cpufreq_add_dev(dev, sif, false); +} + static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) { int j; @@ -1130,7 +1144,7 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) } static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *data, - unsigned int old_cpu) + unsigned int old_cpu, bool frozen) { struct device *cpu_dev; unsigned long flags; @@ -1138,6 +1152,11 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *data, /* first sibling now owns the new sysfs dir */ cpu_dev = get_cpu_device(cpumask_first(data->cpus)); + + /* Don't touch sysfs files during light-weight tear-down */ + if (frozen) + return cpu_dev->id; + sysfs_remove_link(&cpu_dev->kobj, "cpufreq"); ret = kobject_move(&data->kobj, &cpu_dev->kobj); if (ret) { @@ -1169,7 +1188,7 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *data, * This routine frees the rwsem before returning. */ static int __cpufreq_remove_dev(struct device *dev, - struct subsys_interface *sif) + struct subsys_interface *sif, bool frozen) { unsigned int cpu = dev->id, cpus; int new_cpu; @@ -1208,17 +1227,20 @@ static int __cpufreq_remove_dev(struct device *dev, cpumask_clear_cpu(cpu, data->cpus); unlock_policy_rwsem_write(cpu); - if (cpu != data->cpu) { + if (cpu != data->cpu && !frozen) { sysfs_remove_link(&dev->kobj, "cpufreq"); } else if (cpus > 1) { - new_cpu = cpufreq_nominate_new_policy_cpu(data, cpu); + new_cpu = cpufreq_nominate_new_policy_cpu(data, cpu, frozen); if (new_cpu >= 0) { WARN_ON(lock_policy_rwsem_write(cpu)); update_policy_cpu(data, new_cpu); unlock_policy_rwsem_write(cpu); - pr_debug("%s: policy Kobject moved to cpu: %d " - "from: %d\n",__func__, new_cpu, cpu); + + if (!frozen) { + pr_debug("%s: policy Kobject moved to cpu: %d " + "from: %d\n",__func__, new_cpu, cpu); + } } } @@ -1266,7 +1288,7 @@ static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) if (cpu_is_offline(cpu)) return 0; - retval = __cpufreq_remove_dev(dev, sif); + retval = __cpufreq_remove_dev(dev, sif, false); return retval; } @@ -1992,7 +2014,7 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, break; case CPU_DOWN_PREPARE: case CPU_DOWN_PREPARE_FROZEN: - __cpufreq_remove_dev(dev, NULL); + __cpufreq_remove_dev(dev, NULL, false); break; case CPU_DOWN_FAILED: case CPU_DOWN_FAILED_FROZEN: -- cgit v1.2.3-58-ga151 From 8414809c6a1e8479e331e09254adb58b33a36d25 Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Tue, 30 Jul 2013 04:25:10 +0530 Subject: cpufreq: Preserve policy structure across suspend/resume To perform light-weight cpu-init and teardown in the cpufreq subsystem during suspend/resume, we need to separate out the 2 main functionalities of the cpufreq CPU hotplug callbacks, as outlined below: 1. Init/tear-down of core cpufreq and CPU-specific components, which are critical to the correct functioning of the cpufreq subsystem. 2. Init/tear-down of cpufreq sysfs files during suspend/resume. The first part requires accurate updates to the policy structure such as its ->cpus and ->related_cpus masks, whereas the second part requires that the policy->kobj structure is not released or re-initialized during suspend/resume. To handle both these requirements, we need to allow updates to the policy structure throughout suspend/resume, but prevent the structure from getting freed up. Also, we must have a mechanism by which the cpu-up callbacks can restore the policy structure, without allocating things afresh. (That also helps avoid memory leaks). To achieve this, we use 2 schemes: a. Use a fallback per-cpu storage area for preserving the policy structures during suspend, so that they can be restored during resume appropriately. b. Use the 'frozen' flag to determine when to free or allocate the policy structure vs when to restore the policy from the saved fallback storage. Thus we can successfully preserve the structure across suspend/resume. Effectively, this helps us complete the separation of the 'light-weight' and the 'full' init/tear-down sequences in the cpufreq subsystem, so that this can be made use of in the suspend/resume scenario. Signed-off-by: Srivatsa S. Bhat Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 69 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1d041aff4d48..e0ace3d9382c 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -44,6 +44,7 @@ */ static struct cpufreq_driver *cpufreq_driver; static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); +static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback); static DEFINE_RWLOCK(cpufreq_driver_lock); static DEFINE_MUTEX(cpufreq_governor_lock); @@ -946,6 +947,20 @@ static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling, } #endif +static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu) +{ + struct cpufreq_policy *policy; + unsigned long flags; + + write_lock_irqsave(&cpufreq_driver_lock, flags); + + policy = per_cpu(cpufreq_cpu_data_fallback, cpu); + + write_unlock_irqrestore(&cpufreq_driver_lock, flags); + + return policy; +} + static struct cpufreq_policy *cpufreq_policy_alloc(void) { struct cpufreq_policy *policy; @@ -1023,7 +1038,12 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, goto module_out; } - policy = cpufreq_policy_alloc(); + if (frozen) + /* Restore the saved policy when doing light-weight init */ + policy = cpufreq_policy_restore(cpu); + else + policy = cpufreq_policy_alloc(); + if (!policy) goto nomem_out; @@ -1204,6 +1224,10 @@ static int __cpufreq_remove_dev(struct device *dev, data = per_cpu(cpufreq_cpu_data, cpu); per_cpu(cpufreq_cpu_data, cpu) = NULL; + /* Save the policy somewhere when doing a light-weight tear-down */ + if (frozen) + per_cpu(cpufreq_cpu_data_fallback, cpu) = data; + write_unlock_irqrestore(&cpufreq_driver_lock, flags); if (!data) { @@ -1249,27 +1273,40 @@ static int __cpufreq_remove_dev(struct device *dev, if (cpufreq_driver->target) __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); - lock_policy_rwsem_read(cpu); - kobj = &data->kobj; - cmp = &data->kobj_unregister; - unlock_policy_rwsem_read(cpu); - kobject_put(kobj); + if (!frozen) { + lock_policy_rwsem_read(cpu); + kobj = &data->kobj; + cmp = &data->kobj_unregister; + unlock_policy_rwsem_read(cpu); + kobject_put(kobj); + + /* + * We need to make sure that the underlying kobj is + * actually not referenced anymore by anybody before we + * proceed with unloading. + */ + pr_debug("waiting for dropping of refcount\n"); + wait_for_completion(cmp); + pr_debug("wait complete\n"); + } - /* we need to make sure that the underlying kobj is actually - * not referenced anymore by anybody before we proceed with - * unloading. + /* + * Perform the ->exit() even during light-weight tear-down, + * since this is a core component, and is essential for the + * subsequent light-weight ->init() to succeed. */ - pr_debug("waiting for dropping of refcount\n"); - wait_for_completion(cmp); - pr_debug("wait complete\n"); - if (cpufreq_driver->exit) cpufreq_driver->exit(data); - cpufreq_policy_free(data); + if (!frozen) + cpufreq_policy_free(data); } else { - pr_debug("%s: removing link, cpu: %d\n", __func__, cpu); - cpufreq_cpu_put(data); + + if (!frozen) { + pr_debug("%s: removing link, cpu: %d\n", __func__, cpu); + cpufreq_cpu_put(data); + } + if (cpufreq_driver->target) { __cpufreq_governor(data, CPUFREQ_GOV_START); __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); -- cgit v1.2.3-58-ga151 From 5302c3fb2e62f4ca5e43e060491ba299f58c5231 Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Tue, 30 Jul 2013 04:25:25 +0530 Subject: cpufreq: Perform light-weight init/teardown during suspend/resume Now that we have the infrastructure to perform a light-weight init/tear-down, use that in the cpufreq CPU hotplug notifier when invoked from the suspend/resume path. This also ensures that the file permissions of the cpufreq sysfs files are preserved across suspend/resume, something which commit a66b2e (cpufreq: Preserve sysfs files across suspend/resume) originally intended to do, but had to be reverted due to other problems. Signed-off-by: Srivatsa S. Bhat Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 18 +++++++++++------- drivers/cpufreq/cpufreq_stats.c | 2 -- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index e0ace3d9382c..370abb66babc 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2040,22 +2040,26 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, { unsigned int cpu = (unsigned long)hcpu; struct device *dev; + bool frozen = false; dev = get_cpu_device(cpu); if (dev) { - switch (action) { + + if (action & CPU_TASKS_FROZEN) + frozen = true; + + switch (action & ~CPU_TASKS_FROZEN) { case CPU_ONLINE: - case CPU_ONLINE_FROZEN: - cpufreq_add_dev(dev, NULL); + __cpufreq_add_dev(dev, NULL, frozen); cpufreq_update_policy(cpu); break; + case CPU_DOWN_PREPARE: - case CPU_DOWN_PREPARE_FROZEN: - __cpufreq_remove_dev(dev, NULL, false); + __cpufreq_remove_dev(dev, NULL, frozen); break; + case CPU_DOWN_FAILED: - case CPU_DOWN_FAILED_FROZEN: - cpufreq_add_dev(dev, NULL); + __cpufreq_add_dev(dev, NULL, frozen); break; } } diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index bc73be225be5..cb3841355454 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -349,11 +349,9 @@ static int cpufreq_stat_cpu_callback(struct notifier_block *nfb, switch (action) { case CPU_DOWN_PREPARE: - case CPU_DOWN_PREPARE_FROZEN: cpufreq_stats_free_sysfs(cpu); break; case CPU_DEAD: - case CPU_DEAD_FROZEN: cpufreq_stats_free_table(cpu); break; } -- cgit v1.2.3-58-ga151 From e8fdde1011ea45792e60f14f620b01f78cb0d34d Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 31 Jul 2013 14:31:33 +0200 Subject: cpufreq: Remove extra variables from cpufreq_add_dev_symlink() We call cpufreq_cpu_get() in cpufreq_add_dev_symlink() to increase usage refcount of policy, but not to get a policy for the given CPU. So, we don't really need to capture the return value of this routine. We can simply use policy passed as an argument to cpufreq_add_dev_symlink(). Moreover debug print is rewritten to make it more clear. [rjw: Changelog] Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 370abb66babc..b6154ca1f896 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -813,19 +813,18 @@ static int cpufreq_add_dev_symlink(unsigned int cpu, int ret = 0; for_each_cpu(j, policy->cpus) { - struct cpufreq_policy *managed_policy; struct device *cpu_dev; if (j == cpu) continue; - pr_debug("CPU %u already managed, adding link\n", j); - managed_policy = cpufreq_cpu_get(cpu); + pr_debug("Adding link for CPU: %u\n", j); + cpufreq_cpu_get(cpu); cpu_dev = get_cpu_device(j); ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, "cpufreq"); if (ret) { - cpufreq_cpu_put(managed_policy); + cpufreq_cpu_put(policy); return ret; } } -- cgit v1.2.3-58-ga151 From 308b60e71541518f3fe97171b4daf71adc607f3d Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 31 Jul 2013 14:35:14 +0200 Subject: cpufreq: Don't pass CPU to cpufreq_add_dev_{symlink|interface}() Pointer to struct cpufreq_policy is already passed to these routines and we don't need to send policy->cpu to them as well. So, get rid of this extra argument and use policy->cpu everywhere. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index b6154ca1f896..576b312645a5 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -806,8 +806,7 @@ void cpufreq_sysfs_remove_file(const struct attribute *attr) EXPORT_SYMBOL(cpufreq_sysfs_remove_file); /* symlink affected CPUs */ -static int cpufreq_add_dev_symlink(unsigned int cpu, - struct cpufreq_policy *policy) +static int cpufreq_add_dev_symlink(struct cpufreq_policy *policy) { unsigned int j; int ret = 0; @@ -815,11 +814,11 @@ static int cpufreq_add_dev_symlink(unsigned int cpu, for_each_cpu(j, policy->cpus) { struct device *cpu_dev; - if (j == cpu) + if (j == policy->cpu) continue; pr_debug("Adding link for CPU: %u\n", j); - cpufreq_cpu_get(cpu); + cpufreq_cpu_get(policy->cpu); cpu_dev = get_cpu_device(j); ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, "cpufreq"); @@ -831,8 +830,7 @@ static int cpufreq_add_dev_symlink(unsigned int cpu, return ret; } -static int cpufreq_add_dev_interface(unsigned int cpu, - struct cpufreq_policy *policy, +static int cpufreq_add_dev_interface(struct cpufreq_policy *policy, struct device *dev) { struct freq_attr **drv_attr; @@ -868,7 +866,7 @@ static int cpufreq_add_dev_interface(unsigned int cpu, goto err_out_kobj_put; } - ret = cpufreq_add_dev_symlink(cpu, policy); + ret = cpufreq_add_dev_symlink(policy); if (ret) goto err_out_kobj_put; @@ -1097,7 +1095,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, write_unlock_irqrestore(&cpufreq_driver_lock, flags); if (!frozen) { - ret = cpufreq_add_dev_interface(cpu, policy, dev); + ret = cpufreq_add_dev_interface(policy, dev); if (ret) goto err_out_unregister; } -- cgit v1.2.3-58-ga151 From 71c3461ef7c67024792d283b88630245a6c169ba Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 4 Aug 2013 01:19:34 +0200 Subject: cpufreq: Do not hold driver module references for additional policy CPUs The cpufreq core is a little inconsistent in the way it uses the driver module refcount. Namely, if __cpufreq_add_dev() is called for a CPU that doesn't share the policy object with any other CPUs, the driver module refcount it grabs to start with will be dropped by it before returning and will be equal to whatever it had been before that function was invoked. However, if the given CPU does share the policy object with other CPUs, either cpufreq_add_policy_cpu() is called to link the new CPU to the existing policy, or cpufreq_add_dev_symlink() is used to link the other CPUs sharing the policy with it to the just created policy object. In that case, because both cpufreq_add_policy_cpu() and cpufreq_add_dev_symlink() call cpufreq_cpu_get() for the given policy (the latter possibly many times) without the balancing cpufreq_cpu_put() (unless there is an error), the driver module refcount will be left by __cpufreq_add_dev() with a nonzero value (different from the initial one). To remove that inconsistency make cpufreq_add_policy_cpu() execute cpufreq_cpu_put() for the given policy before returning, which decrements the driver module refcount so that it will be equal to its initial value after __cpufreq_add_dev() returns. Also remove the cpufreq_cpu_get() call from cpufreq_add_dev_symlink(), since both the policy refcount and the driver module refcount are nonzero when it is called and they don't need to be bumped up by it. Accordingly, drop the cpufreq_cpu_put() from __cpufreq_remove_dev(), since it is only necessary to balance the cpufreq_cpu_get() called by cpufreq_add_policy_cpu() or cpufreq_add_dev_symlink(). Signed-off-by: Rafael J. Wysocki Reviewed-by: Srivatsa S. Bhat Acked-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 576b312645a5..c8b2ca0f44ae 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -818,14 +818,11 @@ static int cpufreq_add_dev_symlink(struct cpufreq_policy *policy) continue; pr_debug("Adding link for CPU: %u\n", j); - cpufreq_cpu_get(policy->cpu); cpu_dev = get_cpu_device(j); ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, "cpufreq"); - if (ret) { - cpufreq_cpu_put(policy); - return ret; - } + if (ret) + break; } return ret; } @@ -908,7 +905,8 @@ static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling, unsigned long flags; policy = cpufreq_cpu_get(sibling); - WARN_ON(!policy); + if (WARN_ON_ONCE(!policy)) + return -ENODATA; if (has_target) __cpufreq_governor(policy, CPUFREQ_GOV_STOP); @@ -930,16 +928,10 @@ static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling, } /* Don't touch sysfs links during light-weight init */ - if (frozen) { - /* Drop the extra refcount that we took above */ - cpufreq_cpu_put(policy); - return 0; - } - - ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); - if (ret) - cpufreq_cpu_put(policy); + if (!frozen) + ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); + cpufreq_cpu_put(policy); return ret; } #endif @@ -1298,12 +1290,6 @@ static int __cpufreq_remove_dev(struct device *dev, if (!frozen) cpufreq_policy_free(data); } else { - - if (!frozen) { - pr_debug("%s: removing link, cpu: %d\n", __func__, cpu); - cpufreq_cpu_put(data); - } - if (cpufreq_driver->target) { __cpufreq_governor(data, CPUFREQ_GOV_START); __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); -- cgit v1.2.3-58-ga151 From 10659ab7b50e963429f1a681882404ca37aa584c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 4 Aug 2013 01:19:41 +0200 Subject: cpufreq: Avoid double kobject_put() for the same kobject in error code path The only case triggering a jump to the err_out_unregister label in __cpufreq_add_dev() is when cpufreq_add_dev_interface() fails. However, if cpufreq_add_dev_interface() fails, it calls kobject_put() for the policy kobject in its error code path and since that causes the kobject's refcount to become 0, the additional kobject_put() for the same kobject under err_out_unregister and the wait_for_completion() following it are pointless, so drop them. Signed-off-by: Rafael J. Wysocki Reviewed-by: Srivatsa S. Bhat Acked-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index c8b2ca0f44ae..924d3f5df26d 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1109,9 +1109,6 @@ err_out_unregister: } write_unlock_irqrestore(&cpufreq_driver_lock, flags); - kobject_put(&policy->kobj); - wait_for_completion(&policy->kobj_unregister); - err_set_policy_cpu: per_cpu(cpufreq_policy_cpu, cpu) = -1; cpufreq_policy_free(policy); -- cgit v1.2.3-58-ga151 From d8d3b4711297e101bbad826474013edbe342c333 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Sun, 4 Aug 2013 01:20:07 +0200 Subject: cpufreq: Pass policy to cpufreq_add_policy_cpu() The caller of cpufreq_add_policy_cpu() already has a pointer to the policy structure and there is no need to look it up again in cpufreq_add_policy_cpu(). Let's pass it directly. Signed-off-by: Viresh Kumar Reviewed-by: Srivatsa S. Bhat Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 924d3f5df26d..1faf320a5038 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -897,21 +897,17 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy) } #ifdef CONFIG_HOTPLUG_CPU -static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling, - struct device *dev, bool frozen) +static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, + unsigned int cpu, struct device *dev, + bool frozen) { - struct cpufreq_policy *policy; int ret = 0, has_target = !!cpufreq_driver->target; unsigned long flags; - policy = cpufreq_cpu_get(sibling); - if (WARN_ON_ONCE(!policy)) - return -ENODATA; - if (has_target) __cpufreq_governor(policy, CPUFREQ_GOV_STOP); - lock_policy_rwsem_write(sibling); + lock_policy_rwsem_write(policy->cpu); write_lock_irqsave(&cpufreq_driver_lock, flags); @@ -920,7 +916,7 @@ static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling, per_cpu(cpufreq_cpu_data, cpu) = policy; write_unlock_irqrestore(&cpufreq_driver_lock, flags); - unlock_policy_rwsem_write(sibling); + unlock_policy_rwsem_write(policy->cpu); if (has_target) { __cpufreq_governor(policy, CPUFREQ_GOV_START); @@ -931,7 +927,6 @@ static int cpufreq_add_policy_cpu(unsigned int cpu, unsigned int sibling, if (!frozen) ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); - cpufreq_cpu_put(policy); return ret; } #endif @@ -1014,8 +1009,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling); if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) { read_unlock_irqrestore(&cpufreq_driver_lock, flags); - return cpufreq_add_policy_cpu(cpu, sibling, dev, - frozen); + return cpufreq_add_policy_cpu(cp, cpu, dev, frozen); } } read_unlock_irqrestore(&cpufreq_driver_lock, flags); -- cgit v1.2.3-58-ga151 From 5ff0a268037d344f86df690ccb994d8bc015d2d9 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 6 Aug 2013 22:53:03 +0530 Subject: cpufreq: Clean up header files included in the core This patch addresses the following issues in the header files in the cpufreq core: - Include headers in ascending order, so that we don't add same many times by mistake. - must be included after , so that they override whatever they need to. - Remove unnecessary includes. - Don't include files already included by cpufreq.h or cpufreq_governor.h. [rjw: Changelog] Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 19 ++++++------------- drivers/cpufreq/cpufreq_conservative.c | 12 ------------ drivers/cpufreq/cpufreq_governor.c | 6 ------ drivers/cpufreq/cpufreq_governor.h | 5 ++--- drivers/cpufreq/cpufreq_ondemand.c | 12 +----------- drivers/cpufreq/cpufreq_performance.c | 3 +-- drivers/cpufreq/cpufreq_powersave.c | 3 +-- drivers/cpufreq/cpufreq_stats.c | 9 +-------- drivers/cpufreq/freq_table.c | 4 +--- include/linux/cpufreq.h | 11 +++-------- 10 files changed, 16 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index e34bd94e12b4..845837174878 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -17,24 +17,17 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include -#include -#include -#include -#include -#include +#include #include #include -#include -#include -#include #include -#include -#include -#include +#include +#include +#include #include +#include #include - +#include #include /** diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 0ceb2eff5a7e..841e25699656 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -11,19 +11,7 @@ * published by the Free Software Foundation. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include - #include "cpufreq_governor.h" /* Conservative governor macros */ diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 7409dbd1d897..556064e9cc01 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -16,15 +16,9 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include -#include -#include #include #include -#include #include -#include -#include #include "cpufreq_governor.h" diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index 0e0dd4c82020..cf0b7a4425b0 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h @@ -18,10 +18,9 @@ #define _CPUFREQ_GOVERNOR_H #include -#include +#include +#include #include -#include -#include /* * The polling frequency depends on the capability of the processor. Default diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index a3c5574f9b3a..27c732eee431 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -12,20 +12,10 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include -#include -#include -#include -#include -#include -#include +#include #include #include -#include #include -#include -#include - #include "cpufreq_governor.h" /* On-demand governor macros */ diff --git a/drivers/cpufreq/cpufreq_performance.c b/drivers/cpufreq/cpufreq_performance.c index 9fef7d6e4e6a..cf117deb39b1 100644 --- a/drivers/cpufreq/cpufreq_performance.c +++ b/drivers/cpufreq/cpufreq_performance.c @@ -12,10 +12,9 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include -#include #include #include +#include static int cpufreq_governor_performance(struct cpufreq_policy *policy, unsigned int event) diff --git a/drivers/cpufreq/cpufreq_powersave.c b/drivers/cpufreq/cpufreq_powersave.c index 32109a14f5dc..e3b874c235ea 100644 --- a/drivers/cpufreq/cpufreq_powersave.c +++ b/drivers/cpufreq/cpufreq_powersave.c @@ -12,10 +12,9 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include -#include #include #include +#include static int cpufreq_governor_powersave(struct cpufreq_policy *policy, unsigned int event) diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index cb3841355454..a7143b0597af 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -9,17 +9,10 @@ * published by the Free Software Foundation. */ -#include -#include #include -#include #include #include -#include -#include -#include -#include -#include +#include #include static spinlock_t cpufreq_stats_lock; diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index f0d87412cc91..f111454a7aea 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -11,10 +11,8 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include -#include -#include #include +#include /********************************************************************* * FREQUENCY TABLE HELPERS * diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index e1fd215e16c9..97627bbbca82 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -11,16 +11,11 @@ #ifndef _LINUX_CPUFREQ_H #define _LINUX_CPUFREQ_H -#include -#include -#include -#include +#include +#include #include +#include #include -#include -#include -#include -#include #define CPUFREQ_NAME_LEN 16 /* Print length for names. Extra 1 space for accomodating '\n' in prints */ -- cgit v1.2.3-58-ga151 From 3a3e9e06d0c11b8efa95933a88c9e67209fa4330 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 6 Aug 2013 22:53:05 +0530 Subject: cpufreq: Give consistent names to cpufreq_policy objects They are called policy, cur_policy, new_policy, data, etc. Just call them policy wherever possible. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 200 ++++++++++++++++++------------------- drivers/cpufreq/cpufreq_governor.h | 2 +- drivers/cpufreq/cpufreq_ondemand.c | 10 +- drivers/cpufreq/cpufreq_stats.c | 12 +-- include/linux/cpufreq.h | 2 +- 5 files changed, 113 insertions(+), 113 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 845837174878..1793fe82595d 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -179,7 +179,7 @@ EXPORT_SYMBOL_GPL(get_cpu_idle_time); static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs) { - struct cpufreq_policy *data; + struct cpufreq_policy *policy; unsigned long flags; if (cpu >= nr_cpu_ids) @@ -195,16 +195,16 @@ static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs) goto err_out_unlock; /* get the CPU */ - data = per_cpu(cpufreq_cpu_data, cpu); + policy = per_cpu(cpufreq_cpu_data, cpu); - if (!data) + if (!policy) goto err_out_put_module; - if (!sysfs && !kobject_get(&data->kobj)) + if (!sysfs && !kobject_get(&policy->kobj)) goto err_out_put_module; read_unlock_irqrestore(&cpufreq_driver_lock, flags); - return data; + return policy; err_out_put_module: module_put(cpufreq_driver->owner); @@ -228,25 +228,25 @@ static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu) return __cpufreq_cpu_get(cpu, true); } -static void __cpufreq_cpu_put(struct cpufreq_policy *data, bool sysfs) +static void __cpufreq_cpu_put(struct cpufreq_policy *policy, bool sysfs) { if (!sysfs) - kobject_put(&data->kobj); + kobject_put(&policy->kobj); module_put(cpufreq_driver->owner); } -void cpufreq_cpu_put(struct cpufreq_policy *data) +void cpufreq_cpu_put(struct cpufreq_policy *policy) { if (cpufreq_disabled()) return; - __cpufreq_cpu_put(data, false); + __cpufreq_cpu_put(policy, false); } EXPORT_SYMBOL_GPL(cpufreq_cpu_put); -static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *data) +static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *policy) { - __cpufreq_cpu_put(data, true); + __cpufreq_cpu_put(policy, true); } /********************************************************************* @@ -453,8 +453,8 @@ show_one(scaling_min_freq, min); show_one(scaling_max_freq, max); show_one(scaling_cur_freq, cur); -static int __cpufreq_set_policy(struct cpufreq_policy *data, - struct cpufreq_policy *policy); +static int __cpufreq_set_policy(struct cpufreq_policy *policy, + struct cpufreq_policy *new_policy); /** * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access @@ -1136,7 +1136,7 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) CPUFREQ_UPDATE_POLICY_CPU, policy); } -static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *data, +static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, unsigned int old_cpu, bool frozen) { struct device *cpu_dev; @@ -1144,27 +1144,27 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *data, int ret; /* first sibling now owns the new sysfs dir */ - cpu_dev = get_cpu_device(cpumask_first(data->cpus)); + cpu_dev = get_cpu_device(cpumask_first(policy->cpus)); /* Don't touch sysfs files during light-weight tear-down */ if (frozen) return cpu_dev->id; sysfs_remove_link(&cpu_dev->kobj, "cpufreq"); - ret = kobject_move(&data->kobj, &cpu_dev->kobj); + ret = kobject_move(&policy->kobj, &cpu_dev->kobj); if (ret) { pr_err("%s: Failed to move kobj: %d", __func__, ret); WARN_ON(lock_policy_rwsem_write(old_cpu)); - cpumask_set_cpu(old_cpu, data->cpus); + cpumask_set_cpu(old_cpu, policy->cpus); write_lock_irqsave(&cpufreq_driver_lock, flags); - per_cpu(cpufreq_cpu_data, old_cpu) = data; + per_cpu(cpufreq_cpu_data, old_cpu) = policy; write_unlock_irqrestore(&cpufreq_driver_lock, flags); unlock_policy_rwsem_write(old_cpu); - ret = sysfs_create_link(&cpu_dev->kobj, &data->kobj, + ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, "cpufreq"); return -EINVAL; @@ -1186,7 +1186,7 @@ static int __cpufreq_remove_dev(struct device *dev, unsigned int cpu = dev->id, cpus; int new_cpu; unsigned long flags; - struct cpufreq_policy *data; + struct cpufreq_policy *policy; struct kobject *kobj; struct completion *cmp; @@ -1194,44 +1194,44 @@ static int __cpufreq_remove_dev(struct device *dev, write_lock_irqsave(&cpufreq_driver_lock, flags); - data = per_cpu(cpufreq_cpu_data, cpu); + policy = per_cpu(cpufreq_cpu_data, cpu); per_cpu(cpufreq_cpu_data, cpu) = NULL; /* Save the policy somewhere when doing a light-weight tear-down */ if (frozen) - per_cpu(cpufreq_cpu_data_fallback, cpu) = data; + per_cpu(cpufreq_cpu_data_fallback, cpu) = policy; write_unlock_irqrestore(&cpufreq_driver_lock, flags); - if (!data) { + if (!policy) { pr_debug("%s: No cpu_data found\n", __func__); return -EINVAL; } if (cpufreq_driver->target) - __cpufreq_governor(data, CPUFREQ_GOV_STOP); + __cpufreq_governor(policy, CPUFREQ_GOV_STOP); #ifdef CONFIG_HOTPLUG_CPU if (!cpufreq_driver->setpolicy) strncpy(per_cpu(cpufreq_cpu_governor, cpu), - data->governor->name, CPUFREQ_NAME_LEN); + policy->governor->name, CPUFREQ_NAME_LEN); #endif WARN_ON(lock_policy_rwsem_write(cpu)); - cpus = cpumask_weight(data->cpus); + cpus = cpumask_weight(policy->cpus); if (cpus > 1) - cpumask_clear_cpu(cpu, data->cpus); + cpumask_clear_cpu(cpu, policy->cpus); unlock_policy_rwsem_write(cpu); - if (cpu != data->cpu && !frozen) { + if (cpu != policy->cpu && !frozen) { sysfs_remove_link(&dev->kobj, "cpufreq"); } else if (cpus > 1) { - new_cpu = cpufreq_nominate_new_policy_cpu(data, cpu, frozen); + new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu, frozen); if (new_cpu >= 0) { WARN_ON(lock_policy_rwsem_write(cpu)); - update_policy_cpu(data, new_cpu); + update_policy_cpu(policy, new_cpu); unlock_policy_rwsem_write(cpu); if (!frozen) { @@ -1244,12 +1244,12 @@ static int __cpufreq_remove_dev(struct device *dev, /* If cpu is last user of policy, free policy */ if (cpus == 1) { if (cpufreq_driver->target) - __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); + __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); if (!frozen) { lock_policy_rwsem_read(cpu); - kobj = &data->kobj; - cmp = &data->kobj_unregister; + kobj = &policy->kobj; + cmp = &policy->kobj_unregister; unlock_policy_rwsem_read(cpu); kobject_put(kobj); @@ -1269,14 +1269,14 @@ static int __cpufreq_remove_dev(struct device *dev, * subsequent light-weight ->init() to succeed. */ if (cpufreq_driver->exit) - cpufreq_driver->exit(data); + cpufreq_driver->exit(policy); if (!frozen) - cpufreq_policy_free(data); + cpufreq_policy_free(policy); } else { if (cpufreq_driver->target) { - __cpufreq_governor(data, CPUFREQ_GOV_START); - __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); + __cpufreq_governor(policy, CPUFREQ_GOV_START); + __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); } } @@ -1450,23 +1450,23 @@ static int cpufreq_bp_suspend(void) int ret = 0; int cpu = smp_processor_id(); - struct cpufreq_policy *cpu_policy; + struct cpufreq_policy *policy; pr_debug("suspending cpu %u\n", cpu); /* If there's no policy for the boot CPU, we have nothing to do. */ - cpu_policy = cpufreq_cpu_get(cpu); - if (!cpu_policy) + policy = cpufreq_cpu_get(cpu); + if (!policy) return 0; if (cpufreq_driver->suspend) { - ret = cpufreq_driver->suspend(cpu_policy); + ret = cpufreq_driver->suspend(policy); if (ret) printk(KERN_ERR "cpufreq: suspend failed in ->suspend " - "step on CPU %u\n", cpu_policy->cpu); + "step on CPU %u\n", policy->cpu); } - cpufreq_cpu_put(cpu_policy); + cpufreq_cpu_put(policy); return ret; } @@ -1488,28 +1488,28 @@ static void cpufreq_bp_resume(void) int ret = 0; int cpu = smp_processor_id(); - struct cpufreq_policy *cpu_policy; + struct cpufreq_policy *policy; pr_debug("resuming cpu %u\n", cpu); /* If there's no policy for the boot CPU, we have nothing to do. */ - cpu_policy = cpufreq_cpu_get(cpu); - if (!cpu_policy) + policy = cpufreq_cpu_get(cpu); + if (!policy) return; if (cpufreq_driver->resume) { - ret = cpufreq_driver->resume(cpu_policy); + ret = cpufreq_driver->resume(policy); if (ret) { printk(KERN_ERR "cpufreq: resume failed in ->resume " - "step on CPU %u\n", cpu_policy->cpu); + "step on CPU %u\n", policy->cpu); goto fail; } } - schedule_work(&cpu_policy->update); + schedule_work(&policy->update); fail: - cpufreq_cpu_put(cpu_policy); + cpufreq_cpu_put(policy); } static struct syscore_ops cpufreq_syscore_ops = { @@ -1829,95 +1829,95 @@ EXPORT_SYMBOL(cpufreq_get_policy); * data : current policy. * policy : policy to be set. */ -static int __cpufreq_set_policy(struct cpufreq_policy *data, - struct cpufreq_policy *policy) +static int __cpufreq_set_policy(struct cpufreq_policy *policy, + struct cpufreq_policy *new_policy) { int ret = 0, failed = 1; - pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu, - policy->min, policy->max); + pr_debug("setting new policy for CPU %u: %u - %u kHz\n", new_policy->cpu, + new_policy->min, new_policy->max); - memcpy(&policy->cpuinfo, &data->cpuinfo, + memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(struct cpufreq_cpuinfo)); - if (policy->min > data->max || policy->max < data->min) { + if (new_policy->min > policy->max || new_policy->max < policy->min) { ret = -EINVAL; goto error_out; } /* verify the cpu speed can be set within this limit */ - ret = cpufreq_driver->verify(policy); + ret = cpufreq_driver->verify(new_policy); if (ret) goto error_out; /* adjust if necessary - all reasons */ blocking_notifier_call_chain(&cpufreq_policy_notifier_list, - CPUFREQ_ADJUST, policy); + CPUFREQ_ADJUST, new_policy); /* adjust if necessary - hardware incompatibility*/ blocking_notifier_call_chain(&cpufreq_policy_notifier_list, - CPUFREQ_INCOMPATIBLE, policy); + CPUFREQ_INCOMPATIBLE, new_policy); /* * verify the cpu speed can be set within this limit, which might be * different to the first one */ - ret = cpufreq_driver->verify(policy); + ret = cpufreq_driver->verify(new_policy); if (ret) goto error_out; /* notification of the new policy */ blocking_notifier_call_chain(&cpufreq_policy_notifier_list, - CPUFREQ_NOTIFY, policy); + CPUFREQ_NOTIFY, new_policy); - data->min = policy->min; - data->max = policy->max; + policy->min = new_policy->min; + policy->max = new_policy->max; pr_debug("new min and max freqs are %u - %u kHz\n", - data->min, data->max); + policy->min, policy->max); if (cpufreq_driver->setpolicy) { - data->policy = policy->policy; + policy->policy = new_policy->policy; pr_debug("setting range\n"); - ret = cpufreq_driver->setpolicy(policy); + ret = cpufreq_driver->setpolicy(new_policy); } else { - if (policy->governor != data->governor) { + if (new_policy->governor != policy->governor) { /* save old, working values */ - struct cpufreq_governor *old_gov = data->governor; + struct cpufreq_governor *old_gov = policy->governor; pr_debug("governor switch\n"); /* end old governor */ - if (data->governor) { - __cpufreq_governor(data, CPUFREQ_GOV_STOP); - unlock_policy_rwsem_write(policy->cpu); - __cpufreq_governor(data, + if (policy->governor) { + __cpufreq_governor(policy, CPUFREQ_GOV_STOP); + unlock_policy_rwsem_write(new_policy->cpu); + __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); - lock_policy_rwsem_write(policy->cpu); + lock_policy_rwsem_write(new_policy->cpu); } /* start new governor */ - data->governor = policy->governor; - if (!__cpufreq_governor(data, CPUFREQ_GOV_POLICY_INIT)) { - if (!__cpufreq_governor(data, CPUFREQ_GOV_START)) { + policy->governor = new_policy->governor; + if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) { + if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) { failed = 0; } else { - unlock_policy_rwsem_write(policy->cpu); - __cpufreq_governor(data, + unlock_policy_rwsem_write(new_policy->cpu); + __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); - lock_policy_rwsem_write(policy->cpu); + lock_policy_rwsem_write(new_policy->cpu); } } if (failed) { /* new governor failed, so re-start old one */ pr_debug("starting governor %s failed\n", - data->governor->name); + policy->governor->name); if (old_gov) { - data->governor = old_gov; - __cpufreq_governor(data, + policy->governor = old_gov; + __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); - __cpufreq_governor(data, + __cpufreq_governor(policy, CPUFREQ_GOV_START); } ret = -EINVAL; @@ -1926,7 +1926,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, /* might be a policy change, too, so fall through */ } pr_debug("governor: change or update limits\n"); - __cpufreq_governor(data, CPUFREQ_GOV_LIMITS); + __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); } error_out: @@ -1942,11 +1942,11 @@ error_out: */ int cpufreq_update_policy(unsigned int cpu) { - struct cpufreq_policy *data = cpufreq_cpu_get(cpu); - struct cpufreq_policy policy; + struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); + struct cpufreq_policy new_policy; int ret; - if (!data) { + if (!policy) { ret = -ENODEV; goto no_policy; } @@ -1957,34 +1957,34 @@ int cpufreq_update_policy(unsigned int cpu) } pr_debug("updating policy for CPU %u\n", cpu); - memcpy(&policy, data, sizeof(struct cpufreq_policy)); - policy.min = data->user_policy.min; - policy.max = data->user_policy.max; - policy.policy = data->user_policy.policy; - policy.governor = data->user_policy.governor; + memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); + new_policy.min = policy->user_policy.min; + new_policy.max = policy->user_policy.max; + new_policy.policy = policy->user_policy.policy; + new_policy.governor = policy->user_policy.governor; /* * BIOS might change freq behind our back * -> ask driver for current freq and notify governors about a change */ if (cpufreq_driver->get) { - policy.cur = cpufreq_driver->get(cpu); - if (!data->cur) { + new_policy.cur = cpufreq_driver->get(cpu); + if (!policy->cur) { pr_debug("Driver did not initialize current freq"); - data->cur = policy.cur; + policy->cur = new_policy.cur; } else { - if (data->cur != policy.cur && cpufreq_driver->target) - cpufreq_out_of_sync(cpu, data->cur, - policy.cur); + if (policy->cur != new_policy.cur && cpufreq_driver->target) + cpufreq_out_of_sync(cpu, policy->cur, + new_policy.cur); } } - ret = __cpufreq_set_policy(data, &policy); + ret = __cpufreq_set_policy(policy, &new_policy); unlock_policy_rwsem_write(cpu); fail: - cpufreq_cpu_put(data); + cpufreq_cpu_put(policy); no_policy: return ret; } diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index cf0b7a4425b0..264e509a9149 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h @@ -221,7 +221,7 @@ struct od_ops { void (*powersave_bias_init_cpu)(int cpu); unsigned int (*powersave_bias_target)(struct cpufreq_policy *policy, unsigned int freq_next, unsigned int relation); - void (*freq_increase)(struct cpufreq_policy *p, unsigned int freq); + void (*freq_increase)(struct cpufreq_policy *policy, unsigned int freq); }; struct cs_ops { diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 27c732eee431..47d4b69be7c6 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -132,18 +132,18 @@ static void ondemand_powersave_bias_init(void) } } -static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq) +static void dbs_freq_increase(struct cpufreq_policy *policy, unsigned int freq) { - struct dbs_data *dbs_data = p->governor_data; + struct dbs_data *dbs_data = policy->governor_data; struct od_dbs_tuners *od_tuners = dbs_data->tuners; if (od_tuners->powersave_bias) - freq = od_ops.powersave_bias_target(p, freq, + freq = od_ops.powersave_bias_target(policy, freq, CPUFREQ_RELATION_H); - else if (p->cur == p->max) + else if (policy->cur == policy->max) return; - __cpufreq_driver_target(p, freq, od_tuners->powersave_bias ? + __cpufreq_driver_target(policy, freq, od_tuners->powersave_bias ? CPUFREQ_RELATION_L : CPUFREQ_RELATION_H); } diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index a7143b0597af..a17b14ee37d8 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -193,7 +193,7 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy, { unsigned int i, j, count = 0, ret = 0; struct cpufreq_stats *stat; - struct cpufreq_policy *data; + struct cpufreq_policy *current_policy; unsigned int alloc_size; unsigned int cpu = policy->cpu; if (per_cpu(cpufreq_stats_table, cpu)) @@ -202,13 +202,13 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy, if ((stat) == NULL) return -ENOMEM; - data = cpufreq_cpu_get(cpu); - if (data == NULL) { + current_policy = cpufreq_cpu_get(cpu); + if (current_policy == NULL) { ret = -EINVAL; goto error_get_fail; } - ret = sysfs_create_group(&data->kobj, &stats_attr_group); + ret = sysfs_create_group(¤t_policy->kobj, &stats_attr_group); if (ret) goto error_out; @@ -251,10 +251,10 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy, stat->last_time = get_jiffies_64(); stat->last_index = freq_table_get_index(stat, policy->cur); spin_unlock(&cpufreq_stats_lock); - cpufreq_cpu_put(data); + cpufreq_cpu_put(current_policy); return 0; error_out: - cpufreq_cpu_put(data); + cpufreq_cpu_put(current_policy); error_get_fail: kfree(stat); per_cpu(cpufreq_stats_table, cpu) = NULL; diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 0d3b0266bc98..29208923c9d3 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -94,7 +94,7 @@ struct cpufreq_policy { #define CPUFREQ_SHARED_TYPE_ANY (3) /* Freq can be set from any dependent CPU*/ struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu); -void cpufreq_cpu_put(struct cpufreq_policy *data); +void cpufreq_cpu_put(struct cpufreq_policy *policy); static inline bool policy_is_shared(struct cpufreq_policy *policy) { -- cgit v1.2.3-58-ga151 From d5b73cd870e2b049ef566aec2791dbf5fd26a7ec Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 6 Aug 2013 22:53:06 +0530 Subject: cpufreq: Use sizeof(*ptr) convetion for computing sizes Chapter 14 of Documentation/CodingStyle says: The preferred form for passing a size of a struct is the following: p = kmalloc(sizeof(*p), ...); The alternative form where struct name is spelled out hurts readability and introduces an opportunity for a bug when the pointer variable type is changed but the corresponding sizeof that is passed to a memory allocator is not. This wasn't followed consistently in drivers/cpufreq, let's make it more consistent by always following this rule. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/acpi-cpufreq.c | 4 ++-- drivers/cpufreq/cpufreq.c | 9 ++++----- drivers/cpufreq/cpufreq_conservative.c | 2 +- drivers/cpufreq/cpufreq_ondemand.c | 2 +- drivers/cpufreq/cpufreq_stats.c | 2 +- drivers/cpufreq/e_powersaver.c | 4 ++-- drivers/cpufreq/exynos-cpufreq.c | 2 +- drivers/cpufreq/gx-suspmod.c | 2 +- drivers/cpufreq/ia64-acpi-cpufreq.c | 4 ++-- drivers/cpufreq/pmac64-cpufreq.c | 5 ++--- drivers/cpufreq/powernow-k7.c | 13 ++++++------- drivers/cpufreq/powernow-k8.c | 6 +++--- drivers/cpufreq/s3c24xx-cpufreq.c | 6 +++--- drivers/cpufreq/sparc-us2e-cpufreq.c | 5 ++--- drivers/cpufreq/sparc-us3-cpufreq.c | 5 ++--- 15 files changed, 33 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index e673670d2321..44758ce9936d 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -709,7 +709,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) return blacklisted; #endif - data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL); + data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -799,7 +799,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) goto err_unreg; } - data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * + data->freq_table = kmalloc(sizeof(*data->freq_table) * (perf->state_count+1), GFP_KERNEL); if (!data->freq_table) { result = -ENOMEM; diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1793fe82595d..9e83d9142072 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -873,7 +873,7 @@ static void cpufreq_init_policy(struct cpufreq_policy *policy) struct cpufreq_policy new_policy; int ret = 0; - memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); + memcpy(&new_policy, policy, sizeof(*policy)); /* assure that the starting sequence is run in __cpufreq_set_policy */ policy->governor = NULL; @@ -1818,7 +1818,7 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) if (!cpu_policy) return -EINVAL; - memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy)); + memcpy(policy, cpu_policy, sizeof(*policy)); cpufreq_cpu_put(cpu_policy); return 0; @@ -1837,8 +1837,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *policy, pr_debug("setting new policy for CPU %u: %u - %u kHz\n", new_policy->cpu, new_policy->min, new_policy->max); - memcpy(&new_policy->cpuinfo, &policy->cpuinfo, - sizeof(struct cpufreq_cpuinfo)); + memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo)); if (new_policy->min > policy->max || new_policy->max < policy->min) { ret = -EINVAL; @@ -1957,7 +1956,7 @@ int cpufreq_update_policy(unsigned int cpu) } pr_debug("updating policy for CPU %u\n", cpu); - memcpy(&new_policy, policy, sizeof(struct cpufreq_policy)); + memcpy(&new_policy, policy, sizeof(*policy)); new_policy.min = policy->user_policy.min; new_policy.max = policy->user_policy.max; new_policy.policy = policy->user_policy.policy; diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 841e25699656..c4009241e733 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -317,7 +317,7 @@ static int cs_init(struct dbs_data *dbs_data) { struct cs_dbs_tuners *tuners; - tuners = kzalloc(sizeof(struct cs_dbs_tuners), GFP_KERNEL); + tuners = kzalloc(sizeof(*tuners), GFP_KERNEL); if (!tuners) { pr_err("%s: kzalloc failed\n", __func__); return -ENOMEM; diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 47d4b69be7c6..117278ab5869 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -482,7 +482,7 @@ static int od_init(struct dbs_data *dbs_data) u64 idle_time; int cpu; - tuners = kzalloc(sizeof(struct od_dbs_tuners), GFP_KERNEL); + tuners = kzalloc(sizeof(*tuners), GFP_KERNEL); if (!tuners) { pr_err("%s: kzalloc failed\n", __func__); return -ENOMEM; diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index a17b14ee37d8..04452f026ed0 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -198,7 +198,7 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy, unsigned int cpu = policy->cpu; if (per_cpu(cpufreq_stats_table, cpu)) return -EBUSY; - stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL); + stat = kzalloc(sizeof(*stat), GFP_KERNEL); if ((stat) == NULL) return -ENOMEM; diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c index a60efaeb4cf8..de974be6b773 100644 --- a/drivers/cpufreq/e_powersaver.c +++ b/drivers/cpufreq/e_powersaver.c @@ -54,7 +54,7 @@ static struct acpi_processor_performance *eps_acpi_cpu_perf; /* Minimum necessary to get acpi_processor_get_bios_limit() working */ static int eps_acpi_init(void) { - eps_acpi_cpu_perf = kzalloc(sizeof(struct acpi_processor_performance), + eps_acpi_cpu_perf = kzalloc(sizeof(*eps_acpi_cpu_perf), GFP_KERNEL); if (!eps_acpi_cpu_perf) return -ENOMEM; @@ -366,7 +366,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy) states = 2; /* Allocate private data and frequency table for current cpu */ - centaur = kzalloc(sizeof(struct eps_cpu_data) + centaur = kzalloc(sizeof(*centaur) + (states + 1) * sizeof(struct cpufreq_frequency_table), GFP_KERNEL); if (!centaur) diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index 0d32f02ef4d6..366475161c76 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c @@ -289,7 +289,7 @@ static int __init exynos_cpufreq_init(void) { int ret = -EINVAL; - exynos_info = kzalloc(sizeof(struct exynos_dvfs_info), GFP_KERNEL); + exynos_info = kzalloc(sizeof(*exynos_info), GFP_KERNEL); if (!exynos_info) return -ENOMEM; diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c index 3dfc99b9ca86..4f25fb63c097 100644 --- a/drivers/cpufreq/gx-suspmod.c +++ b/drivers/cpufreq/gx-suspmod.c @@ -466,7 +466,7 @@ static int __init cpufreq_gx_init(void) pr_debug("geode suspend modulation available.\n"); - params = kzalloc(sizeof(struct gxfreq_params), GFP_KERNEL); + params = kzalloc(sizeof(*params), GFP_KERNEL); if (params == NULL) return -ENOMEM; diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c index 573c14ea802d..08792dd4d62a 100644 --- a/drivers/cpufreq/ia64-acpi-cpufreq.c +++ b/drivers/cpufreq/ia64-acpi-cpufreq.c @@ -274,7 +274,7 @@ acpi_cpufreq_cpu_init ( pr_debug("acpi_cpufreq_cpu_init\n"); - data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); + data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) return (-ENOMEM); @@ -304,7 +304,7 @@ acpi_cpufreq_cpu_init ( } /* alloc freq_table */ - data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) * + data->freq_table = kmalloc(sizeof(*data->freq_table) * (data->acpi_data.state_count + 1), GFP_KERNEL); if (!data->freq_table) { diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c index 7ba423431cfe..4d7799b7af86 100644 --- a/drivers/cpufreq/pmac64-cpufreq.c +++ b/drivers/cpufreq/pmac64-cpufreq.c @@ -447,9 +447,8 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) if (!shdr) goto bail_noprops; g5_fvt_table = (struct smu_sdbp_fvt *)&shdr[1]; - ssize = (shdr->len * sizeof(u32)) - - sizeof(struct smu_sdbp_header); - g5_fvt_count = ssize / sizeof(struct smu_sdbp_fvt); + ssize = (shdr->len * sizeof(u32)) - sizeof(*shdr); + g5_fvt_count = ssize / sizeof(*g5_fvt_table); g5_fvt_cur = 0; /* Sanity checking */ diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index 955870877935..4687d40d0219 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c @@ -177,7 +177,7 @@ static int get_ranges(unsigned char *pst) unsigned int speed; u8 fid, vid; - powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * + powernow_table = kzalloc((sizeof(*powernow_table) * (number_scales + 1)), GFP_KERNEL); if (!powernow_table) return -ENOMEM; @@ -309,8 +309,7 @@ static int powernow_acpi_init(void) goto err0; } - acpi_processor_perf = kzalloc(sizeof(struct acpi_processor_performance), - GFP_KERNEL); + acpi_processor_perf = kzalloc(sizeof(*acpi_processor_perf), GFP_KERNEL); if (!acpi_processor_perf) { retval = -ENOMEM; goto err0; @@ -346,7 +345,7 @@ static int powernow_acpi_init(void) goto err2; } - powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * + powernow_table = kzalloc((sizeof(*powernow_table) * (number_scales + 1)), GFP_KERNEL); if (!powernow_table) { retval = -ENOMEM; @@ -497,7 +496,7 @@ static int powernow_decode_bios(int maxfid, int startvid) "relevant to this CPU).\n", psb->numpst); - p += sizeof(struct psb_s); + p += sizeof(*psb); pst = (struct pst_s *) p; @@ -510,12 +509,12 @@ static int powernow_decode_bios(int maxfid, int startvid) (maxfid == pst->maxfid) && (startvid == pst->startvid)) { print_pst_entry(pst, j); - p = (char *)pst + sizeof(struct pst_s); + p = (char *)pst + sizeof(*pst); ret = get_ranges(p); return ret; } else { unsigned int k; - p = (char *)pst + sizeof(struct pst_s); + p = (char *)pst + sizeof(*pst); for (k = 0; k < number_scales; k++) p += 2; } diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index c39d189217cb..3f3c6cae91d0 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -623,7 +623,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, if (check_pst_table(data, pst, maxvid)) return -EINVAL; - powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) + powernow_table = kmalloc((sizeof(*powernow_table) * (data->numps + 1)), GFP_KERNEL); if (!powernow_table) { printk(KERN_ERR PFX "powernow_table memory alloc failure\n"); @@ -793,7 +793,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) } /* fill in data->powernow_table */ - powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) + powernow_table = kmalloc((sizeof(*powernow_table) * (data->acpi_data.state_count + 1)), GFP_KERNEL); if (!powernow_table) { pr_debug("powernow_table memory alloc failure\n"); @@ -1106,7 +1106,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) if (rc) return -ENODEV; - data = kzalloc(sizeof(struct powernow_k8_data), GFP_KERNEL); + data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) { printk(KERN_ERR PFX "unable to alloc powernow_k8_data"); return -ENOMEM; diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c index 87781eb20d6d..f169ee52e6eb 100644 --- a/drivers/cpufreq/s3c24xx-cpufreq.c +++ b/drivers/cpufreq/s3c24xx-cpufreq.c @@ -522,7 +522,7 @@ int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board) /* Copy the board information so that each board can make this * initdata. */ - ours = kzalloc(sizeof(struct s3c_cpufreq_board), GFP_KERNEL); + ours = kzalloc(sizeof(*ours), GFP_KERNEL); if (ours == NULL) { printk(KERN_ERR "%s: no memory\n", __func__); return -ENOMEM; @@ -615,7 +615,7 @@ static int s3c_cpufreq_build_freq(void) size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0); size++; - ftab = kmalloc(sizeof(struct cpufreq_frequency_table) * size, GFP_KERNEL); + ftab = kmalloc(sizeof(*ftab) * size, GFP_KERNEL); if (!ftab) { printk(KERN_ERR "%s: no memory for tables\n", __func__); return -ENOMEM; @@ -691,7 +691,7 @@ int __init s3c_plltab_register(struct cpufreq_frequency_table *plls, struct cpufreq_frequency_table *vals; unsigned int size; - size = sizeof(struct cpufreq_frequency_table) * (plls_no + 1); + size = sizeof(*vals) * (plls_no + 1); vals = kmalloc(size, GFP_KERNEL); if (vals) { diff --git a/drivers/cpufreq/sparc-us2e-cpufreq.c b/drivers/cpufreq/sparc-us2e-cpufreq.c index 93061a408773..7c43a725e5da 100644 --- a/drivers/cpufreq/sparc-us2e-cpufreq.c +++ b/drivers/cpufreq/sparc-us2e-cpufreq.c @@ -351,12 +351,11 @@ static int __init us2e_freq_init(void) struct cpufreq_driver *driver; ret = -ENOMEM; - driver = kzalloc(sizeof(struct cpufreq_driver), GFP_KERNEL); + driver = kzalloc(sizeof(*driver), GFP_KERNEL); if (!driver) goto err_out; - us2e_freq_table = kzalloc( - (NR_CPUS * sizeof(struct us2e_freq_percpu_info)), + us2e_freq_table = kzalloc((NR_CPUS * sizeof(*us2e_freq_table)), GFP_KERNEL); if (!us2e_freq_table) goto err_out; diff --git a/drivers/cpufreq/sparc-us3-cpufreq.c b/drivers/cpufreq/sparc-us3-cpufreq.c index 880ee293d61e..7f500c140bc3 100644 --- a/drivers/cpufreq/sparc-us3-cpufreq.c +++ b/drivers/cpufreq/sparc-us3-cpufreq.c @@ -212,12 +212,11 @@ static int __init us3_freq_init(void) struct cpufreq_driver *driver; ret = -ENOMEM; - driver = kzalloc(sizeof(struct cpufreq_driver), GFP_KERNEL); + driver = kzalloc(sizeof(*driver), GFP_KERNEL); if (!driver) goto err_out; - us3_freq_table = kzalloc( - (NR_CPUS * sizeof(struct us3_freq_percpu_info)), + us3_freq_table = kzalloc((NR_CPUS * sizeof(*us3_freq_table)), GFP_KERNEL); if (!us3_freq_table) goto err_out; -- cgit v1.2.3-58-ga151 From c88a1f8b96e7384627b918dfabbfc0c615a4a914 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Tue, 6 Aug 2013 22:53:08 +0530 Subject: cpufreq: Store cpufreq policies in a list Policies available in the cpufreq framework are now linked together. They are accessible via cpufreq_policy_list defined in the cpufreq core. [rjw: Fix from Yinghai Lu folded in] Signed-off-by: Lukasz Majewski Signed-off-by: Myungjoo Ham Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 12 ++++++++++++ include/linux/cpufreq.h | 1 + 2 files changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 9e83d9142072..75c5bd424d59 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -40,6 +40,7 @@ static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data); static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data_fallback); static DEFINE_RWLOCK(cpufreq_driver_lock); static DEFINE_MUTEX(cpufreq_governor_lock); +static LIST_HEAD(cpufreq_policy_list); #ifdef CONFIG_HOTPLUG_CPU /* This one keeps track of the previously set governor of a removed CPU */ @@ -952,6 +953,7 @@ static struct cpufreq_policy *cpufreq_policy_alloc(void) if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) goto err_free_cpumask; + INIT_LIST_HEAD(&policy->policy_list); return policy; err_free_cpumask: @@ -964,6 +966,12 @@ err_free_policy: static void cpufreq_policy_free(struct cpufreq_policy *policy) { + unsigned long flags; + + write_lock_irqsave(&cpufreq_driver_lock, flags); + list_del(&policy->policy_list); + write_unlock_irqrestore(&cpufreq_driver_lock, flags); + free_cpumask_var(policy->related_cpus); free_cpumask_var(policy->cpus); kfree(policy); @@ -1077,6 +1085,10 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, ret = cpufreq_add_dev_interface(policy, dev); if (ret) goto err_out_unregister; + + write_lock_irqsave(&cpufreq_driver_lock, flags); + list_add(&policy->policy_list, &cpufreq_policy_list); + write_unlock_irqrestore(&cpufreq_driver_lock, flags); } cpufreq_init_policy(policy); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 29208923c9d3..431a05d4b4c9 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -82,6 +82,7 @@ struct cpufreq_policy { struct cpufreq_real_policy user_policy; + struct list_head policy_list; struct kobject kobj; struct completion kobj_unregister; int transition_ongoing; /* Tracks transition status */ -- cgit v1.2.3-58-ga151 From eb608521f1e25a8c14295b6d9a3853c3cd8c6cf8 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 6 Aug 2013 22:53:09 +0530 Subject: cpufreq: Use cpufreq_policy_list for iterating over policies To iterate over all policies we currently iterate over all CPUs and then get the policy for each of them. Let's use the newly created cpufreq_policy_list for this purpose. [rjw: Changelog] Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 75c5bd424d59..37af929746af 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -985,8 +985,8 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, struct cpufreq_policy *policy; unsigned long flags; #ifdef CONFIG_HOTPLUG_CPU + struct cpufreq_policy *tpolicy; struct cpufreq_governor *gov; - int sibling; #endif if (cpu_is_offline(cpu)) @@ -1006,11 +1006,11 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, #ifdef CONFIG_HOTPLUG_CPU /* Check if this cpu was hot-unplugged earlier and has siblings */ read_lock_irqsave(&cpufreq_driver_lock, flags); - for_each_online_cpu(sibling) { - struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling); - if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) { + list_for_each_entry(tpolicy, &cpufreq_policy_list, policy_list) { + if (cpumask_test_cpu(cpu, tpolicy->related_cpus)) { read_unlock_irqrestore(&cpufreq_driver_lock, flags); - return cpufreq_add_policy_cpu(cp, cpu, dev, frozen); + return cpufreq_add_policy_cpu(tpolicy, cpu, dev, + frozen); } } read_unlock_irqrestore(&cpufreq_driver_lock, flags); -- cgit v1.2.3-58-ga151 From fe492f3f0332e23cc6ca4913e5a2ed78e1888902 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 6 Aug 2013 22:53:10 +0530 Subject: cpufreq: Fix broken usage of governor->owner's refcount The cpufreq governor owner refcount usage is broken. We should only increment that refcount when a CPUFREQ_GOV_POLICY_INIT event has come and it should only be decremented if CPUFREQ_GOV_POLICY_EXIT has come. Currently, there can be situations where the governor is in use, but we have allowed it to be unloaded which may result in undefined behavior. Let's fix it. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 37af929746af..f149e14f77c7 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1709,8 +1709,9 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, } } - if (!try_module_get(policy->governor->owner)) - return -EINVAL; + if (event == CPUFREQ_GOV_POLICY_INIT) + if (!try_module_get(policy->governor->owner)) + return -EINVAL; pr_debug("__cpufreq_governor for CPU %u, event %u\n", policy->cpu, event); @@ -1719,6 +1720,8 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) || (policy->governor_enabled && (event == CPUFREQ_GOV_START))) { mutex_unlock(&cpufreq_governor_lock); + if (event == CPUFREQ_GOV_POLICY_INIT) + module_put(policy->governor->owner); return -EBUSY; } @@ -1746,11 +1749,8 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, mutex_unlock(&cpufreq_governor_lock); } - /* we keep one module reference alive for - each CPU governed by this CPU */ - if ((event != CPUFREQ_GOV_START) || ret) - module_put(policy->governor->owner); - if ((event == CPUFREQ_GOV_STOP) && !ret) + if (((event == CPUFREQ_GOV_POLICY_INIT) && ret) || + ((event == CPUFREQ_GOV_POLICY_EXIT) && !ret)) module_put(policy->governor->owner); return ret; -- cgit v1.2.3-58-ga151 From 6eed9404ab3c4baea54ce4c7e862e69df1d39f38 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 6 Aug 2013 22:53:11 +0530 Subject: cpufreq: Use rwsem for protecting critical sections Critical sections of the cpufreq core are protected with the help of the driver module owner's refcount, which isn't the correct approach, because it causes rmmod to return an error when some routine has updated that refcount. Let's use rwsem for this purpose instead. Only cpufreq_unregister_driver() will use write sem and everybody else will use read sem. [rjw: Subject & changelog] Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 135 ++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 78 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index f149e14f77c7..c9bbfeef92e3 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -91,6 +91,12 @@ static void unlock_policy_rwsem_##mode(int cpu) \ unlock_policy_rwsem(read, cpu); unlock_policy_rwsem(write, cpu); +/* + * rwsem to guarantee that cpufreq driver module doesn't unload during critical + * sections + */ +static DECLARE_RWSEM(cpufreq_rwsem); + /* internal prototypes */ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); @@ -178,78 +184,46 @@ u64 get_cpu_idle_time(unsigned int cpu, u64 *wall, int io_busy) } EXPORT_SYMBOL_GPL(get_cpu_idle_time); -static struct cpufreq_policy *__cpufreq_cpu_get(unsigned int cpu, bool sysfs) +struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) { - struct cpufreq_policy *policy; + struct cpufreq_policy *policy = NULL; unsigned long flags; - if (cpu >= nr_cpu_ids) - goto err_out; + if (cpufreq_disabled() || (cpu >= nr_cpu_ids)) + return NULL; + + if (!down_read_trylock(&cpufreq_rwsem)) + return NULL; /* get the cpufreq driver */ read_lock_irqsave(&cpufreq_driver_lock, flags); - if (!cpufreq_driver) - goto err_out_unlock; - - if (!try_module_get(cpufreq_driver->owner)) - goto err_out_unlock; + if (cpufreq_driver) { + /* get the CPU */ + policy = per_cpu(cpufreq_cpu_data, cpu); + if (policy) + kobject_get(&policy->kobj); + } - /* get the CPU */ - policy = per_cpu(cpufreq_cpu_data, cpu); + read_unlock_irqrestore(&cpufreq_driver_lock, flags); if (!policy) - goto err_out_put_module; - - if (!sysfs && !kobject_get(&policy->kobj)) - goto err_out_put_module; + up_read(&cpufreq_rwsem); - read_unlock_irqrestore(&cpufreq_driver_lock, flags); return policy; - -err_out_put_module: - module_put(cpufreq_driver->owner); -err_out_unlock: - read_unlock_irqrestore(&cpufreq_driver_lock, flags); -err_out: - return NULL; -} - -struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) -{ - if (cpufreq_disabled()) - return NULL; - - return __cpufreq_cpu_get(cpu, false); } EXPORT_SYMBOL_GPL(cpufreq_cpu_get); -static struct cpufreq_policy *cpufreq_cpu_get_sysfs(unsigned int cpu) -{ - return __cpufreq_cpu_get(cpu, true); -} - -static void __cpufreq_cpu_put(struct cpufreq_policy *policy, bool sysfs) -{ - if (!sysfs) - kobject_put(&policy->kobj); - module_put(cpufreq_driver->owner); -} - void cpufreq_cpu_put(struct cpufreq_policy *policy) { if (cpufreq_disabled()) return; - __cpufreq_cpu_put(policy, false); + kobject_put(&policy->kobj); + up_read(&cpufreq_rwsem); } EXPORT_SYMBOL_GPL(cpufreq_cpu_put); -static void cpufreq_cpu_put_sysfs(struct cpufreq_policy *policy) -{ - __cpufreq_cpu_put(policy, true); -} - /********************************************************************* * EXTERNALLY AFFECTING FREQUENCY CHANGES * *********************************************************************/ @@ -694,12 +668,12 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) struct cpufreq_policy *policy = to_policy(kobj); struct freq_attr *fattr = to_attr(attr); ssize_t ret = -EINVAL; - policy = cpufreq_cpu_get_sysfs(policy->cpu); - if (!policy) - goto no_policy; + + if (!down_read_trylock(&cpufreq_rwsem)) + goto exit; if (lock_policy_rwsem_read(policy->cpu) < 0) - goto fail; + goto up_read; if (fattr->show) ret = fattr->show(policy, buf); @@ -707,9 +681,10 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) ret = -EIO; unlock_policy_rwsem_read(policy->cpu); -fail: - cpufreq_cpu_put_sysfs(policy); -no_policy: + +up_read: + up_read(&cpufreq_rwsem); +exit: return ret; } @@ -719,12 +694,12 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, struct cpufreq_policy *policy = to_policy(kobj); struct freq_attr *fattr = to_attr(attr); ssize_t ret = -EINVAL; - policy = cpufreq_cpu_get_sysfs(policy->cpu); - if (!policy) - goto no_policy; + + if (!down_read_trylock(&cpufreq_rwsem)) + goto exit; if (lock_policy_rwsem_write(policy->cpu) < 0) - goto fail; + goto up_read; if (fattr->store) ret = fattr->store(policy, buf, count); @@ -732,9 +707,10 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, ret = -EIO; unlock_policy_rwsem_write(policy->cpu); -fail: - cpufreq_cpu_put_sysfs(policy); -no_policy: + +up_read: + up_read(&cpufreq_rwsem); +exit: return ret; } @@ -1003,25 +979,24 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, return 0; } + if (!down_read_trylock(&cpufreq_rwsem)) + return 0; + #ifdef CONFIG_HOTPLUG_CPU /* Check if this cpu was hot-unplugged earlier and has siblings */ read_lock_irqsave(&cpufreq_driver_lock, flags); list_for_each_entry(tpolicy, &cpufreq_policy_list, policy_list) { if (cpumask_test_cpu(cpu, tpolicy->related_cpus)) { read_unlock_irqrestore(&cpufreq_driver_lock, flags); - return cpufreq_add_policy_cpu(tpolicy, cpu, dev, - frozen); + ret = cpufreq_add_policy_cpu(tpolicy, cpu, dev, frozen); + up_read(&cpufreq_rwsem); + return ret; } } read_unlock_irqrestore(&cpufreq_driver_lock, flags); #endif #endif - if (!try_module_get(cpufreq_driver->owner)) { - ret = -EINVAL; - goto module_out; - } - if (frozen) /* Restore the saved policy when doing light-weight init */ policy = cpufreq_policy_restore(cpu); @@ -1094,7 +1069,8 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, cpufreq_init_policy(policy); kobject_uevent(&policy->kobj, KOBJ_ADD); - module_put(cpufreq_driver->owner); + up_read(&cpufreq_rwsem); + pr_debug("initialization complete\n"); return 0; @@ -1112,8 +1088,8 @@ err_set_policy_cpu: per_cpu(cpufreq_policy_cpu, cpu) = -1; cpufreq_policy_free(policy); nomem_out: - module_put(cpufreq_driver->owner); -module_out: + up_read(&cpufreq_rwsem); + return ret; } @@ -1425,10 +1401,9 @@ static unsigned int __cpufreq_get(unsigned int cpu) unsigned int cpufreq_get(unsigned int cpu) { unsigned int ret_freq = 0; - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - if (!policy) - goto out; + if (!down_read_trylock(&cpufreq_rwsem)) + return 0; if (unlikely(lock_policy_rwsem_read(cpu))) goto out_policy; @@ -1438,8 +1413,8 @@ unsigned int cpufreq_get(unsigned int cpu) unlock_policy_rwsem_read(cpu); out_policy: - cpufreq_cpu_put(policy); -out: + up_read(&cpufreq_rwsem); + return ret_freq; } EXPORT_SYMBOL(cpufreq_get); @@ -2132,9 +2107,13 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver) subsys_interface_unregister(&cpufreq_interface); unregister_hotcpu_notifier(&cpufreq_cpu_notifier); + down_write(&cpufreq_rwsem); write_lock_irqsave(&cpufreq_driver_lock, flags); + cpufreq_driver = NULL; + write_unlock_irqrestore(&cpufreq_driver_lock, flags); + up_write(&cpufreq_rwsem); return 0; } -- cgit v1.2.3-58-ga151 From adc97d6a735dbb1e94cb4f1bf0b55f258b349941 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 6 Aug 2013 22:53:12 +0530 Subject: cpufreq: Drop the owner field from struct cpufreq_driver We don't need to set .owner = THIS_MODULE any more in cpufreq drivers as this field isn't used any more by the cpufreq core. This patch removes it and updates all dependent drivers accordingly. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- Documentation/cpu-freq/cpu-drivers.txt | 2 -- drivers/cpufreq/acpi-cpufreq.c | 1 - drivers/cpufreq/at32ap-cpufreq.c | 1 - drivers/cpufreq/blackfin-cpufreq.c | 1 - drivers/cpufreq/cpufreq-nforce2.c | 1 - drivers/cpufreq/cris-artpec3-cpufreq.c | 1 - drivers/cpufreq/cris-etraxfs-cpufreq.c | 1 - drivers/cpufreq/e_powersaver.c | 1 - drivers/cpufreq/elanfreq.c | 1 - drivers/cpufreq/gx-suspmod.c | 1 - drivers/cpufreq/ia64-acpi-cpufreq.c | 1 - drivers/cpufreq/intel_pstate.c | 1 - drivers/cpufreq/kirkwood-cpufreq.c | 1 - drivers/cpufreq/longhaul.c | 1 - drivers/cpufreq/longrun.c | 1 - drivers/cpufreq/loongson2_cpufreq.c | 1 - drivers/cpufreq/maple-cpufreq.c | 1 - drivers/cpufreq/p4-clockmod.c | 1 - drivers/cpufreq/pasemi-cpufreq.c | 1 - drivers/cpufreq/pcc-cpufreq.c | 1 - drivers/cpufreq/pmac32-cpufreq.c | 1 - drivers/cpufreq/pmac64-cpufreq.c | 1 - drivers/cpufreq/powernow-k6.c | 1 - drivers/cpufreq/powernow-k7.c | 1 - drivers/cpufreq/powernow-k8.c | 1 - drivers/cpufreq/ppc-corenet-cpufreq.c | 1 - drivers/cpufreq/ppc_cbe_cpufreq.c | 1 - drivers/cpufreq/s3c2416-cpufreq.c | 1 - drivers/cpufreq/s3c64xx-cpufreq.c | 1 - drivers/cpufreq/sc520_freq.c | 1 - drivers/cpufreq/sh-cpufreq.c | 1 - drivers/cpufreq/sparc-us2e-cpufreq.c | 1 - drivers/cpufreq/sparc-us3-cpufreq.c | 1 - drivers/cpufreq/speedstep-centrino.c | 1 - drivers/cpufreq/speedstep-ich.c | 1 - drivers/cpufreq/speedstep-smi.c | 1 - include/linux/cpufreq.h | 1 - 37 files changed, 38 deletions(-) (limited to 'drivers') diff --git a/Documentation/cpu-freq/cpu-drivers.txt b/Documentation/cpu-freq/cpu-drivers.txt index 19fa98e07bf7..40282e617913 100644 --- a/Documentation/cpu-freq/cpu-drivers.txt +++ b/Documentation/cpu-freq/cpu-drivers.txt @@ -50,8 +50,6 @@ What shall this struct cpufreq_driver contain? cpufreq_driver.name - The name of this driver. -cpufreq_driver.owner - THIS_MODULE; - cpufreq_driver.init - A pointer to the per-CPU initialization function. diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 44758ce9936d..9b5d1b1a9c03 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -936,7 +936,6 @@ static struct cpufreq_driver acpi_cpufreq_driver = { .exit = acpi_cpufreq_cpu_exit, .resume = acpi_cpufreq_resume, .name = "acpi-cpufreq", - .owner = THIS_MODULE, .attr = acpi_cpufreq_attr, }; diff --git a/drivers/cpufreq/at32ap-cpufreq.c b/drivers/cpufreq/at32ap-cpufreq.c index 654488723cb5..e0c38d938997 100644 --- a/drivers/cpufreq/at32ap-cpufreq.c +++ b/drivers/cpufreq/at32ap-cpufreq.c @@ -108,7 +108,6 @@ static int __init at32_cpufreq_driver_init(struct cpufreq_policy *policy) static struct cpufreq_driver at32_driver = { .name = "at32ap", - .owner = THIS_MODULE, .init = at32_cpufreq_driver_init, .verify = at32_verify_speed, .target = at32_set_target, diff --git a/drivers/cpufreq/blackfin-cpufreq.c b/drivers/cpufreq/blackfin-cpufreq.c index 9cdbbd278a80..ef05978a7237 100644 --- a/drivers/cpufreq/blackfin-cpufreq.c +++ b/drivers/cpufreq/blackfin-cpufreq.c @@ -225,7 +225,6 @@ static struct cpufreq_driver bfin_driver = { .get = bfin_getfreq_khz, .init = __bfin_cpu_init, .name = "bfin cpufreq", - .owner = THIS_MODULE, .attr = bfin_freq_attr, }; diff --git a/drivers/cpufreq/cpufreq-nforce2.c b/drivers/cpufreq/cpufreq-nforce2.c index af1542d41440..b83d45f68574 100644 --- a/drivers/cpufreq/cpufreq-nforce2.c +++ b/drivers/cpufreq/cpufreq-nforce2.c @@ -379,7 +379,6 @@ static struct cpufreq_driver nforce2_driver = { .get = nforce2_get, .init = nforce2_cpu_init, .exit = nforce2_cpu_exit, - .owner = THIS_MODULE, }; #ifdef MODULE diff --git a/drivers/cpufreq/cris-artpec3-cpufreq.c b/drivers/cpufreq/cris-artpec3-cpufreq.c index ee142c490575..cb8276dd19ca 100644 --- a/drivers/cpufreq/cris-artpec3-cpufreq.c +++ b/drivers/cpufreq/cris-artpec3-cpufreq.c @@ -111,7 +111,6 @@ static struct cpufreq_driver cris_freq_driver = { .init = cris_freq_cpu_init, .exit = cris_freq_cpu_exit, .name = "cris_freq", - .owner = THIS_MODULE, .attr = cris_freq_attr, }; diff --git a/drivers/cpufreq/cris-etraxfs-cpufreq.c b/drivers/cpufreq/cris-etraxfs-cpufreq.c index 12952235d5db..72328f77dc53 100644 --- a/drivers/cpufreq/cris-etraxfs-cpufreq.c +++ b/drivers/cpufreq/cris-etraxfs-cpufreq.c @@ -108,7 +108,6 @@ static struct cpufreq_driver cris_freq_driver = { .init = cris_freq_cpu_init, .exit = cris_freq_cpu_exit, .name = "cris_freq", - .owner = THIS_MODULE, .attr = cris_freq_attr, }; diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c index de974be6b773..09f64cc83019 100644 --- a/drivers/cpufreq/e_powersaver.c +++ b/drivers/cpufreq/e_powersaver.c @@ -436,7 +436,6 @@ static struct cpufreq_driver eps_driver = { .exit = eps_cpu_exit, .get = eps_get, .name = "e_powersaver", - .owner = THIS_MODULE, .attr = eps_attr, }; diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c index 658d860344b0..823a400d98fd 100644 --- a/drivers/cpufreq/elanfreq.c +++ b/drivers/cpufreq/elanfreq.c @@ -274,7 +274,6 @@ static struct cpufreq_driver elanfreq_driver = { .init = elanfreq_cpu_init, .exit = elanfreq_cpu_exit, .name = "elanfreq", - .owner = THIS_MODULE, .attr = elanfreq_attr, }; diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c index 4f25fb63c097..ef5fee7dc0b3 100644 --- a/drivers/cpufreq/gx-suspmod.c +++ b/drivers/cpufreq/gx-suspmod.c @@ -446,7 +446,6 @@ static struct cpufreq_driver gx_suspmod_driver = { .target = cpufreq_gx_target, .init = cpufreq_gx_cpu_init, .name = "gx-suspmod", - .owner = THIS_MODULE, }; static int __init cpufreq_gx_init(void) diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c index 08792dd4d62a..3e14f0317175 100644 --- a/drivers/cpufreq/ia64-acpi-cpufreq.c +++ b/drivers/cpufreq/ia64-acpi-cpufreq.c @@ -409,7 +409,6 @@ static struct cpufreq_driver acpi_cpufreq_driver = { .init = acpi_cpufreq_cpu_init, .exit = acpi_cpufreq_cpu_exit, .name = "acpi-cpufreq", - .owner = THIS_MODULE, .attr = acpi_cpufreq_attr, }; diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 7cde885011ed..6efd96c196b2 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -665,7 +665,6 @@ static struct cpufreq_driver intel_pstate_driver = { .init = intel_pstate_cpu_init, .exit = intel_pstate_cpu_exit, .name = "intel_pstate", - .owner = THIS_MODULE, }; static int __initdata no_load; diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c index c233ea617366..45e4d7fc261d 100644 --- a/drivers/cpufreq/kirkwood-cpufreq.c +++ b/drivers/cpufreq/kirkwood-cpufreq.c @@ -158,7 +158,6 @@ static struct cpufreq_driver kirkwood_cpufreq_driver = { .init = kirkwood_cpufreq_cpu_init, .exit = kirkwood_cpufreq_cpu_exit, .name = "kirkwood-cpufreq", - .owner = THIS_MODULE, .attr = kirkwood_cpufreq_attr, }; diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index 8c49261df57d..4ada1cccb052 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -948,7 +948,6 @@ static struct cpufreq_driver longhaul_driver = { .init = longhaul_cpu_init, .exit = longhaul_cpu_exit, .name = "longhaul", - .owner = THIS_MODULE, .attr = longhaul_attr, }; diff --git a/drivers/cpufreq/longrun.c b/drivers/cpufreq/longrun.c index 0fe041d1f77f..5aa031612d53 100644 --- a/drivers/cpufreq/longrun.c +++ b/drivers/cpufreq/longrun.c @@ -286,7 +286,6 @@ static struct cpufreq_driver longrun_driver = { .get = longrun_get, .init = longrun_cpu_init, .name = "longrun", - .owner = THIS_MODULE, }; static const struct x86_cpu_id longrun_ids[] = { diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c index bb838b985077..e65de91b534b 100644 --- a/drivers/cpufreq/loongson2_cpufreq.c +++ b/drivers/cpufreq/loongson2_cpufreq.c @@ -157,7 +157,6 @@ static struct freq_attr *loongson2_table_attr[] = { }; static struct cpufreq_driver loongson2_cpufreq_driver = { - .owner = THIS_MODULE, .name = "loongson2", .init = loongson2_cpufreq_cpu_init, .verify = loongson2_cpufreq_verify, diff --git a/drivers/cpufreq/maple-cpufreq.c b/drivers/cpufreq/maple-cpufreq.c index cdd62915efaf..41c601f4631e 100644 --- a/drivers/cpufreq/maple-cpufreq.c +++ b/drivers/cpufreq/maple-cpufreq.c @@ -190,7 +190,6 @@ static int maple_cpufreq_cpu_init(struct cpufreq_policy *policy) static struct cpufreq_driver maple_cpufreq_driver = { .name = "maple", - .owner = THIS_MODULE, .flags = CPUFREQ_CONST_LOOPS, .init = maple_cpufreq_cpu_init, .verify = maple_cpufreq_verify, diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c index 9ee78170ff86..2f0a2a65c37f 100644 --- a/drivers/cpufreq/p4-clockmod.c +++ b/drivers/cpufreq/p4-clockmod.c @@ -279,7 +279,6 @@ static struct cpufreq_driver p4clockmod_driver = { .exit = cpufreq_p4_cpu_exit, .get = cpufreq_p4_get, .name = "p4-clockmod", - .owner = THIS_MODULE, .attr = p4clockmod_attr, }; diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c index b704da404067..534e43a60d1f 100644 --- a/drivers/cpufreq/pasemi-cpufreq.c +++ b/drivers/cpufreq/pasemi-cpufreq.c @@ -297,7 +297,6 @@ static int pas_cpufreq_target(struct cpufreq_policy *policy, static struct cpufreq_driver pas_cpufreq_driver = { .name = "pas-cpufreq", - .owner = THIS_MODULE, .flags = CPUFREQ_CONST_LOOPS, .init = pas_cpufreq_cpu_init, .exit = pas_cpufreq_cpu_exit, diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c index 1581fcc4cf4a..d81c4e5ea0ad 100644 --- a/drivers/cpufreq/pcc-cpufreq.c +++ b/drivers/cpufreq/pcc-cpufreq.c @@ -587,7 +587,6 @@ static struct cpufreq_driver pcc_cpufreq_driver = { .init = pcc_cpufreq_cpu_init, .exit = pcc_cpufreq_cpu_exit, .name = "pcc-cpufreq", - .owner = THIS_MODULE, }; static int __init pcc_cpufreq_init(void) diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c index 3104fad82480..38cdc63c38da 100644 --- a/drivers/cpufreq/pmac32-cpufreq.c +++ b/drivers/cpufreq/pmac32-cpufreq.c @@ -477,7 +477,6 @@ static struct cpufreq_driver pmac_cpufreq_driver = { .flags = CPUFREQ_PM_NO_WARN, .attr = pmac_cpu_freqs_attr, .name = "powermac", - .owner = THIS_MODULE, }; diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c index 4d7799b7af86..b6850d97f0d5 100644 --- a/drivers/cpufreq/pmac64-cpufreq.c +++ b/drivers/cpufreq/pmac64-cpufreq.c @@ -371,7 +371,6 @@ static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy) static struct cpufreq_driver g5_cpufreq_driver = { .name = "powermac", - .owner = THIS_MODULE, .flags = CPUFREQ_CONST_LOOPS, .init = g5_cpufreq_cpu_init, .verify = g5_cpufreq_verify, diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index ea8e10382ec5..85f1c8c25ddc 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c @@ -207,7 +207,6 @@ static struct cpufreq_driver powernow_k6_driver = { .exit = powernow_k6_cpu_exit, .get = powernow_k6_get, .name = "powernow-k6", - .owner = THIS_MODULE, .attr = powernow_k6_attr, }; diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index 4687d40d0219..14ce480be8ab 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c @@ -716,7 +716,6 @@ static struct cpufreq_driver powernow_driver = { .init = powernow_cpu_init, .exit = powernow_cpu_exit, .name = "powernow-k7", - .owner = THIS_MODULE, .attr = powernow_table_attr, }; diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 3f3c6cae91d0..2344a9ed17f3 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -1240,7 +1240,6 @@ static struct cpufreq_driver cpufreq_amd64_driver = { .exit = powernowk8_cpu_exit, .get = powernowk8_get, .name = "powernow-k8", - .owner = THIS_MODULE, .attr = powernow_k8_attr, }; diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c index 3cae4529f959..60e81d524ea8 100644 --- a/drivers/cpufreq/ppc-corenet-cpufreq.c +++ b/drivers/cpufreq/ppc-corenet-cpufreq.c @@ -300,7 +300,6 @@ static struct freq_attr *corenet_cpufreq_attr[] = { static struct cpufreq_driver ppc_corenet_cpufreq_driver = { .name = "ppc_cpufreq", - .owner = THIS_MODULE, .flags = CPUFREQ_CONST_LOOPS, .init = corenet_cpufreq_cpu_init, .exit = __exit_p(corenet_cpufreq_cpu_exit), diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c index 5936f8d6f2cc..2e448f0bbdc5 100644 --- a/drivers/cpufreq/ppc_cbe_cpufreq.c +++ b/drivers/cpufreq/ppc_cbe_cpufreq.c @@ -181,7 +181,6 @@ static struct cpufreq_driver cbe_cpufreq_driver = { .init = cbe_cpufreq_cpu_init, .exit = cbe_cpufreq_cpu_exit, .name = "cbe-cpufreq", - .owner = THIS_MODULE, .flags = CPUFREQ_CONST_LOOPS, }; diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c index ce5b9fca9c18..22dcb81ef9d0 100644 --- a/drivers/cpufreq/s3c2416-cpufreq.c +++ b/drivers/cpufreq/s3c2416-cpufreq.c @@ -524,7 +524,6 @@ static struct freq_attr *s3c2416_cpufreq_attr[] = { }; static struct cpufreq_driver s3c2416_cpufreq_driver = { - .owner = THIS_MODULE, .flags = 0, .verify = s3c2416_cpufreq_verify_speed, .target = s3c2416_cpufreq_set_target, diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c index 13bb4bae64ee..8a72b0c555f8 100644 --- a/drivers/cpufreq/s3c64xx-cpufreq.c +++ b/drivers/cpufreq/s3c64xx-cpufreq.c @@ -263,7 +263,6 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) } static struct cpufreq_driver s3c64xx_cpufreq_driver = { - .owner = THIS_MODULE, .flags = 0, .verify = s3c64xx_cpufreq_verify_speed, .target = s3c64xx_cpufreq_set_target, diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c index 77a210975fc4..d6f6c6f4efa7 100644 --- a/drivers/cpufreq/sc520_freq.c +++ b/drivers/cpufreq/sc520_freq.c @@ -147,7 +147,6 @@ static struct cpufreq_driver sc520_freq_driver = { .init = sc520_freq_cpu_init, .exit = sc520_freq_cpu_exit, .name = "sc520_freq", - .owner = THIS_MODULE, .attr = sc520_freq_attr, }; diff --git a/drivers/cpufreq/sh-cpufreq.c b/drivers/cpufreq/sh-cpufreq.c index 73adb64651e8..ffc6d24b0cfb 100644 --- a/drivers/cpufreq/sh-cpufreq.c +++ b/drivers/cpufreq/sh-cpufreq.c @@ -160,7 +160,6 @@ static struct freq_attr *sh_freq_attr[] = { }; static struct cpufreq_driver sh_cpufreq_driver = { - .owner = THIS_MODULE, .name = "sh", .get = sh_cpufreq_get, .target = sh_cpufreq_target, diff --git a/drivers/cpufreq/sparc-us2e-cpufreq.c b/drivers/cpufreq/sparc-us2e-cpufreq.c index 7c43a725e5da..cf5bc2ca16fa 100644 --- a/drivers/cpufreq/sparc-us2e-cpufreq.c +++ b/drivers/cpufreq/sparc-us2e-cpufreq.c @@ -365,7 +365,6 @@ static int __init us2e_freq_init(void) driver->target = us2e_freq_target; driver->get = us2e_freq_get; driver->exit = us2e_freq_cpu_exit; - driver->owner = THIS_MODULE, strcpy(driver->name, "UltraSPARC-IIe"); cpufreq_us2e_driver = driver; diff --git a/drivers/cpufreq/sparc-us3-cpufreq.c b/drivers/cpufreq/sparc-us3-cpufreq.c index 7f500c140bc3..ac76b489979d 100644 --- a/drivers/cpufreq/sparc-us3-cpufreq.c +++ b/drivers/cpufreq/sparc-us3-cpufreq.c @@ -226,7 +226,6 @@ static int __init us3_freq_init(void) driver->target = us3_freq_target; driver->get = us3_freq_get; driver->exit = us3_freq_cpu_exit; - driver->owner = THIS_MODULE, strcpy(driver->name, "UltraSPARC-III"); cpufreq_us3_driver = driver; diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c index 0915e712fbdc..f897d5105842 100644 --- a/drivers/cpufreq/speedstep-centrino.c +++ b/drivers/cpufreq/speedstep-centrino.c @@ -575,7 +575,6 @@ static struct cpufreq_driver centrino_driver = { .target = centrino_target, .get = get_cur_freq, .attr = centrino_attr, - .owner = THIS_MODULE, }; /* diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c index e2e5aa971452..5355abb69afc 100644 --- a/drivers/cpufreq/speedstep-ich.c +++ b/drivers/cpufreq/speedstep-ich.c @@ -378,7 +378,6 @@ static struct cpufreq_driver speedstep_driver = { .init = speedstep_cpu_init, .exit = speedstep_cpu_exit, .get = speedstep_get, - .owner = THIS_MODULE, .attr = speedstep_attr, }; diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c index f5a6b70ee6c0..abfba4f731eb 100644 --- a/drivers/cpufreq/speedstep-smi.c +++ b/drivers/cpufreq/speedstep-smi.c @@ -375,7 +375,6 @@ static struct cpufreq_driver speedstep_driver = { .exit = speedstep_cpu_exit, .get = speedstep_get, .resume = speedstep_resume, - .owner = THIS_MODULE, .attr = speedstep_attr, }; diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 431a05d4b4c9..d568f3975eeb 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -179,7 +179,6 @@ __ATTR(_name, 0644, show_##_name, store_##_name) struct cpufreq_driver { - struct module *owner; char name[CPUFREQ_NAME_LEN]; u8 flags; /* -- cgit v1.2.3-58-ga151 From 3de9bdeb28638e164d1f0eb38dd68e3f5d2ac95c Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 6 Aug 2013 22:53:13 +0530 Subject: cpufreq: improve error checking on return values of __cpufreq_governor() The __cpufreq_governor() function can fail in rare cases especially if there are bugs in cpufreq drivers. Thus we must stop processing as soon as this routine fails, otherwise it may result in undefined behavior. This patch adds error checking code whenever this routine is called from any place. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 48 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index c9bbfeef92e3..37a687467329 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -874,8 +874,13 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, int ret = 0, has_target = !!cpufreq_driver->target; unsigned long flags; - if (has_target) - __cpufreq_governor(policy, CPUFREQ_GOV_STOP); + if (has_target) { + ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); + if (ret) { + pr_err("%s: Failed to stop governor\n", __func__); + return ret; + } + } lock_policy_rwsem_write(policy->cpu); @@ -889,8 +894,11 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unlock_policy_rwsem_write(policy->cpu); if (has_target) { - __cpufreq_governor(policy, CPUFREQ_GOV_START); - __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); + if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || + (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { + pr_err("%s: Failed to start governor\n", __func__); + return ret; + } } /* Don't touch sysfs links during light-weight init */ @@ -1172,7 +1180,7 @@ static int __cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif, bool frozen) { unsigned int cpu = dev->id, cpus; - int new_cpu; + int new_cpu, ret; unsigned long flags; struct cpufreq_policy *policy; struct kobject *kobj; @@ -1196,8 +1204,13 @@ static int __cpufreq_remove_dev(struct device *dev, return -EINVAL; } - if (cpufreq_driver->target) - __cpufreq_governor(policy, CPUFREQ_GOV_STOP); + if (cpufreq_driver->target) { + ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP); + if (ret) { + pr_err("%s: Failed to stop governor\n", __func__); + return ret; + } + } #ifdef CONFIG_HOTPLUG_CPU if (!cpufreq_driver->setpolicy) @@ -1231,8 +1244,15 @@ static int __cpufreq_remove_dev(struct device *dev, /* If cpu is last user of policy, free policy */ if (cpus == 1) { - if (cpufreq_driver->target) - __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); + if (cpufreq_driver->target) { + ret = __cpufreq_governor(policy, + CPUFREQ_GOV_POLICY_EXIT); + if (ret) { + pr_err("%s: Failed to exit governor\n", + __func__); + return ret; + } + } if (!frozen) { lock_policy_rwsem_read(cpu); @@ -1263,8 +1283,12 @@ static int __cpufreq_remove_dev(struct device *dev, cpufreq_policy_free(policy); } else { if (cpufreq_driver->target) { - __cpufreq_governor(policy, CPUFREQ_GOV_START); - __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); + if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || + (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { + pr_err("%s: Failed to start governor\n", + __func__); + return ret; + } } } @@ -1912,7 +1936,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *policy, /* might be a policy change, too, so fall through */ } pr_debug("governor: change or update limits\n"); - __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); + ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); } error_out: -- cgit v1.2.3-58-ga151 From c721d15a5cc1dade16f068123070c570378c5cc0 Mon Sep 17 00:00:00 2001 From: Amit Daniel Kachhap Date: Wed, 7 Aug 2013 16:46:11 +0530 Subject: cpufreq: exynos5440: Fix to skip when new frequency same as current This patch fixes the issue of un-necessary setting the clock controller when the new target frequency is same as the current one. This case usually occurs with governors like ondemand which passes the target frequency as the percentage of average frequency. This check is present in most of the cpufreq drivers. Cc: Viresh Kumar Cc: Rafael J. Wysocki Cc: Kukjin Kim Signed-off-by: Amit Daniel Kachhap Signed-off-by: Viresh Kumar --- drivers/cpufreq/exynos5440-cpufreq.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index 0c74018eda47..d514c152fd1a 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c @@ -238,6 +238,9 @@ static int exynos_target(struct cpufreq_policy *policy, freqs.old = dvfs_info->cur_frequency; freqs.new = freq_table[index].frequency; + if (freqs.old == freqs.new) + goto out; + cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); /* Set the target frequency in all C0_3_PSTATE register */ -- cgit v1.2.3-58-ga151 From 45e12086263a53f16b489fc7f4f8f6348a688661 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 9 Aug 2013 14:04:55 +0200 Subject: cpufreq: fix EXYNOS drivers selection * remove superfluous pr_debug() call from exynos_cpufreq_init() (init errors are always logged anyway) * add dummy per-SoC type init functions to exynos-cpufreq.h * make per-SoC type cpufreq config options selectable * make CONFIG_ARM_EXYNOS_CPUFREQ config option invisible to user and automatically enable it when needed This patch fixes following issues: * EXYNOS per-SoC type cpufreq support (i.e. exynos4210-cpufreq.c) being always built if given SoC support was enabled (i.e. CPU_EXYNOS4210), even if common EXYNOS cpufreq support was disabled * inability to select cpufreq for each SoC type separately (it could be only enabled/disabled for all SoCs for which support was enabled) * EXYNOS5440 cpufreq support was always enabled when EXYNOS5440 support was enabled and couldn't be disabled Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Kyungmin Park Reviewed-by: Tomasz Figa Signed-off-by: Viresh Kumar --- drivers/cpufreq/Kconfig.arm | 36 ++++++++++++++++++++++++------------ drivers/cpufreq/exynos-cpufreq.c | 1 - drivers/cpufreq/exynos-cpufreq.h | 21 +++++++++++++++++++++ 3 files changed, 45 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index de4d5d93c3fd..0fa204b244bd 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -17,37 +17,47 @@ config ARM_DT_BL_CPUFREQ big.LITTLE platform. This gets frequency tables from DT. config ARM_EXYNOS_CPUFREQ - bool "SAMSUNG EXYNOS SoCs" - depends on ARCH_EXYNOS + bool select CPU_FREQ_TABLE - default y - help - This adds the CPUFreq driver common part for Samsung - EXYNOS SoCs. - - If in doubt, say N. config ARM_EXYNOS4210_CPUFREQ - def_bool CPU_EXYNOS4210 + bool "SAMSUNG EXYNOS4210" + depends on CPU_EXYNOS4210 + default y + select ARM_EXYNOS_CPUFREQ help This adds the CPUFreq driver for Samsung EXYNOS4210 SoC (S5PV310 or S5PC210). + If in doubt, say N. + config ARM_EXYNOS4X12_CPUFREQ - def_bool (SOC_EXYNOS4212 || SOC_EXYNOS4412) + bool "SAMSUNG EXYNOS4x12" + depends on (SOC_EXYNOS4212 || SOC_EXYNOS4412) + default y + select ARM_EXYNOS_CPUFREQ help This adds the CPUFreq driver for Samsung EXYNOS4X12 SoC (EXYNOS4212 or EXYNOS4412). + If in doubt, say N. + config ARM_EXYNOS5250_CPUFREQ - def_bool SOC_EXYNOS5250 + bool "SAMSUNG EXYNOS5250" + depends on SOC_EXYNOS5250 + default y + select ARM_EXYNOS_CPUFREQ help This adds the CPUFreq driver for Samsung EXYNOS5250 SoC. + If in doubt, say N. + config ARM_EXYNOS5440_CPUFREQ - def_bool SOC_EXYNOS5440 + bool "SAMSUNG EXYNOS5440" + depends on SOC_EXYNOS5440 depends on HAVE_CLK && PM_OPP && OF + default y select CPU_FREQ_TABLE help This adds the CPUFreq driver for Samsung EXYNOS5440 @@ -55,6 +65,8 @@ config ARM_EXYNOS5440_CPUFREQ different than previous exynos controllers so not using the common exynos framework. + If in doubt, say N. + config ARM_HIGHBANK_CPUFREQ tristate "Calxeda Highbank-based" depends on ARCH_HIGHBANK diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index 0d32f02ef4d6..51cb1168fa98 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c @@ -332,7 +332,6 @@ err_cpufreq: regulator_put(arm_regulator); err_vdd_arm: kfree(exynos_info); - pr_debug("%s: failed initialization\n", __func__); return -EINVAL; } late_initcall(exynos_cpufreq_init); diff --git a/drivers/cpufreq/exynos-cpufreq.h b/drivers/cpufreq/exynos-cpufreq.h index 92b852ee5ddc..7f25cee8cec2 100644 --- a/drivers/cpufreq/exynos-cpufreq.h +++ b/drivers/cpufreq/exynos-cpufreq.h @@ -43,6 +43,27 @@ struct exynos_dvfs_info { bool (*need_apll_change)(unsigned int, unsigned int); }; +#ifdef CONFIG_ARM_EXYNOS4210_CPUFREQ extern int exynos4210_cpufreq_init(struct exynos_dvfs_info *); +#else +static inline int exynos4210_cpufreq_init(struct exynos_dvfs_info *info) +{ + return -EOPNOTSUPP; +} +#endif +#ifdef CONFIG_ARM_EXYNOS4X12_CPUFREQ extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *); +#else +static inline int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info) +{ + return -EOPNOTSUPP; +} +#endif +#ifdef CONFIG_ARM_EXYNOS5250_CPUFREQ extern int exynos5250_cpufreq_init(struct exynos_dvfs_info *); +#else +static inline int exynos5250_cpufreq_init(struct exynos_dvfs_info *info) +{ + return -EOPNOTSUPP; +} +#endif -- cgit v1.2.3-58-ga151 From 59027d356666a2c1d576baacb98de9fb30e4c48e Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Tue, 13 Aug 2013 10:05:53 +0800 Subject: acpi-cpufreq: Use cpufreq_freq_attr_rw to define the cpb attribute Standardise the defintion of the cpb (Core Performance Boost) attribute in the acpi-cpufreq driver via the cpufreq_freq_attr_rw macro. [rjw: Subject and changelog] Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/acpi-cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 9b5d1b1a9c03..a1260b4549db 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -197,7 +197,7 @@ static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf) return sprintf(buf, "%u\n", boost_enabled); } -static struct freq_attr cpb = __ATTR(cpb, 0644, show_cpb, store_cpb); +cpufreq_freq_attr_rw(cpb); #endif static int check_est_cpu(unsigned int cpuid) -- cgit v1.2.3-58-ga151 From 4a511de96d692f2dfa126c10dda4e41636c0ef27 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 13 Aug 2013 14:58:24 +0200 Subject: cpufreq: cpufreq-cpu0: NULL is a valid regulator Since NULL could in theory be a valid regulator we ought to check for IS_ERR() rather than for NULL. In practice this is unlikely to be an issue but it's better for neatness. Signed-off-by: Mark Brown Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq-cpu0.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index ad1fde277661..09cd3a76fb2e 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -69,7 +69,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); - if (cpu_reg) { + if (!IS_ERR(cpu_reg)) { rcu_read_lock(); opp = opp_find_freq_ceil(cpu_dev, &freq_Hz); if (IS_ERR(opp)) { @@ -90,7 +90,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, freqs.new / 1000, volt ? volt / 1000 : -1); /* scaling up? scale voltage before frequency */ - if (cpu_reg && freqs.new > freqs.old) { + if (!IS_ERR(cpu_reg) && freqs.new > freqs.old) { ret = regulator_set_voltage_tol(cpu_reg, volt, tol); if (ret) { pr_err("failed to scale voltage up: %d\n", ret); @@ -102,14 +102,14 @@ static int cpu0_set_target(struct cpufreq_policy *policy, ret = clk_set_rate(cpu_clk, freq_exact); if (ret) { pr_err("failed to set clock rate: %d\n", ret); - if (cpu_reg) + if (!IS_ERR(cpu_reg)) regulator_set_voltage_tol(cpu_reg, volt_old, tol); freqs.new = freqs.old; goto post_notify; } /* scaling down? scale voltage after frequency */ - if (cpu_reg && freqs.new < freqs.old) { + if (!IS_ERR(cpu_reg) && freqs.new < freqs.old) { ret = regulator_set_voltage_tol(cpu_reg, volt, tol); if (ret) { pr_err("failed to scale voltage down: %d\n", ret); @@ -210,7 +210,6 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) } pr_warn("failed to get cpu0 regulator: %ld\n", PTR_ERR(cpu_reg)); - cpu_reg = NULL; } cpu_clk = devm_clk_get(cpu_dev, NULL); -- cgit v1.2.3-58-ga151 From 8ee3f8e038d4261f70940364415c0680f4014eb6 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 13 Aug 2013 15:02:25 +0200 Subject: pxa3xx-cpufreq.c: Avoid using ARRAY_AND_SIZE(e) as a function argument Replace ARRAY_AND_SIZE(e) in function argument position to avoid hiding the arity of the called function. The semantic match that makes this change is as follows: (http://coccinelle.lip6.fr/) // @@ expression e,f; @@ f(..., - ARRAY_AND_SIZE(e) + e,ARRAY_SIZE(e) ,...) // Signed-off-by: Julia Lawall Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/pxa3xx-cpufreq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpufreq.c index 9c92ef032a9e..d26306fb00d2 100644 --- a/drivers/cpufreq/pxa3xx-cpufreq.c +++ b/drivers/cpufreq/pxa3xx-cpufreq.c @@ -213,10 +213,12 @@ static int pxa3xx_cpufreq_init(struct cpufreq_policy *policy) policy->cur = policy->min = policy->max; if (cpu_is_pxa300() || cpu_is_pxa310()) - ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa300_freqs)); + ret = setup_freqs_table(policy, pxa300_freqs, + ARRAY_SIZE(pxa300_freqs)); if (cpu_is_pxa320()) - ret = setup_freqs_table(policy, ARRAY_AND_SIZE(pxa320_freqs)); + ret = setup_freqs_table(policy, pxa320_freqs, + ARRAY_SIZE(pxa320_freqs)); if (ret) { pr_err("failed to setup frequency table\n"); -- cgit v1.2.3-58-ga151 From af97385ad4054fc2f2e1eddfe3d9f4a12e36e051 Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Tue, 13 Aug 2013 18:20:08 +0800 Subject: cpufreq / gx: Fix gx_detect_chipset() __init attribute location __init belongs after the return type on functions, not before it. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/gx-suspmod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c index ef5fee7dc0b3..70442c7b5e71 100644 --- a/drivers/cpufreq/gx-suspmod.c +++ b/drivers/cpufreq/gx-suspmod.c @@ -183,7 +183,7 @@ static void gx_write_byte(int reg, int value) * gx_detect_chipset: * **/ -static __init struct pci_dev *gx_detect_chipset(void) +static struct pci_dev * __init gx_detect_chipset(void) { struct pci_dev *gx_pci = NULL; -- cgit v1.2.3-58-ga151 From 295dbde1c6d5a07979d2f0ba7aff4c170656314a Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Tue, 13 Aug 2013 18:20:09 +0800 Subject: cpufreq / pxa2xx: Fix pxa_cpufreq_init_voltages() __init attribute location __init belongs after the return type on functions, not before it. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/pxa2xx-cpufreq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c index fb3981ac829f..8749eaf18793 100644 --- a/drivers/cpufreq/pxa2xx-cpufreq.c +++ b/drivers/cpufreq/pxa2xx-cpufreq.c @@ -191,7 +191,7 @@ static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq) return ret; } -static __init void pxa_cpufreq_init_voltages(void) +static void __init pxa_cpufreq_init_voltages(void) { vcc_core = regulator_get(NULL, "vcc_core"); if (IS_ERR(vcc_core)) { @@ -207,7 +207,7 @@ static int pxa_cpufreq_change_voltage(pxa_freqs_t *pxa_freq) return 0; } -static __init void pxa_cpufreq_init_voltages(void) { } +static void __init pxa_cpufreq_init_voltages(void) { } #endif static void find_freq_tables(struct cpufreq_frequency_table **freq_table, -- cgit v1.2.3-58-ga151 From 21b4c415e43717b3dbc17ebef66ee2054f8f2e21 Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Tue, 13 Aug 2013 18:20:10 +0800 Subject: cpufreq / s3c24xx: Fix s3c_cpufreq_initclks() __init attribute location __init belongs after the return type on functions, not before it. Signed-off-by: Hanjun Guo Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/s3c24xx-cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c index f169ee52e6eb..b0f343fcb7ee 100644 --- a/drivers/cpufreq/s3c24xx-cpufreq.c +++ b/drivers/cpufreq/s3c24xx-cpufreq.c @@ -392,7 +392,7 @@ static int s3c_cpufreq_init(struct cpufreq_policy *policy) return 0; } -static __init int s3c_cpufreq_initclks(void) +static int __init s3c_cpufreq_initclks(void) { _clk_mpll = s3c_cpufreq_clk_get(NULL, "mpll"); _clk_xtal = s3c_cpufreq_clk_get(NULL, "xtal"); -- cgit v1.2.3-58-ga151 From 0e25246fb3d7455dc3405435da70156370e285ec Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 9 Aug 2013 16:14:51 +0900 Subject: cpufreq: unicore2: Staticize local symbol This local symbol is used only in this file. Fix the following sparse warnings: drivers/cpufreq/unicore2-cpufreq.c:27:5: warning: symbol 'ucv2_verify_speed' was not declared. Should it be static? Signed-off-by: Jingoo Han Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/unicore2-cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/unicore2-cpufreq.c b/drivers/cpufreq/unicore2-cpufreq.c index 12fc904d7dab..b225f04d8ae5 100644 --- a/drivers/cpufreq/unicore2-cpufreq.c +++ b/drivers/cpufreq/unicore2-cpufreq.c @@ -24,7 +24,7 @@ static struct cpufreq_driver ucv2_driver; /* make sure that only the "userspace" governor is run * -- anything else wouldn't make sense on this platform, anyway. */ -int ucv2_verify_speed(struct cpufreq_policy *policy) +static int ucv2_verify_speed(struct cpufreq_policy *policy) { if (policy->cpu) return -EINVAL; -- cgit v1.2.3-58-ga151 From 878f6e074e9a7784a6e351512eace4ccb3542eef Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 18 Aug 2013 15:35:59 +0200 Subject: Revert "cpufreq: Use cpufreq_policy_list for iterating over policies" Revert commit eb60852 (cpufreq: Use cpufreq_policy_list for iterating over policies), because it breaks system suspend/resume on multiple machines. It either causes resume to block indefinitely or causes the BUG_ON() in lock_policy_rwsem_##mode() to trigger on sysfs accesses to cpufreq attributes. Conflicts: drivers/cpufreq/cpufreq.c --- drivers/cpufreq/cpufreq.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 37a687467329..c0ef84d601b7 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -969,8 +969,8 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, struct cpufreq_policy *policy; unsigned long flags; #ifdef CONFIG_HOTPLUG_CPU - struct cpufreq_policy *tpolicy; struct cpufreq_governor *gov; + int sibling; #endif if (cpu_is_offline(cpu)) @@ -993,10 +993,11 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, #ifdef CONFIG_HOTPLUG_CPU /* Check if this cpu was hot-unplugged earlier and has siblings */ read_lock_irqsave(&cpufreq_driver_lock, flags); - list_for_each_entry(tpolicy, &cpufreq_policy_list, policy_list) { - if (cpumask_test_cpu(cpu, tpolicy->related_cpus)) { + for_each_online_cpu(sibling) { + struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling); + if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) { read_unlock_irqrestore(&cpufreq_driver_lock, flags); - ret = cpufreq_add_policy_cpu(tpolicy, cpu, dev, frozen); + ret = cpufreq_add_policy_cpu(cp, cpu, dev, frozen); up_read(&cpufreq_rwsem); return ret; } -- cgit v1.2.3-58-ga151 From edab2fbc21b9eb37007ad8bffe1159d536bbb451 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 20 Aug 2013 12:08:22 +0530 Subject: cpufreq: Fix white space in __cpufreq_remove_dev() Align closing brace '}' of an if block. [rjw: Subject and changelog] Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index c0ef84d601b7..fedc8420214e 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1253,7 +1253,7 @@ static int __cpufreq_remove_dev(struct device *dev, __func__); return ret; } - } + } if (!frozen) { lock_policy_rwsem_read(cpu); -- cgit v1.2.3-58-ga151 From 9515f4d69b92feafe37581047a1bb41e41602faa Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 20 Aug 2013 12:08:23 +0530 Subject: cpufreq: remove policy from cpufreq_policy_list during suspend cpufreq_policy_list is a list of active policies. We do remove policies from this list when all CPUs belonging to that policy are removed. But during system suspend we don't really free a policy struct as it will be used again during resume, so we didn't remove it from cpufreq_policy_list as well.. However, this is incorrect. We are saying this policy isn't valid anymore and must not be referenced (though we haven't freed it), but it can still be used by code that iterates over cpufreq_policy_list. Remove policy from this list during system suspend as well. Of course, we must add it back whenever the first CPU belonging to that policy shows up. [rjw: Changelog] Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index fedc8420214e..030212104fe6 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -950,12 +950,6 @@ err_free_policy: static void cpufreq_policy_free(struct cpufreq_policy *policy) { - unsigned long flags; - - write_lock_irqsave(&cpufreq_driver_lock, flags); - list_del(&policy->policy_list); - write_unlock_irqrestore(&cpufreq_driver_lock, flags); - free_cpumask_var(policy->related_cpus); free_cpumask_var(policy->cpus); kfree(policy); @@ -1069,12 +1063,12 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, ret = cpufreq_add_dev_interface(policy, dev); if (ret) goto err_out_unregister; - - write_lock_irqsave(&cpufreq_driver_lock, flags); - list_add(&policy->policy_list, &cpufreq_policy_list); - write_unlock_irqrestore(&cpufreq_driver_lock, flags); } + write_lock_irqsave(&cpufreq_driver_lock, flags); + list_add(&policy->policy_list, &cpufreq_policy_list); + write_unlock_irqrestore(&cpufreq_driver_lock, flags); + cpufreq_init_policy(policy); kobject_uevent(&policy->kobj, KOBJ_ADD); @@ -1280,6 +1274,11 @@ static int __cpufreq_remove_dev(struct device *dev, if (cpufreq_driver->exit) cpufreq_driver->exit(policy); + /* Remove policy from list of active policies */ + write_lock_irqsave(&cpufreq_driver_lock, flags); + list_del(&policy->policy_list); + write_unlock_irqrestore(&cpufreq_driver_lock, flags); + if (!frozen) cpufreq_policy_free(policy); } else { -- cgit v1.2.3-58-ga151 From 9e9fd801676a946b759a8669baa24ba327c8c903 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 20 Aug 2013 12:08:24 +0530 Subject: cpufreq: remove unnecessary check in __cpufreq_governor() We don't need to check if event is CPUFREQ_GOV_POLICY_INIT and put governor module as we are sure event can only be START/STOP here. Remove the useless check. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 030212104fe6..b03a8514b574 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1719,8 +1719,6 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) || (policy->governor_enabled && (event == CPUFREQ_GOV_START))) { mutex_unlock(&cpufreq_governor_lock); - if (event == CPUFREQ_GOV_POLICY_INIT) - module_put(policy->governor->owner); return -EBUSY; } -- cgit v1.2.3-58-ga151 From 474deff744c4012f07cfa994947d7c6260c9ab89 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 20 Aug 2013 12:08:25 +0530 Subject: cpufreq: remove cpufreq_policy_cpu per-cpu variable cpufreq_policy_cpu per-cpu variables are used for storing the ID of the CPU that manages the given CPU's policy. However, we also store a policy pointer for each cpu in cpufreq_cpu_data, so the cpufreq_policy_cpu information is simply redundant. It is better to use cpufreq_cpu_data to retrieve a policy and get policy->cpu from there, so make that happen everywhere and drop the cpufreq_policy_cpu per-cpu variables which aren't necessary any more. [rjw: Changelog] Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 45 ++++++++++----------------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index b03a8514b574..0586bd20a474 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -64,15 +64,14 @@ static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); * - Lock should not be held across * __cpufreq_governor(data, CPUFREQ_GOV_STOP); */ -static DEFINE_PER_CPU(int, cpufreq_policy_cpu); static DEFINE_PER_CPU(struct rw_semaphore, cpu_policy_rwsem); #define lock_policy_rwsem(mode, cpu) \ static int lock_policy_rwsem_##mode(int cpu) \ { \ - int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \ - BUG_ON(policy_cpu == -1); \ - down_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \ + struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); \ + BUG_ON(!policy); \ + down_##mode(&per_cpu(cpu_policy_rwsem, policy->cpu)); \ \ return 0; \ } @@ -83,9 +82,9 @@ lock_policy_rwsem(write, cpu); #define unlock_policy_rwsem(mode, cpu) \ static void unlock_policy_rwsem_##mode(int cpu) \ { \ - int policy_cpu = per_cpu(cpufreq_policy_cpu, cpu); \ - BUG_ON(policy_cpu == -1); \ - up_##mode(&per_cpu(cpu_policy_rwsem, policy_cpu)); \ + struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); \ + BUG_ON(!policy); \ + up_##mode(&per_cpu(cpu_policy_rwsem, policy->cpu)); \ } unlock_policy_rwsem(read, cpu); @@ -887,7 +886,6 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, write_lock_irqsave(&cpufreq_driver_lock, flags); cpumask_set_cpu(cpu, policy->cpus); - per_cpu(cpufreq_policy_cpu, cpu) = policy->cpu; per_cpu(cpufreq_cpu_data, cpu) = policy; write_unlock_irqrestore(&cpufreq_driver_lock, flags); @@ -1013,9 +1011,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, policy->governor = CPUFREQ_DEFAULT_GOVERNOR; cpumask_copy(policy->cpus, cpumask_of(cpu)); - /* Initially set CPU itself as the policy_cpu */ - per_cpu(cpufreq_policy_cpu, cpu) = cpu; - init_completion(&policy->kobj_unregister); INIT_WORK(&policy->update, handle_update); @@ -1053,10 +1048,8 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, #endif write_lock_irqsave(&cpufreq_driver_lock, flags); - for_each_cpu(j, policy->cpus) { + for_each_cpu(j, policy->cpus) per_cpu(cpufreq_cpu_data, j) = policy; - per_cpu(cpufreq_policy_cpu, j) = policy->cpu; - } write_unlock_irqrestore(&cpufreq_driver_lock, flags); if (!frozen) { @@ -1080,15 +1073,11 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, err_out_unregister: write_lock_irqsave(&cpufreq_driver_lock, flags); - for_each_cpu(j, policy->cpus) { + for_each_cpu(j, policy->cpus) per_cpu(cpufreq_cpu_data, j) = NULL; - if (j != cpu) - per_cpu(cpufreq_policy_cpu, j) = -1; - } write_unlock_irqrestore(&cpufreq_driver_lock, flags); err_set_policy_cpu: - per_cpu(cpufreq_policy_cpu, cpu) = -1; cpufreq_policy_free(policy); nomem_out: up_read(&cpufreq_rwsem); @@ -1112,14 +1101,9 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) { - int j; - policy->last_cpu = policy->cpu; policy->cpu = cpu; - for_each_cpu(j, policy->cpus) - per_cpu(cpufreq_policy_cpu, j) = cpu; - #ifdef CONFIG_CPU_FREQ_TABLE cpufreq_frequency_table_update_policy_cpu(policy); #endif @@ -1131,7 +1115,6 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, unsigned int old_cpu, bool frozen) { struct device *cpu_dev; - unsigned long flags; int ret; /* first sibling now owns the new sysfs dir */ @@ -1148,11 +1131,6 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, WARN_ON(lock_policy_rwsem_write(old_cpu)); cpumask_set_cpu(old_cpu, policy->cpus); - - write_lock_irqsave(&cpufreq_driver_lock, flags); - per_cpu(cpufreq_cpu_data, old_cpu) = policy; - write_unlock_irqrestore(&cpufreq_driver_lock, flags); - unlock_policy_rwsem_write(old_cpu); ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj, @@ -1186,7 +1164,6 @@ static int __cpufreq_remove_dev(struct device *dev, write_lock_irqsave(&cpufreq_driver_lock, flags); policy = per_cpu(cpufreq_cpu_data, cpu); - per_cpu(cpufreq_cpu_data, cpu) = NULL; /* Save the policy somewhere when doing a light-weight tear-down */ if (frozen) @@ -1292,7 +1269,7 @@ static int __cpufreq_remove_dev(struct device *dev, } } - per_cpu(cpufreq_policy_cpu, cpu) = -1; + per_cpu(cpufreq_cpu_data, cpu) = NULL; return 0; } @@ -2148,10 +2125,8 @@ static int __init cpufreq_core_init(void) if (cpufreq_disabled()) return -ENODEV; - for_each_possible_cpu(cpu) { - per_cpu(cpufreq_policy_cpu, cpu) = -1; + for_each_possible_cpu(cpu) init_rwsem(&per_cpu(cpu_policy_rwsem, cpu)); - } cpufreq_global_kobject = kobject_create(); BUG_ON(!cpufreq_global_kobject); -- cgit v1.2.3-58-ga151 From 1b27429446f0c37353179544e844dc2086fa2353 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 20 Aug 2013 12:08:26 +0530 Subject: cpufreq: Use cpufreq_policy_list for iterating over policies To iterate over all policies we currently iterate over all online CPUs and then get the policy for each of them which is suboptimal. Use the newly created cpufreq_policy_list for this purpose instead. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 0586bd20a474..81ceea6ed630 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -961,8 +961,8 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, struct cpufreq_policy *policy; unsigned long flags; #ifdef CONFIG_HOTPLUG_CPU + struct cpufreq_policy *tpolicy; struct cpufreq_governor *gov; - int sibling; #endif if (cpu_is_offline(cpu)) @@ -985,11 +985,10 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, #ifdef CONFIG_HOTPLUG_CPU /* Check if this cpu was hot-unplugged earlier and has siblings */ read_lock_irqsave(&cpufreq_driver_lock, flags); - for_each_online_cpu(sibling) { - struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling); - if (cp && cpumask_test_cpu(cpu, cp->related_cpus)) { + list_for_each_entry(tpolicy, &cpufreq_policy_list, policy_list) { + if (cpumask_test_cpu(cpu, tpolicy->related_cpus)) { read_unlock_irqrestore(&cpufreq_driver_lock, flags); - ret = cpufreq_add_policy_cpu(cp, cpu, dev, frozen); + ret = cpufreq_add_policy_cpu(tpolicy, cpu, dev, frozen); up_read(&cpufreq_rwsem); return ret; } -- cgit v1.2.3-58-ga151 From 5025d628c8659fbf939f929107bf76db81dcdfff Mon Sep 17 00:00:00 2001 From: Li Zhong Date: Wed, 21 Aug 2013 01:31:08 +0200 Subject: cpufreq: fix bad unlock balance on !CONFIG_SMP This patch tries to fix lockdep complaint attached below. It seems that we should always read acquire the cpufreq_rwsem, whether CONFIG_SMP is enabled or not. And CONFIG_HOTPLUG_CPU depends on CONFIG_SMP, so it seems we don't need CONFIG_SMP for the code enabled by CONFIG_HOTPLUG_CPU. [ 0.504191] ===================================== [ 0.504627] [ BUG: bad unlock balance detected! ] [ 0.504627] 3.11.0-rc6-next-20130819 #1 Not tainted [ 0.504627] ------------------------------------- [ 0.504627] swapper/1 is trying to release lock (cpufreq_rwsem) at: [ 0.504627] [] cpufreq_add_dev+0x13a/0x3e0 [ 0.504627] but there are no more locks to release! [ 0.504627] [ 0.504627] other info that might help us debug this: [ 0.504627] 1 lock held by swapper/1: [ 0.504627] #0: (subsys mutex#4){+.+.+.}, at: [] subsys_interface_register+0x4f/0xe0 [ 0.504627] [ 0.504627] stack backtrace: [ 0.504627] CPU: 0 PID: 1 Comm: swapper Not tainted 3.11.0-rc6-next-20130819 #1 [ 0.504627] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007 [ 0.504627] ffffffff813d927a ffff88007f847c98 ffffffff814c062b ffff88007f847cc8 [ 0.504627] ffffffff81098bce ffff88007f847cf8 ffffffff81aadc30 ffffffff813d927a [ 0.504627] 00000000ffffffff ffff88007f847d68 ffffffff8109d0be 0000000000000006 [ 0.504627] Call Trace: [ 0.504627] [] ? cpufreq_add_dev+0x13a/0x3e0 [ 0.504627] [] dump_stack+0x19/0x1b [ 0.504627] [] print_unlock_imbalance_bug+0xfe/0x110 [ 0.504627] [] ? cpufreq_add_dev+0x13a/0x3e0 [ 0.504627] [] lock_release_non_nested+0x1ee/0x310 [ 0.504627] [] ? mark_held_locks+0xae/0x120 [ 0.504627] [] ? kfree+0xcb/0x1d0 [ 0.504627] [] ? cpufreq_policy_free+0x4a/0x60 [ 0.504627] [] ? cpufreq_add_dev+0x13a/0x3e0 [ 0.504627] [] lock_release+0xc4/0x250 [ 0.504627] [] up_read+0x23/0x40 [ 0.504627] [] cpufreq_add_dev+0x13a/0x3e0 [ 0.504627] [] subsys_interface_register+0x99/0xe0 [ 0.504627] [] ? cpufreq_gov_dbs_init+0x12/0x12 [ 0.504627] [] cpufreq_register_driver+0x9d/0x1d0 [ 0.504627] [] ? cpufreq_gov_dbs_init+0x12/0x12 [ 0.504627] [] acpi_cpufreq_init+0xfe/0x1f8 [ 0.504627] [] do_one_initcall+0xda/0x180 [ 0.504627] [] kernel_init_freeable+0x12c/0x1bb [ 0.504627] [] ? do_early_param+0x8c/0x8c [ 0.504627] [] ? rest_init+0x140/0x140 [ 0.504627] [] kernel_init+0xe/0xf0 [ 0.504627] [] ret_from_fork+0x7a/0xb0 [ 0.504627] [] ? rest_init+0x140/0x140 Signed-off-by: Li Zhong Acked-and-tested-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 81ceea6ed630..5c75e3147a60 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -978,6 +978,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, cpufreq_cpu_put(policy); return 0; } +#endif if (!down_read_trylock(&cpufreq_rwsem)) return 0; @@ -994,7 +995,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, } } read_unlock_irqrestore(&cpufreq_driver_lock, flags); -#endif #endif if (frozen) -- cgit v1.2.3-58-ga151 From 183912d352a242a276a7877852f107459a13aff9 Mon Sep 17 00:00:00 2001 From: Sudeep KarkadaNagesha Date: Thu, 15 Aug 2013 14:01:40 +0100 Subject: of: move of_get_cpu_node implementation to DT core library This patch moves the generalized implementation of of_get_cpu_node from PowerPC to DT core library, thereby adding support for retrieving cpu node for a given logical cpu index on any architecture. The CPU subsystem can now use this function to assign of_node in the cpu device while registering CPUs. It is recommended to use these helper function only in pre-SMP/early initialisation stages to retrieve CPU device node pointers in logical ordering. Once the cpu devices are registered, it can be retrieved easily from cpu device of_node which avoids unnecessary parsing and matching. Cc: Benjamin Herrenschmidt Cc: Grant Likely Acked-by: Rob Herring Signed-off-by: Sudeep KarkadaNagesha --- arch/powerpc/include/asm/prom.h | 3 -- arch/powerpc/kernel/prom.c | 57 ------------------------- drivers/of/base.c | 95 +++++++++++++++++++++++++++++++++++++++++ include/linux/cpu.h | 1 + include/linux/of.h | 7 +++ 5 files changed, 103 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index bc2da154f68b..ac204e022922 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -43,9 +43,6 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, extern void kdump_move_device_tree(void); -/* CPU OF node matching */ -struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); - /* cache lookup */ struct device_node *of_find_next_cache_node(struct device_node *np); diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index f7b8c0be982e..1c14cd4a5e05 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -870,63 +870,6 @@ bool arch_match_cpu_phys_id(int cpu, u64 phys_id) return (int)phys_id == get_hard_smp_processor_id(cpu); } -static bool __of_find_n_match_cpu_property(struct device_node *cpun, - const char *prop_name, int cpu, unsigned int *thread) -{ - const __be32 *cell; - int ac, prop_len, tid; - u64 hwid; - - ac = of_n_addr_cells(cpun); - cell = of_get_property(cpun, prop_name, &prop_len); - if (!cell) - return false; - prop_len /= sizeof(*cell); - for (tid = 0; tid < prop_len; tid++) { - hwid = of_read_number(cell, ac); - if (arch_match_cpu_phys_id(cpu, hwid)) { - if (thread) - *thread = tid; - return true; - } - cell += ac; - } - return false; -} - -/* Find the device node for a given logical cpu number, also returns the cpu - * local thread number (index in ibm,interrupt-server#s) if relevant and - * asked for (non NULL) - */ -struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) -{ - struct device_node *cpun, *cpus; - - cpus = of_find_node_by_path("/cpus"); - if (!cpus) { - pr_warn("Missing cpus node, bailing out\n"); - return NULL; - } - - for_each_child_of_node(cpus, cpun) { - if (of_node_cmp(cpun->type, "cpu")) - continue; - - /* Check for non-standard "ibm,ppc-interrupt-server#s" property - * for thread ids on PowerPC. If it doesn't exist fallback to - * standard "reg" property. - */ - if (__of_find_n_match_cpu_property(cpun, - "ibm,ppc-interrupt-server#s", cpu, thread)) - return cpun; - - if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread)) - return cpun; - } - return NULL; -} -EXPORT_SYMBOL(of_get_cpu_node); - #if defined(CONFIG_DEBUG_FS) && defined(DEBUG) static struct debugfs_blob_wrapper flat_dt_blob; diff --git a/drivers/of/base.c b/drivers/of/base.c index 5c5427918eb2..605afa9fbe5e 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -18,6 +18,7 @@ * 2 of the License, or (at your option) any later version. */ #include +#include #include #include #include @@ -230,6 +231,100 @@ const void *of_get_property(const struct device_node *np, const char *name, } EXPORT_SYMBOL(of_get_property); +/* + * arch_match_cpu_phys_id - Match the given logical CPU and physical id + * + * @cpu: logical cpu index of a core/thread + * @phys_id: physical identifier of a core/thread + * + * CPU logical to physical index mapping is architecture specific. + * However this __weak function provides a default match of physical + * id to logical cpu index. phys_id provided here is usually values read + * from the device tree which must match the hardware internal registers. + * + * Returns true if the physical identifier and the logical cpu index + * correspond to the same core/thread, false otherwise. + */ +bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id) +{ + return (u32)phys_id == cpu; +} + +/** + * Checks if the given "prop_name" property holds the physical id of the + * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not + * NULL, local thread number within the core is returned in it. + */ +static bool __of_find_n_match_cpu_property(struct device_node *cpun, + const char *prop_name, int cpu, unsigned int *thread) +{ + const __be32 *cell; + int ac, prop_len, tid; + u64 hwid; + + ac = of_n_addr_cells(cpun); + cell = of_get_property(cpun, prop_name, &prop_len); + if (!cell) + return false; + prop_len /= sizeof(*cell); + for (tid = 0; tid < prop_len; tid++) { + hwid = of_read_number(cell, ac); + if (arch_match_cpu_phys_id(cpu, hwid)) { + if (thread) + *thread = tid; + return true; + } + cell += ac; + } + return false; +} + +/** + * of_get_cpu_node - Get device node associated with the given logical CPU + * + * @cpu: CPU number(logical index) for which device node is required + * @thread: if not NULL, local thread number within the physical core is + * returned + * + * The main purpose of this function is to retrieve the device node for the + * given logical CPU index. It should be used to initialize the of_node in + * cpu device. Once of_node in cpu device is populated, all the further + * references can use that instead. + * + * CPU logical to physical index mapping is architecture specific and is built + * before booting secondary cores. This function uses arch_match_cpu_phys_id + * which can be overridden by architecture specific implementation. + * + * Returns a node pointer for the logical cpu if found, else NULL. + */ +struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) +{ + struct device_node *cpun, *cpus; + + cpus = of_find_node_by_path("/cpus"); + if (!cpus) { + pr_warn("Missing cpus node, bailing out\n"); + return NULL; + } + + for_each_child_of_node(cpus, cpun) { + if (of_node_cmp(cpun->type, "cpu")) + continue; + /* Check for non-standard "ibm,ppc-interrupt-server#s" property + * for thread ids on PowerPC. If it doesn't exist fallback to + * standard "reg" property. + */ + if (IS_ENABLED(CONFIG_PPC) && + __of_find_n_match_cpu_property(cpun, + "ibm,ppc-interrupt-server#s", cpu, thread)) + return cpun; + if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread)) + return cpun; + } + return NULL; +} +EXPORT_SYMBOL(of_get_cpu_node); + /** Checks if the given "compat" string matches one of the strings in * the device's "compatible" property */ diff --git a/include/linux/cpu.h b/include/linux/cpu.h index ab0eade73039..3dfed2b9ae2e 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -28,6 +28,7 @@ struct cpu { extern int register_cpu(struct cpu *cpu, int num); extern struct device *get_cpu_device(unsigned cpu); extern bool cpu_is_hotpluggable(unsigned cpu); +extern bool arch_match_cpu_phys_id(int cpu, u64 phys_id); extern int cpu_add_dev_attr(struct device_attribute *attr); extern void cpu_remove_dev_attr(struct device_attribute *attr); diff --git a/include/linux/of.h b/include/linux/of.h index 1fd08ca23106..c0bb2f188048 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -266,6 +266,7 @@ extern int of_device_is_available(const struct device_node *device); extern const void *of_get_property(const struct device_node *node, const char *name, int *lenp); +extern struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); #define for_each_property_of_node(dn, pp) \ for (pp = dn->properties; pp != NULL; pp = pp->next) @@ -459,6 +460,12 @@ static inline const void *of_get_property(const struct device_node *node, return NULL; } +static inline struct device_node *of_get_cpu_node(int cpu, + unsigned int *thread) +{ + return NULL; +} + static inline int of_property_read_u64(const struct device_node *np, const char *propname, u64 *out_value) { -- cgit v1.2.3-58-ga151 From f86e4718f24b83be0c42894d2b97accc993d65d3 Mon Sep 17 00:00:00 2001 From: Sudeep KarkadaNagesha Date: Mon, 17 Jun 2013 12:58:45 +0100 Subject: driver/core: cpu: initialize of_node in cpu's device struture CPUs are also registered as devices but the of_node in these cpu devices are not initialized. Currently different drivers requiring to access cpu device node are parsing the nodes themselves and initialising the of_node in cpu device. The of_node in all the cpu devices needs to be initialized properly and at one place. The best place to update this is CPU subsystem driver when registering the cpu devices. The OF/DT core library now provides of_get_cpu_node to retrieve a cpu device node for a given logical index by abstracting the architecture specific details. This patch uses of_get_cpu_node to assign of_node when registering the cpu devices. Acked-by: Greg Kroah-Hartman Acked-by: Rob Herring Signed-off-by: Sudeep KarkadaNagesha --- drivers/base/cpu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 4c358bc44c72..4cf071764be3 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "base.h" @@ -289,6 +290,7 @@ int register_cpu(struct cpu *cpu, int num) cpu->dev.release = cpu_device_release; cpu->dev.offline_disabled = !cpu->hotpluggable; cpu->dev.offline = !cpu_online(num); + cpu->dev.of_node = of_get_cpu_node(num, NULL); #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE cpu->dev.bus->uevent = arch_cpu_uevent; #endif -- cgit v1.2.3-58-ga151 From 78b4d6e0fd2695da3019c86133444578d1ceeed3 Mon Sep 17 00:00:00 2001 From: Sudeep KarkadaNagesha Date: Mon, 17 Jun 2013 14:51:48 +0100 Subject: drivers/bus: arm-cci: avoid parsing DT for cpu device nodes Since the CPU device nodes can be retrieved using arch_of_get_cpu_node, we can use it to avoid parsing the cpus node searching the cpu nodes and mapping to logical index. This patch removes parsing DT for cpu nodes by using of_get_cpu_node. Cc: Lorenzo Pieralisi Acked-by: Nicolas Pitre Signed-off-by: Sudeep KarkadaNagesha --- drivers/bus/arm-cci.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index 733288967d4d..200926699778 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c @@ -122,17 +122,8 @@ EXPORT_SYMBOL_GPL(cci_ace_get_port); static void __init cci_ace_init_ports(void) { - int port, ac, cpu; - u64 hwid; - const u32 *cell; - struct device_node *cpun, *cpus; - - cpus = of_find_node_by_path("/cpus"); - if (WARN(!cpus, "Missing cpus node, bailing out\n")) - return; - - if (WARN_ON(of_property_read_u32(cpus, "#address-cells", &ac))) - ac = of_n_addr_cells(cpus); + int port, cpu; + struct device_node *cpun; /* * Port index look-up speeds up the function disabling ports by CPU, @@ -141,18 +132,13 @@ static void __init cci_ace_init_ports(void) * The stashed index array is initialized for all possible CPUs * at probe time. */ - for_each_child_of_node(cpus, cpun) { - if (of_node_cmp(cpun->type, "cpu")) - continue; - cell = of_get_property(cpun, "reg", NULL); - if (WARN(!cell, "%s: missing reg property\n", cpun->full_name)) - continue; - - hwid = of_read_number(cell, ac); - cpu = get_logical_index(hwid & MPIDR_HWID_BITMASK); + for_each_possible_cpu(cpu) { + /* too early to use cpu->of_node */ + cpun = of_get_cpu_node(cpu, NULL); - if (cpu < 0 || !cpu_possible(cpu)) + if (WARN(!cpun, "Missing cpu device node\n")) continue; + port = __cci_ace_get_port(cpun, ACE_PORT); if (port < 0) continue; -- cgit v1.2.3-58-ga151 From cdc58d602d2e657602a90c190cbf745886c95977 Mon Sep 17 00:00:00 2001 From: Sudeep KarkadaNagesha Date: Mon, 17 Jun 2013 14:58:48 +0100 Subject: cpufreq: imx6q-cpufreq: remove device tree parsing for cpu nodes Now that the cpu device registration initialises the of_node(if available) appropriately for all the cpus, parsing here is redundant. This patch removes all DT parsing and uses cpu->of_node instead. Acked-by: Shawn Guo Acked-by: Viresh Kumar Signed-off-by: Sudeep KarkadaNagesha --- arch/arm/mach-imx/mach-imx6q.c | 3 +-- drivers/cpufreq/imx6q-cpufreq.c | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 7be13f8e69a0..a02f275a198d 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -254,13 +254,12 @@ static void __init imx6q_opp_init(struct device *cpu_dev) { struct device_node *np; - np = of_find_node_by_path("/cpus/cpu@0"); + np = of_node_get(cpu_dev->of_node); if (!np) { pr_warn("failed to find cpu0 node\n"); return; } - cpu_dev->of_node = np; if (of_init_opp_table(cpu_dev)) { pr_warn("failed to init OPP table\n"); goto put_node; diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index e37cdaedbb5b..b16632bb5a56 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -221,14 +221,12 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) cpu_dev = &pdev->dev; - np = of_find_node_by_path("/cpus/cpu@0"); + np = of_node_get(cpu_dev->of_node); if (!np) { dev_err(cpu_dev, "failed to find cpu0 node\n"); return -ENOENT; } - cpu_dev->of_node = np; - arm_clk = devm_clk_get(cpu_dev, "arm"); pll1_sys_clk = devm_clk_get(cpu_dev, "pll1_sys"); pll1_sw_clk = devm_clk_get(cpu_dev, "pll1_sw"); -- cgit v1.2.3-58-ga151 From f837a9b5ab05c52a07108c6f09ca66f2e0aee757 Mon Sep 17 00:00:00 2001 From: Sudeep KarkadaNagesha Date: Mon, 17 Jun 2013 15:04:19 +0100 Subject: cpufreq: cpufreq-cpu0: remove device tree parsing for cpu nodes Now that the cpu device registration initialises the of_node(if available) appropriately for all the cpus, parsing here is redundant. This patch removes all DT parsing and uses cpu->of_node instead. Acked-by: Shawn Guo Acked-by: Rob Herring Acked-by: Viresh Kumar Signed-off-by: Sudeep KarkadaNagesha --- drivers/cpufreq/cpufreq-cpu0.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index ad1fde277661..5b05c26efb96 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -174,29 +174,17 @@ static struct cpufreq_driver cpu0_cpufreq_driver = { static int cpu0_cpufreq_probe(struct platform_device *pdev) { - struct device_node *np, *parent; + struct device_node *np; int ret; - parent = of_find_node_by_path("/cpus"); - if (!parent) { - pr_err("failed to find OF /cpus\n"); - return -ENOENT; - } - - for_each_child_of_node(parent, np) { - if (of_get_property(np, "operating-points", NULL)) - break; - } + cpu_dev = &pdev->dev; + np = of_node_get(cpu_dev->of_node); if (!np) { pr_err("failed to find cpu0 node\n"); - ret = -ENOENT; - goto out_put_parent; + return -ENOENT; } - cpu_dev = &pdev->dev; - cpu_dev->of_node = np; - cpu_reg = devm_regulator_get(cpu_dev, "cpu0"); if (IS_ERR(cpu_reg)) { /* @@ -269,15 +257,12 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev) } of_node_put(np); - of_node_put(parent); return 0; out_free_table: opp_free_cpufreq_table(cpu_dev, &freq_table); out_put_node: of_node_put(np); -out_put_parent: - of_node_put(parent); return ret; } -- cgit v1.2.3-58-ga151 From 5de6e94a298576c2774ba43c0c3b0a0410cd100e Mon Sep 17 00:00:00 2001 From: Sudeep KarkadaNagesha Date: Mon, 17 Jun 2013 15:07:28 +0100 Subject: cpufreq: highbank-cpufreq: remove device tree parsing for cpu nodes Now that the cpu device registration initialises the of_node(if available) appropriately for all the cpus, parsing here is redundant. This patch removes all DT parsing and uses cpu->of_node instead. Cc: Mark Langsdorf Acked-by: Rob Herring Acked-by: Viresh Kumar Signed-off-by: Sudeep KarkadaNagesha --- drivers/cpufreq/highbank-cpufreq.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/highbank-cpufreq.c b/drivers/cpufreq/highbank-cpufreq.c index b61b5a3fad64..794123fcf3e3 100644 --- a/drivers/cpufreq/highbank-cpufreq.c +++ b/drivers/cpufreq/highbank-cpufreq.c @@ -69,23 +69,17 @@ static int hb_cpufreq_driver_init(void) if (!of_machine_is_compatible("calxeda,highbank")) return -ENODEV; - for_each_child_of_node(of_find_node_by_path("/cpus"), np) - if (of_get_property(np, "operating-points", NULL)) - break; - - if (!np) { - pr_err("failed to find highbank cpufreq node\n"); - return -ENOENT; - } - cpu_dev = get_cpu_device(0); if (!cpu_dev) { pr_err("failed to get highbank cpufreq device\n"); - ret = -ENODEV; - goto out_put_node; + return -ENODEV; } - cpu_dev->of_node = np; + np = of_node_get(cpu_dev->of_node); + if (!np) { + pr_err("failed to find highbank cpufreq node\n"); + return -ENOENT; + } cpu_clk = clk_get(cpu_dev, NULL); if (IS_ERR(cpu_clk)) { -- cgit v1.2.3-58-ga151 From c0e469487d2327e644e8d86e091c0d4e4351a1a1 Mon Sep 17 00:00:00 2001 From: Sudeep KarkadaNagesha Date: Mon, 17 Jun 2013 15:09:15 +0100 Subject: cpufreq: spear-cpufreq: remove device tree parsing for cpu nodes Now that the cpu device registration initialises the of_node(if available) appropriately for all the cpus, parsing here is redundant. This patch removes all DT parsing and uses cpu->of_node instead. Cc: Deepak Sikri Acked-by: Viresh Kumar Signed-off-by: Sudeep KarkadaNagesha --- drivers/cpufreq/spear-cpufreq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index c3efa7f2a908..19e364fa5955 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include @@ -223,7 +223,7 @@ static int spear_cpufreq_driver_init(void) const __be32 *val; int cnt, i, ret; - np = of_find_node_by_path("/cpus/cpu@0"); + np = of_cpu_device_node_get(0); if (!np) { pr_err("No cpu node found"); return -ENODEV; -- cgit v1.2.3-58-ga151 From e768f350c8c3d4253011282db771f35af37ee59a Mon Sep 17 00:00:00 2001 From: Sudeep KarkadaNagesha Date: Mon, 17 Jun 2013 15:09:51 +0100 Subject: cpufreq: kirkwood-cpufreq: remove device tree parsing for cpu nodes Now that the cpu device registration initialises the of_node(if available) appropriately for all the cpus, parsing here is redundant. This patch removes all DT parsing and uses cpu->of_node instead. Cc: Jason Cooper Acked-by: Andrew Lunn Acked-by: Viresh Kumar Signed-off-by: Sudeep KarkadaNagesha --- drivers/cpufreq/kirkwood-cpufreq.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c index c233ea617366..25ac2cb15a43 100644 --- a/drivers/cpufreq/kirkwood-cpufreq.c +++ b/drivers/cpufreq/kirkwood-cpufreq.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -175,9 +175,11 @@ static int kirkwood_cpufreq_probe(struct platform_device *pdev) if (IS_ERR(priv.base)) return PTR_ERR(priv.base); - np = of_find_node_by_path("/cpus/cpu@0"); - if (!np) + np = of_cpu_device_node_get(0); + if (!np) { + dev_err(&pdev->dev, "failed to get cpu device node\n"); return -ENODEV; + } priv.cpu_clk = of_clk_get_by_name(np, "cpu_clk"); if (IS_ERR(priv.cpu_clk)) { -- cgit v1.2.3-58-ga151 From da0eb143dbbaf26b6f084bee81d56fc64efb5390 Mon Sep 17 00:00:00 2001 From: Sudeep KarkadaNagesha Date: Mon, 17 Jun 2013 15:51:44 +0100 Subject: cpufreq: arm_big_little: remove device tree parsing for cpu nodes Now that the cpu device registration initialises the of_node(if available) appropriately for all the cpus, parsing here is redundant. This patch removes all DT parsing and uses cpu->of_node instead. Acked-by: Viresh Kumar Signed-off-by: Sudeep KarkadaNagesha --- drivers/cpufreq/arm_big_little_dt.c | 40 +++++++++++++------------------------ 1 file changed, 14 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/arm_big_little_dt.c b/drivers/cpufreq/arm_big_little_dt.c index fd9e3ea6a480..480c0bd0468d 100644 --- a/drivers/cpufreq/arm_big_little_dt.c +++ b/drivers/cpufreq/arm_big_little_dt.c @@ -19,12 +19,11 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include #include #include #include #include -#include +#include #include #include #include @@ -34,27 +33,13 @@ /* get cpu node with valid operating-points */ static struct device_node *get_cpu_node_with_valid_op(int cpu) { - struct device_node *np = NULL, *parent; - int count = 0; + struct device_node *np = of_cpu_device_node_get(cpu); - parent = of_find_node_by_path("/cpus"); - if (!parent) { - pr_err("failed to find OF /cpus\n"); - return NULL; + if (!of_get_property(np, "operating-points", NULL)) { + of_node_put(np); + np = NULL; } - for_each_child_of_node(parent, np) { - if (count++ != cpu) - continue; - if (!of_get_property(np, "operating-points", NULL)) { - of_node_put(np); - np = NULL; - } - - break; - } - - of_node_put(parent); return np; } @@ -63,11 +48,12 @@ static int dt_init_opp_table(struct device *cpu_dev) struct device_node *np; int ret; - np = get_cpu_node_with_valid_op(cpu_dev->id); - if (!np) - return -ENODATA; + np = of_node_get(cpu_dev->of_node); + if (!np) { + pr_err("failed to find cpu%d node\n", cpu_dev->id); + return -ENOENT; + } - cpu_dev->of_node = np; ret = of_init_opp_table(cpu_dev); of_node_put(np); @@ -79,9 +65,11 @@ static int dt_get_transition_latency(struct device *cpu_dev) struct device_node *np; u32 transition_latency = CPUFREQ_ETERNAL; - np = get_cpu_node_with_valid_op(cpu_dev->id); - if (!np) + np = of_node_get(cpu_dev->of_node); + if (!np) { + pr_info("Failed to find cpu node. Use CPUFREQ_ETERNAL transition latency\n"); return CPUFREQ_ETERNAL; + } of_property_read_u32(np, "clock-latency", &transition_latency); of_node_put(np); -- cgit v1.2.3-58-ga151 From 2421d4c34d492efd8b116ce62ae5612b5b9864b2 Mon Sep 17 00:00:00 2001 From: Sudeep KarkadaNagesha Date: Wed, 17 Jul 2013 12:39:29 +0100 Subject: cpufreq: maple-cpufreq: remove device tree parsing for cpu nodes Now that the cpu device registration initialises the of_node(if available) appropriately for all the cpus, parsing here is redundant. This patch removes all DT parsing and uses cpu->of_node instead. Cc: Dmitry Eremin-Solenikov Acked-by: Viresh Kumar Signed-off-by: Sudeep KarkadaNagesha --- drivers/cpufreq/maple-cpufreq.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/maple-cpufreq.c b/drivers/cpufreq/maple-cpufreq.c index cdd62915efaf..f071dc49f129 100644 --- a/drivers/cpufreq/maple-cpufreq.c +++ b/drivers/cpufreq/maple-cpufreq.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #define DBG(fmt...) pr_debug(fmt) @@ -201,7 +201,6 @@ static struct cpufreq_driver maple_cpufreq_driver = { static int __init maple_cpufreq_init(void) { - struct device_node *cpus; struct device_node *cpunode; unsigned int psize; unsigned long max_freq; @@ -217,24 +216,11 @@ static int __init maple_cpufreq_init(void) !of_machine_is_compatible("Momentum,Apache")) return 0; - cpus = of_find_node_by_path("/cpus"); - if (cpus == NULL) { - DBG("No /cpus node !\n"); - return -ENODEV; - } - /* Get first CPU node */ - for (cpunode = NULL; - (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { - const u32 *reg = of_get_property(cpunode, "reg", NULL); - if (reg == NULL || (*reg) != 0) - continue; - if (!strcmp(cpunode->type, "cpu")) - break; - } + cpunode = of_cpu_device_node_get(0); if (cpunode == NULL) { printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n"); - goto bail_cpus; + goto bail_noprops; } /* Check 970FX for now */ @@ -290,14 +276,11 @@ static int __init maple_cpufreq_init(void) rc = cpufreq_register_driver(&maple_cpufreq_driver); of_node_put(cpunode); - of_node_put(cpus); return rc; bail_noprops: of_node_put(cpunode); -bail_cpus: - of_node_put(cpus); return rc; } -- cgit v1.2.3-58-ga151 From 760287ab90a3ca93a2f87f7e7137e06e89a26b01 Mon Sep 17 00:00:00 2001 From: Sudeep KarkadaNagesha Date: Wed, 17 Jul 2013 13:42:56 +0100 Subject: cpufreq: pmac64-cpufreq: remove device tree parsing for cpu nodes Now that the cpu device registration initialises the of_node(if available) appropriately for all the cpus, parsing here is redundant. This patch removes all DT parsing and uses cpu->of_node instead. Cc: Benjamin Herrenschmidt Acked-by: Viresh Kumar Signed-off-by: Sudeep KarkadaNagesha --- drivers/cpufreq/pmac64-cpufreq.c | 47 ++++++++++------------------------------ 1 file changed, 11 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c index 7ba423431cfe..97b719f5c744 100644 --- a/drivers/cpufreq/pmac64-cpufreq.c +++ b/drivers/cpufreq/pmac64-cpufreq.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -383,9 +384,8 @@ static struct cpufreq_driver g5_cpufreq_driver = { #ifdef CONFIG_PMAC_SMU -static int __init g5_neo2_cpufreq_init(struct device_node *cpus) +static int __init g5_neo2_cpufreq_init(struct device_node *cpunode) { - struct device_node *cpunode; unsigned int psize, ssize; unsigned long max_freq; char *freq_method, *volt_method; @@ -405,20 +405,6 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) else return -ENODEV; - /* Get first CPU node */ - for (cpunode = NULL; - (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { - const u32 *reg = of_get_property(cpunode, "reg", NULL); - if (reg == NULL || (*reg) != 0) - continue; - if (!strcmp(cpunode->type, "cpu")) - break; - } - if (cpunode == NULL) { - printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n"); - return -ENODEV; - } - /* Check 970FX for now */ valp = of_get_property(cpunode, "cpu-version", NULL); if (!valp) { @@ -537,9 +523,9 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) #endif /* CONFIG_PMAC_SMU */ -static int __init g5_pm72_cpufreq_init(struct device_node *cpus) +static int __init g5_pm72_cpufreq_init(struct device_node *cpunode) { - struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL; + struct device_node *cpuid = NULL, *hwclock = NULL; const u8 *eeprom = NULL; const u32 *valp; u64 max_freq, min_freq, ih, il; @@ -548,17 +534,6 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) DBG("cpufreq: Initializing for PowerMac7,2, PowerMac7,3 and" " RackMac3,1...\n"); - /* Get first CPU node */ - for (cpunode = NULL; - (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { - if (!strcmp(cpunode->type, "cpu")) - break; - } - if (cpunode == NULL) { - printk(KERN_ERR "cpufreq: Can't find any CPU node\n"); - return -ENODEV; - } - /* Lookup the cpuid eeprom node */ cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0"); if (cpuid != NULL) @@ -718,25 +693,25 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) static int __init g5_cpufreq_init(void) { - struct device_node *cpus; + struct device_node *cpunode; int rc = 0; - cpus = of_find_node_by_path("/cpus"); - if (cpus == NULL) { - DBG("No /cpus node !\n"); + /* Get first CPU node */ + cpunode = of_cpu_device_node_get(0); + if (cpunode == NULL) { + pr_err("cpufreq: Can't find any CPU node\n"); return -ENODEV; } if (of_machine_is_compatible("PowerMac7,2") || of_machine_is_compatible("PowerMac7,3") || of_machine_is_compatible("RackMac3,1")) - rc = g5_pm72_cpufreq_init(cpus); + rc = g5_pm72_cpufreq_init(cpunode); #ifdef CONFIG_PMAC_SMU else - rc = g5_neo2_cpufreq_init(cpus); + rc = g5_neo2_cpufreq_init(cpunode); #endif /* CONFIG_PMAC_SMU */ - of_node_put(cpus); return rc; } -- cgit v1.2.3-58-ga151 From 1037b2752345cc5666e90b711a913ab2ae6c5920 Mon Sep 17 00:00:00 2001 From: Sudeep KarkadaNagesha Date: Wed, 17 Jul 2013 13:52:17 +0100 Subject: cpufreq: pmac32-cpufreq: remove device tree parsing for cpu nodes Now that the cpu device registration initialises the of_node(if available) appropriately for all the cpus, parsing here is redundant. This patch removes DT parsing and uses cpu->of_node instead. Cc: Benjamin Herrenschmidt Acked-by: Viresh Kumar Signed-off-by: Sudeep KarkadaNagesha --- drivers/cpufreq/pmac32-cpufreq.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c index 3104fad82480..56bfb6f93630 100644 --- a/drivers/cpufreq/pmac32-cpufreq.c +++ b/drivers/cpufreq/pmac32-cpufreq.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -649,8 +650,8 @@ static int __init pmac_cpufreq_setup(void) if (strstr(cmd_line, "nocpufreq")) return 0; - /* Assume only one CPU */ - cpunode = of_find_node_by_type(NULL, "cpu"); + /* Get first CPU node */ + cpunode = of_cpu_device_node_get(0); if (!cpunode) goto out; -- cgit v1.2.3-58-ga151