Skip to content

Commit e0e5b2b

Browse files
PabloPLvireshk
authored andcommitted
cpufreq: s5pv210: Defer probe if getting regulators fail
There is possibility, that when probing driver, regulators are not yet initialized. In this case we should return EPROBE_DEFER and wait till they're initialized, since they're required currently for cpufreq driver to work. Also move regulator initialization code at beginning of probe, so we can defer as fast as posibble. Signed-off-by: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com> Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
1 parent 70e6e7d commit e0e5b2b

File tree

1 file changed

+48
-19
lines changed

1 file changed

+48
-19
lines changed

drivers/cpufreq/s5pv210-cpufreq.c

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ static struct notifier_block s5pv210_cpufreq_reboot_notifier = {
584584
static int s5pv210_cpufreq_probe(struct platform_device *pdev)
585585
{
586586
struct device_node *np;
587-
int id;
587+
int id, result = 0;
588588

589589
/*
590590
* HACK: This is a temporary workaround to get access to clock
@@ -594,18 +594,39 @@ static int s5pv210_cpufreq_probe(struct platform_device *pdev)
594594
* this whole driver as soon as S5PV210 gets migrated to use
595595
* cpufreq-dt driver.
596596
*/
597+
arm_regulator = regulator_get(NULL, "vddarm");
598+
if (IS_ERR(arm_regulator)) {
599+
if (PTR_ERR(arm_regulator) == -EPROBE_DEFER)
600+
pr_debug("vddarm regulator not ready, defer\n");
601+
else
602+
pr_err("failed to get regulator vddarm\n");
603+
return PTR_ERR(arm_regulator);
604+
}
605+
606+
int_regulator = regulator_get(NULL, "vddint");
607+
if (IS_ERR(int_regulator)) {
608+
if (PTR_ERR(int_regulator) == -EPROBE_DEFER)
609+
pr_debug("vddint regulator not ready, defer\n");
610+
else
611+
pr_err("failed to get regulator vddint\n");
612+
result = PTR_ERR(int_regulator);
613+
goto err_int_regulator;
614+
}
615+
597616
np = of_find_compatible_node(NULL, NULL, "samsung,s5pv210-clock");
598617
if (!np) {
599618
pr_err("%s: failed to find clock controller DT node\n",
600619
__func__);
601-
return -ENODEV;
620+
result = -ENODEV;
621+
goto err_clock;
602622
}
603623

604624
clk_base = of_iomap(np, 0);
605625
of_node_put(np);
606626
if (!clk_base) {
607627
pr_err("%s: failed to map clock registers\n", __func__);
608-
return -EFAULT;
628+
result = -EFAULT;
629+
goto err_clock;
609630
}
610631

611632
for_each_compatible_node(np, NULL, "samsung,s5pv210-dmc") {
@@ -614,41 +635,49 @@ static int s5pv210_cpufreq_probe(struct platform_device *pdev)
614635
pr_err("%s: failed to get alias of dmc node '%pOFn'\n",
615636
__func__, np);
616637
of_node_put(np);
617-
return id;
638+
result = id;
639+
goto err_clk_base;
618640
}
619641

620642
dmc_base[id] = of_iomap(np, 0);
621643
if (!dmc_base[id]) {
622644
pr_err("%s: failed to map dmc%d registers\n",
623645
__func__, id);
624646
of_node_put(np);
625-
return -EFAULT;
647+
result = -EFAULT;
648+
goto err_dmc;
626649
}
627650
}
628651

629652
for (id = 0; id < ARRAY_SIZE(dmc_base); ++id) {
630653
if (!dmc_base[id]) {
631654
pr_err("%s: failed to find dmc%d node\n", __func__, id);
632-
return -ENODEV;
655+
result = -ENODEV;
656+
goto err_dmc;
633657
}
634658
}
635659

636-
arm_regulator = regulator_get(NULL, "vddarm");
637-
if (IS_ERR(arm_regulator)) {
638-
pr_err("failed to get regulator vddarm\n");
639-
return PTR_ERR(arm_regulator);
640-
}
641-
642-
int_regulator = regulator_get(NULL, "vddint");
643-
if (IS_ERR(int_regulator)) {
644-
pr_err("failed to get regulator vddint\n");
645-
regulator_put(arm_regulator);
646-
return PTR_ERR(int_regulator);
647-
}
648-
649660
register_reboot_notifier(&s5pv210_cpufreq_reboot_notifier);
650661

651662
return cpufreq_register_driver(&s5pv210_driver);
663+
664+
err_dmc:
665+
for (id = 0; id < ARRAY_SIZE(dmc_base); ++id)
666+
if (dmc_base[id]) {
667+
iounmap(dmc_base[id]);
668+
dmc_base[id] = NULL;
669+
}
670+
671+
err_clk_base:
672+
iounmap(clk_base);
673+
674+
err_clock:
675+
regulator_put(int_regulator);
676+
677+
err_int_regulator:
678+
regulator_put(arm_regulator);
679+
680+
return result;
652681
}
653682

654683
static struct platform_driver s5pv210_cpufreq_platdrv = {

0 commit comments

Comments
 (0)