aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/interconnect/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/interconnect/core.c')
-rw-r--r--drivers/interconnect/core.c138
1 files changed, 48 insertions, 90 deletions
diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
index 25debded65a8..ec46bcb16d5e 100644
--- a/drivers/interconnect/core.c
+++ b/drivers/interconnect/core.c
@@ -13,7 +13,6 @@
#include <linux/interconnect.h>
#include <linux/interconnect-provider.h>
#include <linux/list.h>
-#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/of.h>
@@ -451,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;
/*
@@ -544,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;
/*
@@ -850,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);
@@ -907,52 +910,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
* @provider: pointer to the interconnect provider
@@ -977,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;
@@ -1029,65 +989,67 @@ 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" },
+ { .compatible = "qcom,sc8180x-ipa-virt" },
+ { .compatible = "qcom,sdx55-ipa-virt" },
+ { .compatible = "qcom,sm8150-ipa-virt" },
+ { .compatible = "qcom,sm8250-ipa-virt" },
+ {}
+};
static int of_count_icc_providers(struct device_node *np)
{
struct device_node *child;
int count = 0;
- const struct of_device_id __maybe_unused ignore_list[] = {
- { .compatible = "qcom,sc7180-ipa-virt" },
- { .compatible = "qcom,sdx55-ipa-virt" },
- {}
- };
for_each_available_child_of_node(np, child) {
if (of_property_read_bool(child, "#interconnect-cells") &&
@@ -1143,7 +1105,3 @@ static int __init icc_init(void)
}
device_initcall(icc_init);
-
-MODULE_AUTHOR("Georgi Djakov <georgi.djakov@linaro.org>");
-MODULE_DESCRIPTION("Interconnect Driver Core");
-MODULE_LICENSE("GPL v2");