Commit 90562c81 authored by Viresh Kumar's avatar Viresh Kumar
Browse files

Merge remote-tracking branch 'georgi/icc-get-by-index' into opp/linux-next

parents 6c591eec 8fd3574b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
# 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.

+55 −24
Original line number Diff line number Diff line
@@ -351,9 +351,9 @@ static struct icc_node *of_icc_get_from_provider(struct of_phandle_args *spec)
}

/**
 * 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
@@ -365,13 +365,12 @@ static struct icc_node *of_icc_get_from_provider(struct of_phandle_args *spec)
 * 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)
@@ -391,12 +390,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);
@@ -439,12 +432,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);

	if (!path->name) {
		kfree(path);
		return ERR_PTR(-ENOMEM);
@@ -452,6 +441,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);

/**
@@ -908,12 +944,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");
+6 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ struct device;
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 *of_icc_get_by_index(struct device *dev, int idx);
void icc_put(struct icc_path *path);
int icc_set_bw(struct icc_path *path, u32 avg_bw, u32 peak_bw);
void icc_set_tag(struct icc_path *path, u32 tag);
@@ -46,6 +47,11 @@ static inline struct icc_path *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)
{
}