From d9a789c7a07e96eda7515e43932ee608dcece34d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 17 Feb 2014 22:56:35 +0100 Subject: cpufreq: Refactor cpufreq_set_policy() Reduce the rampant usage of goto and the indentation level in cpufreq_set_policy() to improve the readability of that code. No functional changes should result from that. Signed-off-by: Rafael J. Wysocki Acked-by: Viresh Kumar Reviewed-by: Srivatsa S. Bhat diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index cb003a6..37f3055 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2017,22 +2017,21 @@ EXPORT_SYMBOL(cpufreq_get_policy); static int cpufreq_set_policy(struct cpufreq_policy *policy, struct cpufreq_policy *new_policy) { - int ret = 0, failed = 1; + struct cpufreq_governor *old_gov; + int ret; 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(policy->cpuinfo)); - if (new_policy->min > policy->max || new_policy->max < policy->min) { - ret = -EINVAL; - goto error_out; - } + if (new_policy->min > policy->max || new_policy->max < policy->min) + return -EINVAL; /* verify the cpu speed can be set within this limit */ ret = cpufreq_driver->verify(new_policy); if (ret) - goto error_out; + return ret; /* adjust if necessary - all reasons */ blocking_notifier_call_chain(&cpufreq_policy_notifier_list, @@ -2048,7 +2047,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, */ ret = cpufreq_driver->verify(new_policy); if (ret) - goto error_out; + return ret; /* notification of the new policy */ blocking_notifier_call_chain(&cpufreq_policy_notifier_list, @@ -2063,58 +2062,48 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, if (cpufreq_driver->setpolicy) { policy->policy = new_policy->policy; pr_debug("setting range\n"); - ret = cpufreq_driver->setpolicy(new_policy); - } else { - if (new_policy->governor != policy->governor) { - /* save old, working values */ - struct cpufreq_governor *old_gov = policy->governor; - - pr_debug("governor switch\n"); - - /* end old governor */ - if (policy->governor) { - __cpufreq_governor(policy, CPUFREQ_GOV_STOP); - up_write(&policy->rwsem); - __cpufreq_governor(policy, - CPUFREQ_GOV_POLICY_EXIT); - down_write(&policy->rwsem); - } + return cpufreq_driver->setpolicy(new_policy); + } - /* start new governor */ - policy->governor = new_policy->governor; - if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) { - if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) { - failed = 0; - } else { - up_write(&policy->rwsem); - __cpufreq_governor(policy, - CPUFREQ_GOV_POLICY_EXIT); - down_write(&policy->rwsem); - } - } + if (new_policy->governor == policy->governor) + goto out; - if (failed) { - /* new governor failed, so re-start old one */ - pr_debug("starting governor %s failed\n", - policy->governor->name); - if (old_gov) { - policy->governor = old_gov; - __cpufreq_governor(policy, - CPUFREQ_GOV_POLICY_INIT); - __cpufreq_governor(policy, - CPUFREQ_GOV_START); - } - ret = -EINVAL; - goto error_out; - } - /* might be a policy change, too, so fall through */ - } - pr_debug("governor: change or update limits\n"); - ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); + pr_debug("governor switch\n"); + + /* save old, working values */ + old_gov = policy->governor; + /* end old governor */ + if (old_gov) { + __cpufreq_governor(policy, CPUFREQ_GOV_STOP); + up_write(&policy->rwsem); + __cpufreq_governor(policy,CPUFREQ_GOV_POLICY_EXIT); + down_write(&policy->rwsem); } -error_out: - return ret; + /* start new governor */ + policy->governor = new_policy->governor; + if (!__cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) { + if (!__cpufreq_governor(policy, CPUFREQ_GOV_START)) + goto out; + + up_write(&policy->rwsem); + __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); + down_write(&policy->rwsem); + } + + /* new governor failed, so re-start old one */ + pr_debug("starting governor %s failed\n", policy->governor->name); + if (old_gov) { + policy->governor = old_gov; + __cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); + __cpufreq_governor(policy, CPUFREQ_GOV_START); + } + + return -EINVAL; + + out: + pr_debug("governor: change or update limits\n"); + return __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); } /** -- cgit v0.10.2 From 1c0ca90207d61e4868043b5bbbbd7cc0bb1ac974 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 14 Feb 2014 16:30:41 +0530 Subject: cpufreq: don't call cpufreq_update_policy() on CPU addition cpufreq_update_policy() is called from two places currently. From a workqueue handled queued from cpufreq_bp_resume() for boot CPU and from cpufreq_cpu_callback() whenever a CPU is added. The first one makes sure that boot CPU is running on the frequency present in policy->cpu. But we don't really need a call from cpufreq_cpu_callback(), because we always call cpufreq_driver->init() (which will set policy->cur correctly) whenever first CPU of any policy is added back. And so every policy structure is guaranteed to have the right frequency in policy->cur. Signed-off-by: Viresh Kumar Reviewed-by: Srivatsa S. Bhat Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 37f3055..c755b5f 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2175,7 +2175,6 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, switch (action & ~CPU_TASKS_FROZEN) { case CPU_ONLINE: __cpufreq_add_dev(dev, NULL, frozen); - cpufreq_update_policy(cpu); break; case CPU_DOWN_PREPARE: -- cgit v0.10.2 From 8a5c74a175ac117e55a50b489ee041f40ff8866b Mon Sep 17 00:00:00 2001 From: Rashika Kheria Date: Wed, 26 Feb 2014 22:12:42 +0530 Subject: cpufreq: Mark function as static in cpufreq.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mark function as static in cpufreq.c because it is not used outside this file. This eliminates the following warning in cpufreq.c: drivers/cpufreq/cpufreq.c:355:9: warning: no previous prototype for ‘show_boost’ [-Wmissing-prototypes] Signed-off-by: Rashika Kheria Reviewed-by: Josh Triplett Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index c755b5f..5815af5 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -352,7 +352,7 @@ EXPORT_SYMBOL_GPL(cpufreq_notify_post_transition); /********************************************************************* * SYSFS INTERFACE * *********************************************************************/ -ssize_t show_boost(struct kobject *kobj, +static ssize_t show_boost(struct kobject *kobj, struct attribute *attr, char *buf) { return sprintf(buf, "%d\n", cpufreq_driver->boost_enabled); -- cgit v0.10.2 From 52e7e816420383a340cfb6c3ffd12477c3c80b76 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 24 Feb 2014 11:27:57 +0900 Subject: cpufreq: enable ARM drivers on arm64 Enable cpufreq and power kconfig menus on arm64 along with arm cpufreq drivers. The power menu is needed for OPP support. At least on Calxeda systems, the same cpufreq driver is used for arm and arm64 based systems. Signed-off-by: Rob Herring Acked-by: Viresh Kumar Signed-off-by: Mark Brown Signed-off-by: Rafael J. Wysocki diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 27bbcfc..c6e2f5b 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -303,6 +303,14 @@ source "drivers/cpuidle/Kconfig" endmenu +menu "Power management options" + +source "kernel/power/Kconfig" + +source "drivers/cpufreq/Kconfig" + +endmenu + source "net/Kconfig" source "drivers/Kconfig" diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 4b029c0..1fbe11f 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -200,7 +200,7 @@ source "drivers/cpufreq/Kconfig.x86" endmenu menu "ARM CPU frequency scaling drivers" -depends on ARM +depends on ARM || ARM64 source "drivers/cpufreq/Kconfig.arm" endmenu -- cgit v0.10.2 From bd0fa9bb455d9b58ec2d7a36cd08afed9e3411b4 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 25 Feb 2014 14:29:44 +0530 Subject: cpufreq: Return error if ->get() failed in cpufreq_update_policy() cpufreq_update_policy() calls cpufreq_driver->get() to get current frequency of a CPU and it is not supposed to fail or return zero. Return error in case that happens. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 5815af5..56b7b1b 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -2139,6 +2139,11 @@ int cpufreq_update_policy(unsigned int cpu) */ if (cpufreq_driver->get) { new_policy.cur = cpufreq_driver->get(cpu); + if (WARN_ON(!new_policy.cur)) { + ret = -EIO; + goto no_policy; + } + if (!policy->cur) { pr_debug("Driver did not initialize current freq"); policy->cur = new_policy.cur; -- cgit v0.10.2 From d37e2b764499e092ebc493d6f980827feb952e23 Mon Sep 17 00:00:00 2001 From: Dirk Brandewie Date: Wed, 12 Feb 2014 10:01:04 -0800 Subject: intel_pstate: remove unneeded sample buffers Remove unneeded sample buffers, intel_pstate operates on the most recent sample only. This save some memory and make the code more readable. Signed-off-by: Dirk Brandewie Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 2cd36b9..41f9eb2 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -99,8 +99,7 @@ struct cpudata { u64 prev_aperf; u64 prev_mperf; unsigned long long prev_tsc; - int sample_ptr; - struct sample samples[SAMPLE_COUNT]; + struct sample sample; }; static struct cpudata **all_cpu_data; @@ -586,15 +585,14 @@ static inline void intel_pstate_sample(struct cpudata *cpu) mperf = mperf >> FRAC_BITS; tsc = tsc >> FRAC_BITS; - cpu->sample_ptr = (cpu->sample_ptr + 1) % SAMPLE_COUNT; - cpu->samples[cpu->sample_ptr].aperf = aperf; - cpu->samples[cpu->sample_ptr].mperf = mperf; - cpu->samples[cpu->sample_ptr].tsc = tsc; - cpu->samples[cpu->sample_ptr].aperf -= cpu->prev_aperf; - cpu->samples[cpu->sample_ptr].mperf -= cpu->prev_mperf; - cpu->samples[cpu->sample_ptr].tsc -= cpu->prev_tsc; + cpu->sample.aperf = aperf; + cpu->sample.mperf = mperf; + cpu->sample.tsc = tsc; + cpu->sample.aperf -= cpu->prev_aperf; + cpu->sample.mperf -= cpu->prev_mperf; + cpu->sample.tsc -= cpu->prev_tsc; - intel_pstate_calc_busy(cpu, &cpu->samples[cpu->sample_ptr]); + intel_pstate_calc_busy(cpu, &cpu->sample); cpu->prev_aperf = aperf; cpu->prev_mperf = mperf; @@ -614,7 +612,7 @@ static inline int32_t intel_pstate_get_scaled_busy(struct cpudata *cpu) { int32_t core_busy, max_pstate, current_pstate; - core_busy = cpu->samples[cpu->sample_ptr].core_pct_busy; + core_busy = cpu->sample.core_pct_busy; max_pstate = int_tofp(cpu->pstate.max_pstate); current_pstate = int_tofp(cpu->pstate.current_pstate); core_busy = mul_fp(core_busy, div_fp(max_pstate, current_pstate)); @@ -648,7 +646,7 @@ static void intel_pstate_timer_func(unsigned long __data) intel_pstate_sample(cpu); - sample = &cpu->samples[cpu->sample_ptr]; + sample = &cpu->sample; intel_pstate_adjust_busy_pstate(cpu); @@ -729,7 +727,7 @@ static unsigned int intel_pstate_get(unsigned int cpu_num) cpu = all_cpu_data[cpu_num]; if (!cpu) return 0; - sample = &cpu->samples[cpu->sample_ptr]; + sample = &cpu->sample; return sample->freq; } -- cgit v0.10.2 From d98d099b9fbb7bbb20a74efe5327322831c9c9a3 Mon Sep 17 00:00:00 2001 From: Dirk Brandewie Date: Wed, 12 Feb 2014 10:01:05 -0800 Subject: intel_pstate: fix pid_reset to use fixed point values commit d253d2a526 (Improve accuracy by not truncating until final result), changed internal variables of the PID to be fixed point numbers. Update the pid_reset() to reflect this change. Signed-off-by: Dirk Brandewie Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 41f9eb2..9ab109c 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -153,7 +153,7 @@ static inline void pid_reset(struct _pid *pid, int setpoint, int busy, pid->setpoint = setpoint; pid->deadband = deadband; pid->integral = int_tofp(integral); - pid->last_err = setpoint - busy; + pid->last_err = int_tofp(setpoint) - int_tofp(busy); } static inline void pid_p_gain_set(struct _pid *pid, int percent) -- cgit v0.10.2 From b24a5b6512a6fb89f3b99b9b0f829b4448e62db0 Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Thu, 27 Feb 2014 17:58:34 -0800 Subject: cpufreq: stats: Remove redundant cpufreq_cpu_get() call __cpufreq_stats_create_table always gets pass the valid and real policy struct. So, there's no need to call cpufreq_cpu_get() to get the policy again. Acked-by: Viresh Kumar Signed-off-by: Saravana Kannan Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 5793e14..e4bd27f 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -185,7 +185,6 @@ 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 *current_policy; unsigned int alloc_size; unsigned int cpu = policy->cpu; if (per_cpu(cpufreq_stats_table, cpu)) @@ -194,13 +193,7 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy, if ((stat) == NULL) return -ENOMEM; - current_policy = cpufreq_cpu_get(cpu); - if (current_policy == NULL) { - ret = -EINVAL; - goto error_get_fail; - } - - ret = sysfs_create_group(¤t_policy->kobj, &stats_attr_group); + ret = sysfs_create_group(&policy->kobj, &stats_attr_group); if (ret) goto error_out; @@ -243,11 +236,8 @@ 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(current_policy); return 0; error_out: - cpufreq_cpu_put(current_policy); -error_get_fail: kfree(stat); per_cpu(cpufreq_stats_table, cpu) = NULL; return ret; -- cgit v0.10.2 From 0b7528d963e7dda51dd07fa7b1f14a9bf03b1cee Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Thu, 27 Feb 2014 17:58:35 -0800 Subject: cpufreq: stats: Fix error handling in __cpufreq_stats_create_table() Remove sysfs group if __cpufreq_stats_create_table() fails after creating one. Acked-by: Viresh Kumar Signed-off-by: Saravana Kannan Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index e4bd27f..c52b440 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -216,7 +216,7 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy, stat->time_in_state = kzalloc(alloc_size, GFP_KERNEL); if (!stat->time_in_state) { ret = -ENOMEM; - goto error_out; + goto error_alloc; } stat->freq_table = (unsigned int *)(stat->time_in_state + count); @@ -237,6 +237,8 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy, stat->last_index = freq_table_get_index(stat, policy->cur); spin_unlock(&cpufreq_stats_lock); return 0; +error_alloc: + sysfs_remove_group(&policy->kobj, &stats_attr_group); error_out: kfree(stat); per_cpu(cpufreq_stats_table, cpu) = NULL; -- cgit v0.10.2 From ad4c2302c20a6906eb2f10defdb0e982bab5eb0b Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Thu, 27 Feb 2014 17:58:36 -0800 Subject: cpufreq: stats: Refactor common code into __cpufreq_stats_create_table() cpufreq_frequency_get_table() is called from all callers of __cpufreq_stats_create_table(). So, move it inside. Suggested-by: Viresh Kumar Acked-by: Viresh Kumar Signed-off-by: Saravana Kannan Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index c52b440..eb214d8 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -180,13 +180,18 @@ static void cpufreq_stats_free_table(unsigned int cpu) cpufreq_cpu_put(policy); } -static int __cpufreq_stats_create_table(struct cpufreq_policy *policy, - struct cpufreq_frequency_table *table) +static int __cpufreq_stats_create_table(struct cpufreq_policy *policy) { unsigned int i, j, count = 0, ret = 0; struct cpufreq_stats *stat; unsigned int alloc_size; unsigned int cpu = policy->cpu; + struct cpufreq_frequency_table *table; + + table = cpufreq_frequency_get_table(cpu); + if (unlikely(!table)) + return 0; + if (per_cpu(cpufreq_stats_table, cpu)) return -EBUSY; stat = kzalloc(sizeof(*stat), GFP_KERNEL); @@ -248,7 +253,6 @@ error_out: static void cpufreq_stats_create_table(unsigned int cpu) { struct cpufreq_policy *policy; - struct cpufreq_frequency_table *table; /* * "likely(!policy)" because normally cpufreq_stats will be registered @@ -258,9 +262,7 @@ static void cpufreq_stats_create_table(unsigned int cpu) if (likely(!policy)) return; - table = cpufreq_frequency_get_table(policy->cpu); - if (likely(table)) - __cpufreq_stats_create_table(policy, table); + __cpufreq_stats_create_table(policy); cpufreq_cpu_put(policy); } @@ -283,20 +285,14 @@ static int cpufreq_stat_notifier_policy(struct notifier_block *nb, { int ret = 0; struct cpufreq_policy *policy = data; - struct cpufreq_frequency_table *table; - unsigned int cpu = policy->cpu; if (val == CPUFREQ_UPDATE_POLICY_CPU) { cpufreq_stats_update_policy_cpu(policy); return 0; } - table = cpufreq_frequency_get_table(cpu); - if (!table) - return 0; - if (val == CPUFREQ_CREATE_POLICY) - ret = __cpufreq_stats_create_table(policy, table); + ret = __cpufreq_stats_create_table(policy); else if (val == CPUFREQ_REMOVE_POLICY) __cpufreq_stats_free_table(policy); -- cgit v0.10.2 From 6e2c89d16d987e6e11c531b039a42d3f5f1d7c32 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Tue, 4 Mar 2014 11:43:59 +0800 Subject: cpufreq: move call to __find_governor() to cpufreq_init_policy() We call __find_governor() during the addition of the first CPU of each policy from __cpufreq_add_dev() to find the last governor used for this CPU before it was hot-removed. After that we call cpufreq_parse_governor() in cpufreq_init_policy(), either with this governor, or with the default governor. Right after that policy->governor is set to NULL. While that code is not functionally problematic, the structure of it is suboptimal, because some of the code required in cpufreq_init_policy() is being executed by its caller, __cpufreq_add_dev(). So, it would make more sense to get all of it together in a single place to make code more readable. Accordingly, move the code needed for policy initialization to cpufreq_init_policy() and initialize policy->governor to NULL at the beginning. In order to clean up the code a bit more, some of the #ifdefs for CONFIG_HOTPLUG_CPU are dropped too. Signed-off-by: Viresh Kumar [rjw: Changelog] Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index df95c03..2de2f1d 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -42,10 +42,8 @@ static DEFINE_RWLOCK(cpufreq_driver_lock); 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 */ static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); -#endif static inline bool has_target(void) { @@ -879,18 +877,25 @@ err_out_kobj_put: static void cpufreq_init_policy(struct cpufreq_policy *policy) { + struct cpufreq_governor *gov = NULL; struct cpufreq_policy new_policy; int ret = 0; memcpy(&new_policy, policy, sizeof(*policy)); + /* Update governor of new_policy to the governor used before hotplug */ + gov = __find_governor(per_cpu(cpufreq_cpu_governor, policy->cpu)); + if (gov) + pr_debug("Restoring governor %s for cpu %d\n", + policy->governor->name, policy->cpu); + else + gov = CPUFREQ_DEFAULT_GOVERNOR; + + new_policy.governor = gov; + /* Use the default policy if its valid. */ if (cpufreq_driver->setpolicy) - cpufreq_parse_governor(policy->governor->name, - &new_policy.policy, NULL); - - /* assure that the starting sequence is run in cpufreq_set_policy */ - policy->governor = NULL; + cpufreq_parse_governor(gov->name, &new_policy.policy, NULL); /* set default policy */ ret = cpufreq_set_policy(policy, &new_policy); @@ -949,6 +954,8 @@ static struct cpufreq_policy *cpufreq_policy_restore(unsigned int cpu) read_unlock_irqrestore(&cpufreq_driver_lock, flags); + policy->governor = NULL; + return policy; } @@ -1036,7 +1043,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, unsigned long flags; #ifdef CONFIG_HOTPLUG_CPU struct cpufreq_policy *tpolicy; - struct cpufreq_governor *gov; #endif if (cpu_is_offline(cpu)) @@ -1094,7 +1100,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, else policy->cpu = cpu; - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; cpumask_copy(policy->cpus, cpumask_of(cpu)); init_completion(&policy->kobj_unregister); @@ -1180,15 +1185,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_START, policy); -#ifdef CONFIG_HOTPLUG_CPU - gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu)); - if (gov) { - policy->governor = gov; - pr_debug("Restoring governor %s for cpu %d\n", - policy->governor->name, cpu); - } -#endif - if (!frozen) { ret = cpufreq_add_dev_interface(policy, dev); if (ret) @@ -1314,11 +1310,9 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, } } -#ifdef CONFIG_HOTPLUG_CPU if (!cpufreq_driver->setpolicy) strncpy(per_cpu(cpufreq_cpu_governor, cpu), policy->governor->name, CPUFREQ_NAME_LEN); -#endif down_read(&policy->rwsem); cpus = cpumask_weight(policy->cpus); @@ -1950,9 +1944,7 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor) { -#ifdef CONFIG_HOTPLUG_CPU int cpu; -#endif if (!governor) return; @@ -1960,14 +1952,12 @@ void cpufreq_unregister_governor(struct cpufreq_governor *governor) if (cpufreq_disabled()) return; -#ifdef CONFIG_HOTPLUG_CPU for_each_present_cpu(cpu) { if (cpu_online(cpu)) continue; if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name)) strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0"); } -#endif mutex_lock(&cpufreq_governor_mutex); list_del(&governor->governor_list); -- cgit v0.10.2 From 2f0aea9363609433b38ab13f0f86f38372668c68 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 4 Mar 2014 11:00:26 +0800 Subject: cpufreq: suspend governors on system suspend/hibernate This patch adds cpufreq suspend/resume calls to dpm_{suspend|resume}() for handling suspend/resume of cpufreq governors. Lan Tianyu (Intel) & Jinhyuk Choi (Broadcom) found an issue where the tunables configuration for clusters/sockets with non-boot CPUs was lost after system suspend/resume, as we were notifying governors with CPUFREQ_GOV_POLICY_EXIT on removal of the last CPU for that policy which caused the tunables memory to be freed. This is fixed by preventing any governor operations from being carried out between the device suspend and device resume stages of system suspend and resume, respectively. We could have added these callbacks at dpm_{suspend|resume}_noirq() level, but there is an additional problem that the majority of I/O devices is already suspended at that point and if cpufreq drivers want to change the frequency before suspending, then that not be possible on some platforms (which depend on peripherals like i2c, regulators, etc). Reported-and-tested-by: Lan Tianyu Reported-by: Jinhyuk Choi Signed-off-by: Viresh Kumar [rjw: Changelog] Signed-off-by: Rafael J. Wysocki diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 1b41fca..c9fbb9d 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -789,6 +790,8 @@ void dpm_resume(pm_message_t state) mutex_unlock(&dpm_list_mtx); async_synchronize_full(); dpm_show_time(starttime, state, NULL); + + cpufreq_resume(); } /** @@ -1259,6 +1262,8 @@ int dpm_suspend(pm_message_t state) might_sleep(); + cpufreq_suspend(); + mutex_lock(&dpm_list_mtx); pm_transition = state; async_error = 0; diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 2de2f1d..289a407 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include @@ -45,6 +45,9 @@ static LIST_HEAD(cpufreq_policy_list); /* This one keeps track of the previously set governor of a removed CPU */ static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor); +/* Flag to suspend/resume CPUFreq governors */ +static bool cpufreq_suspended; + static inline bool has_target(void) { return cpufreq_driver->target_index || cpufreq_driver->target; @@ -1565,82 +1568,77 @@ static struct subsys_interface cpufreq_interface = { }; /** - * cpufreq_bp_suspend - Prepare the boot CPU for system suspend. + * cpufreq_suspend() - Suspend CPUFreq governors * - * This function is only executed for the boot processor. The other CPUs - * have been put offline by means of CPU hotplug. + * Called during system wide Suspend/Hibernate cycles for suspending governors + * as some platforms can't change frequency after this point in suspend cycle. + * Because some of the devices (like: i2c, regulators, etc) they use for + * changing frequency are suspended quickly after this point. */ -static int cpufreq_bp_suspend(void) +void cpufreq_suspend(void) { - int ret = 0; - - int cpu = smp_processor_id(); struct cpufreq_policy *policy; - pr_debug("suspending cpu %u\n", cpu); + if (!cpufreq_driver) + return; - /* If there's no policy for the boot CPU, we have nothing to do. */ - policy = cpufreq_cpu_get(cpu); - if (!policy) - return 0; + if (!has_target()) + return; - if (cpufreq_driver->suspend) { - ret = cpufreq_driver->suspend(policy); - if (ret) - printk(KERN_ERR "cpufreq: suspend failed in ->suspend " - "step on CPU %u\n", policy->cpu); + pr_debug("%s: Suspending Governors\n", __func__); + + list_for_each_entry(policy, &cpufreq_policy_list, policy_list) { + if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP)) + pr_err("%s: Failed to stop governor for policy: %p\n", + __func__, policy); + else if (cpufreq_driver->suspend + && cpufreq_driver->suspend(policy)) + pr_err("%s: Failed to suspend driver: %p\n", __func__, + policy); } - cpufreq_cpu_put(policy); - return ret; + cpufreq_suspended = true; } /** - * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU. + * cpufreq_resume() - Resume CPUFreq governors * - * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) - * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are - * restored. It will verify that the current freq is in sync with - * what we believe it to be. This is a bit later than when it - * should be, but nonethteless it's better than calling - * cpufreq_driver->get() here which might re-enable interrupts... - * - * This function is only executed for the boot CPU. The other CPUs have not - * been turned on yet. + * Called during system wide Suspend/Hibernate cycle for resuming governors that + * are suspended with cpufreq_suspend(). */ -static void cpufreq_bp_resume(void) +void cpufreq_resume(void) { - int ret = 0; - - int cpu = smp_processor_id(); struct cpufreq_policy *policy; - pr_debug("resuming cpu %u\n", cpu); + if (!cpufreq_driver) + return; - /* If there's no policy for the boot CPU, we have nothing to do. */ - policy = cpufreq_cpu_get(cpu); - if (!policy) + if (!has_target()) return; - if (cpufreq_driver->resume) { - ret = cpufreq_driver->resume(policy); - if (ret) { - printk(KERN_ERR "cpufreq: resume failed in ->resume " - "step on CPU %u\n", policy->cpu); - goto fail; - } - } + pr_debug("%s: Resuming Governors\n", __func__); - schedule_work(&policy->update); + cpufreq_suspended = false; -fail: - cpufreq_cpu_put(policy); -} + list_for_each_entry(policy, &cpufreq_policy_list, policy_list) { + if (__cpufreq_governor(policy, CPUFREQ_GOV_START) + || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS)) + pr_err("%s: Failed to start governor for policy: %p\n", + __func__, policy); + else if (cpufreq_driver->resume + && cpufreq_driver->resume(policy)) + pr_err("%s: Failed to resume driver: %p\n", __func__, + policy); -static struct syscore_ops cpufreq_syscore_ops = { - .suspend = cpufreq_bp_suspend, - .resume = cpufreq_bp_resume, -}; + /* + * schedule call cpufreq_update_policy() for boot CPU, i.e. last + * policy in list. It will verify that the current freq is in + * sync with what we believe it to be. + */ + if (list_is_last(&policy->policy_list, &cpufreq_policy_list)) + schedule_work(&policy->update); + } +} /** * cpufreq_get_current_driver - return current driver's name @@ -1857,6 +1855,10 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, struct cpufreq_governor *gov = NULL; #endif + /* Don't start any governor operations if we are entering suspend */ + if (cpufreq_suspended) + return 0; + if (policy->governor->max_transition_latency && policy->cpuinfo.transition_latency > policy->governor->max_transition_latency) { @@ -2392,7 +2394,6 @@ static int __init cpufreq_core_init(void) cpufreq_global_kobject = kobject_create(); BUG_ON(!cpufreq_global_kobject); - register_syscore_ops(&cpufreq_syscore_ops); return 0; } diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 4d89e0e..94ed907 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -296,6 +296,14 @@ cpufreq_verify_within_cpu_limits(struct cpufreq_policy *policy) policy->cpuinfo.max_freq); } +#ifdef CONFIG_CPU_FREQ +void cpufreq_suspend(void); +void cpufreq_resume(void); +#else +static inline void cpufreq_suspend(void) {} +static inline void cpufreq_resume(void) {} +#endif + /********************************************************************* * CPUFREQ NOTIFIER INTERFACE * *********************************************************************/ -- cgit v0.10.2 From e28867eab7c0a60cddf0cb59f9f6cbbd9561425d Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 4 Mar 2014 11:00:27 +0800 Subject: cpufreq: Implement cpufreq_generic_suspend() Multiple platforms need to set CPUs to a particular frequency before suspending the system, so provide a common infrastructure for them. Those platforms only need to point their ->suspend callback pointers to the generic routine. Tested-by: Stephen Warren Signed-off-by: Viresh Kumar [rjw: Changelog] Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 289a407..61dd72b 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1567,6 +1567,32 @@ static struct subsys_interface cpufreq_interface = { .remove_dev = cpufreq_remove_dev, }; +/* + * In case platform wants some specific frequency to be configured + * during suspend.. + */ +int cpufreq_generic_suspend(struct cpufreq_policy *policy) +{ + int ret; + + if (!policy->suspend_freq) { + pr_err("%s: suspend_freq can't be zero\n", __func__); + return -EINVAL; + } + + pr_debug("%s: Setting suspend-freq: %u\n", __func__, + policy->suspend_freq); + + ret = __cpufreq_driver_target(policy, policy->suspend_freq, + CPUFREQ_RELATION_H); + if (ret) + pr_err("%s: unable to set suspend-freq: %u. err: %d\n", + __func__, policy->suspend_freq, ret); + + return ret; +} +EXPORT_SYMBOL(cpufreq_generic_suspend); + /** * cpufreq_suspend() - Suspend CPUFreq governors * diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 94ed907..325bab0 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -74,6 +74,8 @@ struct cpufreq_policy { unsigned int max; /* in kHz */ unsigned int cur; /* in kHz, only needed if cpufreq * governors are used */ + unsigned int suspend_freq; /* freq to set during suspend */ + unsigned int policy; /* see above */ struct cpufreq_governor *governor; /* see below */ void *governor_data; @@ -299,6 +301,7 @@ cpufreq_verify_within_cpu_limits(struct cpufreq_policy *policy) #ifdef CONFIG_CPU_FREQ void cpufreq_suspend(void); void cpufreq_resume(void); +int cpufreq_generic_suspend(struct cpufreq_policy *policy); #else static inline void cpufreq_suspend(void) {} static inline void cpufreq_resume(void) {} -- cgit v0.10.2 From d248bb89f94c193d5f88dbaeb32858d8d3c5762a Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 4 Mar 2014 11:00:28 +0800 Subject: cpufreq: exynos: Use cpufreq_generic_suspend() The cpufreq core now supports suspending and resuming of cpufreq drivers and governors during systems suspend and resume, so use the common infrastructure instead of defining special PM notifiers for the same thing. Signed-off-by: Viresh Kumar [rjw: Changelog] Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index fcd2914..307f02e 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -24,12 +23,8 @@ #include "exynos-cpufreq.h" static struct exynos_dvfs_info *exynos_info; - static struct regulator *arm_regulator; - static unsigned int locking_frequency; -static bool frequency_locked; -static DEFINE_MUTEX(cpufreq_lock); static int exynos_cpufreq_get_index(unsigned int freq) { @@ -134,83 +129,13 @@ out: static int exynos_target(struct cpufreq_policy *policy, unsigned int index) { - struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; - int ret = 0; - - mutex_lock(&cpufreq_lock); - - if (frequency_locked) - goto out; - - ret = exynos_cpufreq_scale(freq_table[index].frequency); - -out: - mutex_unlock(&cpufreq_lock); - - return ret; -} - -#ifdef CONFIG_PM -static int exynos_cpufreq_suspend(struct cpufreq_policy *policy) -{ - return 0; -} - -static int exynos_cpufreq_resume(struct cpufreq_policy *policy) -{ - return 0; -} -#endif - -/** - * exynos_cpufreq_pm_notifier - block CPUFREQ's activities in suspend-resume - * context - * @notifier - * @pm_event - * @v - * - * While frequency_locked == true, target() ignores every frequency but - * locking_frequency. The locking_frequency value is the initial frequency, - * which is set by the bootloader. In order to eliminate possible - * inconsistency in clock values, we save and restore frequencies during - * suspend and resume and block CPUFREQ activities. Note that the standard - * suspend/resume cannot be used as they are too deep (syscore_ops) for - * regulator actions. - */ -static int exynos_cpufreq_pm_notifier(struct notifier_block *notifier, - unsigned long pm_event, void *v) -{ - int ret; - - switch (pm_event) { - case PM_SUSPEND_PREPARE: - mutex_lock(&cpufreq_lock); - frequency_locked = true; - mutex_unlock(&cpufreq_lock); - - ret = exynos_cpufreq_scale(locking_frequency); - if (ret < 0) - return NOTIFY_BAD; - - break; - - case PM_POST_SUSPEND: - mutex_lock(&cpufreq_lock); - frequency_locked = false; - mutex_unlock(&cpufreq_lock); - break; - } - - return NOTIFY_OK; + return exynos_cpufreq_scale(exynos_info->freq_table[index].frequency); } -static struct notifier_block exynos_cpufreq_nb = { - .notifier_call = exynos_cpufreq_pm_notifier, -}; - static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) { policy->clk = exynos_info->cpu_clk; + policy->suspend_freq = locking_frequency; return cpufreq_generic_init(policy, exynos_info->freq_table, 100000); } @@ -227,8 +152,7 @@ static struct cpufreq_driver exynos_driver = { .boost_supported = true, #endif #ifdef CONFIG_PM - .suspend = exynos_cpufreq_suspend, - .resume = exynos_cpufreq_resume, + .suspend = cpufreq_generic_suspend, #endif }; @@ -263,19 +187,13 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) goto err_vdd_arm; } + /* Done here as we want to capture boot frequency */ locking_frequency = clk_get_rate(exynos_info->cpu_clk) / 1000; - register_pm_notifier(&exynos_cpufreq_nb); - - if (cpufreq_register_driver(&exynos_driver)) { - pr_err("%s: failed to register cpufreq driver\n", __func__); - goto err_cpufreq; - } - - return 0; -err_cpufreq: - unregister_pm_notifier(&exynos_cpufreq_nb); + if (!cpufreq_register_driver(&exynos_driver)) + return 0; + pr_err("%s: failed to register cpufreq driver\n", __func__); regulator_put(arm_regulator); err_vdd_arm: kfree(exynos_info); -- cgit v0.10.2 From 59625ba393881f224b4af9ab1c8ed494c643fb87 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 4 Mar 2014 11:00:29 +0800 Subject: cpufreq: s5pv210: Use cpufreq_generic_suspend() The cpufreq core now supports suspending and resuming of cpufreq drivers and governors during systems suspend and resume, so use the common infrastructure instead of defining special PM notifiers for the same thing. Signed-off-by: Viresh Kumar [rjw: Changelog] Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 55a8e9f..7242153 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -435,18 +434,6 @@ exit: return ret; } -#ifdef CONFIG_PM -static int s5pv210_cpufreq_suspend(struct cpufreq_policy *policy) -{ - return 0; -} - -static int s5pv210_cpufreq_resume(struct cpufreq_policy *policy) -{ - return 0; -} -#endif - static int check_mem_type(void __iomem *dmc_reg) { unsigned long val; @@ -502,6 +489,7 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy) s5pv210_dram_conf[1].refresh = (__raw_readl(S5P_VA_DMC1 + 0x30) * 1000); s5pv210_dram_conf[1].freq = clk_get_rate(dmc1_clk); + policy->suspend_freq = SLEEP_FREQ; return cpufreq_generic_init(policy, s5pv210_freq_table, 40000); out_dmc1: @@ -511,32 +499,6 @@ out_dmc0: return ret; } -static int s5pv210_cpufreq_notifier_event(struct notifier_block *this, - unsigned long event, void *ptr) -{ - int ret; - - switch (event) { - case PM_SUSPEND_PREPARE: - ret = cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0); - if (ret < 0) - return NOTIFY_BAD; - - /* Disable updation of cpu frequency */ - no_cpufreq_access = true; - return NOTIFY_OK; - case PM_POST_RESTORE: - case PM_POST_SUSPEND: - /* Enable updation of cpu frequency */ - no_cpufreq_access = false; - cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ, 0); - - return NOTIFY_OK; - } - - return NOTIFY_DONE; -} - static int s5pv210_cpufreq_reboot_notifier_event(struct notifier_block *this, unsigned long event, void *ptr) { @@ -558,15 +520,11 @@ static struct cpufreq_driver s5pv210_driver = { .init = s5pv210_cpu_init, .name = "s5pv210", #ifdef CONFIG_PM - .suspend = s5pv210_cpufreq_suspend, - .resume = s5pv210_cpufreq_resume, + .suspend = cpufreq_generic_suspend, + .resume = cpufreq_generic_suspend, /* We need to set SLEEP FREQ again */ #endif }; -static struct notifier_block s5pv210_cpufreq_notifier = { - .notifier_call = s5pv210_cpufreq_notifier_event, -}; - static struct notifier_block s5pv210_cpufreq_reboot_notifier = { .notifier_call = s5pv210_cpufreq_reboot_notifier_event, }; @@ -586,7 +544,6 @@ static int __init s5pv210_cpufreq_init(void) return PTR_ERR(int_regulator); } - register_pm_notifier(&s5pv210_cpufreq_notifier); register_reboot_notifier(&s5pv210_cpufreq_reboot_notifier); return cpufreq_register_driver(&s5pv210_driver); -- cgit v0.10.2 From d351cb31146833b67b6db7e46dcd6cb766d584ae Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 4 Mar 2014 11:00:30 +0800 Subject: cpufreq: Tegra: Use cpufreq_generic_suspend() The cpufreq core now supports suspending and resuming of cpufreq drivers and governors during systems suspend and resume, so use the common infrastructure instead of defining special PM notifiers for the same thing. Signed-off-by: Viresh Kumar Tested-by: Stephen Warren [rjw: Changelog] Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/tegra-cpufreq.c b/drivers/cpufreq/tegra-cpufreq.c index e652c1b..bcfed77 100644 --- a/drivers/cpufreq/tegra-cpufreq.c +++ b/drivers/cpufreq/tegra-cpufreq.c @@ -26,7 +26,6 @@ #include #include #include -#include static struct cpufreq_frequency_table freq_table[] = { { .frequency = 216000 }, @@ -47,9 +46,6 @@ static struct clk *pll_x_clk; static struct clk *pll_p_clk; static struct clk *emc_clk; -static DEFINE_MUTEX(tegra_cpu_lock); -static bool is_suspended; - static int tegra_cpu_clk_set_rate(unsigned long rate) { int ret; @@ -112,42 +108,9 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy, static int tegra_target(struct cpufreq_policy *policy, unsigned int index) { - int ret = -EBUSY; - - mutex_lock(&tegra_cpu_lock); - - if (!is_suspended) - ret = tegra_update_cpu_speed(policy, - freq_table[index].frequency); - - mutex_unlock(&tegra_cpu_lock); - return ret; + return tegra_update_cpu_speed(policy, freq_table[index].frequency); } -static int tegra_pm_notify(struct notifier_block *nb, unsigned long event, - void *dummy) -{ - mutex_lock(&tegra_cpu_lock); - if (event == PM_SUSPEND_PREPARE) { - struct cpufreq_policy *policy = cpufreq_cpu_get(0); - is_suspended = true; - pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n", - freq_table[0].frequency); - if (clk_get_rate(cpu_clk) / 1000 != freq_table[0].frequency) - tegra_update_cpu_speed(policy, freq_table[0].frequency); - cpufreq_cpu_put(policy); - } else if (event == PM_POST_SUSPEND) { - is_suspended = false; - } - mutex_unlock(&tegra_cpu_lock); - - return NOTIFY_OK; -} - -static struct notifier_block tegra_cpu_pm_notifier = { - .notifier_call = tegra_pm_notify, -}; - static int tegra_cpu_init(struct cpufreq_policy *policy) { int ret; @@ -166,10 +129,8 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) return ret; } - if (policy->cpu == 0) - register_pm_notifier(&tegra_cpu_pm_notifier); - policy->clk = cpu_clk; + policy->suspend_freq = freq_table[0].frequency; return 0; } @@ -190,6 +151,9 @@ static struct cpufreq_driver tegra_cpufreq_driver = { .exit = tegra_cpu_exit, .name = "tegra", .attr = cpufreq_generic_attr, +#ifdef CONFIG_PM + .suspend = cpufreq_generic_suspend, +#endif }; static int __init tegra_cpufreq_init(void) -- cgit v0.10.2 From e837f9b58b83a705c9c14b26c3ee29fd9870322e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 11 Mar 2014 10:03:00 -0700 Subject: cpufreq: Reformat printk() statements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add missing newlines - Coalesce format fragments - Convert printks to pr_ - Align arguments Based-on-patch-by: Sören Brinkmann Signed-off-by: Joe Perches Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 61dd72b..746f708 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -182,8 +182,8 @@ unsigned int cpufreq_generic_get(unsigned int cpu) struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); if (!policy || IS_ERR(policy->clk)) { - pr_err("%s: No %s associated to cpu: %d\n", __func__, - policy ? "clk" : "policy", cpu); + pr_err("%s: No %s associated to cpu: %d\n", + __func__, policy ? "clk" : "policy", cpu); return 0; } @@ -255,15 +255,15 @@ static void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci) if (!l_p_j_ref_freq) { l_p_j_ref = loops_per_jiffy; l_p_j_ref_freq = ci->old; - pr_debug("saving %lu as reference value for loops_per_jiffy; " - "freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq); + pr_debug("saving %lu as reference value for loops_per_jiffy; freq is %u kHz\n", + l_p_j_ref, l_p_j_ref_freq); } if ((val == CPUFREQ_POSTCHANGE && ci->old != ci->new) || (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) { loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new); - pr_debug("scaling loops_per_jiffy to %lu " - "for frequency %u kHz\n", loops_per_jiffy, ci->new); + pr_debug("scaling loops_per_jiffy to %lu for frequency %u kHz\n", + loops_per_jiffy, ci->new); } } #else @@ -283,7 +283,7 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy, freqs->flags = cpufreq_driver->flags; pr_debug("notification %u of frequency transition to %u kHz\n", - state, freqs->new); + state, freqs->new); switch (state) { @@ -295,9 +295,8 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy, if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) { if ((policy) && (policy->cpu == freqs->cpu) && (policy->cur) && (policy->cur != freqs->old)) { - pr_debug("Warning: CPU frequency is" - " %u, cpufreq assumed %u kHz.\n", - freqs->old, policy->cur); + pr_debug("Warning: CPU frequency is %u, cpufreq assumed %u kHz\n", + freqs->old, policy->cur); freqs->old = policy->cur; } } @@ -308,8 +307,8 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy, case CPUFREQ_POSTCHANGE: adjust_jiffies(CPUFREQ_POSTCHANGE, freqs); - pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new, - (unsigned long)freqs->cpu); + pr_debug("FREQ: %lu - CPU: %lu\n", + (unsigned long)freqs->new, (unsigned long)freqs->cpu); trace_cpu_frequency(freqs->new, freqs->cpu); srcu_notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs); @@ -369,13 +368,13 @@ static ssize_t store_boost(struct kobject *kobj, struct attribute *attr, return -EINVAL; if (cpufreq_boost_trigger_state(enable)) { - pr_err("%s: Cannot %s BOOST!\n", __func__, - enable ? "enable" : "disable"); + pr_err("%s: Cannot %s BOOST!\n", + __func__, enable ? "enable" : "disable"); return -EINVAL; } - pr_debug("%s: cpufreq BOOST %s\n", __func__, - enable ? "enabled" : "disabled"); + pr_debug("%s: cpufreq BOOST %s\n", + __func__, enable ? "enabled" : "disabled"); return count; } @@ -1264,7 +1263,7 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, sysfs_remove_link(&cpu_dev->kobj, "cpufreq"); ret = kobject_move(&policy->kobj, &cpu_dev->kobj); if (ret) { - pr_err("%s: Failed to move kobj: %d", __func__, ret); + pr_err("%s: Failed to move kobj: %d\n", __func__, ret); down_write(&policy->rwsem); cpumask_set_cpu(old_cpu, policy->cpus); @@ -1330,7 +1329,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, if (!frozen) { pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n", - __func__, new_cpu, cpu); + __func__, new_cpu, cpu); } } } @@ -1370,7 +1369,7 @@ static int __cpufreq_remove_dev_finish(struct device *dev, CPUFREQ_GOV_POLICY_EXIT); if (ret) { pr_err("%s: Failed to exit governor\n", - __func__); + __func__); return ret; } } @@ -1398,7 +1397,7 @@ static int __cpufreq_remove_dev_finish(struct device *dev, if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) || (ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) { pr_err("%s: Failed to start governor\n", - __func__); + __func__); return ret; } } @@ -1455,8 +1454,8 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, struct cpufreq_freqs freqs; unsigned long flags; - pr_debug("Warning: CPU frequency out of sync: cpufreq and timing " - "core thinks of %u, is %u kHz.\n", old_freq, new_freq); + pr_debug("Warning: CPU frequency out of sync: cpufreq and timing core thinks of %u, is %u kHz\n", + old_freq, new_freq); freqs.old = old_freq; freqs.new = new_freq; @@ -1780,7 +1779,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, target_freq = policy->min; pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", - policy->cpu, target_freq, relation, old_target_freq); + policy->cpu, target_freq, relation, old_target_freq); /* * This might look like a redundant call as we are checking it again @@ -1825,8 +1824,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, freqs.flags = 0; pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n", - __func__, policy->cpu, freqs.old, - freqs.new); + __func__, policy->cpu, freqs.old, freqs.new); cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); @@ -1835,7 +1833,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, retval = cpufreq_driver->target_index(policy, index); if (retval) pr_err("%s: Failed to change cpu frequency: %d\n", - __func__, retval); + __func__, retval); if (notify) cpufreq_notify_post_transition(policy, &freqs, retval); @@ -1891,11 +1889,8 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, if (!gov) return -EINVAL; else { - printk(KERN_WARNING "%s governor failed, too long" - " transition latency of HW, fallback" - " to %s governor\n", - policy->governor->name, - gov->name); + pr_warn("%s governor failed, too long transition latency of HW, fallback to %s governor\n", + policy->governor->name, gov->name); policy->governor = gov; } } @@ -1905,7 +1900,7 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, return -EINVAL; pr_debug("__cpufreq_governor for CPU %u, event %u\n", - policy->cpu, event); + policy->cpu, event); mutex_lock(&cpufreq_governor_lock); if ((policy->governor_enabled && event == CPUFREQ_GOV_START) @@ -2033,8 +2028,8 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, struct cpufreq_governor *old_gov; int ret; - pr_debug("setting new policy for CPU %u: %u - %u kHz\n", new_policy->cpu, - new_policy->min, new_policy->max); + 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(policy->cpuinfo)); @@ -2070,7 +2065,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, policy->max = new_policy->max; pr_debug("new min and max freqs are %u - %u kHz\n", - policy->min, policy->max); + policy->min, policy->max); if (cpufreq_driver->setpolicy) { policy->policy = new_policy->policy; @@ -2158,7 +2153,7 @@ int cpufreq_update_policy(unsigned int cpu) } if (!policy->cur) { - pr_debug("Driver did not initialize current freq"); + pr_debug("Driver did not initialize current freq\n"); policy->cur = new_policy.cur; } else { if (policy->cur != new_policy.cur && has_target()) @@ -2260,8 +2255,8 @@ int cpufreq_boost_trigger_state(int state) cpufreq_driver->boost_enabled = !state; write_unlock_irqrestore(&cpufreq_driver_lock, flags); - pr_err("%s: Cannot %s BOOST\n", __func__, - state ? "enable" : "disable"); + pr_err("%s: Cannot %s BOOST\n", + __func__, state ? "enable" : "disable"); } return ret; @@ -2333,7 +2328,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) ret = cpufreq_sysfs_create_file(&boost.attr); if (ret) { pr_err("%s: cannot register global BOOST sysfs file\n", - __func__); + __func__); goto err_null_driver; } } @@ -2356,7 +2351,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) /* if all ->init() calls failed, unregister */ if (ret) { pr_debug("no CPU initialized for driver %s\n", - driver_data->name); + driver_data->name); goto err_if_unreg; } } -- cgit v0.10.2 From e0b3165ba521c6824b3e9f563f38a701dfa2d8e6 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 10 Mar 2014 14:53:33 +0530 Subject: cpufreq: add 'freq_table' in struct cpufreq_policy freq table is not per CPU but per policy, so it makes more sense to keep it within struct cpufreq_policy instead of a per-cpu variable. This patch does it. Over that, there is no need to set policy->freq_table to NULL in ->exit(), as policy structure is going to be freed soon. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 18448a7..822ca03 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -855,7 +855,6 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) pr_debug("acpi_cpufreq_cpu_exit\n"); if (data) { - cpufreq_frequency_table_put_attr(policy->cpu); per_cpu(acfreq_data, policy->cpu) = NULL; acpi_processor_unregister_performance(data->acpi_data, policy->cpu); diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index 72f87e9..3d87078 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -478,7 +478,6 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy) return -ENODEV; } - cpufreq_frequency_table_put_attr(policy->cpu); put_cluster_clk_and_freq_table(cpu_dev); dev_dbg(cpu_dev, "%s: Exited, cpu: %d\n", __func__, policy->cpu); diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 746f708..dddbefb 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -191,6 +191,12 @@ unsigned int cpufreq_generic_get(unsigned int cpu) } EXPORT_SYMBOL_GPL(cpufreq_generic_get); +/* Only for cpufreq core internal use */ +struct cpufreq_policy *cpufreq_cpu_get_raw(unsigned int cpu) +{ + return per_cpu(cpufreq_cpu_data, cpu); +} + struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) { struct cpufreq_policy *policy = NULL; @@ -1031,7 +1037,6 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) up_write(&policy->rwsem); - cpufreq_frequency_table_update_policy_cpu(policy); blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_UPDATE_POLICY_CPU, policy); } diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c index 9012b8b..a0d2a42 100644 --- a/drivers/cpufreq/e_powersaver.c +++ b/drivers/cpufreq/e_powersaver.c @@ -382,7 +382,6 @@ static int eps_cpu_exit(struct cpufreq_policy *policy) unsigned int cpu = policy->cpu; /* Bye */ - cpufreq_frequency_table_put_attr(policy->cpu); kfree(eps_cpu[cpu]); eps_cpu[cpu] = NULL; return 0; diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 8e54f97..65a4770 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -91,8 +91,8 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify); /* - * Generic routine to verify policy & frequency table, requires driver to call - * cpufreq_frequency_table_get_attr() prior to it. + * Generic routine to verify policy & frequency table, requires driver to set + * policy->freq_table prior to it. */ int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy) { @@ -203,8 +203,6 @@ int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, } EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_index); -static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table); - /** * show_available_freqs - show available frequencies for the specified CPU */ @@ -212,15 +210,12 @@ static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf, bool show_boost) { unsigned int i = 0; - unsigned int cpu = policy->cpu; ssize_t count = 0; - struct cpufreq_frequency_table *table; + struct cpufreq_frequency_table *table = policy->freq_table; - if (!per_cpu(cpufreq_show_table, cpu)) + if (!table) return -ENODEV; - table = per_cpu(cpufreq_show_table, cpu); - for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) { if (table[i].frequency == CPUFREQ_ENTRY_INVALID) continue; @@ -283,49 +278,24 @@ struct freq_attr *cpufreq_generic_attr[] = { }; EXPORT_SYMBOL_GPL(cpufreq_generic_attr); -/* - * if you use these, you must assure that the frequency table is valid - * all the time between get_attr and put_attr! - */ -void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, - unsigned int cpu) -{ - pr_debug("setting show_table for cpu %u to %p\n", cpu, table); - per_cpu(cpufreq_show_table, cpu) = table; -} -EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_attr); - -void cpufreq_frequency_table_put_attr(unsigned int cpu) -{ - pr_debug("clearing show_table for cpu %u\n", cpu); - per_cpu(cpufreq_show_table, cpu) = NULL; -} -EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr); - int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table) { int ret = cpufreq_frequency_table_cpuinfo(policy, table); if (!ret) - cpufreq_frequency_table_get_attr(table, policy->cpu); + policy->freq_table = table; return ret; } EXPORT_SYMBOL_GPL(cpufreq_table_validate_and_show); -void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy) -{ - pr_debug("Updating show_table for new_cpu %u from last_cpu %u\n", - policy->cpu, policy->last_cpu); - per_cpu(cpufreq_show_table, policy->cpu) = per_cpu(cpufreq_show_table, - policy->last_cpu); - per_cpu(cpufreq_show_table, policy->last_cpu) = NULL; -} +struct cpufreq_policy *cpufreq_cpu_get_raw(unsigned int cpu); struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu) { - return per_cpu(cpufreq_show_table, cpu); + struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu); + return policy ? policy->freq_table : NULL; } EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table); diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c index 53c6ac6..a22b5d1 100644 --- a/drivers/cpufreq/ia64-acpi-cpufreq.c +++ b/drivers/cpufreq/ia64-acpi-cpufreq.c @@ -332,7 +332,6 @@ acpi_cpufreq_cpu_exit ( pr_debug("acpi_cpufreq_cpu_exit\n"); if (data) { - cpufreq_frequency_table_put_attr(policy->cpu); acpi_io_data[policy->cpu] = NULL; acpi_processor_unregister_performance(&data->acpi_data, policy->cpu); diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c index b6581ab..a3588d6 100644 --- a/drivers/cpufreq/loongson2_cpufreq.c +++ b/drivers/cpufreq/loongson2_cpufreq.c @@ -104,7 +104,6 @@ static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) static int loongson2_cpufreq_exit(struct cpufreq_policy *policy) { - cpufreq_frequency_table_put_attr(policy->cpu); clk_put(policy->clk); return 0; } diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 590f5b6..5f69c9a 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c @@ -143,7 +143,6 @@ fail: static int omap_cpu_exit(struct cpufreq_policy *policy) { - cpufreq_frequency_table_put_attr(policy->cpu); freq_table_free(); clk_put(policy->clk); return 0; diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c index 0426008..6a2b7d3 100644 --- a/drivers/cpufreq/pasemi-cpufreq.c +++ b/drivers/cpufreq/pasemi-cpufreq.c @@ -234,7 +234,6 @@ static int pas_cpufreq_cpu_exit(struct cpufreq_policy *policy) if (sdcpwr_mapbase) iounmap(sdcpwr_mapbase); - cpufreq_frequency_table_put_attr(policy->cpu); return 0; } diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index b9a444e..ce27e6c 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c @@ -231,7 +231,6 @@ static int powernow_k6_cpu_exit(struct cpufreq_policy *policy) if (i == max_multiplier) powernow_k6_target(policy, i); } - cpufreq_frequency_table_put_attr(policy->cpu); return 0; } diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index 946708a..0e68e02 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c @@ -664,8 +664,6 @@ static int powernow_cpu_init(struct cpufreq_policy *policy) static int powernow_cpu_exit(struct cpufreq_policy *policy) { - cpufreq_frequency_table_put_attr(policy->cpu); - #ifdef CONFIG_X86_POWERNOW_K7_ACPI if (acpi_processor_perf) { acpi_processor_unregister_performance(acpi_processor_perf, 0); diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 6684e03..27eb2be 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -1164,8 +1164,6 @@ static int powernowk8_cpu_exit(struct cpufreq_policy *pol) powernow_k8_cpu_exit_acpi(data); - cpufreq_frequency_table_put_attr(pol->cpu); - kfree(data->powernow_table); kfree(data); for_each_cpu(cpu, pol->cpus) diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c index 051000f..037949d 100644 --- a/drivers/cpufreq/ppc-corenet-cpufreq.c +++ b/drivers/cpufreq/ppc-corenet-cpufreq.c @@ -228,7 +228,6 @@ static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy) struct cpu_data *data = per_cpu(cpu_data, policy->cpu); unsigned int cpu; - cpufreq_frequency_table_put_attr(policy->cpu); of_node_put(data->parent); kfree(data->table); kfree(data); diff --git a/drivers/cpufreq/sh-cpufreq.c b/drivers/cpufreq/sh-cpufreq.c index 387af12..696170e 100644 --- a/drivers/cpufreq/sh-cpufreq.c +++ b/drivers/cpufreq/sh-cpufreq.c @@ -143,7 +143,6 @@ static int sh_cpufreq_cpu_exit(struct cpufreq_policy *policy) unsigned int cpu = policy->cpu; struct clk *cpuclk = &per_cpu(sh_cpuclk, cpu); - cpufreq_frequency_table_put_attr(cpu); clk_put(cpuclk); return 0; diff --git a/drivers/cpufreq/sparc-us2e-cpufreq.c b/drivers/cpufreq/sparc-us2e-cpufreq.c index 62aa23e..b73feeb 100644 --- a/drivers/cpufreq/sparc-us2e-cpufreq.c +++ b/drivers/cpufreq/sparc-us2e-cpufreq.c @@ -301,10 +301,8 @@ static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy) static int us2e_freq_cpu_exit(struct cpufreq_policy *policy) { - if (cpufreq_us2e_driver) { - cpufreq_frequency_table_put_attr(policy->cpu); + if (cpufreq_us2e_driver) us2e_freq_target(policy, 0); - } return 0; } diff --git a/drivers/cpufreq/sparc-us3-cpufreq.c b/drivers/cpufreq/sparc-us3-cpufreq.c index 724ffbd..9bb42ba 100644 --- a/drivers/cpufreq/sparc-us3-cpufreq.c +++ b/drivers/cpufreq/sparc-us3-cpufreq.c @@ -156,10 +156,8 @@ static int __init us3_freq_cpu_init(struct cpufreq_policy *policy) static int us3_freq_cpu_exit(struct cpufreq_policy *policy) { - if (cpufreq_us3_driver) { - cpufreq_frequency_table_put_attr(policy->cpu); + if (cpufreq_us3_driver) us3_freq_target(policy, 0); - } return 0; } diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c index 4e1daca..6723f03 100644 --- a/drivers/cpufreq/speedstep-centrino.c +++ b/drivers/cpufreq/speedstep-centrino.c @@ -406,8 +406,6 @@ static int centrino_cpu_exit(struct cpufreq_policy *policy) if (!per_cpu(centrino_model, cpu)) return -ENODEV; - cpufreq_frequency_table_put_attr(cpu); - per_cpu(centrino_model, cpu) = NULL; return 0; diff --git a/drivers/cpufreq/tegra-cpufreq.c b/drivers/cpufreq/tegra-cpufreq.c index bcfed77..63f0059 100644 --- a/drivers/cpufreq/tegra-cpufreq.c +++ b/drivers/cpufreq/tegra-cpufreq.c @@ -136,7 +136,6 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) static int tegra_cpu_exit(struct cpufreq_policy *policy) { - cpufreq_frequency_table_put_attr(policy->cpu); clk_disable_unprepare(cpu_clk); clk_disable_unprepare(emc_clk); return 0; diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 325bab0..7934135 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -85,6 +85,7 @@ struct cpufreq_policy { * called, but you're in IRQ context */ struct cpufreq_real_policy user_policy; + struct cpufreq_frequency_table *freq_table; struct list_head policy_list; struct kobject kobj; @@ -474,7 +475,6 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy, unsigned int freq); -void cpufreq_frequency_table_update_policy_cpu(struct cpufreq_policy *policy); ssize_t cpufreq_show_cpus(const struct cpumask *mask, char *buf); #ifdef CONFIG_CPU_FREQ @@ -501,9 +501,6 @@ struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu); /* the following are really really optional */ extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs; extern struct freq_attr *cpufreq_generic_attr[]; -void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, - unsigned int cpu); -void cpufreq_frequency_table_put_attr(unsigned int cpu); int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table); @@ -513,7 +510,6 @@ int cpufreq_generic_init(struct cpufreq_policy *policy, unsigned int transition_latency); static inline int cpufreq_generic_exit(struct cpufreq_policy *policy) { - cpufreq_frequency_table_put_attr(policy->cpu); return 0; } -- cgit v0.10.2 From 979d86fac5e6dbf5c939e9a2a9fe294c9e05e42f Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 10 Mar 2014 14:53:34 +0530 Subject: cpufreq: Remove cpufreq_generic_exit() cpufreq_generic_exit() is empty now and can be deleted. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/blackfin-cpufreq.c b/drivers/cpufreq/blackfin-cpufreq.c index e9e63fc..a9f8e5b 100644 --- a/drivers/cpufreq/blackfin-cpufreq.c +++ b/drivers/cpufreq/blackfin-cpufreq.c @@ -195,7 +195,6 @@ static struct cpufreq_driver bfin_driver = { .target_index = bfin_target, .get = bfin_getfreq_khz, .init = __bfin_cpu_init, - .exit = cpufreq_generic_exit, .name = "bfin cpufreq", .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index 0c12ffc..1bf6bba 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -109,7 +109,6 @@ static struct cpufreq_driver cpu0_cpufreq_driver = { .target_index = cpu0_set_target, .get = cpufreq_generic_get, .init = cpu0_cpufreq_init, - .exit = cpufreq_generic_exit, .name = "generic_cpu0", .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/cris-artpec3-cpufreq.c b/drivers/cpufreq/cris-artpec3-cpufreq.c index 8655904..d457303 100644 --- a/drivers/cpufreq/cris-artpec3-cpufreq.c +++ b/drivers/cpufreq/cris-artpec3-cpufreq.c @@ -57,7 +57,6 @@ static struct cpufreq_driver cris_freq_driver = { .verify = cpufreq_generic_frequency_table_verify, .target_index = cris_freq_target, .init = cris_freq_cpu_init, - .exit = cpufreq_generic_exit, .name = "cris_freq", .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/cris-etraxfs-cpufreq.c b/drivers/cpufreq/cris-etraxfs-cpufreq.c index 26d940d..13c3361 100644 --- a/drivers/cpufreq/cris-etraxfs-cpufreq.c +++ b/drivers/cpufreq/cris-etraxfs-cpufreq.c @@ -57,7 +57,6 @@ static struct cpufreq_driver cris_freq_driver = { .verify = cpufreq_generic_frequency_table_verify, .target_index = cris_freq_target, .init = cris_freq_cpu_init, - .exit = cpufreq_generic_exit, .name = "cris_freq", .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c index 2cf3384..28a16dc 100644 --- a/drivers/cpufreq/davinci-cpufreq.c +++ b/drivers/cpufreq/davinci-cpufreq.c @@ -125,7 +125,6 @@ static struct cpufreq_driver davinci_driver = { .target_index = davinci_target, .get = cpufreq_generic_get, .init = davinci_cpu_init, - .exit = cpufreq_generic_exit, .name = "davinci", .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c index de08acf..c987e94 100644 --- a/drivers/cpufreq/elanfreq.c +++ b/drivers/cpufreq/elanfreq.c @@ -198,7 +198,6 @@ static struct cpufreq_driver elanfreq_driver = { .verify = cpufreq_generic_frequency_table_verify, .target_index = elanfreq_target, .init = elanfreq_cpu_init, - .exit = cpufreq_generic_exit, .name = "elanfreq", .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index 307f02e..f99cfe2 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c @@ -145,7 +145,6 @@ static struct cpufreq_driver exynos_driver = { .target_index = exynos_target, .get = cpufreq_generic_get, .init = exynos_cpufreq_cpu_init, - .exit = cpufreq_generic_exit, .name = "exynos_cpufreq", .attr = cpufreq_generic_attr, #ifdef CONFIG_ARM_EXYNOS_CPU_FREQ_BOOST_SW diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index 49b75601..7f776aa 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c @@ -312,7 +312,6 @@ static struct cpufreq_driver exynos_driver = { .target_index = exynos_target, .get = cpufreq_generic_get, .init = exynos_cpufreq_cpu_init, - .exit = cpufreq_generic_exit, .name = CPUFREQ_NAME, .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index ce69059..e27fca8 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -144,7 +144,6 @@ static struct cpufreq_driver imx6q_cpufreq_driver = { .target_index = imx6q_set_target, .get = cpufreq_generic_get, .init = imx6q_cpufreq_init, - .exit = cpufreq_generic_exit, .name = "imx6q-cpufreq", .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/kirkwood-cpufreq.c b/drivers/cpufreq/kirkwood-cpufreq.c index eb7abe3..3d114bc 100644 --- a/drivers/cpufreq/kirkwood-cpufreq.c +++ b/drivers/cpufreq/kirkwood-cpufreq.c @@ -102,7 +102,6 @@ static struct cpufreq_driver kirkwood_cpufreq_driver = { .verify = cpufreq_generic_frequency_table_verify, .target_index = kirkwood_cpufreq_target, .init = kirkwood_cpufreq_cpu_init, - .exit = cpufreq_generic_exit, .name = "kirkwood-cpufreq", .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index 45bafdd..7b94da3 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -913,7 +913,6 @@ static struct cpufreq_driver longhaul_driver = { .target_index = longhaul_target, .get = longhaul_get, .init = longhaul_cpu_init, - .exit = cpufreq_generic_exit, .name = "longhaul", .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c index 3d1cba9..74f593e 100644 --- a/drivers/cpufreq/p4-clockmod.c +++ b/drivers/cpufreq/p4-clockmod.c @@ -237,7 +237,6 @@ static struct cpufreq_driver p4clockmod_driver = { .verify = cpufreq_generic_frequency_table_verify, .target_index = cpufreq_p4_target, .init = cpufreq_p4_cpu_init, - .exit = cpufreq_generic_exit, .get = cpufreq_p4_get, .name = "p4-clockmod", .attr = cpufreq_generic_attr, diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c index e42ca9c..af7b1ca 100644 --- a/drivers/cpufreq/ppc_cbe_cpufreq.c +++ b/drivers/cpufreq/ppc_cbe_cpufreq.c @@ -141,7 +141,6 @@ static struct cpufreq_driver cbe_cpufreq_driver = { .verify = cpufreq_generic_frequency_table_verify, .target_index = cbe_cpufreq_target, .init = cbe_cpufreq_cpu_init, - .exit = cpufreq_generic_exit, .name = "cbe-cpufreq", .flags = CPUFREQ_CONST_LOOPS, }; diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c index a9195a8..e24269a 100644 --- a/drivers/cpufreq/pxa2xx-cpufreq.c +++ b/drivers/cpufreq/pxa2xx-cpufreq.c @@ -427,7 +427,6 @@ static struct cpufreq_driver pxa_cpufreq_driver = { .verify = cpufreq_generic_frequency_table_verify, .target_index = pxa_set_target, .init = pxa_cpufreq_init, - .exit = cpufreq_generic_exit, .get = pxa_cpufreq_get, .name = "PXA2xx", }; diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpufreq.c index 3785687..a012759 100644 --- a/drivers/cpufreq/pxa3xx-cpufreq.c +++ b/drivers/cpufreq/pxa3xx-cpufreq.c @@ -205,7 +205,6 @@ static struct cpufreq_driver pxa3xx_cpufreq_driver = { .verify = cpufreq_generic_frequency_table_verify, .target_index = pxa3xx_cpufreq_set, .init = pxa3xx_cpufreq_init, - .exit = cpufreq_generic_exit, .get = pxa3xx_cpufreq_get, .name = "pxa3xx-cpufreq", }; diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c index 6adb354..69371bf 100644 --- a/drivers/cpufreq/sc520_freq.c +++ b/drivers/cpufreq/sc520_freq.c @@ -93,7 +93,6 @@ static struct cpufreq_driver sc520_freq_driver = { .verify = cpufreq_generic_frequency_table_verify, .target_index = sc520_freq_target, .init = sc520_freq_cpu_init, - .exit = cpufreq_generic_exit, .name = "sc520_freq", .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index 5c86e3f..410b54a 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c @@ -163,7 +163,6 @@ static struct cpufreq_driver spear_cpufreq_driver = { .target_index = spear_cpufreq_target, .get = cpufreq_generic_get, .init = spear_cpufreq_init, - .exit = cpufreq_generic_exit, .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c index 7639b2b..394ac15 100644 --- a/drivers/cpufreq/speedstep-ich.c +++ b/drivers/cpufreq/speedstep-ich.c @@ -311,7 +311,6 @@ static struct cpufreq_driver speedstep_driver = { .verify = cpufreq_generic_frequency_table_verify, .target_index = speedstep_target, .init = speedstep_cpu_init, - .exit = cpufreq_generic_exit, .get = speedstep_get, .attr = cpufreq_generic_attr, }; diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c index 998c17b..db5d274d 100644 --- a/drivers/cpufreq/speedstep-smi.c +++ b/drivers/cpufreq/speedstep-smi.c @@ -280,7 +280,6 @@ static struct cpufreq_driver speedstep_driver = { .verify = cpufreq_generic_frequency_table_verify, .target_index = speedstep_target, .init = speedstep_cpu_init, - .exit = cpufreq_generic_exit, .get = speedstep_get, .resume = speedstep_resume, .attr = cpufreq_generic_attr, diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 7934135..31c431e 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -508,9 +508,4 @@ unsigned int cpufreq_generic_get(unsigned int cpu); int cpufreq_generic_init(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table, unsigned int transition_latency); -static inline int cpufreq_generic_exit(struct cpufreq_policy *policy) -{ - return 0; -} - #endif /* _LINUX_CPUFREQ_H */ -- cgit v0.10.2 From 96bbbe4a2a5b13c440a19dd7a5ff33de3303aac4 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 10 Mar 2014 14:53:35 +0530 Subject: cpufreq: Remove unnecessary variable/parameter 'frozen' We have used 'frozen' variable/function parameter at many places to distinguish between CPU offline/online on suspend/resume vs sysfs removals. We now have another variable cpufreq_suspended which can be used in these cases, so we can get rid of all those variables or function parameters. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index dddbefb..571723b 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1041,13 +1041,13 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) CPUFREQ_UPDATE_POLICY_CPU, policy); } -static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, - bool frozen) +static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) { unsigned int j, cpu = dev->id; int ret = -ENOMEM; struct cpufreq_policy *policy; unsigned long flags; + bool recover_policy = cpufreq_suspended; #ifdef CONFIG_HOTPLUG_CPU struct cpufreq_policy *tpolicy; #endif @@ -1088,9 +1088,9 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, * Restore the saved policy when doing light-weight init and fall back * to the full init if that fails. */ - policy = frozen ? cpufreq_policy_restore(cpu) : NULL; + policy = recover_policy ? cpufreq_policy_restore(cpu) : NULL; if (!policy) { - frozen = false; + recover_policy = false; policy = cpufreq_policy_alloc(); if (!policy) goto nomem_out; @@ -1102,7 +1102,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, * the creation of a brand new one. So we need to perform this update * by invoking update_policy_cpu(). */ - if (frozen && cpu != policy->cpu) + if (recover_policy && cpu != policy->cpu) update_policy_cpu(policy, cpu); else policy->cpu = cpu; @@ -1130,7 +1130,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, */ cpumask_and(policy->cpus, policy->cpus, cpu_online_mask); - if (!frozen) { + if (!recover_policy) { policy->user_policy.min = policy->min; policy->user_policy.max = policy->max; } @@ -1192,7 +1192,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, blocking_notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_START, policy); - if (!frozen) { + if (!recover_policy) { ret = cpufreq_add_dev_interface(policy, dev); if (ret) goto err_out_unregister; @@ -1206,7 +1206,7 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, cpufreq_init_policy(policy); - if (!frozen) { + if (!recover_policy) { policy->user_policy.policy = policy->policy; policy->user_policy.governor = policy->governor; } @@ -1229,7 +1229,7 @@ err_get_freq: if (cpufreq_driver->exit) cpufreq_driver->exit(policy); err_set_policy_cpu: - if (frozen) { + if (recover_policy) { /* Do not leave stale fallback data behind. */ per_cpu(cpufreq_cpu_data_fallback, cpu) = NULL; cpufreq_policy_put_kobj(policy); @@ -1253,7 +1253,7 @@ nomem_out: */ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) { - return __cpufreq_add_dev(dev, sif, false); + return __cpufreq_add_dev(dev, sif); } static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, @@ -1284,8 +1284,7 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy, } static int __cpufreq_remove_dev_prepare(struct device *dev, - struct subsys_interface *sif, - bool frozen) + struct subsys_interface *sif) { unsigned int cpu = dev->id, cpus; int new_cpu, ret; @@ -1299,7 +1298,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, policy = per_cpu(cpufreq_cpu_data, cpu); /* Save the policy somewhere when doing a light-weight tear-down */ - if (frozen) + if (cpufreq_suspended) per_cpu(cpufreq_cpu_data_fallback, cpu) = policy; write_unlock_irqrestore(&cpufreq_driver_lock, flags); @@ -1332,7 +1331,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, if (new_cpu >= 0) { update_policy_cpu(policy, new_cpu); - if (!frozen) { + if (!cpufreq_suspended) { pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n", __func__, new_cpu, cpu); } @@ -1343,8 +1342,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, } static int __cpufreq_remove_dev_finish(struct device *dev, - struct subsys_interface *sif, - bool frozen) + struct subsys_interface *sif) { unsigned int cpu = dev->id, cpus; int ret; @@ -1379,7 +1377,7 @@ static int __cpufreq_remove_dev_finish(struct device *dev, } } - if (!frozen) + if (!cpufreq_suspended) cpufreq_policy_put_kobj(policy); /* @@ -1395,7 +1393,7 @@ static int __cpufreq_remove_dev_finish(struct device *dev, list_del(&policy->policy_list); write_unlock_irqrestore(&cpufreq_driver_lock, flags); - if (!frozen) + if (!cpufreq_suspended) cpufreq_policy_free(policy); } else { if (has_target()) { @@ -1425,10 +1423,10 @@ static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif) if (cpu_is_offline(cpu)) return 0; - ret = __cpufreq_remove_dev_prepare(dev, sif, false); + ret = __cpufreq_remove_dev_prepare(dev, sif); if (!ret) - ret = __cpufreq_remove_dev_finish(dev, sif, false); + ret = __cpufreq_remove_dev_finish(dev, sif); return ret; } @@ -2182,29 +2180,24 @@ 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) { - - if (action & CPU_TASKS_FROZEN) - frozen = true; - switch (action & ~CPU_TASKS_FROZEN) { case CPU_ONLINE: - __cpufreq_add_dev(dev, NULL, frozen); + __cpufreq_add_dev(dev, NULL); break; case CPU_DOWN_PREPARE: - __cpufreq_remove_dev_prepare(dev, NULL, frozen); + __cpufreq_remove_dev_prepare(dev, NULL); break; case CPU_POST_DEAD: - __cpufreq_remove_dev_finish(dev, NULL, frozen); + __cpufreq_remove_dev_finish(dev, NULL); break; case CPU_DOWN_FAILED: - __cpufreq_add_dev(dev, NULL, frozen); + __cpufreq_add_dev(dev, NULL); break; } } -- cgit v0.10.2 From 2449d33a40553504867f407dd713e9bcf6f9fe24 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 10 Mar 2014 15:43:18 +0530 Subject: cpufreq: SPEAr: Instantiate as platform_driver As multiplatform build is being adopted by more and more ARM platforms, initcall function should be used very carefully. For example, when SPEAr cpufreq driver is enabled on a kernel booted on a non-SPEAr board, we will get following boot time error: spear_cpufreq: Invalid cpufreq_tbl To eliminate this undesired the effect, the patch changes SPEAr driver to have it instantiated as a platform_driver. Then it will only run on platforms that create the platform_device "spear-cpufreq". This patch also creates platform node for SPEAr13xx boards. Reported-by: Josh Cartwright Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki diff --git a/arch/arm/mach-spear/spear1310.c b/arch/arm/mach-spear/spear1310.c index 7ad0030..824b12a 100644 --- a/arch/arm/mach-spear/spear1310.c +++ b/arch/arm/mach-spear/spear1310.c @@ -28,6 +28,7 @@ static void __init spear1310_dt_init(void) { of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + platform_device_register_simple("spear-cpufreq", -1, NULL, 0); } static const char * const spear1310_dt_board_compat[] = { diff --git a/arch/arm/mach-spear/spear1340.c b/arch/arm/mach-spear/spear1340.c index 3fb6834..7b6bff7 100644 --- a/arch/arm/mach-spear/spear1340.c +++ b/arch/arm/mach-spear/spear1340.c @@ -143,6 +143,7 @@ static void __init spear1340_dt_init(void) { of_platform_populate(NULL, of_default_bus_match_table, spear1340_auxdata_lookup, NULL); + platform_device_register_simple("spear-cpufreq", -1, NULL, 0); } static const char * const spear1340_dt_board_compat[] = { diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index 410b54a..4cfdcff 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -166,7 +167,7 @@ static struct cpufreq_driver spear_cpufreq_driver = { .attr = cpufreq_generic_attr, }; -static int spear_cpufreq_driver_init(void) +static int spear_cpufreq_probe(struct platform_device *pdev) { struct device_node *np; const struct property *prop; @@ -234,7 +235,15 @@ out_put_node: of_node_put(np); return ret; } -late_initcall(spear_cpufreq_driver_init); + +static struct platform_driver spear_cpufreq_platdrv = { + .driver = { + .name = "spear-cpufreq", + .owner = THIS_MODULE, + }, + .probe = spear_cpufreq_probe, +}; +module_platform_driver(spear_cpufreq_platdrv); MODULE_AUTHOR("Deepak Sikri "); MODULE_DESCRIPTION("SPEAr CPUFreq driver"); -- cgit v0.10.2