rockchip: fix panic when probe rockchip-cpufreq driver
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
parent
81d0182d18
commit
e6a0be1ac5
|
@ -0,0 +1,178 @@
|
|||
--- a/drivers/cpufreq/rockchip-cpufreq.c
|
||||
+++ b/drivers/cpufreq/rockchip-cpufreq.c
|
||||
@@ -332,13 +332,13 @@ static int rockchip_cpufreq_cluster_init
|
||||
reg_table_token = dev_pm_opp_set_regulators(dev, reg_names);
|
||||
if (reg_table_token < 0) {
|
||||
ret = reg_table_token;
|
||||
- dev_err_probe(dev, ret, "Failed to set opp regulators\n");
|
||||
+ dev_err(dev, "Failed to set opp regulators\n");
|
||||
goto np_err;
|
||||
}
|
||||
|
||||
ret = dev_pm_opp_of_get_sharing_cpus(dev, &cluster->cpus);
|
||||
if (ret) {
|
||||
- dev_err_probe(dev, ret, "Failed to get sharing cpus\n");
|
||||
+ dev_err(dev, "Failed to get sharing cpus\n");
|
||||
goto np_err;
|
||||
}
|
||||
|
||||
@@ -519,67 +519,10 @@ static int rockchip_cpufreq_init(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void rockchip_cpufreq_free_list(void *data)
|
||||
-{
|
||||
- struct cluster_info *cluster, *pos;
|
||||
-
|
||||
- list_for_each_entry_safe(cluster, pos, &cluster_info_list, list_head) {
|
||||
- list_del(&cluster->list_head);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static int rockchip_cpufreq_init_list(struct device *dev)
|
||||
-{
|
||||
- struct cluster_info *cluster;
|
||||
- int cpu, ret;
|
||||
-
|
||||
- for_each_possible_cpu(cpu) {
|
||||
- cluster = rockchip_cluster_info_lookup(cpu);
|
||||
- if (cluster)
|
||||
- continue;
|
||||
-
|
||||
- cluster = devm_kzalloc(dev, sizeof(*cluster), GFP_KERNEL);
|
||||
- if (!cluster) {
|
||||
- ret = -ENOMEM;
|
||||
- goto release_cluster_info;
|
||||
- }
|
||||
-
|
||||
- ret = rockchip_cpufreq_cluster_init(cpu, cluster);
|
||||
- if (ret) {
|
||||
- dev_err_probe(dev, ret, "Failed to initialize dvfs info cpu%d\n", cpu);
|
||||
- goto release_cluster_info;
|
||||
- }
|
||||
- list_add(&cluster->list_head, &cluster_info_list);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-
|
||||
-release_cluster_info:
|
||||
- rockchip_cpufreq_free_list(NULL);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static void rockchip_cpufreq_unregister(void *data)
|
||||
-{
|
||||
- cpufreq_unregister_driver(&rockchip_cpufreq_driver);
|
||||
-}
|
||||
-
|
||||
static int rockchip_cpufreq_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret, cpu;
|
||||
|
||||
- ret = rockchip_cpufreq_init_list(&pdev->dev);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = devm_add_action_or_reset(&pdev->dev, rockchip_cpufreq_free_list, NULL);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- ret = devm_register_reboot_notifier(&pdev->dev, &rockchip_cpufreq_reboot_notifier);
|
||||
- if (ret)
|
||||
- return dev_err_probe(&pdev->dev, ret, "Failed to register reboot handler\n");
|
||||
-
|
||||
for_each_possible_cpu(cpu) {
|
||||
ret = rockchip_cpufreq_init(&pdev->dev, cpu);
|
||||
if (ret)
|
||||
@@ -590,10 +533,12 @@ static int rockchip_cpufreq_probe(struct
|
||||
if (ret)
|
||||
return dev_err_probe(&pdev->dev, ret, "failed register driver\n");
|
||||
|
||||
- ret = devm_add_action_or_reset(&pdev->dev, rockchip_cpufreq_unregister, NULL);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
+static int rockchip_cpufreq_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ cpufreq_unregister_driver(&rockchip_cpufreq_driver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -602,15 +547,42 @@ static struct platform_driver rockchip_c
|
||||
.name = "rockchip-cpufreq",
|
||||
},
|
||||
.probe = rockchip_cpufreq_probe,
|
||||
+ .remove = rockchip_cpufreq_remove,
|
||||
};
|
||||
|
||||
static int __init rockchip_cpufreq_driver_init(void)
|
||||
{
|
||||
- int ret;
|
||||
+ struct cluster_info *cluster, *pos;
|
||||
+ int cpu, ret;
|
||||
+
|
||||
+ for_each_possible_cpu(cpu) {
|
||||
+ cluster = rockchip_cluster_info_lookup(cpu);
|
||||
+ if (cluster)
|
||||
+ continue;
|
||||
+
|
||||
+ cluster = kzalloc(sizeof(*cluster), GFP_KERNEL);
|
||||
+ if (!cluster) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto release_cluster_info;
|
||||
+ }
|
||||
+
|
||||
+ ret = rockchip_cpufreq_cluster_init(cpu, cluster);
|
||||
+ if (ret) {
|
||||
+ pr_err("Failed to initialize dvfs info cpu%d\n", cpu);
|
||||
+ goto release_cluster_info;
|
||||
+ }
|
||||
+ list_add(&cluster->list_head, &cluster_info_list);
|
||||
+ }
|
||||
+
|
||||
+ ret = register_reboot_notifier(&rockchip_cpufreq_reboot_notifier);
|
||||
+ if (ret) {
|
||||
+ pr_err("Failed to register reboot handler\n");
|
||||
+ goto release_cluster_info;
|
||||
+ }
|
||||
|
||||
ret = platform_driver_register(&rockchip_cpufreq_platdrv);
|
||||
if (ret)
|
||||
- return ret;
|
||||
+ goto remove_reboot_notifier;
|
||||
|
||||
cpufreq_pdev = platform_device_register_data(NULL, "rockchip-cpufreq", -1,
|
||||
NULL, 0);
|
||||
@@ -624,14 +596,30 @@ static int __init rockchip_cpufreq_drive
|
||||
|
||||
unregister_platform_driver:
|
||||
platform_driver_unregister(&rockchip_cpufreq_platdrv);
|
||||
+
|
||||
+remove_reboot_notifier:
|
||||
+ unregister_reboot_notifier(&rockchip_cpufreq_reboot_notifier);
|
||||
+
|
||||
+release_cluster_info:
|
||||
+ list_for_each_entry_safe(cluster, pos, &cluster_info_list, list_head) {
|
||||
+ list_del(&cluster->list_head);
|
||||
+ kfree(cluster);
|
||||
+ }
|
||||
return ret;
|
||||
}
|
||||
module_init(rockchip_cpufreq_driver_init);
|
||||
|
||||
static void __exit rockchip_cpufreq_driver_exit(void)
|
||||
{
|
||||
+ struct cluster_info *cluster, *pos;
|
||||
+
|
||||
platform_device_unregister(cpufreq_pdev);
|
||||
platform_driver_unregister(&rockchip_cpufreq_platdrv);
|
||||
+ unregister_reboot_notifier(&rockchip_cpufreq_reboot_notifier);
|
||||
+ list_for_each_entry_safe(cluster, pos, &cluster_info_list, list_head) {
|
||||
+ list_del(&cluster->list_head);
|
||||
+ kfree(cluster);
|
||||
+ }
|
||||
}
|
||||
module_exit(rockchip_cpufreq_driver_exit)
|
||||
|
Loading…
Reference in New Issue
Block a user