diff options
| -rw-r--r-- | drivers/cpufreq/at32ap-cpufreq.c | 17 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq-cpu0.c | 8 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 26 | ||||
| -rw-r--r-- | drivers/cpufreq/davinci-cpufreq.c | 14 | ||||
| -rw-r--r-- | drivers/cpufreq/dbx500-cpufreq.c | 19 | ||||
| -rw-r--r-- | drivers/cpufreq/exynos-cpufreq.c | 10 | ||||
| -rw-r--r-- | drivers/cpufreq/exynos5440-cpufreq.c | 33 | ||||
| -rw-r--r-- | drivers/cpufreq/imx6q-cpufreq.c | 8 | ||||
| -rw-r--r-- | drivers/cpufreq/loongson2_cpufreq.c | 15 | ||||
| -rw-r--r-- | drivers/cpufreq/omap-cpufreq.c | 32 | ||||
| -rw-r--r-- | drivers/cpufreq/ppc-corenet-cpufreq.c | 17 | ||||
| -rw-r--r-- | drivers/cpufreq/s3c24xx-cpufreq.c | 10 | ||||
| -rw-r--r-- | drivers/cpufreq/s3c64xx-cpufreq.c | 33 | ||||
| -rw-r--r-- | drivers/cpufreq/s5pv210-cpufreq.c | 21 | ||||
| -rw-r--r-- | drivers/cpufreq/spear-cpufreq.c | 8 | ||||
| -rw-r--r-- | drivers/cpufreq/tegra-cpufreq.c | 48 | ||||
| -rw-r--r-- | drivers/cpufreq/unicore2-cpufreq.c | 19 | ||||
| -rw-r--r-- | include/linux/cpufreq.h | 3 |
18 files changed, 112 insertions, 229 deletions
diff --git a/drivers/cpufreq/at32ap-cpufreq.c b/drivers/cpufreq/at32ap-cpufreq.c index 7c03dd84f66a..a1c79f549edb 100644 --- a/drivers/cpufreq/at32ap-cpufreq.c +++ b/drivers/cpufreq/at32ap-cpufreq.c | |||
| @@ -21,17 +21,8 @@ | |||
| 21 | #include <linux/export.h> | 21 | #include <linux/export.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | 23 | ||
| 24 | static struct clk *cpuclk; | ||
| 25 | static struct cpufreq_frequency_table *freq_table; | 24 | static struct cpufreq_frequency_table *freq_table; |
| 26 | 25 | ||
| 27 | static unsigned int at32_get_speed(unsigned int cpu) | ||
| 28 | { | ||
| 29 | /* No SMP support */ | ||
| 30 | if (cpu) | ||
| 31 | return 0; | ||
| 32 | return (unsigned int)((clk_get_rate(cpuclk) + 500) / 1000); | ||
| 33 | } | ||
| 34 | |||
| 35 | static unsigned int ref_freq; | 26 | static unsigned int ref_freq; |
| 36 | static unsigned long loops_per_jiffy_ref; | 27 | static unsigned long loops_per_jiffy_ref; |
| 37 | 28 | ||
| @@ -39,7 +30,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
| 39 | { | 30 | { |
| 40 | unsigned int old_freq, new_freq; | 31 | unsigned int old_freq, new_freq; |
| 41 | 32 | ||
| 42 | old_freq = at32_get_speed(0); | 33 | old_freq = policy->cur; |
| 43 | new_freq = freq_table[index].frequency; | 34 | new_freq = freq_table[index].frequency; |
| 44 | 35 | ||
| 45 | if (!ref_freq) { | 36 | if (!ref_freq) { |
| @@ -50,7 +41,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
| 50 | if (old_freq < new_freq) | 41 | if (old_freq < new_freq) |
| 51 | boot_cpu_data.loops_per_jiffy = cpufreq_scale( | 42 | boot_cpu_data.loops_per_jiffy = cpufreq_scale( |
| 52 | loops_per_jiffy_ref, ref_freq, new_freq); | 43 | loops_per_jiffy_ref, ref_freq, new_freq); |
| 53 | clk_set_rate(cpuclk, new_freq * 1000); | 44 | clk_set_rate(policy->clk, new_freq * 1000); |
| 54 | if (new_freq < old_freq) | 45 | if (new_freq < old_freq) |
| 55 | boot_cpu_data.loops_per_jiffy = cpufreq_scale( | 46 | boot_cpu_data.loops_per_jiffy = cpufreq_scale( |
| 56 | loops_per_jiffy_ref, ref_freq, new_freq); | 47 | loops_per_jiffy_ref, ref_freq, new_freq); |
| @@ -61,6 +52,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
| 61 | static int at32_cpufreq_driver_init(struct cpufreq_policy *policy) | 52 | static int at32_cpufreq_driver_init(struct cpufreq_policy *policy) |
| 62 | { | 53 | { |
| 63 | unsigned int frequency, rate, min_freq; | 54 | unsigned int frequency, rate, min_freq; |
| 55 | static struct clk *cpuclk; | ||
| 64 | int retval, steps, i; | 56 | int retval, steps, i; |
| 65 | 57 | ||
| 66 | if (policy->cpu != 0) | 58 | if (policy->cpu != 0) |
| @@ -103,6 +95,7 @@ static int at32_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
| 103 | frequency /= 2; | 95 | frequency /= 2; |
| 104 | } | 96 | } |
| 105 | 97 | ||
| 98 | policy->clk = cpuclk; | ||
| 106 | freq_table[steps - 1].frequency = CPUFREQ_TABLE_END; | 99 | freq_table[steps - 1].frequency = CPUFREQ_TABLE_END; |
| 107 | 100 | ||
| 108 | retval = cpufreq_table_validate_and_show(policy, freq_table); | 101 | retval = cpufreq_table_validate_and_show(policy, freq_table); |
| @@ -123,7 +116,7 @@ static struct cpufreq_driver at32_driver = { | |||
| 123 | .init = at32_cpufreq_driver_init, | 116 | .init = at32_cpufreq_driver_init, |
| 124 | .verify = cpufreq_generic_frequency_table_verify, | 117 | .verify = cpufreq_generic_frequency_table_verify, |
| 125 | .target_index = at32_set_target, | 118 | .target_index = at32_set_target, |
| 126 | .get = at32_get_speed, | 119 | .get = cpufreq_generic_get, |
| 127 | .flags = CPUFREQ_STICKY, | 120 | .flags = CPUFREQ_STICKY, |
| 128 | }; | 121 | }; |
| 129 | 122 | ||
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index 0faf756f6197..bb7b3082efb3 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c | |||
| @@ -30,11 +30,6 @@ static struct clk *cpu_clk; | |||
| 30 | static struct regulator *cpu_reg; | 30 | static struct regulator *cpu_reg; |
| 31 | static struct cpufreq_frequency_table *freq_table; | 31 | static struct cpufreq_frequency_table *freq_table; |
| 32 | 32 | ||
| 33 | static unsigned int cpu0_get_speed(unsigned int cpu) | ||
| 34 | { | ||
| 35 | return clk_get_rate(cpu_clk) / 1000; | ||
| 36 | } | ||
| 37 | |||
| 38 | static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index) | 33 | static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index) |
| 39 | { | 34 | { |
| 40 | struct dev_pm_opp *opp; | 35 | struct dev_pm_opp *opp; |
| @@ -100,6 +95,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
| 100 | 95 | ||
| 101 | static int cpu0_cpufreq_init(struct cpufreq_policy *policy) | 96 | static int cpu0_cpufreq_init(struct cpufreq_policy *policy) |
| 102 | { | 97 | { |
| 98 | policy->clk = cpu_clk; | ||
| 103 | return cpufreq_generic_init(policy, freq_table, transition_latency); | 99 | return cpufreq_generic_init(policy, freq_table, transition_latency); |
| 104 | } | 100 | } |
| 105 | 101 | ||
| @@ -107,7 +103,7 @@ static struct cpufreq_driver cpu0_cpufreq_driver = { | |||
| 107 | .flags = CPUFREQ_STICKY, | 103 | .flags = CPUFREQ_STICKY, |
| 108 | .verify = cpufreq_generic_frequency_table_verify, | 104 | .verify = cpufreq_generic_frequency_table_verify, |
| 109 | .target_index = cpu0_set_target, | 105 | .target_index = cpu0_set_target, |
| 110 | .get = cpu0_get_speed, | 106 | .get = cpufreq_generic_get, |
| 111 | .init = cpu0_cpufreq_init, | 107 | .init = cpu0_cpufreq_init, |
| 112 | .exit = cpufreq_generic_exit, | 108 | .exit = cpufreq_generic_exit, |
| 113 | .name = "generic_cpu0", | 109 | .name = "generic_cpu0", |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1afbe52d6782..d7efdfe0c12c 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -176,6 +176,20 @@ int cpufreq_generic_init(struct cpufreq_policy *policy, | |||
| 176 | } | 176 | } |
| 177 | EXPORT_SYMBOL_GPL(cpufreq_generic_init); | 177 | EXPORT_SYMBOL_GPL(cpufreq_generic_init); |
| 178 | 178 | ||
| 179 | unsigned int cpufreq_generic_get(unsigned int cpu) | ||
| 180 | { | ||
| 181 | struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu); | ||
| 182 | |||
| 183 | if (!policy || IS_ERR(policy->clk)) { | ||
| 184 | pr_err("%s: No %s associated to cpu: %d\n", __func__, | ||
| 185 | policy ? "clk" : "policy", cpu); | ||
| 186 | return 0; | ||
| 187 | } | ||
| 188 | |||
| 189 | return clk_get_rate(policy->clk) / 1000; | ||
| 190 | } | ||
| 191 | EXPORT_SYMBOL_GPL(cpufreq_generic_get); | ||
| 192 | |||
| 179 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) | 193 | struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu) |
| 180 | { | 194 | { |
| 181 | struct cpufreq_policy *policy = NULL; | 195 | struct cpufreq_policy *policy = NULL; |
| @@ -1068,6 +1082,11 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | |||
| 1068 | goto err_set_policy_cpu; | 1082 | goto err_set_policy_cpu; |
| 1069 | } | 1083 | } |
| 1070 | 1084 | ||
| 1085 | write_lock_irqsave(&cpufreq_driver_lock, flags); | ||
| 1086 | for_each_cpu(j, policy->cpus) | ||
| 1087 | per_cpu(cpufreq_cpu_data, j) = policy; | ||
| 1088 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
| 1089 | |||
| 1071 | if (cpufreq_driver->get) { | 1090 | if (cpufreq_driver->get) { |
| 1072 | policy->cur = cpufreq_driver->get(policy->cpu); | 1091 | policy->cur = cpufreq_driver->get(policy->cpu); |
| 1073 | if (!policy->cur) { | 1092 | if (!policy->cur) { |
| @@ -1142,11 +1161,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | |||
| 1142 | } | 1161 | } |
| 1143 | #endif | 1162 | #endif |
| 1144 | 1163 | ||
| 1145 | write_lock_irqsave(&cpufreq_driver_lock, flags); | ||
| 1146 | for_each_cpu(j, policy->cpus) | ||
| 1147 | per_cpu(cpufreq_cpu_data, j) = policy; | ||
| 1148 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | ||
| 1149 | |||
| 1150 | if (!frozen) { | 1164 | if (!frozen) { |
| 1151 | ret = cpufreq_add_dev_interface(policy, dev); | 1165 | ret = cpufreq_add_dev_interface(policy, dev); |
| 1152 | if (ret) | 1166 | if (ret) |
| @@ -1174,12 +1188,12 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, | |||
| 1174 | return 0; | 1188 | return 0; |
| 1175 | 1189 | ||
| 1176 | err_out_unregister: | 1190 | err_out_unregister: |
| 1191 | err_get_freq: | ||
| 1177 | write_lock_irqsave(&cpufreq_driver_lock, flags); | 1192 | write_lock_irqsave(&cpufreq_driver_lock, flags); |
| 1178 | for_each_cpu(j, policy->cpus) | 1193 | for_each_cpu(j, policy->cpus) |
| 1179 | per_cpu(cpufreq_cpu_data, j) = NULL; | 1194 | per_cpu(cpufreq_cpu_data, j) = NULL; |
| 1180 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); | 1195 | write_unlock_irqrestore(&cpufreq_driver_lock, flags); |
| 1181 | 1196 | ||
| 1182 | err_get_freq: | ||
| 1183 | if (cpufreq_driver->exit) | 1197 | if (cpufreq_driver->exit) |
| 1184 | cpufreq_driver->exit(policy); | 1198 | cpufreq_driver->exit(policy); |
| 1185 | err_set_policy_cpu: | 1199 | err_set_policy_cpu: |
diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c index 04f3390a7a2c..2cf33848d86e 100644 --- a/drivers/cpufreq/davinci-cpufreq.c +++ b/drivers/cpufreq/davinci-cpufreq.c | |||
| @@ -58,14 +58,6 @@ static int davinci_verify_speed(struct cpufreq_policy *policy) | |||
| 58 | return 0; | 58 | return 0; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | static unsigned int davinci_getspeed(unsigned int cpu) | ||
| 62 | { | ||
| 63 | if (cpu) | ||
| 64 | return 0; | ||
| 65 | |||
| 66 | return clk_get_rate(cpufreq.armclk) / 1000; | ||
| 67 | } | ||
| 68 | |||
| 69 | static int davinci_target(struct cpufreq_policy *policy, unsigned int idx) | 61 | static int davinci_target(struct cpufreq_policy *policy, unsigned int idx) |
| 70 | { | 62 | { |
| 71 | struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; | 63 | struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; |
| @@ -73,7 +65,7 @@ static int davinci_target(struct cpufreq_policy *policy, unsigned int idx) | |||
| 73 | unsigned int old_freq, new_freq; | 65 | unsigned int old_freq, new_freq; |
| 74 | int ret = 0; | 66 | int ret = 0; |
| 75 | 67 | ||
| 76 | old_freq = davinci_getspeed(0); | 68 | old_freq = policy->cur; |
| 77 | new_freq = pdata->freq_table[idx].frequency; | 69 | new_freq = pdata->freq_table[idx].frequency; |
| 78 | 70 | ||
| 79 | /* if moving to higher frequency, up the voltage beforehand */ | 71 | /* if moving to higher frequency, up the voltage beforehand */ |
| @@ -116,6 +108,8 @@ static int davinci_cpu_init(struct cpufreq_policy *policy) | |||
| 116 | return result; | 108 | return result; |
| 117 | } | 109 | } |
| 118 | 110 | ||
| 111 | policy->clk = cpufreq.armclk; | ||
| 112 | |||
| 119 | /* | 113 | /* |
| 120 | * Time measurement across the target() function yields ~1500-1800us | 114 | * Time measurement across the target() function yields ~1500-1800us |
| 121 | * time taken with no drivers on notification list. | 115 | * time taken with no drivers on notification list. |
| @@ -129,7 +123,7 @@ static struct cpufreq_driver davinci_driver = { | |||
| 129 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | 123 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
| 130 | .verify = davinci_verify_speed, | 124 | .verify = davinci_verify_speed, |
| 131 | .target_index = davinci_target, | 125 | .target_index = davinci_target, |
| 132 | .get = davinci_getspeed, | 126 | .get = cpufreq_generic_get, |
| 133 | .init = davinci_cpu_init, | 127 | .init = davinci_cpu_init, |
| 134 | .exit = cpufreq_generic_exit, | 128 | .exit = cpufreq_generic_exit, |
| 135 | .name = "davinci", | 129 | .name = "davinci", |
diff --git a/drivers/cpufreq/dbx500-cpufreq.c b/drivers/cpufreq/dbx500-cpufreq.c index 21d9898e000c..412a78bb0c94 100644 --- a/drivers/cpufreq/dbx500-cpufreq.c +++ b/drivers/cpufreq/dbx500-cpufreq.c | |||
| @@ -26,24 +26,9 @@ static int dbx500_cpufreq_target(struct cpufreq_policy *policy, | |||
| 26 | return clk_set_rate(armss_clk, freq_table[index].frequency * 1000); | 26 | return clk_set_rate(armss_clk, freq_table[index].frequency * 1000); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | static unsigned int dbx500_cpufreq_getspeed(unsigned int cpu) | ||
| 30 | { | ||
| 31 | int i = 0; | ||
| 32 | unsigned long freq = clk_get_rate(armss_clk) / 1000; | ||
| 33 | |||
| 34 | /* The value is rounded to closest frequency in the defined table. */ | ||
| 35 | while (freq_table[i + 1].frequency != CPUFREQ_TABLE_END) { | ||
| 36 | if (freq < freq_table[i].frequency + | ||
| 37 | (freq_table[i + 1].frequency - freq_table[i].frequency) / 2) | ||
| 38 | return freq_table[i].frequency; | ||
| 39 | i++; | ||
| 40 | } | ||
| 41 | |||
| 42 | return freq_table[i].frequency; | ||
| 43 | } | ||
| 44 | |||
| 45 | static int dbx500_cpufreq_init(struct cpufreq_policy *policy) | 29 | static int dbx500_cpufreq_init(struct cpufreq_policy *policy) |
| 46 | { | 30 | { |
| 31 | policy->clk = armss_clk; | ||
| 47 | return cpufreq_generic_init(policy, freq_table, 20 * 1000); | 32 | return cpufreq_generic_init(policy, freq_table, 20 * 1000); |
| 48 | } | 33 | } |
| 49 | 34 | ||
| @@ -52,7 +37,7 @@ static struct cpufreq_driver dbx500_cpufreq_driver = { | |||
| 52 | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | 37 | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
| 53 | .verify = cpufreq_generic_frequency_table_verify, | 38 | .verify = cpufreq_generic_frequency_table_verify, |
| 54 | .target_index = dbx500_cpufreq_target, | 39 | .target_index = dbx500_cpufreq_target, |
| 55 | .get = dbx500_cpufreq_getspeed, | 40 | .get = cpufreq_generic_get, |
| 56 | .init = dbx500_cpufreq_init, | 41 | .init = dbx500_cpufreq_init, |
| 57 | .name = "DBX500", | 42 | .name = "DBX500", |
| 58 | .attr = cpufreq_generic_attr, | 43 | .attr = cpufreq_generic_attr, |
diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c index f7c322c7d7ed..4ee3804637be 100644 --- a/drivers/cpufreq/exynos-cpufreq.c +++ b/drivers/cpufreq/exynos-cpufreq.c | |||
| @@ -31,11 +31,6 @@ static unsigned int locking_frequency; | |||
| 31 | static bool frequency_locked; | 31 | static bool frequency_locked; |
| 32 | static DEFINE_MUTEX(cpufreq_lock); | 32 | static DEFINE_MUTEX(cpufreq_lock); |
| 33 | 33 | ||
| 34 | static unsigned int exynos_getspeed(unsigned int cpu) | ||
| 35 | { | ||
| 36 | return clk_get_rate(exynos_info->cpu_clk) / 1000; | ||
| 37 | } | ||
| 38 | |||
| 39 | static int exynos_cpufreq_get_index(unsigned int freq) | 34 | static int exynos_cpufreq_get_index(unsigned int freq) |
| 40 | { | 35 | { |
| 41 | struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; | 36 | struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; |
| @@ -215,6 +210,7 @@ static struct notifier_block exynos_cpufreq_nb = { | |||
| 215 | 210 | ||
| 216 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) | 211 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) |
| 217 | { | 212 | { |
| 213 | policy->clk = exynos_info->cpu_clk; | ||
| 218 | return cpufreq_generic_init(policy, exynos_info->freq_table, 100000); | 214 | return cpufreq_generic_init(policy, exynos_info->freq_table, 100000); |
| 219 | } | 215 | } |
| 220 | 216 | ||
| @@ -222,7 +218,7 @@ static struct cpufreq_driver exynos_driver = { | |||
| 222 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | 218 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
| 223 | .verify = cpufreq_generic_frequency_table_verify, | 219 | .verify = cpufreq_generic_frequency_table_verify, |
| 224 | .target_index = exynos_target, | 220 | .target_index = exynos_target, |
| 225 | .get = exynos_getspeed, | 221 | .get = cpufreq_generic_get, |
| 226 | .init = exynos_cpufreq_cpu_init, | 222 | .init = exynos_cpufreq_cpu_init, |
| 227 | .exit = cpufreq_generic_exit, | 223 | .exit = cpufreq_generic_exit, |
| 228 | .name = "exynos_cpufreq", | 224 | .name = "exynos_cpufreq", |
| @@ -264,7 +260,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
| 264 | goto err_vdd_arm; | 260 | goto err_vdd_arm; |
| 265 | } | 261 | } |
| 266 | 262 | ||
| 267 | locking_frequency = exynos_getspeed(0); | 263 | locking_frequency = clk_get_rate(exynos_info->cpu_clk) / 1000; |
| 268 | 264 | ||
| 269 | register_pm_notifier(&exynos_cpufreq_nb); | 265 | register_pm_notifier(&exynos_cpufreq_nb); |
| 270 | 266 | ||
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index ffe6faea3a5f..49b756015316 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c | |||
| @@ -100,7 +100,6 @@ struct exynos_dvfs_data { | |||
| 100 | struct resource *mem; | 100 | struct resource *mem; |
| 101 | int irq; | 101 | int irq; |
| 102 | struct clk *cpu_clk; | 102 | struct clk *cpu_clk; |
| 103 | unsigned int cur_frequency; | ||
| 104 | unsigned int latency; | 103 | unsigned int latency; |
| 105 | struct cpufreq_frequency_table *freq_table; | 104 | struct cpufreq_frequency_table *freq_table; |
| 106 | unsigned int freq_count; | 105 | unsigned int freq_count; |
| @@ -165,7 +164,7 @@ static int init_div_table(void) | |||
| 165 | return 0; | 164 | return 0; |
| 166 | } | 165 | } |
| 167 | 166 | ||
| 168 | static void exynos_enable_dvfs(void) | 167 | static void exynos_enable_dvfs(unsigned int cur_frequency) |
| 169 | { | 168 | { |
| 170 | unsigned int tmp, i, cpu; | 169 | unsigned int tmp, i, cpu; |
| 171 | struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; | 170 | struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; |
| @@ -184,18 +183,18 @@ static void exynos_enable_dvfs(void) | |||
| 184 | 183 | ||
| 185 | /* Set initial performance index */ | 184 | /* Set initial performance index */ |
| 186 | for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) | 185 | for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) |
| 187 | if (freq_table[i].frequency == dvfs_info->cur_frequency) | 186 | if (freq_table[i].frequency == cur_frequency) |
| 188 | break; | 187 | break; |
| 189 | 188 | ||
| 190 | if (freq_table[i].frequency == CPUFREQ_TABLE_END) { | 189 | if (freq_table[i].frequency == CPUFREQ_TABLE_END) { |
| 191 | dev_crit(dvfs_info->dev, "Boot up frequency not supported\n"); | 190 | dev_crit(dvfs_info->dev, "Boot up frequency not supported\n"); |
| 192 | /* Assign the highest frequency */ | 191 | /* Assign the highest frequency */ |
| 193 | i = 0; | 192 | i = 0; |
| 194 | dvfs_info->cur_frequency = freq_table[i].frequency; | 193 | cur_frequency = freq_table[i].frequency; |
| 195 | } | 194 | } |
| 196 | 195 | ||
| 197 | dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ", | 196 | dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ", |
| 198 | dvfs_info->cur_frequency); | 197 | cur_frequency); |
| 199 | 198 | ||
| 200 | for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) { | 199 | for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) { |
| 201 | tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); | 200 | tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); |
| @@ -209,11 +208,6 @@ static void exynos_enable_dvfs(void) | |||
| 209 | dvfs_info->base + XMU_DVFS_CTRL); | 208 | dvfs_info->base + XMU_DVFS_CTRL); |
| 210 | } | 209 | } |
| 211 | 210 | ||
| 212 | static unsigned int exynos_getspeed(unsigned int cpu) | ||
| 213 | { | ||
| 214 | return dvfs_info->cur_frequency; | ||
| 215 | } | ||
| 216 | |||
| 217 | static int exynos_target(struct cpufreq_policy *policy, unsigned int index) | 211 | static int exynos_target(struct cpufreq_policy *policy, unsigned int index) |
| 218 | { | 212 | { |
| 219 | unsigned int tmp; | 213 | unsigned int tmp; |
| @@ -222,7 +216,7 @@ static int exynos_target(struct cpufreq_policy *policy, unsigned int index) | |||
| 222 | 216 | ||
| 223 | mutex_lock(&cpufreq_lock); | 217 | mutex_lock(&cpufreq_lock); |
| 224 | 218 | ||
| 225 | freqs.old = dvfs_info->cur_frequency; | 219 | freqs.old = policy->cur; |
| 226 | freqs.new = freq_table[index].frequency; | 220 | freqs.new = freq_table[index].frequency; |
| 227 | 221 | ||
| 228 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 222 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
| @@ -250,7 +244,7 @@ static void exynos_cpufreq_work(struct work_struct *work) | |||
| 250 | goto skip_work; | 244 | goto skip_work; |
| 251 | 245 | ||
| 252 | mutex_lock(&cpufreq_lock); | 246 | mutex_lock(&cpufreq_lock); |
| 253 | freqs.old = dvfs_info->cur_frequency; | 247 | freqs.old = policy->cur; |
| 254 | 248 | ||
| 255 | cur_pstate = __raw_readl(dvfs_info->base + XMU_P_STATUS); | 249 | cur_pstate = __raw_readl(dvfs_info->base + XMU_P_STATUS); |
| 256 | if (cur_pstate >> C0_3_PSTATE_VALID_SHIFT & 0x1) | 250 | if (cur_pstate >> C0_3_PSTATE_VALID_SHIFT & 0x1) |
| @@ -260,10 +254,9 @@ static void exynos_cpufreq_work(struct work_struct *work) | |||
| 260 | 254 | ||
| 261 | if (likely(index < dvfs_info->freq_count)) { | 255 | if (likely(index < dvfs_info->freq_count)) { |
| 262 | freqs.new = freq_table[index].frequency; | 256 | freqs.new = freq_table[index].frequency; |
| 263 | dvfs_info->cur_frequency = freqs.new; | ||
| 264 | } else { | 257 | } else { |
| 265 | dev_crit(dvfs_info->dev, "New frequency out of range\n"); | 258 | dev_crit(dvfs_info->dev, "New frequency out of range\n"); |
| 266 | freqs.new = dvfs_info->cur_frequency; | 259 | freqs.new = freqs.old; |
| 267 | } | 260 | } |
| 268 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | 261 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); |
| 269 | 262 | ||
| @@ -307,6 +300,7 @@ static void exynos_sort_descend_freq_table(void) | |||
| 307 | 300 | ||
| 308 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) | 301 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) |
| 309 | { | 302 | { |
| 303 | policy->clk = dvfs_info->cpu_clk; | ||
| 310 | return cpufreq_generic_init(policy, dvfs_info->freq_table, | 304 | return cpufreq_generic_init(policy, dvfs_info->freq_table, |
| 311 | dvfs_info->latency); | 305 | dvfs_info->latency); |
| 312 | } | 306 | } |
| @@ -316,7 +310,7 @@ static struct cpufreq_driver exynos_driver = { | |||
| 316 | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | 310 | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
| 317 | .verify = cpufreq_generic_frequency_table_verify, | 311 | .verify = cpufreq_generic_frequency_table_verify, |
| 318 | .target_index = exynos_target, | 312 | .target_index = exynos_target, |
| 319 | .get = exynos_getspeed, | 313 | .get = cpufreq_generic_get, |
| 320 | .init = exynos_cpufreq_cpu_init, | 314 | .init = exynos_cpufreq_cpu_init, |
| 321 | .exit = cpufreq_generic_exit, | 315 | .exit = cpufreq_generic_exit, |
| 322 | .name = CPUFREQ_NAME, | 316 | .name = CPUFREQ_NAME, |
| @@ -336,6 +330,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
| 336 | int ret = -EINVAL; | 330 | int ret = -EINVAL; |
| 337 | struct device_node *np; | 331 | struct device_node *np; |
| 338 | struct resource res; | 332 | struct resource res; |
| 333 | unsigned int cur_frequency; | ||
| 339 | 334 | ||
| 340 | np = pdev->dev.of_node; | 335 | np = pdev->dev.of_node; |
| 341 | if (!np) | 336 | if (!np) |
| @@ -392,13 +387,13 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
| 392 | goto err_free_table; | 387 | goto err_free_table; |
| 393 | } | 388 | } |
| 394 | 389 | ||
| 395 | dvfs_info->cur_frequency = clk_get_rate(dvfs_info->cpu_clk); | 390 | cur_frequency = clk_get_rate(dvfs_info->cpu_clk); |
| 396 | if (!dvfs_info->cur_frequency) { | 391 | if (!cur_frequency) { |
| 397 | dev_err(dvfs_info->dev, "Failed to get clock rate\n"); | 392 | dev_err(dvfs_info->dev, "Failed to get clock rate\n"); |
| 398 | ret = -EINVAL; | 393 | ret = -EINVAL; |
| 399 | goto err_free_table; | 394 | goto err_free_table; |
| 400 | } | 395 | } |
| 401 | dvfs_info->cur_frequency /= 1000; | 396 | cur_frequency /= 1000; |
| 402 | 397 | ||
| 403 | INIT_WORK(&dvfs_info->irq_work, exynos_cpufreq_work); | 398 | INIT_WORK(&dvfs_info->irq_work, exynos_cpufreq_work); |
| 404 | ret = devm_request_irq(dvfs_info->dev, dvfs_info->irq, | 399 | ret = devm_request_irq(dvfs_info->dev, dvfs_info->irq, |
| @@ -415,7 +410,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
| 415 | goto err_free_table; | 410 | goto err_free_table; |
| 416 | } | 411 | } |
| 417 | 412 | ||
| 418 | exynos_enable_dvfs(); | 413 | exynos_enable_dvfs(cur_frequency); |
| 419 | ret = cpufreq_register_driver(&exynos_driver); | 414 | ret = cpufreq_register_driver(&exynos_driver); |
| 420 | if (ret) { | 415 | if (ret) { |
| 421 | dev_err(dvfs_info->dev, | 416 | dev_err(dvfs_info->dev, |
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index 2938257b8c19..ce69059be1fc 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c | |||
| @@ -38,11 +38,6 @@ static unsigned int transition_latency; | |||
| 38 | static u32 *imx6_soc_volt; | 38 | static u32 *imx6_soc_volt; |
| 39 | static u32 soc_opp_count; | 39 | static u32 soc_opp_count; |
| 40 | 40 | ||
| 41 | static unsigned int imx6q_get_speed(unsigned int cpu) | ||
| 42 | { | ||
| 43 | return clk_get_rate(arm_clk) / 1000; | ||
| 44 | } | ||
| 45 | |||
| 46 | static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) | 41 | static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) |
| 47 | { | 42 | { |
| 48 | struct dev_pm_opp *opp; | 43 | struct dev_pm_opp *opp; |
| @@ -139,6 +134,7 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) | |||
| 139 | 134 | ||
| 140 | static int imx6q_cpufreq_init(struct cpufreq_policy *policy) | 135 | static int imx6q_cpufreq_init(struct cpufreq_policy *policy) |
| 141 | { | 136 | { |
| 137 | policy->clk = arm_clk; | ||
| 142 | return cpufreq_generic_init(policy, freq_table, transition_latency); | 138 | return cpufreq_generic_init(policy, freq_table, transition_latency); |
| 143 | } | 139 | } |
| 144 | 140 | ||
| @@ -146,7 +142,7 @@ static struct cpufreq_driver imx6q_cpufreq_driver = { | |||
| 146 | .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, | 142 | .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
| 147 | .verify = cpufreq_generic_frequency_table_verify, | 143 | .verify = cpufreq_generic_frequency_table_verify, |
| 148 | .target_index = imx6q_set_target, | 144 | .target_index = imx6q_set_target, |
| 149 | .get = imx6q_get_speed, | 145 | .get = cpufreq_generic_get, |
| 150 | .init = imx6q_cpufreq_init, | 146 | .init = imx6q_cpufreq_init, |
| 151 | .exit = cpufreq_generic_exit, | 147 | .exit = cpufreq_generic_exit, |
| 152 | .name = "imx6q-cpufreq", | 148 | .name = "imx6q-cpufreq", |
diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c index a43609218105..b6581abc9207 100644 --- a/drivers/cpufreq/loongson2_cpufreq.c +++ b/drivers/cpufreq/loongson2_cpufreq.c | |||
| @@ -24,8 +24,6 @@ | |||
| 24 | 24 | ||
| 25 | static uint nowait; | 25 | static uint nowait; |
| 26 | 26 | ||
| 27 | static struct clk *cpuclk; | ||
| 28 | |||
| 29 | static void (*saved_cpu_wait) (void); | 27 | static void (*saved_cpu_wait) (void); |
| 30 | 28 | ||
| 31 | static int loongson2_cpu_freq_notifier(struct notifier_block *nb, | 29 | static int loongson2_cpu_freq_notifier(struct notifier_block *nb, |
| @@ -44,11 +42,6 @@ static int loongson2_cpu_freq_notifier(struct notifier_block *nb, | |||
| 44 | return 0; | 42 | return 0; |
| 45 | } | 43 | } |
| 46 | 44 | ||
| 47 | static unsigned int loongson2_cpufreq_get(unsigned int cpu) | ||
| 48 | { | ||
| 49 | return clk_get_rate(cpuclk); | ||
| 50 | } | ||
| 51 | |||
| 52 | /* | 45 | /* |
| 53 | * Here we notify other drivers of the proposed change and the final change. | 46 | * Here we notify other drivers of the proposed change and the final change. |
| 54 | */ | 47 | */ |
| @@ -69,13 +62,14 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy, | |||
| 69 | set_cpus_allowed_ptr(current, &cpus_allowed); | 62 | set_cpus_allowed_ptr(current, &cpus_allowed); |
| 70 | 63 | ||
| 71 | /* setting the cpu frequency */ | 64 | /* setting the cpu frequency */ |
| 72 | clk_set_rate(cpuclk, freq); | 65 | clk_set_rate(policy->clk, freq); |
| 73 | 66 | ||
| 74 | return 0; | 67 | return 0; |
| 75 | } | 68 | } |
| 76 | 69 | ||
| 77 | static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) | 70 | static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) |
| 78 | { | 71 | { |
| 72 | static struct clk *cpuclk; | ||
| 79 | int i; | 73 | int i; |
| 80 | unsigned long rate; | 74 | unsigned long rate; |
| 81 | int ret; | 75 | int ret; |
| @@ -104,13 +98,14 @@ static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
| 104 | return ret; | 98 | return ret; |
| 105 | } | 99 | } |
| 106 | 100 | ||
| 101 | policy->clk = cpuclk; | ||
| 107 | return cpufreq_generic_init(policy, &loongson2_clockmod_table[0], 0); | 102 | return cpufreq_generic_init(policy, &loongson2_clockmod_table[0], 0); |
| 108 | } | 103 | } |
| 109 | 104 | ||
| 110 | static int loongson2_cpufreq_exit(struct cpufreq_policy *policy) | 105 | static int loongson2_cpufreq_exit(struct cpufreq_policy *policy) |
| 111 | { | 106 | { |
| 112 | cpufreq_frequency_table_put_attr(policy->cpu); | 107 | cpufreq_frequency_table_put_attr(policy->cpu); |
| 113 | clk_put(cpuclk); | 108 | clk_put(policy->clk); |
| 114 | return 0; | 109 | return 0; |
| 115 | } | 110 | } |
| 116 | 111 | ||
| @@ -119,7 +114,7 @@ static struct cpufreq_driver loongson2_cpufreq_driver = { | |||
| 119 | .init = loongson2_cpufreq_cpu_init, | 114 | .init = loongson2_cpufreq_cpu_init, |
| 120 | .verify = cpufreq_generic_frequency_table_verify, | 115 | .verify = cpufreq_generic_frequency_table_verify, |
| 121 | .target_index = loongson2_cpufreq_target, | 116 | .target_index = loongson2_cpufreq_target, |
| 122 | .get = loongson2_cpufreq_get, | 117 | .get = cpufreq_generic_get, |
| 123 | .exit = loongson2_cpufreq_exit, | 118 | .exit = loongson2_cpufreq_exit, |
| 124 | .attr = cpufreq_generic_attr, | 119 | .attr = cpufreq_generic_attr, |
| 125 | }; | 120 | }; |
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c index 5de1e5f73eca..590f5b66d181 100644 --- a/drivers/cpufreq/omap-cpufreq.c +++ b/drivers/cpufreq/omap-cpufreq.c | |||
| @@ -36,21 +36,9 @@ | |||
| 36 | 36 | ||
| 37 | static struct cpufreq_frequency_table *freq_table; | 37 | static struct cpufreq_frequency_table *freq_table; |
| 38 | static atomic_t freq_table_users = ATOMIC_INIT(0); | 38 | static atomic_t freq_table_users = ATOMIC_INIT(0); |
| 39 | static struct clk *mpu_clk; | ||
| 40 | static struct device *mpu_dev; | 39 | static struct device *mpu_dev; |
| 41 | static struct regulator *mpu_reg; | 40 | static struct regulator *mpu_reg; |
| 42 | 41 | ||
| 43 | static unsigned int omap_getspeed(unsigned int cpu) | ||
| 44 | { | ||
| 45 | unsigned long rate; | ||
| 46 | |||
| 47 | if (cpu >= NR_CPUS) | ||
| 48 | return 0; | ||
| 49 | |||
| 50 | rate = clk_get_rate(mpu_clk) / 1000; | ||
| 51 | return rate; | ||
| 52 | } | ||
| 53 | |||
| 54 | static int omap_target(struct cpufreq_policy *policy, unsigned int index) | 42 | static int omap_target(struct cpufreq_policy *policy, unsigned int index) |
| 55 | { | 43 | { |
| 56 | int r, ret; | 44 | int r, ret; |
| @@ -58,11 +46,11 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index) | |||
| 58 | unsigned long freq, volt = 0, volt_old = 0, tol = 0; | 46 | unsigned long freq, volt = 0, volt_old = 0, tol = 0; |
| 59 | unsigned int old_freq, new_freq; | 47 | unsigned int old_freq, new_freq; |
| 60 | 48 | ||
| 61 | old_freq = omap_getspeed(policy->cpu); | 49 | old_freq = policy->cur; |
| 62 | new_freq = freq_table[index].frequency; | 50 | new_freq = freq_table[index].frequency; |
| 63 | 51 | ||
| 64 | freq = new_freq * 1000; | 52 | freq = new_freq * 1000; |
| 65 | ret = clk_round_rate(mpu_clk, freq); | 53 | ret = clk_round_rate(policy->clk, freq); |
| 66 | if (IS_ERR_VALUE(ret)) { | 54 | if (IS_ERR_VALUE(ret)) { |
| 67 | dev_warn(mpu_dev, | 55 | dev_warn(mpu_dev, |
| 68 | "CPUfreq: Cannot find matching frequency for %lu\n", | 56 | "CPUfreq: Cannot find matching frequency for %lu\n", |
| @@ -100,7 +88,7 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index) | |||
| 100 | } | 88 | } |
| 101 | } | 89 | } |
| 102 | 90 | ||
| 103 | ret = clk_set_rate(mpu_clk, new_freq * 1000); | 91 | ret = clk_set_rate(policy->clk, new_freq * 1000); |
| 104 | 92 | ||
| 105 | /* scaling down? scale voltage after frequency */ | 93 | /* scaling down? scale voltage after frequency */ |
| 106 | if (mpu_reg && (new_freq < old_freq)) { | 94 | if (mpu_reg && (new_freq < old_freq)) { |
| @@ -108,7 +96,7 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index) | |||
| 108 | if (r < 0) { | 96 | if (r < 0) { |
| 109 | dev_warn(mpu_dev, "%s: unable to scale voltage down.\n", | 97 | dev_warn(mpu_dev, "%s: unable to scale voltage down.\n", |
| 110 | __func__); | 98 | __func__); |
| 111 | clk_set_rate(mpu_clk, old_freq * 1000); | 99 | clk_set_rate(policy->clk, old_freq * 1000); |
| 112 | return r; | 100 | return r; |
| 113 | } | 101 | } |
| 114 | } | 102 | } |
| @@ -126,9 +114,9 @@ static int omap_cpu_init(struct cpufreq_policy *policy) | |||
| 126 | { | 114 | { |
| 127 | int result; | 115 | int result; |
| 128 | 116 | ||
| 129 | mpu_clk = clk_get(NULL, "cpufreq_ck"); | 117 | policy->clk = clk_get(NULL, "cpufreq_ck"); |
| 130 | if (IS_ERR(mpu_clk)) | 118 | if (IS_ERR(policy->clk)) |
| 131 | return PTR_ERR(mpu_clk); | 119 | return PTR_ERR(policy->clk); |
| 132 | 120 | ||
| 133 | if (!freq_table) { | 121 | if (!freq_table) { |
| 134 | result = dev_pm_opp_init_cpufreq_table(mpu_dev, &freq_table); | 122 | result = dev_pm_opp_init_cpufreq_table(mpu_dev, &freq_table); |
| @@ -149,7 +137,7 @@ static int omap_cpu_init(struct cpufreq_policy *policy) | |||
| 149 | 137 | ||
| 150 | freq_table_free(); | 138 | freq_table_free(); |
| 151 | fail: | 139 | fail: |
| 152 | clk_put(mpu_clk); | 140 | clk_put(policy->clk); |
| 153 | return result; | 141 | return result; |
| 154 | } | 142 | } |
| 155 | 143 | ||
| @@ -157,7 +145,7 @@ static int omap_cpu_exit(struct cpufreq_policy *policy) | |||
| 157 | { | 145 | { |
| 158 | cpufreq_frequency_table_put_attr(policy->cpu); | 146 | cpufreq_frequency_table_put_attr(policy->cpu); |
| 159 | freq_table_free(); | 147 | freq_table_free(); |
| 160 | clk_put(mpu_clk); | 148 | clk_put(policy->clk); |
| 161 | return 0; | 149 | return 0; |
| 162 | } | 150 | } |
| 163 | 151 | ||
| @@ -165,7 +153,7 @@ static struct cpufreq_driver omap_driver = { | |||
| 165 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | 153 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
| 166 | .verify = cpufreq_generic_frequency_table_verify, | 154 | .verify = cpufreq_generic_frequency_table_verify, |
| 167 | .target_index = omap_target, | 155 | .target_index = omap_target, |
| 168 | .get = omap_getspeed, | 156 | .get = cpufreq_generic_get, |
| 169 | .init = omap_cpu_init, | 157 | .init = omap_cpu_init, |
| 170 | .exit = omap_cpu_exit, | 158 | .exit = omap_cpu_exit, |
| 171 | .name = "omap", | 159 | .name = "omap", |
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c index 3f7be46d2b27..051000f44ca2 100644 --- a/drivers/cpufreq/ppc-corenet-cpufreq.c +++ b/drivers/cpufreq/ppc-corenet-cpufreq.c | |||
| @@ -24,12 +24,10 @@ | |||
| 24 | 24 | ||
| 25 | /** | 25 | /** |
| 26 | * struct cpu_data - per CPU data struct | 26 | * struct cpu_data - per CPU data struct |
| 27 | * @clk: the clk of CPU | ||
| 28 | * @parent: the parent node of cpu clock | 27 | * @parent: the parent node of cpu clock |
| 29 | * @table: frequency table | 28 | * @table: frequency table |
| 30 | */ | 29 | */ |
| 31 | struct cpu_data { | 30 | struct cpu_data { |
| 32 | struct clk *clk; | ||
| 33 | struct device_node *parent; | 31 | struct device_node *parent; |
| 34 | struct cpufreq_frequency_table *table; | 32 | struct cpufreq_frequency_table *table; |
| 35 | }; | 33 | }; |
| @@ -81,13 +79,6 @@ static inline const struct cpumask *cpu_core_mask(int cpu) | |||
| 81 | } | 79 | } |
| 82 | #endif | 80 | #endif |
| 83 | 81 | ||
| 84 | static unsigned int corenet_cpufreq_get_speed(unsigned int cpu) | ||
| 85 | { | ||
| 86 | struct cpu_data *data = per_cpu(cpu_data, cpu); | ||
| 87 | |||
| 88 | return clk_get_rate(data->clk) / 1000; | ||
| 89 | } | ||
| 90 | |||
| 91 | /* reduce the duplicated frequencies in frequency table */ | 82 | /* reduce the duplicated frequencies in frequency table */ |
| 92 | static void freq_table_redup(struct cpufreq_frequency_table *freq_table, | 83 | static void freq_table_redup(struct cpufreq_frequency_table *freq_table, |
| 93 | int count) | 84 | int count) |
| @@ -158,8 +149,8 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
| 158 | goto err_np; | 149 | goto err_np; |
| 159 | } | 150 | } |
| 160 | 151 | ||
| 161 | data->clk = of_clk_get(np, 0); | 152 | policy->clk = of_clk_get(np, 0); |
| 162 | if (IS_ERR(data->clk)) { | 153 | if (IS_ERR(policy->clk)) { |
| 163 | pr_err("%s: no clock information\n", __func__); | 154 | pr_err("%s: no clock information\n", __func__); |
| 164 | goto err_nomem2; | 155 | goto err_nomem2; |
| 165 | } | 156 | } |
| @@ -255,7 +246,7 @@ static int corenet_cpufreq_target(struct cpufreq_policy *policy, | |||
| 255 | struct cpu_data *data = per_cpu(cpu_data, policy->cpu); | 246 | struct cpu_data *data = per_cpu(cpu_data, policy->cpu); |
| 256 | 247 | ||
| 257 | parent = of_clk_get(data->parent, data->table[index].driver_data); | 248 | parent = of_clk_get(data->parent, data->table[index].driver_data); |
| 258 | return clk_set_parent(data->clk, parent); | 249 | return clk_set_parent(policy->clk, parent); |
| 259 | } | 250 | } |
| 260 | 251 | ||
| 261 | static struct cpufreq_driver ppc_corenet_cpufreq_driver = { | 252 | static struct cpufreq_driver ppc_corenet_cpufreq_driver = { |
| @@ -265,7 +256,7 @@ static struct cpufreq_driver ppc_corenet_cpufreq_driver = { | |||
| 265 | .exit = __exit_p(corenet_cpufreq_cpu_exit), | 256 | .exit = __exit_p(corenet_cpufreq_cpu_exit), |
| 266 | .verify = cpufreq_generic_frequency_table_verify, | 257 | .verify = cpufreq_generic_frequency_table_verify, |
| 267 | .target_index = corenet_cpufreq_target, | 258 | .target_index = corenet_cpufreq_target, |
| 268 | .get = corenet_cpufreq_get_speed, | 259 | .get = cpufreq_generic_get, |
| 269 | .attr = cpufreq_generic_attr, | 260 | .attr = cpufreq_generic_attr, |
| 270 | }; | 261 | }; |
| 271 | 262 | ||
diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c index 6a1bf96deec0..25069741b507 100644 --- a/drivers/cpufreq/s3c24xx-cpufreq.c +++ b/drivers/cpufreq/s3c24xx-cpufreq.c | |||
| @@ -355,11 +355,6 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy, | |||
| 355 | return -EINVAL; | 355 | return -EINVAL; |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | static unsigned int s3c_cpufreq_get(unsigned int cpu) | ||
| 359 | { | ||
| 360 | return clk_get_rate(clk_arm) / 1000; | ||
| 361 | } | ||
| 362 | |||
| 363 | struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) | 358 | struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) |
| 364 | { | 359 | { |
| 365 | struct clk *clk; | 360 | struct clk *clk; |
| @@ -373,6 +368,7 @@ struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) | |||
| 373 | 368 | ||
| 374 | static int s3c_cpufreq_init(struct cpufreq_policy *policy) | 369 | static int s3c_cpufreq_init(struct cpufreq_policy *policy) |
| 375 | { | 370 | { |
| 371 | policy->clk = clk_arm; | ||
| 376 | return cpufreq_generic_init(policy, ftab, cpu_cur.info->latency); | 372 | return cpufreq_generic_init(policy, ftab, cpu_cur.info->latency); |
| 377 | } | 373 | } |
| 378 | 374 | ||
| @@ -408,7 +404,7 @@ static int s3c_cpufreq_suspend(struct cpufreq_policy *policy) | |||
| 408 | { | 404 | { |
| 409 | suspend_pll.frequency = clk_get_rate(_clk_mpll); | 405 | suspend_pll.frequency = clk_get_rate(_clk_mpll); |
| 410 | suspend_pll.driver_data = __raw_readl(S3C2410_MPLLCON); | 406 | suspend_pll.driver_data = __raw_readl(S3C2410_MPLLCON); |
| 411 | suspend_freq = s3c_cpufreq_get(0) * 1000; | 407 | suspend_freq = clk_get_rate(clk_arm); |
| 412 | 408 | ||
| 413 | return 0; | 409 | return 0; |
| 414 | } | 410 | } |
| @@ -450,7 +446,7 @@ static int s3c_cpufreq_resume(struct cpufreq_policy *policy) | |||
| 450 | static struct cpufreq_driver s3c24xx_driver = { | 446 | static struct cpufreq_driver s3c24xx_driver = { |
| 451 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | 447 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
| 452 | .target = s3c_cpufreq_target, | 448 | .target = s3c_cpufreq_target, |
| 453 | .get = s3c_cpufreq_get, | 449 | .get = cpufreq_generic_get, |
| 454 | .init = s3c_cpufreq_init, | 450 | .init = s3c_cpufreq_init, |
| 455 | .suspend = s3c_cpufreq_suspend, | 451 | .suspend = s3c_cpufreq_suspend, |
| 456 | .resume = s3c_cpufreq_resume, | 452 | .resume = s3c_cpufreq_resume, |
diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c index 8435f45d7e9d..c4226de079ab 100644 --- a/drivers/cpufreq/s3c64xx-cpufreq.c +++ b/drivers/cpufreq/s3c64xx-cpufreq.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | #include <linux/regulator/consumer.h> | 19 | #include <linux/regulator/consumer.h> |
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 21 | 21 | ||
| 22 | static struct clk *armclk; | ||
| 23 | static struct regulator *vddarm; | 22 | static struct regulator *vddarm; |
| 24 | static unsigned long regulator_latency; | 23 | static unsigned long regulator_latency; |
| 25 | 24 | ||
| @@ -54,14 +53,6 @@ static struct cpufreq_frequency_table s3c64xx_freq_table[] = { | |||
| 54 | }; | 53 | }; |
| 55 | #endif | 54 | #endif |
| 56 | 55 | ||
| 57 | static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu) | ||
| 58 | { | ||
| 59 | if (cpu != 0) | ||
| 60 | return 0; | ||
| 61 | |||
| 62 | return clk_get_rate(armclk) / 1000; | ||
| 63 | } | ||
| 64 | |||
| 65 | static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, | 56 | static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, |
| 66 | unsigned int index) | 57 | unsigned int index) |
| 67 | { | 58 | { |
| @@ -69,7 +60,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, | |||
| 69 | unsigned int old_freq, new_freq; | 60 | unsigned int old_freq, new_freq; |
| 70 | int ret; | 61 | int ret; |
| 71 | 62 | ||
| 72 | old_freq = clk_get_rate(armclk) / 1000; | 63 | old_freq = clk_get_rate(policy->clk) / 1000; |
| 73 | new_freq = s3c64xx_freq_table[index].frequency; | 64 | new_freq = s3c64xx_freq_table[index].frequency; |
| 74 | dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data]; | 65 | dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data]; |
| 75 | 66 | ||
| @@ -86,7 +77,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, | |||
| 86 | } | 77 | } |
| 87 | #endif | 78 | #endif |
| 88 | 79 | ||
| 89 | ret = clk_set_rate(armclk, new_freq * 1000); | 80 | ret = clk_set_rate(policy->clk, new_freq * 1000); |
| 90 | if (ret < 0) { | 81 | if (ret < 0) { |
| 91 | pr_err("Failed to set rate %dkHz: %d\n", | 82 | pr_err("Failed to set rate %dkHz: %d\n", |
| 92 | new_freq, ret); | 83 | new_freq, ret); |
| @@ -101,7 +92,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, | |||
| 101 | if (ret != 0) { | 92 | if (ret != 0) { |
| 102 | pr_err("Failed to set VDDARM for %dkHz: %d\n", | 93 | pr_err("Failed to set VDDARM for %dkHz: %d\n", |
| 103 | new_freq, ret); | 94 | new_freq, ret); |
| 104 | if (clk_set_rate(armclk, old_freq * 1000) < 0) | 95 | if (clk_set_rate(policy->clk, old_freq * 1000) < 0) |
| 105 | pr_err("Failed to restore original clock rate\n"); | 96 | pr_err("Failed to restore original clock rate\n"); |
| 106 | 97 | ||
| 107 | return ret; | 98 | return ret; |
| @@ -110,7 +101,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, | |||
| 110 | #endif | 101 | #endif |
| 111 | 102 | ||
| 112 | pr_debug("Set actual frequency %lukHz\n", | 103 | pr_debug("Set actual frequency %lukHz\n", |
| 113 | clk_get_rate(armclk) / 1000); | 104 | clk_get_rate(policy->clk) / 1000); |
| 114 | 105 | ||
| 115 | return 0; | 106 | return 0; |
| 116 | } | 107 | } |
| @@ -169,11 +160,11 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
| 169 | return -ENODEV; | 160 | return -ENODEV; |
| 170 | } | 161 | } |
| 171 | 162 | ||
| 172 | armclk = clk_get(NULL, "armclk"); | 163 | policy->clk = clk_get(NULL, "armclk"); |
| 173 | if (IS_ERR(armclk)) { | 164 | if (IS_ERR(policy->clk)) { |
| 174 | pr_err("Unable to obtain ARMCLK: %ld\n", | 165 | pr_err("Unable to obtain ARMCLK: %ld\n", |
| 175 | PTR_ERR(armclk)); | 166 | PTR_ERR(policy->clk)); |
| 176 | return PTR_ERR(armclk); | 167 | return PTR_ERR(policy->clk); |
| 177 | } | 168 | } |
| 178 | 169 | ||
| 179 | #ifdef CONFIG_REGULATOR | 170 | #ifdef CONFIG_REGULATOR |
| @@ -193,7 +184,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
| 193 | unsigned long r; | 184 | unsigned long r; |
| 194 | 185 | ||
| 195 | /* Check for frequencies we can generate */ | 186 | /* Check for frequencies we can generate */ |
| 196 | r = clk_round_rate(armclk, freq->frequency * 1000); | 187 | r = clk_round_rate(policy->clk, freq->frequency * 1000); |
| 197 | r /= 1000; | 188 | r /= 1000; |
| 198 | if (r != freq->frequency) { | 189 | if (r != freq->frequency) { |
| 199 | pr_debug("%dkHz unsupported by clock\n", | 190 | pr_debug("%dkHz unsupported by clock\n", |
| @@ -203,7 +194,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
| 203 | 194 | ||
| 204 | /* If we have no regulator then assume startup | 195 | /* If we have no regulator then assume startup |
| 205 | * frequency is the maximum we can support. */ | 196 | * frequency is the maximum we can support. */ |
| 206 | if (!vddarm && freq->frequency > s3c64xx_cpufreq_get_speed(0)) | 197 | if (!vddarm && freq->frequency > clk_get_rate(policy->clk) / 1000) |
| 207 | freq->frequency = CPUFREQ_ENTRY_INVALID; | 198 | freq->frequency = CPUFREQ_ENTRY_INVALID; |
| 208 | 199 | ||
| 209 | freq++; | 200 | freq++; |
| @@ -219,7 +210,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) | |||
| 219 | pr_err("Failed to configure frequency table: %d\n", | 210 | pr_err("Failed to configure frequency table: %d\n", |
| 220 | ret); | 211 | ret); |
| 221 | regulator_put(vddarm); | 212 | regulator_put(vddarm); |
| 222 | clk_put(armclk); | 213 | clk_put(policy->clk); |
| 223 | } | 214 | } |
| 224 | 215 | ||
| 225 | return ret; | 216 | return ret; |
| @@ -229,7 +220,7 @@ static struct cpufreq_driver s3c64xx_cpufreq_driver = { | |||
| 229 | .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, | 220 | .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
| 230 | .verify = cpufreq_generic_frequency_table_verify, | 221 | .verify = cpufreq_generic_frequency_table_verify, |
| 231 | .target_index = s3c64xx_cpufreq_set_target, | 222 | .target_index = s3c64xx_cpufreq_set_target, |
| 232 | .get = s3c64xx_cpufreq_get_speed, | 223 | .get = cpufreq_generic_get, |
| 233 | .init = s3c64xx_cpufreq_driver_init, | 224 | .init = s3c64xx_cpufreq_driver_init, |
| 234 | .name = "s3c", | 225 | .name = "s3c", |
| 235 | }; | 226 | }; |
diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index ccd548c6f0c1..55a8e9fa9435 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include <mach/map.h> | 23 | #include <mach/map.h> |
| 24 | #include <mach/regs-clock.h> | 24 | #include <mach/regs-clock.h> |
| 25 | 25 | ||
| 26 | static struct clk *cpu_clk; | ||
| 27 | static struct clk *dmc0_clk; | 26 | static struct clk *dmc0_clk; |
| 28 | static struct clk *dmc1_clk; | 27 | static struct clk *dmc1_clk; |
| 29 | static DEFINE_MUTEX(set_freq_lock); | 28 | static DEFINE_MUTEX(set_freq_lock); |
| @@ -164,14 +163,6 @@ static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq) | |||
| 164 | __raw_writel(tmp1, reg); | 163 | __raw_writel(tmp1, reg); |
| 165 | } | 164 | } |
| 166 | 165 | ||
| 167 | static unsigned int s5pv210_getspeed(unsigned int cpu) | ||
| 168 | { | ||
| 169 | if (cpu) | ||
| 170 | return 0; | ||
| 171 | |||
| 172 | return clk_get_rate(cpu_clk) / 1000; | ||
| 173 | } | ||
| 174 | |||
| 175 | static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) | 166 | static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) |
| 176 | { | 167 | { |
| 177 | unsigned long reg; | 168 | unsigned long reg; |
| @@ -193,7 +184,7 @@ static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) | |||
| 193 | goto exit; | 184 | goto exit; |
| 194 | } | 185 | } |
| 195 | 186 | ||
| 196 | old_freq = s5pv210_getspeed(0); | 187 | old_freq = policy->cur; |
| 197 | new_freq = s5pv210_freq_table[index].frequency; | 188 | new_freq = s5pv210_freq_table[index].frequency; |
| 198 | 189 | ||
| 199 | /* Finding current running level index */ | 190 | /* Finding current running level index */ |
| @@ -471,9 +462,9 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy) | |||
| 471 | unsigned long mem_type; | 462 | unsigned long mem_type; |
| 472 | int ret; | 463 | int ret; |
| 473 | 464 | ||
| 474 | cpu_clk = clk_get(NULL, "armclk"); | 465 | policy->clk = clk_get(NULL, "armclk"); |
| 475 | if (IS_ERR(cpu_clk)) | 466 | if (IS_ERR(policy->clk)) |
| 476 | return PTR_ERR(cpu_clk); | 467 | return PTR_ERR(policy->clk); |
| 477 | 468 | ||
| 478 | dmc0_clk = clk_get(NULL, "sclk_dmc0"); | 469 | dmc0_clk = clk_get(NULL, "sclk_dmc0"); |
| 479 | if (IS_ERR(dmc0_clk)) { | 470 | if (IS_ERR(dmc0_clk)) { |
| @@ -516,7 +507,7 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy) | |||
| 516 | out_dmc1: | 507 | out_dmc1: |
| 517 | clk_put(dmc0_clk); | 508 | clk_put(dmc0_clk); |
| 518 | out_dmc0: | 509 | out_dmc0: |
| 519 | clk_put(cpu_clk); | 510 | clk_put(policy->clk); |
| 520 | return ret; | 511 | return ret; |
| 521 | } | 512 | } |
| 522 | 513 | ||
| @@ -563,7 +554,7 @@ static struct cpufreq_driver s5pv210_driver = { | |||
| 563 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | 554 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
| 564 | .verify = cpufreq_generic_frequency_table_verify, | 555 | .verify = cpufreq_generic_frequency_table_verify, |
| 565 | .target_index = s5pv210_target, | 556 | .target_index = s5pv210_target, |
| 566 | .get = s5pv210_getspeed, | 557 | .get = cpufreq_generic_get, |
| 567 | .init = s5pv210_cpu_init, | 558 | .init = s5pv210_cpu_init, |
| 568 | .name = "s5pv210", | 559 | .name = "s5pv210", |
| 569 | #ifdef CONFIG_PM | 560 | #ifdef CONFIG_PM |
diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index c7525fe33407..5c86e3fa5593 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c | |||
| @@ -30,11 +30,6 @@ static struct { | |||
| 30 | u32 cnt; | 30 | u32 cnt; |
| 31 | } spear_cpufreq; | 31 | } spear_cpufreq; |
| 32 | 32 | ||
| 33 | static unsigned int spear_cpufreq_get(unsigned int cpu) | ||
| 34 | { | ||
| 35 | return clk_get_rate(spear_cpufreq.clk) / 1000; | ||
| 36 | } | ||
| 37 | |||
| 38 | static struct clk *spear1340_cpu_get_possible_parent(unsigned long newfreq) | 33 | static struct clk *spear1340_cpu_get_possible_parent(unsigned long newfreq) |
| 39 | { | 34 | { |
| 40 | struct clk *sys_pclk; | 35 | struct clk *sys_pclk; |
| @@ -156,6 +151,7 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy, | |||
| 156 | 151 | ||
| 157 | static int spear_cpufreq_init(struct cpufreq_policy *policy) | 152 | static int spear_cpufreq_init(struct cpufreq_policy *policy) |
| 158 | { | 153 | { |
| 154 | policy->clk = spear_cpufreq.clk; | ||
| 159 | return cpufreq_generic_init(policy, spear_cpufreq.freq_tbl, | 155 | return cpufreq_generic_init(policy, spear_cpufreq.freq_tbl, |
| 160 | spear_cpufreq.transition_latency); | 156 | spear_cpufreq.transition_latency); |
| 161 | } | 157 | } |
| @@ -165,7 +161,7 @@ static struct cpufreq_driver spear_cpufreq_driver = { | |||
| 165 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | 161 | .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
| 166 | .verify = cpufreq_generic_frequency_table_verify, | 162 | .verify = cpufreq_generic_frequency_table_verify, |
| 167 | .target_index = spear_cpufreq_target, | 163 | .target_index = spear_cpufreq_target, |
| 168 | .get = spear_cpufreq_get, | 164 | .get = cpufreq_generic_get, |
| 169 | .init = spear_cpufreq_init, | 165 | .init = spear_cpufreq_init, |
| 170 | .exit = cpufreq_generic_exit, | 166 | .exit = cpufreq_generic_exit, |
| 171 | .attr = cpufreq_generic_attr, | 167 | .attr = cpufreq_generic_attr, |
diff --git a/drivers/cpufreq/tegra-cpufreq.c b/drivers/cpufreq/tegra-cpufreq.c index 01b5578ffecf..e652c1bd8d0f 100644 --- a/drivers/cpufreq/tegra-cpufreq.c +++ b/drivers/cpufreq/tegra-cpufreq.c | |||
| @@ -47,21 +47,9 @@ static struct clk *pll_x_clk; | |||
| 47 | static struct clk *pll_p_clk; | 47 | static struct clk *pll_p_clk; |
| 48 | static struct clk *emc_clk; | 48 | static struct clk *emc_clk; |
| 49 | 49 | ||
| 50 | static unsigned long target_cpu_speed[NUM_CPUS]; | ||
| 51 | static DEFINE_MUTEX(tegra_cpu_lock); | 50 | static DEFINE_MUTEX(tegra_cpu_lock); |
| 52 | static bool is_suspended; | 51 | static bool is_suspended; |
| 53 | 52 | ||
| 54 | static unsigned int tegra_getspeed(unsigned int cpu) | ||
| 55 | { | ||
| 56 | unsigned long rate; | ||
| 57 | |||
| 58 | if (cpu >= NUM_CPUS) | ||
| 59 | return 0; | ||
| 60 | |||
| 61 | rate = clk_get_rate(cpu_clk) / 1000; | ||
| 62 | return rate; | ||
| 63 | } | ||
| 64 | |||
| 65 | static int tegra_cpu_clk_set_rate(unsigned long rate) | 53 | static int tegra_cpu_clk_set_rate(unsigned long rate) |
| 66 | { | 54 | { |
| 67 | int ret; | 55 | int ret; |
| @@ -103,9 +91,6 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy, | |||
| 103 | { | 91 | { |
| 104 | int ret = 0; | 92 | int ret = 0; |
| 105 | 93 | ||
| 106 | if (tegra_getspeed(0) == rate) | ||
| 107 | return ret; | ||
| 108 | |||
| 109 | /* | 94 | /* |
| 110 | * Vote on memory bus frequency based on cpu frequency | 95 | * Vote on memory bus frequency based on cpu frequency |
| 111 | * This sets the minimum frequency, display or avp may request higher | 96 | * This sets the minimum frequency, display or avp may request higher |
| @@ -125,33 +110,16 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy, | |||
| 125 | return ret; | 110 | return ret; |
| 126 | } | 111 | } |
| 127 | 112 | ||
| 128 | static unsigned long tegra_cpu_highest_speed(void) | ||
| 129 | { | ||
| 130 | unsigned long rate = 0; | ||
| 131 | int i; | ||
| 132 | |||
| 133 | for_each_online_cpu(i) | ||
| 134 | rate = max(rate, target_cpu_speed[i]); | ||
| 135 | return rate; | ||
| 136 | } | ||
| 137 | |||
| 138 | static int tegra_target(struct cpufreq_policy *policy, unsigned int index) | 113 | static int tegra_target(struct cpufreq_policy *policy, unsigned int index) |
| 139 | { | 114 | { |
| 140 | unsigned int freq; | 115 | int ret = -EBUSY; |
| 141 | int ret = 0; | ||
| 142 | 116 | ||
| 143 | mutex_lock(&tegra_cpu_lock); | 117 | mutex_lock(&tegra_cpu_lock); |
| 144 | 118 | ||
| 145 | if (is_suspended) | 119 | if (!is_suspended) |
| 146 | goto out; | 120 | ret = tegra_update_cpu_speed(policy, |
| 147 | 121 | freq_table[index].frequency); | |
| 148 | freq = freq_table[index].frequency; | ||
| 149 | 122 | ||
| 150 | target_cpu_speed[policy->cpu] = freq; | ||
| 151 | |||
| 152 | ret = tegra_update_cpu_speed(policy, tegra_cpu_highest_speed()); | ||
| 153 | |||
| 154 | out: | ||
| 155 | mutex_unlock(&tegra_cpu_lock); | 123 | mutex_unlock(&tegra_cpu_lock); |
| 156 | return ret; | 124 | return ret; |
| 157 | } | 125 | } |
| @@ -165,7 +133,8 @@ static int tegra_pm_notify(struct notifier_block *nb, unsigned long event, | |||
| 165 | is_suspended = true; | 133 | is_suspended = true; |
| 166 | pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n", | 134 | pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n", |
| 167 | freq_table[0].frequency); | 135 | freq_table[0].frequency); |
| 168 | tegra_update_cpu_speed(policy, freq_table[0].frequency); | 136 | if (clk_get_rate(cpu_clk) / 1000 != freq_table[0].frequency) |
| 137 | tegra_update_cpu_speed(policy, freq_table[0].frequency); | ||
| 169 | cpufreq_cpu_put(policy); | 138 | cpufreq_cpu_put(policy); |
| 170 | } else if (event == PM_POST_SUSPEND) { | 139 | } else if (event == PM_POST_SUSPEND) { |
| 171 | is_suspended = false; | 140 | is_suspended = false; |
| @@ -189,8 +158,6 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) | |||
| 189 | clk_prepare_enable(emc_clk); | 158 | clk_prepare_enable(emc_clk); |
| 190 | clk_prepare_enable(cpu_clk); | 159 | clk_prepare_enable(cpu_clk); |
| 191 | 160 | ||
| 192 | target_cpu_speed[policy->cpu] = tegra_getspeed(policy->cpu); | ||
| 193 | |||
| 194 | /* FIXME: what's the actual transition time? */ | 161 | /* FIXME: what's the actual transition time? */ |
| 195 | ret = cpufreq_generic_init(policy, freq_table, 300 * 1000); | 162 | ret = cpufreq_generic_init(policy, freq_table, 300 * 1000); |
| 196 | if (ret) { | 163 | if (ret) { |
| @@ -202,6 +169,7 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) | |||
| 202 | if (policy->cpu == 0) | 169 | if (policy->cpu == 0) |
| 203 | register_pm_notifier(&tegra_cpu_pm_notifier); | 170 | register_pm_notifier(&tegra_cpu_pm_notifier); |
| 204 | 171 | ||
| 172 | policy->clk = cpu_clk; | ||
| 205 | return 0; | 173 | return 0; |
| 206 | } | 174 | } |
| 207 | 175 | ||
| @@ -217,7 +185,7 @@ static struct cpufreq_driver tegra_cpufreq_driver = { | |||
| 217 | .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, | 185 | .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
| 218 | .verify = cpufreq_generic_frequency_table_verify, | 186 | .verify = cpufreq_generic_frequency_table_verify, |
| 219 | .target_index = tegra_target, | 187 | .target_index = tegra_target, |
| 220 | .get = tegra_getspeed, | 188 | .get = cpufreq_generic_get, |
| 221 | .init = tegra_cpu_init, | 189 | .init = tegra_cpu_init, |
| 222 | .exit = tegra_cpu_exit, | 190 | .exit = tegra_cpu_exit, |
| 223 | .name = "tegra", | 191 | .name = "tegra", |
diff --git a/drivers/cpufreq/unicore2-cpufreq.c b/drivers/cpufreq/unicore2-cpufreq.c index 86f6cfec2e09..36cc330b8747 100644 --- a/drivers/cpufreq/unicore2-cpufreq.c +++ b/drivers/cpufreq/unicore2-cpufreq.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <linux/err.h> | ||
| 14 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
| 15 | #include <linux/types.h> | 16 | #include <linux/types.h> |
| 16 | #include <linux/init.h> | 17 | #include <linux/init.h> |
| @@ -33,28 +34,18 @@ static int ucv2_verify_speed(struct cpufreq_policy *policy) | |||
| 33 | return 0; | 34 | return 0; |
| 34 | } | 35 | } |
| 35 | 36 | ||
| 36 | static unsigned int ucv2_getspeed(unsigned int cpu) | ||
| 37 | { | ||
| 38 | struct clk *mclk = clk_get(NULL, "MAIN_CLK"); | ||
| 39 | |||
| 40 | if (cpu) | ||
| 41 | return 0; | ||
| 42 | return clk_get_rate(mclk)/1000; | ||
| 43 | } | ||
| 44 | |||
| 45 | static int ucv2_target(struct cpufreq_policy *policy, | 37 | static int ucv2_target(struct cpufreq_policy *policy, |
| 46 | unsigned int target_freq, | 38 | unsigned int target_freq, |
| 47 | unsigned int relation) | 39 | unsigned int relation) |
| 48 | { | 40 | { |
| 49 | struct cpufreq_freqs freqs; | 41 | struct cpufreq_freqs freqs; |
| 50 | struct clk *mclk = clk_get(NULL, "MAIN_CLK"); | ||
| 51 | int ret; | 42 | int ret; |
| 52 | 43 | ||
| 53 | freqs.old = policy->cur; | 44 | freqs.old = policy->cur; |
| 54 | freqs.new = target_freq; | 45 | freqs.new = target_freq; |
| 55 | 46 | ||
| 56 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 47 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
| 57 | ret = clk_set_rate(mclk, target_freq * 1000); | 48 | ret = clk_set_rate(policy->mclk, target_freq * 1000); |
| 58 | cpufreq_notify_post_transition(policy, &freqs, ret); | 49 | cpufreq_notify_post_transition(policy, &freqs, ret); |
| 59 | 50 | ||
| 60 | return ret; | 51 | return ret; |
| @@ -64,9 +55,13 @@ static int __init ucv2_cpu_init(struct cpufreq_policy *policy) | |||
| 64 | { | 55 | { |
| 65 | if (policy->cpu != 0) | 56 | if (policy->cpu != 0) |
| 66 | return -EINVAL; | 57 | return -EINVAL; |
| 58 | |||
| 67 | policy->min = policy->cpuinfo.min_freq = 250000; | 59 | policy->min = policy->cpuinfo.min_freq = 250000; |
| 68 | policy->max = policy->cpuinfo.max_freq = 1000000; | 60 | policy->max = policy->cpuinfo.max_freq = 1000000; |
| 69 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 61 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
| 62 | policy->clk = clk_get(NULL, "MAIN_CLK"); | ||
| 63 | if (IS_ERR(policy->clk)) | ||
| 64 | return PTR_ERR(policy->clk); | ||
| 70 | return 0; | 65 | return 0; |
| 71 | } | 66 | } |
| 72 | 67 | ||
| @@ -74,7 +69,7 @@ static struct cpufreq_driver ucv2_driver = { | |||
| 74 | .flags = CPUFREQ_STICKY, | 69 | .flags = CPUFREQ_STICKY, |
| 75 | .verify = ucv2_verify_speed, | 70 | .verify = ucv2_verify_speed, |
| 76 | .target = ucv2_target, | 71 | .target = ucv2_target, |
| 77 | .get = ucv2_getspeed, | 72 | .get = cpufreq_generic_get, |
| 78 | .init = ucv2_cpu_init, | 73 | .init = ucv2_cpu_init, |
| 79 | .name = "UniCore-II", | 74 | .name = "UniCore-II", |
| 80 | }; | 75 | }; |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index bb727eb98ed5..422f10561e0b 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #ifndef _LINUX_CPUFREQ_H | 11 | #ifndef _LINUX_CPUFREQ_H |
| 12 | #define _LINUX_CPUFREQ_H | 12 | #define _LINUX_CPUFREQ_H |
| 13 | 13 | ||
| 14 | #include <linux/clk.h> | ||
| 14 | #include <linux/cpumask.h> | 15 | #include <linux/cpumask.h> |
| 15 | #include <linux/completion.h> | 16 | #include <linux/completion.h> |
| 16 | #include <linux/kobject.h> | 17 | #include <linux/kobject.h> |
| @@ -66,6 +67,7 @@ struct cpufreq_policy { | |||
| 66 | unsigned int cpu; /* cpu nr of CPU managing this policy */ | 67 | unsigned int cpu; /* cpu nr of CPU managing this policy */ |
| 67 | unsigned int last_cpu; /* cpu nr of previous CPU that managed | 68 | unsigned int last_cpu; /* cpu nr of previous CPU that managed |
| 68 | * this policy */ | 69 | * this policy */ |
| 70 | struct clk *clk; | ||
| 69 | struct cpufreq_cpuinfo cpuinfo;/* see above */ | 71 | struct cpufreq_cpuinfo cpuinfo;/* see above */ |
| 70 | 72 | ||
| 71 | unsigned int min; /* in kHz */ | 73 | unsigned int min; /* in kHz */ |
| @@ -470,6 +472,7 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu); | |||
| 470 | int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, | 472 | int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, |
| 471 | struct cpufreq_frequency_table *table); | 473 | struct cpufreq_frequency_table *table); |
| 472 | 474 | ||
| 475 | unsigned int cpufreq_generic_get(unsigned int cpu); | ||
| 473 | int cpufreq_generic_init(struct cpufreq_policy *policy, | 476 | int cpufreq_generic_init(struct cpufreq_policy *policy, |
| 474 | struct cpufreq_frequency_table *table, | 477 | struct cpufreq_frequency_table *table, |
| 475 | unsigned int transition_latency); | 478 | unsigned int transition_latency); |
