summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2018-12-05 06:01:22 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2018-12-05 06:01:22 -0800
commit22b90bcbe5286095200538fc6d89980599ea7d1b (patch)
treece064ac630e05326ace2400f0084f0cc8d39c34f
parenta3eba1613d5b0ab4a281cb71576d8ddaddec558f (diff)
parente3051954fbf9b3c452496d9db80abb0db0e93499 (diff)
Merge "soc: qcom: glink: Add support to set affinities"
-rw-r--r--Documentation/devicetree/bindings/arm/msm/glink_smem_native_xprt.txt2
-rw-r--r--drivers/soc/qcom/glink.c1
-rw-r--r--drivers/soc/qcom/glink_core_if.h5
-rw-r--r--drivers/soc/qcom/glink_smem_native_xprt.c40
4 files changed, 46 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/glink_smem_native_xprt.txt b/Documentation/devicetree/bindings/arm/msm/glink_smem_native_xprt.txt
index f68c8e4a4554..7011d5cf4bf5 100644
--- a/Documentation/devicetree/bindings/arm/msm/glink_smem_native_xprt.txt
+++ b/Documentation/devicetree/bindings/arm/msm/glink_smem_native_xprt.txt
@@ -11,6 +11,7 @@ Required properties:
-label : the name of the subsystem this link connects to
Optional properties:
+-cpu-affinity: Cores to pin the interrupt and receiving work thread to.
-qcom,qos-config: Reference to the qos configuration elements.It depends on
ramp-time.
-qcom,ramp-time: Worst case time in microseconds to transition to this power
@@ -36,6 +37,7 @@ Example:
qcom,irq-mask = <0x1000>;
interrupts = <0 25 1>;
label = "lpass";
+ cpu-affinity = <1 2>;
qcom,qos-config = <&glink_qos_adsp>;
qcom,ramp-time = <0x10>,
<0x20>,
diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c
index 813c97bb4a50..af7d22e7bb23 100644
--- a/drivers/soc/qcom/glink.c
+++ b/drivers/soc/qcom/glink.c
@@ -4108,6 +4108,7 @@ int glink_core_register_transport(struct glink_transport_if *if_ptr,
kfree(xprt_ptr);
return -ENOMEM;
}
+ cfg->tx_task = xprt_ptr->tx_task;
ret = glink_core_init_xprt_qos_cfg(xprt_ptr, cfg);
if (ret < 0) {
kfree(xprt_ptr);
diff --git a/drivers/soc/qcom/glink_core_if.h b/drivers/soc/qcom/glink_core_if.h
index 14113305a50e..704171fdbf34 100644
--- a/drivers/soc/qcom/glink_core_if.h
+++ b/drivers/soc/qcom/glink_core_if.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,7 @@
#include <linux/of.h>
#include <linux/types.h>
+#include <linux/sched.h>
#include "glink_private.h"
/* Local Channel state */
@@ -105,6 +106,7 @@ struct glink_core_flow_info {
* @versions_entries: Number of entries in @versions.
* @max_cid: Maximum number of channel identifiers supported.
* @max_iid: Maximum number of intent identifiers supported.
+ * @tx_task: Task structure for tx thread.
* @mtu: MTU supported by this transport.
* @num_flows: Number of traffic flows/priority buckets.
* @flow_info: Information about each flow/priority.
@@ -117,6 +119,7 @@ struct glink_core_transport_cfg {
size_t versions_entries;
uint32_t max_cid;
uint32_t max_iid;
+ struct task_struct *tx_task;
size_t mtu;
uint32_t num_flows;
diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c
index e532f071c9ee..431fe6748990 100644
--- a/drivers/soc/qcom/glink_smem_native_xprt.c
+++ b/drivers/soc/qcom/glink_smem_native_xprt.c
@@ -33,6 +33,7 @@
#include <linux/spinlock.h>
#include <linux/srcu.h>
#include <linux/wait.h>
+#include <linux/cpumask.h>
#include <soc/qcom/smem.h>
#include <soc/qcom/tracer_pkt.h>
#include "glink_core_if.h"
@@ -2299,17 +2300,40 @@ static int subsys_name_to_id(const char *name)
return -ENODEV;
}
+static void glink_set_affinity(struct edge_info *einfo, u32 *arr, size_t size)
+{
+ struct cpumask cpumask;
+ pid_t pid;
+ int i;
+
+ cpumask_clear(&cpumask);
+ for (i = 0; i < size; i++) {
+ if (arr[i] < num_possible_cpus())
+ cpumask_set_cpu(arr[i], &cpumask);
+ }
+ if (irq_set_affinity(einfo->irq_line, &cpumask))
+ pr_err("%s: Failed to set irq affinity\n", __func__);
+
+ if (sched_setaffinity(einfo->task->pid, &cpumask))
+ pr_err("%s: Failed to set rx cpu affinity\n", __func__);
+
+ pid = einfo->xprt_cfg.tx_task->pid;
+ if (sched_setaffinity(pid, &cpumask))
+ pr_err("%s: Failed to set tx cpu affinity\n", __func__);
+}
+
static int glink_smem_native_probe(struct platform_device *pdev)
{
struct device_node *node;
struct device_node *phandle_node;
struct edge_info *einfo;
- int rc;
+ int rc, cpu_size;
char *key;
const char *subsys_name;
uint32_t irq_line;
uint32_t irq_mask;
struct resource *r;
+ u32 *cpu_array;
node = pdev->dev.of_node;
@@ -2456,6 +2480,20 @@ static int glink_smem_native_probe(struct platform_device *pdev)
pr_err("%s: enable_irq_wake() failed on %d\n", __func__,
irq_line);
+ key = "cpu-affinity";
+ cpu_size = of_property_count_u32_elems(node, key);
+ if (cpu_size > 0) {
+ cpu_array = kmalloc_array(cpu_size, sizeof(u32), GFP_KERNEL);
+ if (!cpu_array) {
+ rc = -ENOMEM;
+ goto request_irq_fail;
+ }
+ rc = of_property_read_u32_array(node, key, cpu_array, cpu_size);
+ if (!rc)
+ glink_set_affinity(einfo, cpu_array, cpu_size);
+ kfree(cpu_array);
+ }
+
register_debugfs_info(einfo);
/* fake an interrupt on this edge to see if the remote side is up */
irq_handler(0, einfo);