Merge tag 'modules-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof...
[linux-2.6-microblaze.git] / drivers / interconnect / core.c
index a112d7d..ec46bcb 100644 (file)
@@ -450,7 +450,7 @@ struct icc_path *of_icc_get_by_index(struct device *dev, int idx)
         * When the consumer DT node do not have "interconnects" property
         * return a NULL path to skip setting constraints.
         */
-       if (!of_find_property(np, "interconnects", NULL))
+       if (!of_property_present(np, "interconnects"))
                return NULL;
 
        /*
@@ -543,7 +543,7 @@ struct icc_path *of_icc_get(struct device *dev, const char *name)
         * When the consumer DT node do not have "interconnects" property
         * return a NULL path to skip setting constraints.
         */
-       if (!of_find_property(np, "interconnects", NULL))
+       if (!of_property_present(np, "interconnects"))
                return NULL;
 
        /*
@@ -849,6 +849,10 @@ void icc_node_destroy(int id)
 
        mutex_unlock(&icc_lock);
 
+       if (!node)
+               return;
+
+       kfree(node->links);
        kfree(node);
 }
 EXPORT_SYMBOL_GPL(icc_node_destroy);
@@ -905,52 +909,6 @@ out:
 }
 EXPORT_SYMBOL_GPL(icc_link_create);
 
-/**
- * icc_link_destroy() - destroy a link between two nodes
- * @src: pointer to source node
- * @dst: pointer to destination node
- *
- * Return: 0 on success, or an error code otherwise
- */
-int icc_link_destroy(struct icc_node *src, struct icc_node *dst)
-{
-       struct icc_node **new;
-       size_t slot;
-       int ret = 0;
-
-       if (IS_ERR_OR_NULL(src))
-               return -EINVAL;
-
-       if (IS_ERR_OR_NULL(dst))
-               return -EINVAL;
-
-       mutex_lock(&icc_lock);
-
-       for (slot = 0; slot < src->num_links; slot++)
-               if (src->links[slot] == dst)
-                       break;
-
-       if (WARN_ON(slot == src->num_links)) {
-               ret = -ENXIO;
-               goto out;
-       }
-
-       src->links[slot] = src->links[--src->num_links];
-
-       new = krealloc(src->links, src->num_links * sizeof(*src->links),
-                      GFP_KERNEL);
-       if (new)
-               src->links = new;
-       else
-               ret = -ENOMEM;
-
-out:
-       mutex_unlock(&icc_lock);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(icc_link_destroy);
-
 /**
  * icc_node_add() - add interconnect node to interconnect provider
  * @node: pointer to the interconnect node
@@ -976,14 +934,17 @@ void icc_node_add(struct icc_node *node, struct icc_provider *provider)
        node->avg_bw = node->init_avg;
        node->peak_bw = node->init_peak;
 
-       if (provider->pre_aggregate)
-               provider->pre_aggregate(node);
+       if (node->avg_bw || node->peak_bw) {
+               if (provider->pre_aggregate)
+                       provider->pre_aggregate(node);
 
-       if (provider->aggregate)
-               provider->aggregate(node, 0, node->init_avg, node->init_peak,
-                                   &node->avg_bw, &node->peak_bw);
+               if (provider->aggregate)
+                       provider->aggregate(node, 0, node->init_avg, node->init_peak,
+                                           &node->avg_bw, &node->peak_bw);
+               if (provider->set)
+                       provider->set(node, node);
+       }
 
-       provider->set(node, node);
        node->avg_bw = 0;
        node->peak_bw = 0;
 
@@ -1028,55 +989,53 @@ int icc_nodes_remove(struct icc_provider *provider)
 EXPORT_SYMBOL_GPL(icc_nodes_remove);
 
 /**
- * icc_provider_add() - add a new interconnect provider
- * @provider: the interconnect provider that will be added into topology
+ * icc_provider_init() - initialize a new interconnect provider
+ * @provider: the interconnect provider to initialize
+ *
+ * Must be called before adding nodes to the provider.
+ */
+void icc_provider_init(struct icc_provider *provider)
+{
+       WARN_ON(!provider->set);
+
+       INIT_LIST_HEAD(&provider->nodes);
+}
+EXPORT_SYMBOL_GPL(icc_provider_init);
+
+/**
+ * icc_provider_register() - register a new interconnect provider
+ * @provider: the interconnect provider to register
  *
  * Return: 0 on success, or an error code otherwise
  */
-int icc_provider_add(struct icc_provider *provider)
+int icc_provider_register(struct icc_provider *provider)
 {
-       if (WARN_ON(!provider->set))
-               return -EINVAL;
        if (WARN_ON(!provider->xlate && !provider->xlate_extended))
                return -EINVAL;
 
        mutex_lock(&icc_lock);
-
-       INIT_LIST_HEAD(&provider->nodes);
        list_add_tail(&provider->provider_list, &icc_providers);
-
        mutex_unlock(&icc_lock);
 
-       dev_dbg(provider->dev, "interconnect provider added to topology\n");
+       dev_dbg(provider->dev, "interconnect provider registered\n");
 
        return 0;
 }
-EXPORT_SYMBOL_GPL(icc_provider_add);
+EXPORT_SYMBOL_GPL(icc_provider_register);
 
 /**
- * icc_provider_del() - delete previously added interconnect provider
- * @provider: the interconnect provider that will be removed from topology
+ * icc_provider_deregister() - deregister an interconnect provider
+ * @provider: the interconnect provider to deregister
  */
-void icc_provider_del(struct icc_provider *provider)
+void icc_provider_deregister(struct icc_provider *provider)
 {
        mutex_lock(&icc_lock);
-       if (provider->users) {
-               pr_warn("interconnect provider still has %d users\n",
-                       provider->users);
-               mutex_unlock(&icc_lock);
-               return;
-       }
-
-       if (!list_empty(&provider->nodes)) {
-               pr_warn("interconnect provider still has nodes\n");
-               mutex_unlock(&icc_lock);
-               return;
-       }
+       WARN_ON(provider->users);
 
        list_del(&provider->provider_list);
        mutex_unlock(&icc_lock);
 }
-EXPORT_SYMBOL_GPL(icc_provider_del);
+EXPORT_SYMBOL_GPL(icc_provider_deregister);
 
 static const struct of_device_id __maybe_unused ignore_list[] = {
        { .compatible = "qcom,sc7180-ipa-virt" },