summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2018-04-24 05:39:46 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-05-10 05:43:59 -0400
commitcfd84631d976777e4b598d158e968c7bd55cf70a (patch)
treed76d983d2349e319a6412218681f78fa76a4242a /drivers
parent67782701157141048e065970ddb241a0461c55be (diff)
cpufreq: armada: Free resources on error paths
The resources weren't freed on failures, free them properly. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Tested-by: Miquel Raynal <miquel.raynal@bootlin.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/cpufreq/armada-37xx-cpufreq.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c
index 72a2975499db..1d5db6f6ace9 100644
--- a/drivers/cpufreq/armada-37xx-cpufreq.c
+++ b/drivers/cpufreq/armada-37xx-cpufreq.c
@@ -166,6 +166,7 @@ static int __init armada37xx_cpufreq_driver_init(void)
166{ 166{
167 struct armada_37xx_dvfs *dvfs; 167 struct armada_37xx_dvfs *dvfs;
168 struct platform_device *pdev; 168 struct platform_device *pdev;
169 unsigned long freq;
169 unsigned int cur_frequency; 170 unsigned int cur_frequency;
170 struct regmap *nb_pm_base; 171 struct regmap *nb_pm_base;
171 struct device *cpu_dev; 172 struct device *cpu_dev;
@@ -207,33 +208,43 @@ static int __init armada37xx_cpufreq_driver_init(void)
207 } 208 }
208 209
209 dvfs = armada_37xx_cpu_freq_info_get(cur_frequency); 210 dvfs = armada_37xx_cpu_freq_info_get(cur_frequency);
210 if (!dvfs) 211 if (!dvfs) {
212 clk_put(clk);
211 return -EINVAL; 213 return -EINVAL;
214 }
212 215
213 armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider); 216 armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider);
214 clk_put(clk); 217 clk_put(clk);
215 218
216 for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR; 219 for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR;
217 load_lvl++) { 220 load_lvl++) {
218 unsigned long freq = cur_frequency / dvfs->divider[load_lvl]; 221 freq = cur_frequency / dvfs->divider[load_lvl];
219 222
220 ret = dev_pm_opp_add(cpu_dev, freq, 0); 223 ret = dev_pm_opp_add(cpu_dev, freq, 0);
221 if (ret) { 224 if (ret)
222 /* clean-up the already added opp before leaving */ 225 goto remove_opp;
223 while (load_lvl-- > ARMADA_37XX_DVFS_LOAD_0) {
224 freq = cur_frequency / dvfs->divider[load_lvl];
225 dev_pm_opp_remove(cpu_dev, freq);
226 }
227 return ret;
228 }
229 } 226 }
230 227
231 /* Now that everything is setup, enable the DVFS at hardware level */ 228 /* Now that everything is setup, enable the DVFS at hardware level */
232 armada37xx_cpufreq_enable_dvfs(nb_pm_base); 229 armada37xx_cpufreq_enable_dvfs(nb_pm_base);
233 230
234 pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0); 231 pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
232 ret = PTR_ERR_OR_ZERO(pdev);
233 if (ret)
234 goto disable_dvfs;
235
236 return 0;
237
238disable_dvfs:
239 armada37xx_cpufreq_disable_dvfs(nb_pm_base);
240remove_opp:
241 /* clean-up the already added opp before leaving */
242 while (load_lvl-- > ARMADA_37XX_DVFS_LOAD_0) {
243 freq = cur_frequency / dvfs->divider[load_lvl];
244 dev_pm_opp_remove(cpu_dev, freq);
245 }
235 246
236 return PTR_ERR_OR_ZERO(pdev); 247 return ret;
237} 248}
238/* late_initcall, to guarantee the driver is loaded after A37xx clock driver */ 249/* late_initcall, to guarantee the driver is loaded after A37xx clock driver */
239late_initcall(armada37xx_cpufreq_driver_init); 250late_initcall(armada37xx_cpufreq_driver_init);