aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinaro CI <ci_notify@linaro.org>2020-07-26 22:35:07 +0000
committerLinaro CI <ci_notify@linaro.org>2020-07-26 22:35:07 +0000
commit99f1d2d1d744ff78ab22584e21554dc2002eba06 (patch)
treede9597756c8413a2c189e17eab00baf6170058ee
parent45b678c84e915dbfa7fd3ae250482121650db1db (diff)
parent627223c5ca0d54b0334a1178384e7ed382012f3a (diff)
Merge remote-tracking branch 'bus-scaling/icc-testing' into integration-linux-qcomlt
-rw-r--r--drivers/interconnect/Makefile2
-rw-r--r--drivers/interconnect/bulk.c119
-rw-r--r--drivers/interconnect/core.c8
-rw-r--r--drivers/interconnect/qcom/msm8916.c4
-rw-r--r--drivers/interconnect/qcom/qcs404.c4
-rw-r--r--drivers/pci/controller/dwc/pcie-qcom.c8
-rw-r--r--include/linux/interconnect-provider.h8
-rw-r--r--include/linux/interconnect.h22
8 files changed, 162 insertions, 13 deletions
diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
index 4825c287ca13..d203520b0a56 100644
--- a/drivers/interconnect/Makefile
+++ b/drivers/interconnect/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
CFLAGS_core.o := -I$(src)
-icc-core-objs := core.o
+icc-core-objs := core.o bulk.o
obj-$(CONFIG_INTERCONNECT) += icc-core.o
obj-$(CONFIG_INTERCONNECT_IMX) += imx/
diff --git a/drivers/interconnect/bulk.c b/drivers/interconnect/bulk.c
new file mode 100644
index 000000000000..9bd418594665
--- /dev/null
+++ b/drivers/interconnect/bulk.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/interconnect-provider.h>
+#include <linux/device.h>
+#include <linux/export.h>
+
+/**
+ * of_icc_bulk_get - get interconnect paths
+ * @dev: the device requesting the path
+ * @num_paths: the number of icc_bulk_data
+ * @paths: the table with the paths we want to get
+ *
+ * Returns 0 on success or -EERROR otherwise.
+ */
+int __must_check of_icc_bulk_get(struct device *dev, int num_paths,
+ struct icc_bulk_data *paths)
+{
+ int ret, i;
+
+ for (i = 0; i < num_paths; i++) {
+ paths[i].path = of_icc_get(dev, paths[i].name);
+ if (IS_ERR(paths[i].path)) {
+ ret = PTR_ERR(paths[i].path);
+ dev_err(dev, "of_icc_get() failed on path %s (%d)\n",
+ paths[i].name, ret);
+ paths[i].path = NULL;
+ goto err;
+ }
+ }
+
+ return 0;
+
+err:
+ icc_bulk_put(i, paths);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(of_icc_bulk_get);
+
+/**
+ * icc_bulk_put - put a list of interconnect paths
+ * @num_paths: the number of icc_bulk_data
+ * @paths: the icc_bulk_data table with the paths being put
+ */
+void icc_bulk_put(int num_paths, struct icc_bulk_data *paths)
+{
+ while (--num_paths >= 0) {
+ icc_put(paths[num_paths].path);
+ paths[num_paths].path = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(icc_bulk_put);
+
+/**
+ * icc_bulk_set - set bandwidth to a set of paths
+ * @num_paths: the number of icc_bulk_data
+ * @paths: the icc_bulk_data table containing the paths and bandwidth
+ *
+ * Returns 0 on success or -EERROR otherwise.
+ */
+int icc_bulk_set_bw(int num_paths, const struct icc_bulk_data *paths)
+{
+ int ret = 0;
+ int i;
+
+ for (i = 0; i < num_paths; i++) {
+ ret = icc_set_bw(paths[i].path, paths[i].avg_bw,
+ paths[i].peak_bw);
+ if (ret) {
+ pr_err("icc_set_bw() failed on path %s (%d)\n",
+ paths[i].name, ret);
+ return ret;
+ }
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(icc_bulk_set_bw);
+
+/**
+ * icc_bulk_enable - enable a previously disabled set of paths
+ * @num_paths: the number of icc_bulk_data
+ * @paths: the icc_bulk_data table containing the paths and bandwidth
+ *
+ * Returns 0 on success or -EERROR otherwise.
+ */
+int icc_bulk_enable(int num_paths, const struct icc_bulk_data *paths)
+{
+ int ret, i;
+
+ for (i = 0; i < num_paths; i++) {
+ ret = icc_enable(paths[i].path);
+ if (ret) {
+ pr_err("icc_enable() failed on path %s (%d)\n",
+ paths[i].name, ret);
+ goto err;
+ }
+ }
+
+ return 0;
+
+err:
+ icc_bulk_disable(i, paths);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(icc_bulk_enable);
+
+/**
+ * icc_bulk_disable - disable a set of interconnect paths
+ * @num_paths: the number of icc_bulk_data
+ * @paths: the icc_bulk_data table containing the paths and bandwidth
+ */
+void icc_bulk_disable(int num_paths, const struct icc_bulk_data *paths)
+{
+ while (--num_paths >= 0)
+ icc_disable(paths[num_paths].path);
+}
+EXPORT_SYMBOL_GPL(icc_bulk_disable);
diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c
index 9e1ab701785c..305b24e4a185 100644
--- a/drivers/interconnect/core.c
+++ b/drivers/interconnect/core.c
@@ -431,18 +431,16 @@ struct icc_path *of_icc_get_by_index(struct device *dev, int idx)
if (ret)
return ERR_PTR(ret);
- of_node_put(src_args.np);
-
ret = of_parse_phandle_with_args(np, "interconnects",
"#interconnect-cells", idx * 2 + 1,
&dst_args);
if (ret)
return ERR_PTR(ret);
- of_node_put(dst_args.np);
-
src_node = of_icc_get_from_provider(&src_args);
+ of_node_put(src_args.np);
+
if (IS_ERR(src_node)) {
if (PTR_ERR(src_node) != -EPROBE_DEFER)
dev_err(dev, "error finding src node: %ld\n",
@@ -452,6 +450,8 @@ struct icc_path *of_icc_get_by_index(struct device *dev, int idx)
dst_node = of_icc_get_from_provider(&dst_args);
+ of_node_put(dst_args.np);
+
if (IS_ERR(dst_node)) {
if (PTR_ERR(dst_node) != -EPROBE_DEFER)
dev_err(dev, "error finding dst node: %ld\n",
diff --git a/drivers/interconnect/qcom/msm8916.c b/drivers/interconnect/qcom/msm8916.c
index 42c6c5581662..5017409608aa 100644
--- a/drivers/interconnect/qcom/msm8916.c
+++ b/drivers/interconnect/qcom/msm8916.c
@@ -389,7 +389,7 @@ static int msm8916_icc_set(struct icc_node *src, struct icc_node *dst)
ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE,
RPM_BUS_MASTER_REQ,
qn->mas_rpm_id,
- sum_bw);
+ src->avg_bw);
if (ret) {
pr_err("qcom_icc_rpm_smd_send mas %d error %d\n",
qn->mas_rpm_id, ret);
@@ -401,7 +401,7 @@ static int msm8916_icc_set(struct icc_node *src, struct icc_node *dst)
ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE,
RPM_BUS_SLAVE_REQ,
qn->slv_rpm_id,
- sum_bw);
+ src->avg_bw);
if (ret) {
pr_err("qcom_icc_rpm_smd_send slv error %d\n",
ret);
diff --git a/drivers/interconnect/qcom/qcs404.c b/drivers/interconnect/qcom/qcs404.c
index d4769a5ea182..9171fa134de9 100644
--- a/drivers/interconnect/qcom/qcs404.c
+++ b/drivers/interconnect/qcom/qcs404.c
@@ -356,7 +356,7 @@ static int qcom_icc_set(struct icc_node *src, struct icc_node *dst)
ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE,
RPM_BUS_MASTER_REQ,
qn->mas_rpm_id,
- sum_bw);
+ src->avg_bw);
if (ret) {
pr_err("qcom_icc_rpm_smd_send mas %d error %d\n",
qn->mas_rpm_id, ret);
@@ -368,7 +368,7 @@ static int qcom_icc_set(struct icc_node *src, struct icc_node *dst)
ret = qcom_icc_rpm_smd_send(QCOM_SMD_RPM_ACTIVE_STATE,
RPM_BUS_SLAVE_REQ,
qn->slv_rpm_id,
- sum_bw);
+ src->avg_bw);
if (ret) {
pr_err("qcom_icc_rpm_smd_send slv error %d\n",
ret);
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 138e1a2d21cc..c1f502682a19 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -1439,6 +1439,13 @@ static void qcom_fixup_class(struct pci_dev *dev)
{
dev->class = PCI_CLASS_BRIDGE_PCI << 8;
}
+
+static void qcom_fixup_nopm(struct pci_dev *dev)
+{
+ dev->pm_cap = 0;
+ dev_info(&dev->dev, "Disabling PCI power management\n");
+}
+
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0101, qcom_fixup_class);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0104, qcom_fixup_class);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0106, qcom_fixup_class);
@@ -1446,6 +1453,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0107, qcom_fixup_class);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0302, qcom_fixup_class);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x1000, qcom_fixup_class);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x1001, qcom_fixup_class);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_RENESAS, 0x0014, qcom_fixup_nopm);
static struct platform_driver qcom_pcie_driver = {
.probe = qcom_pcie_probe,
diff --git a/include/linux/interconnect-provider.h b/include/linux/interconnect-provider.h
index 0c494534b4d3..5b64e267bfb3 100644
--- a/include/linux/interconnect-provider.h
+++ b/include/linux/interconnect-provider.h
@@ -117,7 +117,7 @@ static inline struct icc_node *icc_node_create(int id)
return ERR_PTR(-ENOTSUPP);
}
-void icc_node_destroy(int id)
+static inline void icc_node_destroy(int id)
{
}
@@ -126,16 +126,16 @@ static inline int icc_link_create(struct icc_node *node, const int dst_id)
return -ENOTSUPP;
}
-int icc_link_destroy(struct icc_node *src, struct icc_node *dst)
+static inline int icc_link_destroy(struct icc_node *src, struct icc_node *dst)
{
return -ENOTSUPP;
}
-void icc_node_add(struct icc_node *node, struct icc_provider *provider)
+static inline void icc_node_add(struct icc_node *node, struct icc_provider *provider)
{
}
-void icc_node_del(struct icc_node *node)
+static inline void icc_node_del(struct icc_node *node)
{
}
diff --git a/include/linux/interconnect.h b/include/linux/interconnect.h
index 3a63d98613fc..e47028096ba8 100644
--- a/include/linux/interconnect.h
+++ b/include/linux/interconnect.h
@@ -23,6 +23,28 @@
struct icc_path;
struct device;
+/**
+ * struct icc_bulk_data - Data used for bulk icc operations.
+ *
+ * @path: reference to the path returned by icc_get()
+ * @name: the name from the "interconnect-names" DT property
+ * @avg_bw: average bandwidth in icc units
+ * @peak_bw: peak bandwidth in icc units
+ */
+struct icc_bulk_data {
+ struct icc_path *path;
+ const char *name;
+ u32 avg_bw;
+ u32 peak_bw;
+};
+
+int __must_check of_icc_bulk_get(struct device *dev, int num_paths,
+ struct icc_bulk_data *paths);
+void icc_bulk_put(int num_paths, struct icc_bulk_data *paths);
+int icc_bulk_set_bw(int num_paths, const struct icc_bulk_data *paths);
+int icc_bulk_enable(int num_paths, const struct icc_bulk_data *paths);
+void icc_bulk_disable(int num_paths, const struct icc_bulk_data *paths);
+
#if IS_ENABLED(CONFIG_INTERCONNECT)
struct icc_path *icc_get(struct device *dev, const int src_id,