1717#include <linux/cpu.h>
1818#include <linux/cpufreq.h>
1919#include <linux/cpuidle.h>
20+ #include <linux/delay.h>
2021#include <linux/err.h>
2122#include <linux/init.h>
2223#include <linux/kernel.h>
3334#include <linux/regmap.h>
3435#include <linux/regulator/consumer.h>
3536#include <linux/rockchip/cpu.h>
37+ #include <linux/workqueue.h>
3638#include <soc/rockchip/rockchip_opp_select.h>
3739#include <soc/rockchip/rockchip_system_monitor.h>
3840
@@ -54,6 +56,11 @@ struct cluster_info {
5456};
5557static LIST_HEAD (cluster_info_list );
5658
59+ #define CPUFREQ_DEFER_DELAY_MS 100
60+ #define CPUFREQ_DEFER_RETRIES 50
61+ static struct delayed_work cpufreq_defer_work ;
62+ static int cpufreq_defer_retry_count ;
63+
5764static struct cluster_info * rockchip_cluster_info_lookup (int cpu );
5865
5966static int px30_get_soc_info (struct device * dev , struct device_node * np ,
@@ -861,7 +868,7 @@ static struct notifier_block rockchip_cpufreq_panic_notifier_block = {
861868 .notifier_call = rockchip_cpufreq_panic_notifier ,
862869};
863870
864- static int __init rockchip_cpufreq_driver_init (void )
871+ static int rockchip_cpufreq_do_init (void )
865872{
866873 struct cluster_info * cluster , * pos ;
867874 struct cpufreq_dt_platform_data pdata = {0 };
@@ -881,6 +888,9 @@ static int __init rockchip_cpufreq_driver_init(void)
881888
882889 ret = rockchip_cpufreq_cluster_init (cpu , cluster );
883890 if (ret ) {
891+ kfree (cluster );
892+ if (ret == - EPROBE_DEFER )
893+ goto release_cluster_info ;
884894 pr_err ("Failed to initialize dvfs info cpu%d\n" , cpu );
885895 goto release_cluster_info ;
886896 }
@@ -929,7 +939,44 @@ static int __init rockchip_cpufreq_driver_init(void)
929939 }
930940 return ret ;
931941}
932- module_init (rockchip_cpufreq_driver_init );
942+
943+ static void rockchip_cpufreq_defer_work_func (struct work_struct * work )
944+ {
945+ int ret ;
946+
947+ ret = rockchip_cpufreq_do_init ();
948+ if (ret == - EPROBE_DEFER ) {
949+ if (++ cpufreq_defer_retry_count < CPUFREQ_DEFER_RETRIES ) {
950+ pr_debug ("cpufreq: regulator not ready, retry %d/%d\n" ,
951+ cpufreq_defer_retry_count , CPUFREQ_DEFER_RETRIES );
952+ schedule_delayed_work (& cpufreq_defer_work ,
953+ msecs_to_jiffies (CPUFREQ_DEFER_DELAY_MS ));
954+ } else {
955+ pr_err ("cpufreq: gave up waiting for regulator after %d retries\n" ,
956+ CPUFREQ_DEFER_RETRIES );
957+ }
958+ } else if (ret ) {
959+ pr_err ("cpufreq: initialization failed with error %d\n" , ret );
960+ }
961+ }
962+
963+ static int __init rockchip_cpufreq_driver_init (void )
964+ {
965+ int ret ;
966+
967+ ret = rockchip_cpufreq_do_init ();
968+ if (ret == - EPROBE_DEFER ) {
969+ pr_info ("cpufreq: regulator not ready, deferring initialization\n" );
970+ INIT_DELAYED_WORK (& cpufreq_defer_work ,
971+ rockchip_cpufreq_defer_work_func );
972+ schedule_delayed_work (& cpufreq_defer_work ,
973+ msecs_to_jiffies (CPUFREQ_DEFER_DELAY_MS ));
974+ return 0 ;
975+ }
976+
977+ return ret ;
978+ }
979+ late_initcall (rockchip_cpufreq_driver_init );
933980
934981MODULE_AUTHOR ("Finley Xiao <finley.xiao@rock-chips.com>" );
935982MODULE_DESCRIPTION ("Rockchip cpufreq driver" );
0 commit comments