summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorgi Djakov <georgi.djakov@linaro.org>2020-05-15 09:46:18 +0200
committerGeorgi Djakov <georgi.djakov@linaro.org>2020-05-15 09:46:18 +0200
commitb35da2e86f256a3a4be7c3b31507016100b00847 (patch)
tree1d3c2cfd2e97f02164cd32b5f92eda6d26ce7d07
parentinterconnect: Add helpers for enabling/disabling a path (diff)
parentinterconnect: Remove unused module exit code from core (diff)
downloadlinux-b35da2e86f256a3a4be7c3b31507016100b00847.tar.xz
linux-b35da2e86f256a3a4be7c3b31507016100b00847.zip
Merge branch 'icc-get-by-index' into icc-next
This is an immutable branch shared with the OPP tree. It contains also the patches to convert the interconnect framework from tristate to bool after Greg agreed with that. This will make the integration between the OPP layer and interconnect much easier. * icc-get-by-index: interconnect: Add of_icc_get_by_index() helper function interconnect: Disallow interconnect core to be built as a module interconnect: Remove unused module exit code from core Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
-rw-r--r--drivers/interconnect/Kconfig2
-rw-r--r--drivers/interconnect/core.c79
-rw-r--r--include/linux/interconnect.h6
3 files changed, 62 insertions, 25 deletions
diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
index 6fea3605f4a8..5b7204ee2eb2 100644
--- a/drivers/interconnect/Kconfig
+++ b/drivers/interconnect/Kconfig
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig INTERCONNECT
- tristate "On-Chip Interconnect management support"
+ bool "On-Chip Interconnect management support"
help
Support for management of the on-chip interconnects.
diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
index f9dd55a632dd..ece2a579a9b0 100644
--- a/drivers/interconnect/core.c
+++ b/drivers/interconnect/core.c
@@ -380,9 +380,9 @@ struct icc_path *devm_of_icc_get(struct device *dev, const char *name)
EXPORT_SYMBOL_GPL(devm_of_icc_get);
/**
- * of_icc_get() - get a path handle from a DT node based on name
+ * of_icc_get_by_index() - get a path handle from a DT node based on index
* @dev: device pointer for the consumer device
- * @name: interconnect path name
+ * @idx: interconnect path index
*
* This function will search for a path between two endpoints and return an
* icc_path handle on success. Use icc_put() to release constraints when they
@@ -394,13 +394,12 @@ EXPORT_SYMBOL_GPL(devm_of_icc_get);
* Return: icc_path pointer on success or ERR_PTR() on error. NULL is returned
* when the API is disabled or the "interconnects" DT property is missing.
*/
-struct icc_path *of_icc_get(struct device *dev, const char *name)
+struct icc_path *of_icc_get_by_index(struct device *dev, int idx)
{
- struct icc_path *path = ERR_PTR(-EPROBE_DEFER);
+ struct icc_path *path;
struct icc_node *src_node, *dst_node;
- struct device_node *np = NULL;
+ struct device_node *np;
struct of_phandle_args src_args, dst_args;
- int idx = 0;
int ret;
if (!dev || !dev->of_node)
@@ -420,12 +419,6 @@ struct icc_path *of_icc_get(struct device *dev, const char *name)
* lets support only global ids and extend this in the future if needed
* without breaking DT compatibility.
*/
- if (name) {
- idx = of_property_match_string(np, "interconnect-names", name);
- if (idx < 0)
- return ERR_PTR(idx);
- }
-
ret = of_parse_phandle_with_args(np, "interconnects",
"#interconnect-cells", idx * 2,
&src_args);
@@ -468,12 +461,8 @@ struct icc_path *of_icc_get(struct device *dev, const char *name)
return path;
}
- if (name)
- path->name = kstrdup_const(name, GFP_KERNEL);
- else
- path->name = kasprintf(GFP_KERNEL, "%s-%s",
- src_node->name, dst_node->name);
-
+ path->name = kasprintf(GFP_KERNEL, "%s-%s",
+ src_node->name, dst_node->name);
if (!path->name) {
kfree(path);
return ERR_PTR(-ENOMEM);
@@ -481,6 +470,53 @@ struct icc_path *of_icc_get(struct device *dev, const char *name)
return path;
}
+EXPORT_SYMBOL_GPL(of_icc_get_by_index);
+
+/**
+ * of_icc_get() - get a path handle from a DT node based on name
+ * @dev: device pointer for the consumer device
+ * @name: interconnect path name
+ *
+ * This function will search for a path between two endpoints and return an
+ * icc_path handle on success. Use icc_put() to release constraints when they
+ * are not needed anymore.
+ * If the interconnect API is disabled, NULL is returned and the consumer
+ * drivers will still build. Drivers are free to handle this specifically,
+ * but they don't have to.
+ *
+ * Return: icc_path pointer on success or ERR_PTR() on error. NULL is returned
+ * when the API is disabled or the "interconnects" DT property is missing.
+ */
+struct icc_path *of_icc_get(struct device *dev, const char *name)
+{
+ struct device_node *np;
+ int idx = 0;
+
+ if (!dev || !dev->of_node)
+ return ERR_PTR(-ENODEV);
+
+ np = dev->of_node;
+
+ /*
+ * 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))
+ return NULL;
+
+ /*
+ * We use a combination of phandle and specifier for endpoint. For now
+ * lets support only global ids and extend this in the future if needed
+ * without breaking DT compatibility.
+ */
+ if (name) {
+ idx = of_property_match_string(np, "interconnect-names", name);
+ if (idx < 0)
+ return ERR_PTR(idx);
+ }
+
+ return of_icc_get_by_index(dev, idx);
+}
EXPORT_SYMBOL_GPL(of_icc_get);
/**
@@ -970,12 +1006,7 @@ static int __init icc_init(void)
return 0;
}
-static void __exit icc_exit(void)
-{
- debugfs_remove_recursive(icc_debugfs_dir);
-}
-module_init(icc_init);
-module_exit(icc_exit);
+device_initcall(icc_init);
MODULE_AUTHOR("Georgi Djakov <georgi.djakov@linaro.org>");
MODULE_DESCRIPTION("Interconnect Driver Core");
diff --git a/include/linux/interconnect.h b/include/linux/interconnect.h
index e56a95e3cf25..d8c29049f066 100644
--- a/include/linux/interconnect.h
+++ b/include/linux/interconnect.h
@@ -29,6 +29,7 @@ struct icc_path *icc_get(struct device *dev, const int src_id,
const int dst_id);
struct icc_path *of_icc_get(struct device *dev, const char *name);
struct icc_path *devm_of_icc_get(struct device *dev, const char *name);
+struct icc_path *of_icc_get_by_index(struct device *dev, int idx);
void icc_put(struct icc_path *path);
int icc_enable(struct icc_path *path);
int icc_disable(struct icc_path *path);
@@ -55,6 +56,11 @@ static inline struct icc_path *devm_of_icc_get(struct device *dev,
return NULL;
}
+static inline struct icc_path *of_icc_get_by_index(struct device *dev, int idx)
+{
+ return NULL;
+}
+
static inline void icc_put(struct icc_path *path)
{
}