interconnect: exynos: fix registration race
[linux-2.6-microblaze.git] / drivers / interconnect / samsung / exynos.c
index e706658..72e4260 100644 (file)
@@ -98,12 +98,13 @@ static int exynos_generic_icc_remove(struct platform_device *pdev)
        struct exynos_icc_priv *priv = platform_get_drvdata(pdev);
        struct icc_node *parent_node, *node = priv->node;
 
+       icc_provider_deregister(&priv->provider);
+
        parent_node = exynos_icc_get_parent(priv->dev->parent->of_node);
        if (parent_node && !IS_ERR(parent_node))
                icc_link_destroy(node, parent_node);
 
        icc_nodes_remove(&priv->provider);
-       icc_provider_del(&priv->provider);
 
        return 0;
 }
@@ -132,15 +133,11 @@ static int exynos_generic_icc_probe(struct platform_device *pdev)
        provider->inter_set = true;
        provider->data = priv;
 
-       ret = icc_provider_add(provider);
-       if (ret < 0)
-               return ret;
+       icc_provider_init(provider);
 
        icc_node = icc_node_create(pdev->id);
-       if (IS_ERR(icc_node)) {
-               ret = PTR_ERR(icc_node);
-               goto err_prov_del;
-       }
+       if (IS_ERR(icc_node))
+               return PTR_ERR(icc_node);
 
        priv->node = icc_node;
        icc_node->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOFn",
@@ -171,14 +168,17 @@ static int exynos_generic_icc_probe(struct platform_device *pdev)
                        goto err_pmqos_del;
        }
 
+       ret = icc_provider_register(provider);
+       if (ret < 0)
+               goto err_pmqos_del;
+
        return 0;
 
 err_pmqos_del:
        dev_pm_qos_remove_request(&priv->qos_req);
 err_node_del:
        icc_nodes_remove(provider);
-err_prov_del:
-       icc_provider_del(provider);
+
        return ret;
 }